@spacelr/cli 0.1.3 → 0.1.5

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/index.js CHANGED
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // libs/cli/src/index.ts
27
- var import_commander13 = require("commander");
27
+ var import_commander14 = require("commander");
28
28
 
29
29
  // libs/cli/src/lib/output.ts
30
30
  var import_ora = __toESM(require("ora"));
@@ -151,23 +151,64 @@ function clearCredentials() {
151
151
  function isTokenExpired(credentials) {
152
152
  return Date.now() >= credentials.expiresAt - 6e4;
153
153
  }
154
- function resolveToken(flagToken) {
154
+ async function resolveToken(flagToken) {
155
155
  if (flagToken) return flagToken;
156
156
  if (process.env["SPACELR_TOKEN"]) return process.env["SPACELR_TOKEN"];
157
157
  const credentials = getStoredCredentials();
158
- if (credentials && !isTokenExpired(credentials)) {
159
- return credentials.accessToken;
158
+ if (!credentials) return null;
159
+ if (!isTokenExpired(credentials)) return credentials.accessToken;
160
+ if (credentials.refreshToken && credentials.apiUrl) {
161
+ const newToken = await refreshStoredToken(credentials);
162
+ if (newToken) return newToken;
160
163
  }
161
164
  return null;
162
165
  }
166
+ var REFRESH_TIMEOUT_MS = 1e4;
167
+ async function refreshStoredToken(credentials) {
168
+ const apiUrl = credentials.apiUrl.replace(/\/+$/, "");
169
+ const controller = new AbortController();
170
+ const timer = setTimeout(() => controller.abort(), REFRESH_TIMEOUT_MS);
171
+ try {
172
+ verbose("Refreshing access token...");
173
+ const response = await fetch(`${apiUrl}/auth/refresh`, {
174
+ method: "POST",
175
+ headers: { "Content-Type": "application/json" },
176
+ body: JSON.stringify({ refreshToken: credentials.refreshToken ?? "" }),
177
+ signal: controller.signal
178
+ });
179
+ if (!response.ok) {
180
+ verbose(`Token refresh failed (HTTP ${response.status})`);
181
+ return null;
182
+ }
183
+ const data = await response.json();
184
+ const newCredentials = {
185
+ accessToken: data.access_token,
186
+ refreshToken: data.refresh_token ?? credentials.refreshToken,
187
+ expiresAt: Date.now() + (data.expires_in ?? 3600) * 1e3,
188
+ apiUrl: credentials.apiUrl
189
+ };
190
+ storeCredentials(newCredentials);
191
+ verbose("Token refreshed successfully");
192
+ return data.access_token;
193
+ } catch (err) {
194
+ if (err instanceof Error && err.name === "AbortError") {
195
+ verbose("Token refresh timed out");
196
+ } else {
197
+ verbose("Token refresh error");
198
+ }
199
+ return null;
200
+ } finally {
201
+ clearTimeout(timer);
202
+ }
203
+ }
163
204
  var AuthRequiredError = class extends Error {
164
205
  constructor() {
165
206
  super('Not logged in. Run "spacelr login" to authenticate.');
166
207
  this.name = "AuthRequiredError";
167
208
  }
168
209
  };
169
- function requireAuth(flagToken) {
170
- const token = resolveToken(flagToken);
210
+ async function requireAuth(flagToken) {
211
+ const token = await resolveToken(flagToken);
171
212
  if (!token) {
172
213
  throw new AuthRequiredError();
173
214
  }
@@ -238,7 +279,7 @@ function resolveProjectId(flagValue, config) {
238
279
  return projectId;
239
280
  }
240
281
  function resolveApiUrl(flagValue, config) {
241
- return flagValue ?? config?.apiUrl ?? process.env["SPACELR_API_URL"] ?? "https://api.spacelr.io";
282
+ return flagValue ?? config?.apiUrl ?? process.env["SPACELR_API_URL"] ?? "https://api.spacelr.com/api/v1";
242
283
  }
243
284
  function loadRules(configPath) {
244
285
  const filePath = resolveSiblingPath(RULES_FILENAME, configPath);
@@ -328,8 +369,8 @@ async function startCallbackServer(expectedState) {
328
369
  return new Promise((resolveServer) => {
329
370
  let resolveCode;
330
371
  let rejectCode;
331
- const waitForCode = new Promise((resolve3, reject) => {
332
- resolveCode = resolve3;
372
+ const waitForCode = new Promise((resolve4, reject) => {
373
+ resolveCode = resolve4;
333
374
  rejectCode = reject;
334
375
  });
335
376
  const server = http.createServer((req, res) => {
@@ -451,6 +492,8 @@ var ApiClient = class {
451
492
  this.refreshing = null;
452
493
  this.apiUrl = options.apiUrl.replace(/\/+$/, "");
453
494
  this.explicitToken = options.token;
495
+ this.clientId = options.clientId ?? "spacelr-cli";
496
+ this.projectId = options.projectId;
454
497
  }
455
498
  async getToken() {
456
499
  if (this.explicitToken) return this.explicitToken;
@@ -468,38 +511,9 @@ var ApiClient = class {
468
511
  }
469
512
  async refreshAccessToken(credentials) {
470
513
  if (this.refreshing) return this.refreshing;
471
- this.refreshing = (async () => {
472
- try {
473
- verbose("Refreshing access token...");
474
- const response = await fetch(`${this.apiUrl}/auth/refresh`, {
475
- method: "POST",
476
- headers: { "Content-Type": "application/json" },
477
- body: JSON.stringify({
478
- refreshToken: credentials.refreshToken ?? ""
479
- })
480
- });
481
- if (!response.ok) {
482
- verbose("Token refresh failed");
483
- return null;
484
- }
485
- const data = await response.json();
486
- const newCredentials = {
487
- accessToken: data.access_token,
488
- refreshToken: data.refresh_token ?? credentials.refreshToken,
489
- // Admin refresh endpoint doesn't return expires_in; default to 1 hour
490
- expiresAt: Date.now() + 3600 * 1e3,
491
- apiUrl: credentials.apiUrl
492
- };
493
- storeCredentials(newCredentials);
494
- verbose("Token refreshed successfully");
495
- return data.access_token;
496
- } catch {
497
- verbose("Token refresh error");
498
- return null;
499
- } finally {
500
- this.refreshing = null;
501
- }
502
- })();
514
+ this.refreshing = refreshStoredToken(credentials).finally(() => {
515
+ this.refreshing = null;
516
+ });
503
517
  return this.refreshing;
504
518
  }
505
519
  serializeBody(body, contentType) {
@@ -509,9 +523,9 @@ var ApiClient = class {
509
523
  }
510
524
  return body;
511
525
  }
512
- async request(path6, options = {}) {
526
+ async request(path7, options = {}) {
513
527
  const { method = "GET", body, headers = {}, timeout = 3e4 } = options;
514
- const url = `${this.apiUrl}${path6}`;
528
+ const url = `${this.apiUrl}${path7}`;
515
529
  const token = await this.getToken();
516
530
  if (token) {
517
531
  headers["Authorization"] = `Bearer ${token}`;
@@ -519,6 +533,10 @@ var ApiClient = class {
519
533
  if (body && !headers["Content-Type"]) {
520
534
  headers["Content-Type"] = "application/json";
521
535
  }
536
+ headers["x-client-id"] = this.clientId;
537
+ if (this.projectId) {
538
+ headers["x-project-id"] = this.projectId;
539
+ }
522
540
  const serializedBody = this.serializeBody(body, headers["Content-Type"]);
523
541
  const controller = new AbortController();
524
542
  const timer = setTimeout(() => controller.abort(), timeout);
@@ -565,7 +583,7 @@ var ApiClient = class {
565
583
  return await response.text();
566
584
  } catch (err) {
567
585
  if (err instanceof Error && err.name === "AbortError") {
568
- throw new Error(`Request timed out: ${method} ${path6}`);
586
+ throw new Error(`Request timed out: ${method} ${path7}`);
569
587
  }
570
588
  throw err;
571
589
  } finally {
@@ -582,19 +600,22 @@ var ApiClient = class {
582
600
  }
583
601
  throw new Error(`API error (${response.status}): ${message}`);
584
602
  }
585
- async get(path6, timeout) {
586
- return this.request(path6, { timeout });
603
+ async get(path7, timeout) {
604
+ return this.request(path7, { timeout });
587
605
  }
588
- async post(path6, body, timeout) {
589
- return this.request(path6, { method: "POST", body, timeout });
606
+ async post(path7, body, timeout) {
607
+ return this.request(path7, { method: "POST", body, timeout });
590
608
  }
591
- async put(path6, body, timeout) {
592
- return this.request(path6, { method: "PUT", body, timeout });
609
+ async put(path7, body, timeout) {
610
+ return this.request(path7, { method: "PUT", body, timeout });
593
611
  }
594
- async delete(path6, timeout) {
595
- return this.request(path6, { method: "DELETE", timeout });
612
+ async patch(path7, body, timeout) {
613
+ return this.request(path7, { method: "PATCH", body, timeout });
596
614
  }
597
- async uploadFile(path6, fileBuffer, filename) {
615
+ async delete(path7, timeout) {
616
+ return this.request(path7, { method: "DELETE", timeout });
617
+ }
618
+ async uploadFile(path7, fileBuffer, filename) {
598
619
  const boundary = `----spacelr${Date.now()}`;
599
620
  const parts = [];
600
621
  const header = Buffer.from(
@@ -609,7 +630,7 @@ Content-Type: application/zip\r
609
630
  `);
610
631
  parts.push(header, fileBuffer, footer);
611
632
  const body = Buffer.concat(parts);
612
- return this.request(path6, {
633
+ return this.request(path7, {
613
634
  method: "POST",
614
635
  body,
615
636
  headers: {
@@ -628,7 +649,7 @@ function createWhoamiCommand() {
628
649
  const config = loadConfig();
629
650
  const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
630
651
  try {
631
- const token = requireAuth(globalOpts.token);
652
+ const token = await requireAuth(globalOpts.token);
632
653
  const client = new ApiClient({ apiUrl, token });
633
654
  const response = await client.get("/auth/me");
634
655
  const user = response.user;
@@ -654,7 +675,7 @@ function createProjectsCommand() {
654
675
  const config = loadConfig();
655
676
  const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
656
677
  try {
657
- const token = requireAuth(globalOpts.token);
678
+ const token = await requireAuth(globalOpts.token);
658
679
  const client = new ApiClient({ apiUrl, token });
659
680
  const spin = spinner("Fetching projects...");
660
681
  const result = await client.get("/projects");
@@ -710,7 +731,7 @@ ${message}
710
731
  console.error(` ${i + 1}) ${choice.label}`);
711
732
  });
712
733
  console.error();
713
- return new Promise((resolve3, reject) => {
734
+ return new Promise((resolve4, reject) => {
714
735
  rl.question(" Enter number: ", (answer) => {
715
736
  rl.close();
716
737
  const index = parseInt(answer, 10) - 1;
@@ -718,7 +739,7 @@ ${message}
718
739
  reject(new Error("Invalid selection"));
719
740
  return;
720
741
  }
721
- resolve3(choices[index]);
742
+ resolve4(choices[index]);
722
743
  });
723
744
  });
724
745
  }
@@ -727,10 +748,10 @@ async function promptConfirm(message) {
727
748
  input: process.stdin,
728
749
  output: process.stderr
729
750
  });
730
- return new Promise((resolve3) => {
751
+ return new Promise((resolve4) => {
731
752
  rl.question(`${message} (y/N) `, (answer) => {
732
753
  rl.close();
733
- resolve3(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
754
+ resolve4(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
734
755
  });
735
756
  });
736
757
  }
@@ -740,10 +761,10 @@ async function promptInput(message, defaultValue) {
740
761
  output: process.stderr
741
762
  });
742
763
  const suffix = defaultValue ? ` (${defaultValue})` : "";
743
- return new Promise((resolve3) => {
764
+ return new Promise((resolve4) => {
744
765
  rl.question(`${message}${suffix}: `, (answer) => {
745
766
  rl.close();
746
- resolve3(answer.trim() || defaultValue || "");
767
+ resolve4(answer.trim() || defaultValue || "");
747
768
  });
748
769
  });
749
770
  }
@@ -755,7 +776,7 @@ function createUseCommand() {
755
776
  const config = loadConfig();
756
777
  const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
757
778
  try {
758
- const token = requireAuth(globalOpts.token);
779
+ const token = await requireAuth(globalOpts.token);
759
780
  const client = new ApiClient({ apiUrl, token });
760
781
  const spin = spinner("Fetching projects...");
761
782
  const projects = await fetchProjects(client);
@@ -819,7 +840,7 @@ function createInitCommand() {
819
840
  }
820
841
  const apiUrl = resolveApiUrl(globalOpts.apiUrl, existingConfig);
821
842
  try {
822
- const token = requireAuth(globalOpts.token);
843
+ const token = await requireAuth(globalOpts.token);
823
844
  const client = new ApiClient({ apiUrl, token });
824
845
  const spin = spinner("Fetching projects...");
825
846
  const projects = await fetchProjects(client);
@@ -842,7 +863,7 @@ function createInitCommand() {
842
863
  );
843
864
  const config = {
844
865
  projectId: selected.id,
845
- apiUrl: apiUrl !== "https://api.spacelr.io" ? apiUrl : void 0,
866
+ apiUrl: apiUrl !== "https://api.spacelr.com/api/v1" ? apiUrl : void 0,
846
867
  hosting: {
847
868
  directory: hostingDir
848
869
  }
@@ -883,11 +904,11 @@ async function createZipBuffer(directory) {
883
904
  if (!fs4.statSync(absDir).isDirectory()) {
884
905
  throw new Error(`Not a directory: ${absDir}`);
885
906
  }
886
- return new Promise((resolve3, reject) => {
907
+ return new Promise((resolve4, reject) => {
887
908
  const chunks = [];
888
909
  const archive = (0, import_archiver.default)("zip", { zlib: { level: 9 } });
889
910
  archive.on("data", (chunk) => chunks.push(chunk));
890
- archive.on("end", () => resolve3(Buffer.concat(chunks)));
911
+ archive.on("end", () => resolve4(Buffer.concat(chunks)));
891
912
  archive.on("error", reject);
892
913
  archive.directory(absDir, false);
893
914
  archive.finalize();
@@ -917,11 +938,11 @@ function createDeployCommand() {
917
938
  const config = loadConfig();
918
939
  const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
919
940
  try {
920
- const token = requireAuth(globalOpts.token);
941
+ const token = await requireAuth(globalOpts.token);
921
942
  const projectId = resolveProjectId(opts.project, config);
922
943
  const deployDir = directory ?? config?.hosting?.directory ?? ".";
923
944
  const absDir = path5.resolve(deployDir);
924
- const client = new ApiClient({ apiUrl, token });
945
+ const client = new ApiClient({ apiUrl, token, projectId });
925
946
  await deploy(client, projectId, absDir, {
926
947
  description: opts.description,
927
948
  wait: opts.wait !== false,
@@ -953,9 +974,8 @@ async function deploy(client, projectId, directory, options) {
953
974
  }
954
975
  spin.text = "Creating deployment...";
955
976
  const deployment = await client.post(
956
- "/hosting/deployments",
977
+ `/hosting/${projectId}/deployments`,
957
978
  {
958
- projectId,
959
979
  description: options.description
960
980
  }
961
981
  );
@@ -1017,7 +1037,7 @@ async function pollDeploymentStatus(client, projectId, deploymentId, spin) {
1017
1037
  throw new Error("Deployment timed out after 10 minutes");
1018
1038
  }
1019
1039
  function sleep(ms) {
1020
- return new Promise((resolve3) => setTimeout(resolve3, ms));
1040
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
1021
1041
  }
1022
1042
 
1023
1043
  // libs/cli/src/commands/db/index.ts
@@ -1031,7 +1051,7 @@ function createIndexesDeployCommand() {
1031
1051
  const config = loadConfig(opts.config);
1032
1052
  const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
1033
1053
  try {
1034
- const token = requireAuth(globalOpts.token);
1054
+ const token = await requireAuth(globalOpts.token);
1035
1055
  const projectId = resolveProjectId(opts.project, config);
1036
1056
  const indexes = loadIndexes(opts.config);
1037
1057
  if (!indexes || Object.keys(indexes).length === 0) {
@@ -1055,7 +1075,7 @@ function createIndexesDeployCommand() {
1055
1075
  }
1056
1076
  }
1057
1077
  const spin = spinner("Deploying indexes...");
1058
- const client = new ApiClient({ apiUrl, token });
1078
+ const client = new ApiClient({ apiUrl, token, projectId });
1059
1079
  const result = await client.put(
1060
1080
  `/databases/${projectId}/index-rules`,
1061
1081
  { indexRules }
@@ -1099,12 +1119,15 @@ function createIndexesPullCommand() {
1099
1119
  const config = loadConfig(opts.config);
1100
1120
  const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
1101
1121
  try {
1102
- const token = requireAuth(globalOpts.token);
1122
+ const token = await requireAuth(globalOpts.token);
1103
1123
  const projectId = resolveProjectId(opts.project, config);
1104
1124
  const spin = spinner("Pulling indexes...");
1105
- const client = new ApiClient({ apiUrl, token });
1106
- const result = await client.get(`/databases/${projectId}/index-rules`);
1107
- const indexes = convertFromRemoteFormat(result.indexRules);
1125
+ const client = new ApiClient({ apiUrl, token, projectId });
1126
+ const response = await client.get(
1127
+ `/databases/${projectId}/index-rules`
1128
+ );
1129
+ const remoteIndexes = response && "indexRules" in response ? response["indexRules"] : response ?? {};
1130
+ const indexes = convertFromRemoteFormat(remoteIndexes);
1108
1131
  saveIndexes(indexes, opts.config);
1109
1132
  if (opts.project && opts.project !== config?.projectId) {
1110
1133
  saveConfig({ ...config, projectId: opts.project }, opts.config);
@@ -1158,7 +1181,7 @@ function createRulesDeployCommand() {
1158
1181
  const config = loadConfig(opts.config);
1159
1182
  const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
1160
1183
  try {
1161
- const token = requireAuth(globalOpts.token);
1184
+ const token = await requireAuth(globalOpts.token);
1162
1185
  const projectId = resolveProjectId(opts.project, config);
1163
1186
  const rules = loadRules(opts.config);
1164
1187
  if (!rules || Object.keys(rules).length === 0) {
@@ -1175,7 +1198,7 @@ function createRulesDeployCommand() {
1175
1198
  }
1176
1199
  }
1177
1200
  const spin = spinner("Validating rules...");
1178
- const client = new ApiClient({ apiUrl, token });
1201
+ const client = new ApiClient({ apiUrl, token, projectId });
1179
1202
  await client.post(
1180
1203
  `/databases/${projectId}/rules/validate`,
1181
1204
  { rules }
@@ -1206,10 +1229,10 @@ function createRulesPullCommand() {
1206
1229
  const config = loadConfig(opts.config);
1207
1230
  const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
1208
1231
  try {
1209
- const token = requireAuth(globalOpts.token);
1232
+ const token = await requireAuth(globalOpts.token);
1210
1233
  const projectId = resolveProjectId(opts.project, config);
1211
1234
  const spin = spinner("Pulling rules...");
1212
- const client = new ApiClient({ apiUrl, token });
1235
+ const client = new ApiClient({ apiUrl, token, projectId });
1213
1236
  const result = await client.get(
1214
1237
  `/databases/${projectId}/rules`
1215
1238
  );
@@ -1247,8 +1270,266 @@ function createDbCommand() {
1247
1270
  return db;
1248
1271
  }
1249
1272
 
1273
+ // libs/cli/src/commands/functions.ts
1274
+ var path6 = __toESM(require("path"));
1275
+ var import_commander13 = require("commander");
1276
+ function createFunctionsCommand() {
1277
+ const functions = new import_commander13.Command("functions").description("Manage serverless functions");
1278
+ functions.command("deploy [directory]").description("Deploy a function").requiredOption("--name <name>", "Function name").option("--entry <file>", "Entry point (default: index.js)").option("--cron <expression>", "Cron schedule expression").option("--timezone <tz>", "Timezone for cron (default: UTC)").option("--timeout <ms>", "Execution timeout in ms").option("--memory <mb>", "Memory limit in MB").option("--env <KEY=VALUE...>", "Environment variables", collectEnvVars, {}).option("--project <id>", "Project ID").action(async (directory, opts, cmd) => {
1279
+ const globalOpts = cmd.optsWithGlobals();
1280
+ const config = loadConfig();
1281
+ const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
1282
+ try {
1283
+ const token = await requireAuth(globalOpts.token);
1284
+ const projectId = resolveProjectId(opts.project, config);
1285
+ const deployDir = directory ?? ".";
1286
+ const absDir = path6.resolve(deployDir);
1287
+ const client = new ApiClient({ apiUrl, token, projectId });
1288
+ const spin = spinner("Preparing deployment...");
1289
+ const fileCount = countFiles(absDir);
1290
+ verbose(`Found ${fileCount} files in ${absDir}`);
1291
+ spin.text = "Creating archive...";
1292
+ const zipBuffer = await createZipBuffer(absDir);
1293
+ verbose(`Archive size: ${formatBytes(zipBuffer.length)}`);
1294
+ spin.text = "Checking for existing function...";
1295
+ const envVars = opts.env;
1296
+ const existingFns = await client.get(`/projects/${projectId}/functions`);
1297
+ const fnList = Array.isArray(existingFns) ? existingFns : existingFns.data || [];
1298
+ const existing = fnList.find(
1299
+ (f) => f.name === opts.name
1300
+ );
1301
+ let functionId;
1302
+ const functionBody = {
1303
+ entryPoint: opts.entry,
1304
+ cronExpression: opts.cron,
1305
+ cronTimezone: opts.timezone,
1306
+ timeout: opts.timeout ? parseInt(opts.timeout, 10) : void 0,
1307
+ memoryLimitMb: opts.memory ? parseInt(opts.memory, 10) : void 0,
1308
+ environmentVariables: Object.keys(envVars).length > 0 ? envVars : void 0
1309
+ };
1310
+ if (existing) {
1311
+ spin.text = "Updating function...";
1312
+ await client.patch(
1313
+ `/projects/${projectId}/functions/${existing.id}`,
1314
+ functionBody
1315
+ );
1316
+ functionId = existing.id;
1317
+ } else {
1318
+ spin.text = "Creating function...";
1319
+ const createResult = await client.post(
1320
+ `/projects/${projectId}/functions`,
1321
+ { name: opts.name, ...functionBody }
1322
+ );
1323
+ const createdId = createResult.id || createResult.data?.id;
1324
+ if (!createdId) {
1325
+ throw new Error("Failed to create function");
1326
+ }
1327
+ functionId = createdId;
1328
+ }
1329
+ spin.text = "Uploading code...";
1330
+ await client.uploadFile(
1331
+ `/projects/${projectId}/functions/${functionId}/deploy`,
1332
+ zipBuffer,
1333
+ "code.zip"
1334
+ );
1335
+ spin.succeed(
1336
+ `Function "${opts.name}" deployed (${formatBytes(zipBuffer.length)}, ${fileCount} files)`
1337
+ );
1338
+ if (opts.cron) {
1339
+ info(`Cron schedule: ${opts.cron}`);
1340
+ }
1341
+ } catch (err) {
1342
+ error(err instanceof Error ? err.message : "Deploy failed");
1343
+ process.exitCode = 1;
1344
+ }
1345
+ });
1346
+ functions.command("list").description("List functions").option("--project <id>", "Project ID").action(async (opts, cmd) => {
1347
+ const globalOpts = cmd.optsWithGlobals();
1348
+ const config = loadConfig();
1349
+ const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
1350
+ try {
1351
+ const token = await requireAuth(globalOpts.token);
1352
+ const projectId = resolveProjectId(opts.project, config);
1353
+ const client = new ApiClient({ apiUrl, token, projectId });
1354
+ const result = await client.get(
1355
+ `/projects/${projectId}/functions`
1356
+ );
1357
+ const fns = Array.isArray(result) ? result : result.data || [];
1358
+ if (isJsonMode()) {
1359
+ json(fns);
1360
+ return;
1361
+ }
1362
+ if (fns.length === 0) {
1363
+ info("No functions found");
1364
+ return;
1365
+ }
1366
+ for (const fn of fns) {
1367
+ const status = fn.enabled ? "enabled" : "disabled";
1368
+ const cron = fn.cronExpression ? ` [${fn.cronExpression}]` : "";
1369
+ info(`${fn.name} (${fn.id}) - ${status}${cron}`);
1370
+ }
1371
+ } catch (err) {
1372
+ error(err instanceof Error ? err.message : "Failed to list functions");
1373
+ process.exitCode = 1;
1374
+ }
1375
+ });
1376
+ functions.command("delete <name>").description("Delete a function").option("--project <id>", "Project ID").action(async (name, opts, cmd) => {
1377
+ const globalOpts = cmd.optsWithGlobals();
1378
+ const config = loadConfig();
1379
+ const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
1380
+ try {
1381
+ const token = await requireAuth(globalOpts.token);
1382
+ const projectId = resolveProjectId(opts.project, config);
1383
+ const client = new ApiClient({ apiUrl, token, projectId });
1384
+ const fn = await findFunctionByName(client, projectId, name);
1385
+ await client.delete(
1386
+ `/projects/${projectId}/functions/${fn.id}`
1387
+ );
1388
+ info(`Function "${name}" deleted`);
1389
+ } catch (err) {
1390
+ error(err instanceof Error ? err.message : "Failed to delete function");
1391
+ process.exitCode = 1;
1392
+ }
1393
+ });
1394
+ functions.command("trigger <name>").description("Trigger a function execution").option("--project <id>", "Project ID").action(async (name, opts, cmd) => {
1395
+ const globalOpts = cmd.optsWithGlobals();
1396
+ const config = loadConfig();
1397
+ const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
1398
+ try {
1399
+ const token = await requireAuth(globalOpts.token);
1400
+ const projectId = resolveProjectId(opts.project, config);
1401
+ const client = new ApiClient({ apiUrl, token, projectId });
1402
+ const fn = await findFunctionByName(client, projectId, name);
1403
+ const spin = spinner("Triggering function...");
1404
+ await client.post(
1405
+ `/projects/${projectId}/functions/${fn.id}/trigger`
1406
+ );
1407
+ spin.succeed(`Function "${name}" triggered`);
1408
+ } catch (err) {
1409
+ error(err instanceof Error ? err.message : "Failed to trigger function");
1410
+ process.exitCode = 1;
1411
+ }
1412
+ });
1413
+ functions.command("logs <name>").description("View function execution logs").option("--limit <n>", "Number of executions to show", "10").option("--project <id>", "Project ID").action(async (name, opts, cmd) => {
1414
+ const globalOpts = cmd.optsWithGlobals();
1415
+ const config = loadConfig();
1416
+ const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
1417
+ try {
1418
+ const token = await requireAuth(globalOpts.token);
1419
+ const projectId = resolveProjectId(opts.project, config);
1420
+ const client = new ApiClient({ apiUrl, token, projectId });
1421
+ const fn = await findFunctionByName(client, projectId, name);
1422
+ const limit = parseInt(opts.limit, 10);
1423
+ const result = await client.get(
1424
+ `/projects/${projectId}/functions/${fn.id}/executions?limit=${limit}`
1425
+ );
1426
+ const executions = result.items || result.data?.items || [];
1427
+ if (isJsonMode()) {
1428
+ json(executions);
1429
+ return;
1430
+ }
1431
+ if (executions.length === 0) {
1432
+ info("No executions found");
1433
+ return;
1434
+ }
1435
+ for (const exec of executions) {
1436
+ const date = new Date(exec.startedAt).toLocaleString();
1437
+ const duration = exec.duration ? `${exec.duration}ms` : "-";
1438
+ info(
1439
+ `[${exec.status}] ${date} (${duration}) - ${exec.triggeredBy}${exec.error ? ` - ${exec.error}` : ""}`
1440
+ );
1441
+ if (exec.logs && exec.logs.length > 0) {
1442
+ for (const log of exec.logs) {
1443
+ const logTime = new Date(log.timestamp).toLocaleTimeString();
1444
+ info(` ${logTime} [${log.level}] ${log.message}`);
1445
+ }
1446
+ }
1447
+ }
1448
+ } catch (err) {
1449
+ error(err instanceof Error ? err.message : "Failed to get logs");
1450
+ process.exitCode = 1;
1451
+ }
1452
+ });
1453
+ const envCmd = functions.command("env").description("Manage function environment variables");
1454
+ envCmd.command("set <name> <keyValue>").description("Set an environment variable (KEY=VALUE)").option("--project <id>", "Project ID").action(async (name, keyValue, opts, cmd) => {
1455
+ const globalOpts = cmd.optsWithGlobals();
1456
+ const config = loadConfig();
1457
+ const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
1458
+ try {
1459
+ const token = await requireAuth(globalOpts.token);
1460
+ const projectId = resolveProjectId(opts.project, config);
1461
+ const client = new ApiClient({ apiUrl, token, projectId });
1462
+ const eqIndex = keyValue.indexOf("=");
1463
+ if (eqIndex === -1) {
1464
+ throw new Error("Format must be KEY=VALUE");
1465
+ }
1466
+ const key = keyValue.substring(0, eqIndex);
1467
+ const value = keyValue.substring(eqIndex + 1);
1468
+ const fn = await findFunctionByName(client, projectId, name);
1469
+ const currentVars = fn.environmentVariables || {};
1470
+ const updatedVars = { ...currentVars, [key]: value };
1471
+ await client.patch(
1472
+ `/projects/${projectId}/functions/${fn.id}`,
1473
+ { environmentVariables: updatedVars }
1474
+ );
1475
+ info(`Set ${key} for function "${name}"`);
1476
+ } catch (err) {
1477
+ error(err instanceof Error ? err.message : "Failed to set env var");
1478
+ process.exitCode = 1;
1479
+ }
1480
+ });
1481
+ envCmd.command("list <name>").description("List environment variables for a function").option("--project <id>", "Project ID").action(async (name, opts, cmd) => {
1482
+ const globalOpts = cmd.optsWithGlobals();
1483
+ const config = loadConfig();
1484
+ const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);
1485
+ try {
1486
+ const token = await requireAuth(globalOpts.token);
1487
+ const projectId = resolveProjectId(opts.project, config);
1488
+ const client = new ApiClient({ apiUrl, token, projectId });
1489
+ const fn = await findFunctionByName(client, projectId, name);
1490
+ const vars = fn.environmentVariables || {};
1491
+ const keys = Object.keys(vars);
1492
+ if (isJsonMode()) {
1493
+ json(vars);
1494
+ return;
1495
+ }
1496
+ if (keys.length === 0) {
1497
+ info("No environment variables set");
1498
+ return;
1499
+ }
1500
+ for (const key of keys) {
1501
+ info(`${key}=${vars[key]}`);
1502
+ }
1503
+ } catch (err) {
1504
+ error(
1505
+ err instanceof Error ? err.message : "Failed to list env vars"
1506
+ );
1507
+ process.exitCode = 1;
1508
+ }
1509
+ });
1510
+ return functions;
1511
+ }
1512
+ async function findFunctionByName(client, projectId, name) {
1513
+ const result = await client.get(
1514
+ `/projects/${projectId}/functions`
1515
+ );
1516
+ const fnList = Array.isArray(result) ? result : result.data || [];
1517
+ const fn = fnList.find((f) => f.name === name);
1518
+ if (!fn) {
1519
+ throw new Error(`Function "${name}" not found`);
1520
+ }
1521
+ return fn;
1522
+ }
1523
+ function collectEnvVars(value, previous) {
1524
+ const eqIndex = value.indexOf("=");
1525
+ if (eqIndex === -1) return previous;
1526
+ const key = value.substring(0, eqIndex);
1527
+ const val = value.substring(eqIndex + 1);
1528
+ return { ...previous, [key]: val };
1529
+ }
1530
+
1250
1531
  // libs/cli/src/index.ts
1251
- var program = new import_commander13.Command();
1532
+ var program = new import_commander14.Command();
1252
1533
  program.name("spacelr").description("CLI tool for the Spacelr platform").version("0.1.0").option("--api-url <url>", "Override API URL").option("--token <token>", "Explicit auth token (CI mode)").option("--json", "Output as JSON").option("--verbose", "Verbose logging").hook("preAction", (thisCommand) => {
1253
1534
  const opts = thisCommand.optsWithGlobals();
1254
1535
  setOutputMode({
@@ -1264,5 +1545,6 @@ program.addCommand(createUseCommand());
1264
1545
  program.addCommand(createInitCommand());
1265
1546
  program.addCommand(createDeployCommand());
1266
1547
  program.addCommand(createDbCommand());
1548
+ program.addCommand(createFunctionsCommand());
1267
1549
  program.parse();
1268
1550
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../libs/cli/src/index.ts","../../../../libs/cli/src/lib/output.ts","../../../../libs/cli/src/commands/login.ts","../../../../libs/cli/src/lib/auth.ts","../../../../libs/cli/src/lib/config.ts","../../../../libs/cli/src/commands/logout.ts","../../../../libs/cli/src/commands/whoami.ts","../../../../libs/cli/src/lib/api-client.ts","../../../../libs/cli/src/commands/projects.ts","../../../../libs/cli/src/commands/use.ts","../../../../libs/cli/src/lib/prompt.ts","../../../../libs/cli/src/commands/init.ts","../../../../libs/cli/src/commands/deploy.ts","../../../../libs/cli/src/lib/zip.ts","../../../../libs/cli/src/commands/db/index.ts","../../../../libs/cli/src/commands/db/indexes-deploy.ts","../../../../libs/cli/src/commands/db/indexes-pull.ts","../../../../libs/cli/src/commands/db/rules-deploy.ts","../../../../libs/cli/src/commands/db/rules-pull.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { setOutputMode } from './lib/output';\nimport { createLoginCommand } from './commands/login';\nimport { createLogoutCommand } from './commands/logout';\nimport { createWhoamiCommand } from './commands/whoami';\nimport { createProjectsCommand } from './commands/projects';\nimport { createUseCommand } from './commands/use';\nimport { createInitCommand } from './commands/init';\nimport { createDeployCommand } from './commands/deploy';\nimport { createDbCommand } from './commands/db';\n\nconst program = new Command();\n\nprogram\n .name('spacelr')\n .description('CLI tool for the Spacelr platform')\n .version('0.1.0')\n .option('--api-url <url>', 'Override API URL')\n .option('--token <token>', 'Explicit auth token (CI mode)')\n .option('--json', 'Output as JSON')\n .option('--verbose', 'Verbose logging')\n .hook('preAction', (thisCommand) => {\n const opts = thisCommand.optsWithGlobals();\n setOutputMode({\n json: opts['json'] as boolean | undefined,\n verbose: opts['verbose'] as boolean | undefined,\n });\n });\n\nprogram.addCommand(createLoginCommand());\nprogram.addCommand(createLogoutCommand());\nprogram.addCommand(createWhoamiCommand());\nprogram.addCommand(createProjectsCommand());\nprogram.addCommand(createUseCommand());\nprogram.addCommand(createInitCommand());\nprogram.addCommand(createDeployCommand());\nprogram.addCommand(createDbCommand());\n\nprogram.parse();\n","import ora, { type Ora } from 'ora';\nimport pc from 'picocolors';\n\nlet jsonMode = false;\nlet verboseMode = false;\n\nexport function setOutputMode(options: {\n json?: boolean;\n verbose?: boolean;\n}): void {\n jsonMode = options.json ?? false;\n verboseMode = options.verbose ?? false;\n}\n\nexport function isJsonMode(): boolean {\n return jsonMode;\n}\n\nexport function success(message: string): void {\n if (!jsonMode) {\n console.log(pc.green(`\\u2713 ${message}`));\n }\n}\n\nexport function error(message: string): void {\n if (!jsonMode) {\n console.error(pc.red(`\\u2717 ${message}`));\n }\n}\n\nexport function warn(message: string): void {\n if (!jsonMode) {\n console.warn(pc.yellow(`! ${message}`));\n }\n}\n\nexport function info(message: string): void {\n if (!jsonMode) {\n console.log(pc.cyan(`\\u2139 ${message}`));\n }\n}\n\nexport function verbose(message: string): void {\n if (verboseMode && !jsonMode) {\n console.log(pc.dim(` ${message}`));\n }\n}\n\nexport function json(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n}\n\nexport function table(\n headers: string[],\n rows: string[][],\n): void {\n if (jsonMode) return;\n\n const colWidths = headers.map((h, i) => {\n const maxRow = rows.reduce(\n (max, row) => Math.max(max, (row[i] ?? '').length),\n 0,\n );\n return Math.max(h.length, maxRow);\n });\n\n const headerLine = headers\n .map((h, i) => pc.bold(h.padEnd(colWidths[i] ?? 0)))\n .join(' ');\n const separator = colWidths.map((w) => '-'.repeat(w)).join(' ');\n\n console.log(headerLine);\n console.log(separator);\n for (const row of rows) {\n console.log(\n row.map((cell, i) => cell.padEnd(colWidths[i] ?? 0)).join(' '),\n );\n }\n}\n\nexport function spinner(text: string): Ora {\n if (jsonMode) {\n return ora({ text, isSilent: true });\n }\n return ora(text).start();\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n const units = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(1024));\n const value = bytes / Math.pow(1024, i);\n return `${value.toFixed(i === 0 ? 0 : 1)} ${units[i]}`;\n}\n","import * as http from 'node:http';\nimport * as crypto from 'node:crypto';\nimport { Command } from 'commander';\nimport open from 'open';\nimport { generatePKCE, storeCredentials } from '../lib/auth';\nimport { resolveApiUrl, loadConfig } from '../lib/config';\nimport { success, error, info, spinner, json, isJsonMode } from '../lib/output';\nimport type { GlobalOptions, TokenResponse, StoredCredentials } from '../lib/types';\n\nconst CLI_CLIENT_ID = 'spacelr-cli';\n\nexport function createLoginCommand(): Command {\n return new Command('login')\n .description('Authenticate with Spacelr via browser')\n .option('--auth-url <url>', 'OAuth server URL (defaults to --api-url)')\n .action(async (opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n const authUrl = (opts.authUrl as string | undefined) ?? apiUrl;\n\n try {\n const credentials = await performLogin(authUrl, apiUrl);\n storeCredentials(credentials);\n\n if (isJsonMode()) {\n json({ success: true, expiresAt: credentials.expiresAt });\n } else {\n success('Logged in successfully');\n info(`Credentials stored in ~/.spacelr/credentials.json`);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Login failed');\n process.exitCode = 1;\n }\n });\n}\n\nasync function performLogin(authUrl: string, apiUrl: string): Promise<StoredCredentials> {\n const { codeVerifier, codeChallenge } = generatePKCE();\n const state = crypto.randomBytes(16).toString('base64url');\n\n // Start local HTTP server on a random port\n const { port, waitForCode, close } = await startCallbackServer(state);\n\n const authorizeUrl = buildAuthorizeUrl(authUrl, port, codeChallenge, state);\n\n info(`Opening browser for authentication...`);\n info(`If the browser doesn't open, visit: ${authorizeUrl}`);\n\n await open(authorizeUrl);\n\n const spin = spinner('Waiting for authentication...');\n\n try {\n const code = await waitForCode;\n spin.text = 'Exchanging authorization code...';\n\n const tokenResponse = await exchangeCode(\n authUrl,\n code,\n codeVerifier,\n port,\n );\n\n spin.succeed('Authentication complete');\n\n return {\n accessToken: tokenResponse.access_token,\n refreshToken: tokenResponse.refresh_token,\n expiresAt: Date.now() + tokenResponse.expires_in * 1000,\n apiUrl,\n };\n } catch (err) {\n spin.fail('Authentication failed');\n throw err;\n } finally {\n close();\n }\n}\n\nfunction buildAuthorizeUrl(\n apiUrl: string,\n port: number,\n codeChallenge: string,\n state: string,\n): string {\n const params = new URLSearchParams({\n client_id: CLI_CLIENT_ID,\n redirect_uri: `http://127.0.0.1:${port}/callback`,\n response_type: 'code',\n code_challenge: codeChallenge,\n code_challenge_method: 'S256',\n scope: 'openid profile email',\n state,\n });\n return `${apiUrl}/auth/authorize?${params.toString()}`;\n}\n\nasync function startCallbackServer(expectedState: string): Promise<{\n port: number;\n waitForCode: Promise<string>;\n close: () => void;\n}> {\n return new Promise((resolveServer) => {\n let resolveCode: (code: string) => void;\n let rejectCode: (err: Error) => void;\n\n const waitForCode = new Promise<string>((resolve, reject) => {\n resolveCode = resolve;\n rejectCode = reject;\n });\n\n const server = http.createServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://127.0.0.1`);\n\n if (url.pathname === '/callback') {\n const code = url.searchParams.get('code');\n const errorParam = url.searchParams.get('error');\n const returnedState = url.searchParams.get('state');\n\n if (errorParam) {\n const description =\n url.searchParams.get('error_description') ?? errorParam;\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(errorPage(description));\n rejectCode(new Error(`OAuth error: ${description}`));\n return;\n }\n\n // CSRF protection: verify state matches\n if (returnedState !== expectedState) {\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(errorPage('Invalid state parameter (possible CSRF attack)'));\n rejectCode(new Error('OAuth state mismatch'));\n return;\n }\n\n if (!code) {\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(errorPage('No authorization code received'));\n rejectCode(new Error('No authorization code received'));\n return;\n }\n\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(successPage());\n resolveCode(code);\n } else {\n res.writeHead(404);\n res.end();\n }\n });\n\n // Timeout after 5 minutes\n const timeout = setTimeout(() => {\n rejectCode(new Error('Login timed out after 5 minutes'));\n server.close();\n }, 5 * 60 * 1000);\n\n server.listen(0, '127.0.0.1', () => {\n const address = server.address();\n const port =\n typeof address === 'object' && address ? address.port : 0;\n\n resolveServer({\n port,\n waitForCode,\n close: () => {\n clearTimeout(timeout);\n server.close();\n },\n });\n });\n });\n}\n\nasync function exchangeCode(\n apiUrl: string,\n code: string,\n codeVerifier: string,\n port: number,\n): Promise<TokenResponse> {\n const response = await fetch(`${apiUrl}/auth/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n code_verifier: codeVerifier,\n client_id: CLI_CLIENT_ID,\n redirect_uri: `http://127.0.0.1:${port}/callback`,\n }),\n });\n\n if (!response.ok) {\n let message: string;\n try {\n const body = (await response.json()) as { message?: string; error?: string };\n message = body.message ?? body.error ?? response.statusText;\n } catch {\n message = response.statusText;\n }\n throw new Error(`Token exchange failed: ${message}`);\n }\n\n return (await response.json()) as TokenResponse;\n}\n\nfunction successPage(): string {\n return `<!DOCTYPE html>\n<html><head><title>Spacelr CLI</title>\n<style>body{font-family:system-ui,sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#f8f9fa;}\n.box{text-align:center;padding:2rem;}.check{font-size:3rem;color:#22c55e;}</style></head>\n<body><div class=\"box\"><div class=\"check\">&#10003;</div><h1>Authenticated</h1><p>You can close this window and return to the terminal.</p></div></body></html>`;\n}\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nfunction errorPage(message: string): string {\n return `<!DOCTYPE html>\n<html><head><title>Spacelr CLI</title>\n<style>body{font-family:system-ui,sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#f8f9fa;}\n.box{text-align:center;padding:2rem;}.x{font-size:3rem;color:#ef4444;}</style></head>\n<body><div class=\"box\"><div class=\"x\">&#10007;</div><h1>Authentication Failed</h1><p>${escapeHtml(message)}</p></div></body></html>`;\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as crypto from 'node:crypto';\nimport type { StoredCredentials, PKCEChallenge } from './types';\n\nfunction getCredentialsDir(): string {\n return path.join(\n process.env['HOME'] ?? process.env['USERPROFILE'] ?? '~',\n '.spacelr',\n );\n}\n\nfunction getCredentialsFile(): string {\n return path.join(getCredentialsDir(), 'credentials.json');\n}\n\nexport function getStoredCredentials(): StoredCredentials | null {\n try {\n const file = getCredentialsFile();\n if (!fs.existsSync(file)) return null;\n const content = fs.readFileSync(file, 'utf-8');\n return JSON.parse(content) as StoredCredentials;\n } catch {\n return null;\n }\n}\n\nexport function storeCredentials(credentials: StoredCredentials): void {\n const dir = getCredentialsDir();\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n fs.writeFileSync(\n getCredentialsFile(),\n JSON.stringify(credentials, null, 2),\n { mode: 0o600 },\n );\n}\n\nexport function clearCredentials(): void {\n try {\n const file = getCredentialsFile();\n if (fs.existsSync(file)) {\n fs.unlinkSync(file);\n }\n } catch {\n // Ignore errors during cleanup\n }\n}\n\nexport function isTokenExpired(credentials: StoredCredentials): boolean {\n // Add 60 second buffer\n return Date.now() >= credentials.expiresAt - 60_000;\n}\n\nexport function resolveToken(flagToken?: string): string | null {\n if (flagToken) return flagToken;\n if (process.env['SPACELR_TOKEN']) return process.env['SPACELR_TOKEN'];\n const credentials = getStoredCredentials();\n if (credentials && !isTokenExpired(credentials)) {\n return credentials.accessToken;\n }\n return null;\n}\n\nexport class AuthRequiredError extends Error {\n constructor() {\n super('Not logged in. Run \"spacelr login\" to authenticate.');\n this.name = 'AuthRequiredError';\n }\n}\n\n/**\n * Resolves a token or throws AuthRequiredError.\n * Use in commands that require authentication.\n */\nexport function requireAuth(flagToken?: string): string {\n const token = resolveToken(flagToken);\n if (!token) {\n throw new AuthRequiredError();\n }\n return token;\n}\n\nexport function generatePKCE(): PKCEChallenge {\n const codeVerifier = crypto.randomBytes(32).toString('base64url');\n const codeChallenge = crypto\n .createHash('sha256')\n .update(codeVerifier)\n .digest('base64url');\n return { codeVerifier, codeChallenge };\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { SpacelrConfig, DatabaseRules, DatabaseIndexes } from './types';\n\nconst CONFIG_FILENAME = 'spacelr.json';\nexport const RULES_FILENAME = 'spacelr.rules.json';\nexport const INDEXES_FILENAME = 'spacelr.indexes.json';\n\nfunction readJsonFile<T>(filePath: string, label: string): T {\n const content = fs.readFileSync(filePath, 'utf-8');\n try {\n return JSON.parse(content) as T;\n } catch (err) {\n const detail = err instanceof Error ? `: ${err.message}` : '';\n throw new Error(\n `Invalid JSON in ${label}: ${filePath}${detail}\\nPlease check the file for syntax errors.`,\n );\n }\n}\n\nfunction writeJsonFile(filePath: string, data: unknown): void {\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\\n', 'utf-8');\n}\n\nfunction resolveSiblingPath(filename: string, configPath?: string): string {\n const resolved = configPath ?? findConfigPath();\n const dir = resolved ? path.dirname(resolved) : process.cwd();\n return path.join(dir, filename);\n}\n\nexport function findConfigPath(startDir?: string): string | null {\n let dir = startDir ?? process.cwd();\n\n while (true) {\n const candidate = path.join(dir, CONFIG_FILENAME);\n if (fs.existsSync(candidate)) {\n return candidate;\n }\n const parent = path.dirname(dir);\n if (parent === dir) {\n return null;\n }\n dir = parent;\n }\n}\n\nexport function loadConfig(configPath?: string): SpacelrConfig | null {\n const resolved = configPath ?? findConfigPath();\n if (!resolved || !fs.existsSync(resolved)) return null;\n return readJsonFile<SpacelrConfig>(resolved, 'config file');\n}\n\nexport function saveConfig(\n config: SpacelrConfig,\n configPath?: string,\n): void {\n const resolved = configPath ?? findConfigPath() ?? path.join(process.cwd(), CONFIG_FILENAME);\n writeJsonFile(resolved, config);\n}\n\nexport function resolveProjectId(\n flagValue?: string,\n config?: SpacelrConfig | null,\n): string {\n const projectId = flagValue ?? config?.projectId;\n if (!projectId) {\n throw new Error(\n 'Project ID is required. Provide --project <id> or set \"projectId\" in spacelr.json',\n );\n }\n return projectId;\n}\n\nexport function resolveApiUrl(\n flagValue?: string,\n config?: SpacelrConfig | null,\n): string {\n return (\n flagValue ??\n config?.apiUrl ??\n process.env['SPACELR_API_URL'] ??\n 'https://api.spacelr.io'\n );\n}\n\nexport function loadRules(configPath?: string): DatabaseRules | null {\n const filePath = resolveSiblingPath(RULES_FILENAME, configPath);\n if (!fs.existsSync(filePath)) return null;\n return readJsonFile<DatabaseRules>(filePath, 'rules file');\n}\n\nexport function saveRules(rules: DatabaseRules, configPath?: string): void {\n writeJsonFile(resolveSiblingPath(RULES_FILENAME, configPath), rules);\n}\n\nexport function loadIndexes(configPath?: string): DatabaseIndexes | null {\n const filePath = resolveSiblingPath(INDEXES_FILENAME, configPath);\n if (!fs.existsSync(filePath)) return null;\n return readJsonFile<DatabaseIndexes>(filePath, 'indexes file');\n}\n\nexport function saveIndexes(indexes: DatabaseIndexes, configPath?: string): void {\n writeJsonFile(resolveSiblingPath(INDEXES_FILENAME, configPath), indexes);\n}\n","import { Command } from 'commander';\nimport { clearCredentials, getStoredCredentials } from '../lib/auth';\nimport { success, warn, json, isJsonMode } from '../lib/output';\nimport type { GlobalOptions } from '../lib/types';\n\nexport function createLogoutCommand(): Command {\n return new Command('logout')\n .description('Clear stored credentials')\n .action(async (_opts, cmd: Command) => {\n cmd.optsWithGlobals<GlobalOptions>();\n\n const existing = getStoredCredentials();\n clearCredentials();\n\n if (isJsonMode()) {\n json({ success: true, hadCredentials: !!existing });\n } else if (existing) {\n success('Logged out successfully');\n } else {\n warn('No credentials found');\n }\n });\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../lib/api-client';\nimport { resolveApiUrl, loadConfig } from '../lib/config';\nimport { requireAuth } from '../lib/auth';\nimport { success, error, info, json, isJsonMode } from '../lib/output';\nimport type { GlobalOptions, UserInfo } from '../lib/types';\n\nexport function createWhoamiCommand(): Command {\n return new Command('whoami')\n .description('Show current authenticated user')\n .action(async (_opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = requireAuth(globalOpts.token);\n const client = new ApiClient({ apiUrl, token });\n const response = await client.get<{ user: UserInfo }>('/auth/me');\n const user = response.user;\n\n if (isJsonMode()) {\n json(user);\n } else {\n success(`Logged in as ${user.email ?? user.username ?? user.id}`);\n if (user.displayName) info(`Name: ${user.displayName}`);\n if (user.roles?.length) info(`Roles: ${user.roles.join(', ')}`);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to get user info');\n process.exitCode = 1;\n }\n });\n}\n","import {\n getStoredCredentials,\n storeCredentials,\n isTokenExpired,\n} from './auth';\nimport { verbose } from './output';\nimport type { StoredCredentials } from './types';\n\ninterface ApiClientOptions {\n apiUrl: string;\n token?: string;\n}\n\ninterface RequestOptions {\n method?: string;\n body?: BodyInit | Record<string, unknown>;\n headers?: Record<string, string>;\n timeout?: number;\n}\n\nexport class ApiClient {\n private readonly apiUrl: string;\n private explicitToken?: string;\n private refreshing: Promise<string | null> | null = null;\n\n constructor(options: ApiClientOptions) {\n this.apiUrl = options.apiUrl.replace(/\\/+$/, '');\n this.explicitToken = options.token;\n }\n\n private async getToken(): Promise<string | null> {\n if (this.explicitToken) return this.explicitToken;\n\n const envToken = process.env['SPACELR_TOKEN'];\n if (envToken) return envToken;\n\n const credentials = getStoredCredentials();\n if (!credentials) return null;\n\n if (!isTokenExpired(credentials)) {\n return credentials.accessToken;\n }\n\n // Token expired, try refreshing\n if (credentials.refreshToken) {\n return this.refreshAccessToken(credentials);\n }\n\n return null;\n }\n\n private async refreshAccessToken(\n credentials: StoredCredentials,\n ): Promise<string | null> {\n // Deduplicate concurrent refreshes\n if (this.refreshing) return this.refreshing;\n\n this.refreshing = (async () => {\n try {\n verbose('Refreshing access token...');\n const response = await fetch(`${this.apiUrl}/auth/refresh`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n refreshToken: credentials.refreshToken ?? '',\n }),\n });\n\n if (!response.ok) {\n verbose('Token refresh failed');\n return null;\n }\n\n const data = (await response.json()) as { access_token: string; refresh_token?: string };\n const newCredentials: StoredCredentials = {\n accessToken: data.access_token,\n refreshToken: data.refresh_token ?? credentials.refreshToken,\n // Admin refresh endpoint doesn't return expires_in; default to 1 hour\n expiresAt: Date.now() + 3600 * 1000,\n apiUrl: credentials.apiUrl,\n };\n storeCredentials(newCredentials);\n verbose('Token refreshed successfully');\n return data.access_token;\n } catch {\n verbose('Token refresh error');\n return null;\n } finally {\n this.refreshing = null;\n }\n })();\n\n return this.refreshing;\n }\n\n private serializeBody(\n body: RequestOptions['body'],\n contentType: string | undefined,\n ): BodyInit | undefined {\n if (!body) return undefined;\n if (contentType === 'application/json') {\n return JSON.stringify(body);\n }\n // Buffer, string, URLSearchParams, etc. are already valid BodyInit\n return body as BodyInit;\n }\n\n private async request<T>(\n path: string,\n options: RequestOptions = {},\n ): Promise<T> {\n const { method = 'GET', body, headers = {}, timeout = 30_000 } = options;\n const url = `${this.apiUrl}${path}`;\n\n const token = await this.getToken();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n if (body && !headers['Content-Type']) {\n headers['Content-Type'] = 'application/json';\n }\n\n const serializedBody = this.serializeBody(body, headers['Content-Type']);\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n\n verbose(`${method} ${url}`);\n\n try {\n const response = await fetch(url, {\n method,\n headers,\n body: serializedBody,\n signal: controller.signal,\n });\n\n if (response.status === 401 && !this.explicitToken) {\n // Try refresh once\n const credentials = getStoredCredentials();\n if (credentials?.refreshToken) {\n const newToken = await this.refreshAccessToken(credentials);\n if (newToken) {\n headers['Authorization'] = `Bearer ${newToken}`;\n const retryController = new AbortController();\n const retryTimer = setTimeout(() => retryController.abort(), timeout);\n const retryResponse = await fetch(url, {\n method,\n headers,\n body: serializedBody,\n signal: retryController.signal,\n });\n clearTimeout(retryTimer);\n if (!retryResponse.ok) {\n await this.throwApiError(retryResponse);\n }\n return (await retryResponse.json()) as T;\n }\n }\n throw new Error(\n 'Authentication required. Run \"spacelr login\" to authenticate.',\n );\n }\n\n if (!response.ok) {\n await this.throwApiError(response);\n }\n\n const contentType = response.headers.get('content-type');\n if (contentType?.includes('application/json')) {\n return (await response.json()) as T;\n }\n return (await response.text()) as unknown as T;\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n throw new Error(`Request timed out: ${method} ${path}`);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async throwApiError(response: Response): Promise<never> {\n let message: string;\n try {\n const body = (await response.json()) as { message?: string; error?: string };\n message = body.message ?? body.error ?? response.statusText;\n } catch {\n message = response.statusText;\n }\n throw new Error(`API error (${response.status}): ${message}`);\n }\n\n async get<T>(path: string, timeout?: number): Promise<T> {\n return this.request<T>(path, { timeout });\n }\n\n async post<T>(path: string, body?: Record<string, unknown> | BodyInit, timeout?: number): Promise<T> {\n return this.request<T>(path, { method: 'POST', body, timeout });\n }\n\n async put<T>(path: string, body?: Record<string, unknown> | BodyInit, timeout?: number): Promise<T> {\n return this.request<T>(path, { method: 'PUT', body, timeout });\n }\n\n async delete<T>(path: string, timeout?: number): Promise<T> {\n return this.request<T>(path, { method: 'DELETE', timeout });\n }\n\n async uploadFile(\n path: string,\n fileBuffer: Buffer,\n filename: string,\n ): Promise<DeploymentUploadResponse> {\n const boundary = `----spacelr${Date.now()}`;\n const parts: Buffer[] = [];\n\n // Build multipart body manually (no form-data dependency needed)\n const header = Buffer.from(\n `--${boundary}\\r\\n` +\n `Content-Disposition: form-data; name=\"file\"; filename=\"${filename}\"\\r\\n` +\n `Content-Type: application/zip\\r\\n\\r\\n`,\n );\n const footer = Buffer.from(`\\r\\n--${boundary}--\\r\\n`);\n parts.push(header, fileBuffer, footer);\n const body = Buffer.concat(parts);\n\n return this.request<DeploymentUploadResponse>(path, {\n method: 'POST',\n body,\n headers: {\n 'Content-Type': `multipart/form-data; boundary=${boundary}`,\n },\n timeout: 300_000, // 5 minutes for uploads\n });\n }\n}\n\ninterface DeploymentUploadResponse {\n deploymentId: string;\n status: string;\n fileCount: number;\n totalSizeBytes: number;\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../lib/api-client';\nimport { resolveApiUrl, loadConfig } from '../lib/config';\nimport { requireAuth } from '../lib/auth';\nimport { error, spinner, json, isJsonMode, table, info } from '../lib/output';\nimport type { GlobalOptions, ProjectInfo } from '../lib/types';\n\nexport function createProjectsCommand(): Command {\n return new Command('projects')\n .description('List your projects')\n .action(async (_opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = requireAuth(globalOpts.token);\n const client = new ApiClient({ apiUrl, token });\n const spin = spinner('Fetching projects...');\n const result = await client.get<{ projects: ProjectInfo[] }>('/projects');\n spin.stop();\n\n const projects = result.projects;\n\n if (projects.length === 0) {\n info('No projects found');\n return;\n }\n\n const activeProjectId = config?.projectId;\n\n if (isJsonMode()) {\n json(projects);\n } else {\n table(\n ['', 'ID', 'Name', 'Slug'],\n projects.map((p) => [\n p.id === activeProjectId ? '*' : ' ',\n p.id,\n p.name,\n p.slug,\n ]),\n );\n if (activeProjectId) {\n info(`\\n* = active project (from spacelr.json)`);\n }\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to list projects');\n process.exitCode = 1;\n }\n });\n}\n\nexport async function fetchProjects(\n client: ApiClient,\n): Promise<ProjectInfo[]> {\n const result = await client.get<{ projects: ProjectInfo[] }>('/projects');\n return result.projects;\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../lib/api-client';\nimport { resolveApiUrl, loadConfig, saveConfig } from '../lib/config';\nimport { requireAuth } from '../lib/auth';\nimport { success, error, spinner, json, isJsonMode, info } from '../lib/output';\nimport { promptChoice } from '../lib/prompt';\nimport { fetchProjects } from './projects';\nimport type { GlobalOptions, ProjectInfo } from '../lib/types';\n\nexport function createUseCommand(): Command {\n return new Command('use')\n .description('Set the active project')\n .argument('[project]', 'Project ID or slug')\n .action(async (project: string | undefined, _opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = requireAuth(globalOpts.token);\n const client = new ApiClient({ apiUrl, token });\n const spin = spinner('Fetching projects...');\n const projects = await fetchProjects(client);\n spin.stop();\n\n if (projects.length === 0) {\n error('No projects found. Create a project first.');\n process.exitCode = 1;\n return;\n }\n\n let selected: ProjectInfo;\n\n if (project) {\n // Find by ID or slug\n const match = projects.find(\n (p) => p.id === project || p.slug === project,\n );\n if (!match) {\n error(`Project \"${project}\" not found`);\n info('Available projects:');\n for (const p of projects) {\n info(` ${p.slug} (${p.id})`);\n }\n process.exitCode = 1;\n return;\n }\n selected = match;\n } else {\n // Interactive selection\n selected = await promptChoice(\n 'Select a project:',\n projects.map((p) => ({\n ...p,\n label: `${p.name} (${p.slug})`,\n })),\n );\n }\n\n // Update config\n const updatedConfig = { ...config, projectId: selected.id };\n saveConfig(updatedConfig);\n\n if (isJsonMode()) {\n json({ projectId: selected.id, name: selected.name, slug: selected.slug });\n } else {\n success(`Now using project \"${selected.name}\" (${selected.slug})`);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to select project');\n process.exitCode = 1;\n }\n });\n}\n","import * as readline from 'node:readline';\n\nexport async function promptChoice<T extends { label: string }>(\n message: string,\n choices: T[],\n): Promise<T> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n\n console.error(`\\n${message}\\n`);\n choices.forEach((choice, i) => {\n console.error(` ${i + 1}) ${choice.label}`);\n });\n console.error();\n\n return new Promise((resolve, reject) => {\n rl.question(' Enter number: ', (answer) => {\n rl.close();\n const index = parseInt(answer, 10) - 1;\n if (isNaN(index) || index < 0 || index >= choices.length) {\n reject(new Error('Invalid selection'));\n return;\n }\n resolve(choices[index]);\n });\n });\n}\n\nexport async function promptConfirm(message: string): Promise<boolean> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n\n return new Promise((resolve) => {\n rl.question(`${message} (y/N) `, (answer) => {\n rl.close();\n resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');\n });\n });\n}\n\nexport async function promptInput(message: string, defaultValue?: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n\n const suffix = defaultValue ? ` (${defaultValue})` : '';\n\n return new Promise((resolve) => {\n rl.question(`${message}${suffix}: `, (answer) => {\n rl.close();\n resolve(answer.trim() || defaultValue || '');\n });\n });\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { Command } from 'commander';\nimport { ApiClient } from '../lib/api-client';\nimport { resolveApiUrl, loadConfig, saveConfig } from '../lib/config';\nimport { requireAuth } from '../lib/auth';\nimport { success, error, warn, spinner, json, isJsonMode, info } from '../lib/output';\nimport { promptChoice, promptInput } from '../lib/prompt';\nimport { fetchProjects } from './projects';\nimport type { GlobalOptions, SpacelrConfig } from '../lib/types';\n\nexport function createInitCommand(): Command {\n return new Command('init')\n .description('Initialize a spacelr.json config in the current directory')\n .action(async (_opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const existingConfig = loadConfig();\n\n const configPath = path.join(process.cwd(), 'spacelr.json');\n if (fs.existsSync(configPath)) {\n warn(`spacelr.json already exists in ${process.cwd()}`);\n info('Use \"spacelr use\" to change the active project');\n return;\n }\n\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, existingConfig);\n\n try {\n const token = requireAuth(globalOpts.token);\n const client = new ApiClient({ apiUrl, token });\n const spin = spinner('Fetching projects...');\n const projects = await fetchProjects(client);\n spin.stop();\n\n if (projects.length === 0) {\n error('No projects found. Create a project in the admin panel first.');\n process.exitCode = 1;\n return;\n }\n\n // Select project\n const selected = await promptChoice(\n 'Select a project:',\n projects.map((p) => ({\n ...p,\n label: `${p.name} (${p.slug})`,\n })),\n );\n\n // Ask for hosting directory\n const hostingDir = await promptInput(\n 'Hosting directory',\n './dist',\n );\n\n const config: SpacelrConfig = {\n projectId: selected.id,\n apiUrl: apiUrl !== 'https://api.spacelr.io' ? apiUrl : undefined,\n hosting: {\n directory: hostingDir,\n },\n };\n\n saveConfig(config, configPath);\n\n if (isJsonMode()) {\n json(config);\n } else {\n success(`Created spacelr.json for \"${selected.name}\"`);\n info(`Project: ${selected.slug} (${selected.id})`);\n info(`Hosting directory: ${hostingDir}`);\n info('');\n info('Next steps:');\n info(' spacelr deploy Deploy your site');\n info(' spacelr db indexes pull Pull database indexes');\n info(' spacelr db rules pull Pull database rules');\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Initialization failed');\n process.exitCode = 1;\n }\n });\n}\n","import * as path from 'node:path';\nimport { Command } from 'commander';\nimport { ApiClient } from '../lib/api-client';\nimport {\n resolveApiUrl,\n resolveProjectId,\n loadConfig,\n} from '../lib/config';\nimport { requireAuth } from '../lib/auth';\nimport { createZipBuffer, countFiles } from '../lib/zip';\nimport {\n error,\n info,\n spinner,\n json,\n isJsonMode,\n formatBytes,\n verbose,\n} from '../lib/output';\nimport type {\n GlobalOptions,\n DeploymentResponse,\n} from '../lib/types';\n\nexport function createDeployCommand(): Command {\n return new Command('deploy')\n .description('Deploy a directory to Spacelr hosting')\n .argument('[directory]', 'Directory to deploy')\n .option('--project <id>', 'Project ID')\n .option('--description <text>', 'Deployment description')\n .option('--no-wait', 'Do not wait for processing to complete')\n .option('--dry-run', 'Show what would be deployed without uploading')\n .action(async (directory: string | undefined, opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n const deployDir = directory ?? config?.hosting?.directory ?? '.';\n const absDir = path.resolve(deployDir);\n\n const client = new ApiClient({ apiUrl, token });\n await deploy(client, projectId, absDir, {\n description: opts.description,\n wait: opts.wait !== false,\n dryRun: opts.dryRun === true,\n });\n } catch (err) {\n error(err instanceof Error ? err.message : 'Deployment failed');\n process.exitCode = 1;\n }\n });\n}\n\ninterface DeployOptions {\n description?: string;\n wait: boolean;\n dryRun: boolean;\n}\n\nasync function deploy(\n client: ApiClient,\n projectId: string,\n directory: string,\n options: DeployOptions,\n): Promise<void> {\n // Step 1: Count files and create ZIP\n const spin = spinner('Preparing deployment...');\n\n const fileCount = countFiles(directory);\n verbose(`Found ${fileCount} files in ${directory}`);\n\n spin.text = 'Creating archive...';\n const zipBuffer = await createZipBuffer(directory);\n verbose(`Archive size: ${formatBytes(zipBuffer.length)}`);\n\n if (options.dryRun) {\n spin.succeed('Dry run complete');\n if (isJsonMode()) {\n json({ dryRun: true, fileCount, archiveSize: zipBuffer.length, directory });\n } else {\n info(`Directory: ${directory}`);\n info(`Files: ${fileCount}`);\n info(`Archive size: ${formatBytes(zipBuffer.length)}`);\n }\n return;\n }\n\n // Step 2: Create deployment\n spin.text = 'Creating deployment...';\n const deployment = await client.post<DeploymentResponse>(\n '/hosting/deployments',\n {\n projectId,\n description: options.description,\n },\n );\n verbose(`Deployment ID: ${deployment.deploymentId}`);\n\n // Step 3: Upload ZIP\n spin.text = `Uploading ${formatBytes(zipBuffer.length)}...`;\n await client.uploadFile(\n `/hosting/${projectId}/deployments/${deployment.deploymentId}/upload`,\n zipBuffer,\n 'deployment.zip',\n );\n\n if (!options.wait) {\n spin.succeed('Upload complete');\n info(`Deployment ${deployment.deploymentId} is processing`);\n if (isJsonMode()) {\n json({ deploymentId: deployment.deploymentId, status: 'processing' });\n }\n return;\n }\n\n // Step 4: Poll for status\n spin.text = 'Processing deployment...';\n const result = await pollDeploymentStatus(\n client,\n projectId,\n deployment.deploymentId,\n spin,\n );\n\n if (result.status === 'active') {\n spin.succeed('Deployment active');\n if (isJsonMode()) {\n json(result);\n } else {\n info(`Deployment ID: ${result.deploymentId}`);\n info(`Files: ${result.fileCount}`);\n info(`Size: ${formatBytes(result.totalSizeBytes)}`);\n }\n } else if (result.status === 'failed') {\n spin.fail('Deployment failed');\n error(result.errorMessage ?? 'Unknown error');\n process.exitCode = 1;\n } else {\n spin.warn(`Deployment status: ${result.status}`);\n if (isJsonMode()) {\n json(result);\n }\n }\n}\n\nasync function pollDeploymentStatus(\n client: ApiClient,\n projectId: string,\n deploymentId: string,\n spin: { text: string },\n): Promise<DeploymentResponse> {\n const maxAttempts = 120; // 10 minutes (5s intervals)\n for (let i = 0; i < maxAttempts; i++) {\n await sleep(5000);\n const status = await client.get<DeploymentResponse>(\n `/hosting/${projectId}/deployments/${deploymentId}/status`,\n );\n\n verbose(`Poll ${i + 1}: status=${status.status}`);\n spin.text = `Processing deployment... (${status.status})`;\n\n if (\n status.status === 'active' ||\n status.status === 'failed'\n ) {\n return status;\n }\n }\n\n throw new Error('Deployment timed out after 10 minutes');\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport archiver from 'archiver';\n\nexport async function createZipBuffer(directory: string): Promise<Buffer> {\n const absDir = path.resolve(directory);\n if (!fs.existsSync(absDir)) {\n throw new Error(`Directory not found: ${absDir}`);\n }\n if (!fs.statSync(absDir).isDirectory()) {\n throw new Error(`Not a directory: ${absDir}`);\n }\n\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n const archive = archiver('zip', { zlib: { level: 9 } });\n\n archive.on('data', (chunk: Buffer) => chunks.push(chunk));\n archive.on('end', () => resolve(Buffer.concat(chunks)));\n archive.on('error', reject);\n\n archive.directory(absDir, false);\n archive.finalize();\n });\n}\n\nexport function countFiles(directory: string): number {\n const absDir = path.resolve(directory);\n let count = 0;\n\n function walk(dir: string): void {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isFile()) {\n count++;\n } else if (entry.isDirectory()) {\n walk(path.join(dir, entry.name));\n }\n }\n }\n\n walk(absDir);\n return count;\n}\n","import { Command } from 'commander';\nimport { createIndexesDeployCommand } from './indexes-deploy';\nimport { createIndexesPullCommand } from './indexes-pull';\nimport { createRulesDeployCommand } from './rules-deploy';\nimport { createRulesPullCommand } from './rules-pull';\n\nexport function createDbCommand(): Command {\n const indexes = new Command('indexes')\n .description('Manage database indexes');\n\n indexes.addCommand(createIndexesDeployCommand());\n indexes.addCommand(createIndexesPullCommand());\n\n const rules = new Command('rules')\n .description('Manage database rules');\n\n rules.addCommand(createRulesDeployCommand());\n rules.addCommand(createRulesPullCommand());\n\n const db = new Command('db')\n .description('Database management commands');\n\n db.addCommand(indexes);\n db.addCommand(rules);\n\n return db;\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../../lib/api-client';\nimport {\n resolveApiUrl,\n resolveProjectId,\n loadConfig,\n loadIndexes,\n} from '../../lib/config';\nimport { requireAuth } from '../../lib/auth';\nimport { success, error, info, spinner, json, isJsonMode, warn } from '../../lib/output';\nimport { promptConfirm } from '../../lib/prompt';\nimport type { GlobalOptions, IndexRuleEntry, RemoteIndexEntry } from '../../lib/types';\n\nexport function createIndexesDeployCommand(): Command {\n return new Command('deploy')\n .description('Deploy indexes from spacelr.indexes.json to remote')\n .option('--project <id>', 'Project ID')\n .option('--config <path>', 'Config file path')\n .option('--yes', 'Skip confirmation')\n .action(async (opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig(opts.config);\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n const indexes = loadIndexes(opts.config);\n\n if (!indexes || Object.keys(indexes).length === 0) {\n warn('No indexes found in spacelr.indexes.json');\n return;\n }\n\n // Convert index format: config uses 1/-1, API expects asc/desc\n const indexRules = convertIndexFormat(indexes);\n\n const collectionCount = Object.keys(indexRules).length;\n const totalIndexes = Object.values(indexRules).reduce(\n (sum, arr) => sum + arr.length,\n 0,\n );\n\n if (!opts.yes) {\n info(\n `Will deploy ${totalIndexes} index(es) across ${collectionCount} collection(s)`,\n );\n const confirmed = await promptConfirm('Proceed with deployment?');\n if (!confirmed) {\n info('Aborted');\n return;\n }\n }\n\n const spin = spinner('Deploying indexes...');\n const client = new ApiClient({ apiUrl, token });\n const result = await client.put<{ message: string }>(\n `/databases/${projectId}/index-rules`,\n { indexRules },\n );\n\n spin.succeed('Indexes deployed');\n\n if (isJsonMode()) {\n json(result);\n } else {\n success(result.message ?? 'Indexes synced successfully');\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to deploy indexes');\n process.exitCode = 1;\n }\n });\n}\n\nfunction convertIndexFormat(\n indexes: Record<string, IndexRuleEntry[]>,\n): Record<string, RemoteIndexEntry[]> {\n const result: Record<string, RemoteIndexEntry[]> = {};\n\n for (const [collection, entries] of Object.entries(indexes)) {\n result[collection] = entries.map((entry) => {\n const fields: Record<string, 'asc' | 'desc'> = {};\n for (const [field, direction] of Object.entries(entry.fields)) {\n fields[field] = direction === 1 ? 'asc' : 'desc';\n }\n return {\n fields,\n ...(entry.unique !== undefined && { unique: entry.unique }),\n ...(entry.sparse !== undefined && { sparse: entry.sparse }),\n ...(entry.ttlSeconds !== undefined && { ttlSeconds: entry.ttlSeconds }),\n };\n });\n }\n\n return result;\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../../lib/api-client';\nimport {\n resolveApiUrl,\n resolveProjectId,\n loadConfig,\n saveConfig,\n saveIndexes,\n} from '../../lib/config';\nimport { requireAuth } from '../../lib/auth';\nimport { success, error, spinner, json, isJsonMode, info } from '../../lib/output';\nimport type { GlobalOptions, IndexRuleEntry, RemoteIndexEntry } from '../../lib/types';\n\nexport function createIndexesPullCommand(): Command {\n return new Command('pull')\n .description('Pull current indexes from remote to spacelr.indexes.json')\n .option('--project <id>', 'Project ID')\n .option('--config <path>', 'Config file path')\n .action(async (opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig(opts.config);\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n\n const spin = spinner('Pulling indexes...');\n const client = new ApiClient({ apiUrl, token });\n const result = await client.get<{\n indexRules: Record<string, RemoteIndexEntry[]>;\n }>(`/databases/${projectId}/index-rules`);\n\n // Convert from API format (asc/desc) to config format (1/-1)\n const indexes = convertFromRemoteFormat(result.indexRules);\n\n saveIndexes(indexes, opts.config);\n\n if (opts.project && opts.project !== config?.projectId) {\n saveConfig({ ...config, projectId: opts.project }, opts.config);\n }\n\n spin.succeed('Indexes pulled');\n\n const collectionCount = Object.keys(indexes).length;\n const totalIndexes = Object.values(indexes).reduce(\n (sum, arr) => sum + arr.length,\n 0,\n );\n\n if (isJsonMode()) {\n json(indexes);\n } else {\n success(\n `Pulled ${totalIndexes} index(es) from ${collectionCount} collection(s)`,\n );\n info('Indexes file updated');\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to pull indexes');\n process.exitCode = 1;\n }\n });\n}\n\nfunction convertFromRemoteFormat(\n remoteIndexes: Record<string, RemoteIndexEntry[]>,\n): Record<string, IndexRuleEntry[]> {\n const result: Record<string, IndexRuleEntry[]> = {};\n\n for (const [collection, entries] of Object.entries(remoteIndexes)) {\n result[collection] = entries.map((entry) => {\n const fields: Record<string, 1 | -1> = {};\n for (const [field, direction] of Object.entries(entry.fields)) {\n fields[field] = direction === 'asc' ? 1 : -1;\n }\n return {\n fields,\n ...(entry.unique !== undefined && { unique: entry.unique }),\n ...(entry.sparse !== undefined && { sparse: entry.sparse }),\n ...(entry.ttlSeconds !== undefined && {\n ttlSeconds: entry.ttlSeconds,\n }),\n };\n });\n }\n\n return result;\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../../lib/api-client';\nimport {\n resolveApiUrl,\n resolveProjectId,\n loadConfig,\n loadRules,\n} from '../../lib/config';\nimport { requireAuth } from '../../lib/auth';\nimport { success, error, info, spinner, json, isJsonMode, warn } from '../../lib/output';\nimport { promptConfirm } from '../../lib/prompt';\nimport type { GlobalOptions } from '../../lib/types';\n\nexport function createRulesDeployCommand(): Command {\n return new Command('deploy')\n .description('Deploy rules from spacelr.rules.json to remote')\n .option('--project <id>', 'Project ID')\n .option('--config <path>', 'Config file path')\n .option('--yes', 'Skip confirmation')\n .action(async (opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig(opts.config);\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n const rules = loadRules(opts.config);\n\n if (!rules || Object.keys(rules).length === 0) {\n warn('No rules found in spacelr.rules.json');\n return;\n }\n\n const ruleCount = Object.keys(rules).length;\n\n if (!opts.yes) {\n info(`Will deploy rules for ${ruleCount} collection(s)`);\n const confirmed = await promptConfirm('Proceed with deployment?');\n if (!confirmed) {\n info('Aborted');\n return;\n }\n }\n\n // Validate first\n const spin = spinner('Validating rules...');\n const client = new ApiClient({ apiUrl, token });\n\n await client.post<{ valid: boolean }>(\n `/databases/${projectId}/rules/validate`,\n { rules },\n );\n\n // Deploy\n spin.text = 'Deploying rules...';\n const result = await client.put<{ message: string }>(\n `/databases/${projectId}/rules`,\n { rules },\n );\n\n spin.succeed('Rules deployed');\n\n if (isJsonMode()) {\n json(result);\n } else {\n success(result.message ?? 'Rules deployed successfully');\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to deploy rules');\n process.exitCode = 1;\n }\n });\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../../lib/api-client';\nimport {\n resolveApiUrl,\n resolveProjectId,\n loadConfig,\n saveConfig,\n saveRules,\n} from '../../lib/config';\nimport { requireAuth } from '../../lib/auth';\nimport { success, error, spinner, json, isJsonMode, info } from '../../lib/output';\nimport type { GlobalOptions } from '../../lib/types';\n\nexport function createRulesPullCommand(): Command {\n return new Command('pull')\n .description('Pull current rules from remote to spacelr.rules.json')\n .option('--project <id>', 'Project ID')\n .option('--config <path>', 'Config file path')\n .action(async (opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig(opts.config);\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n\n const spin = spinner('Pulling rules...');\n const client = new ApiClient({ apiUrl, token });\n const result = await client.get<{ rules: Record<string, unknown> }>(\n `/databases/${projectId}/rules`,\n );\n\n const rules = result.rules;\n\n saveRules(rules, opts.config);\n\n if (opts.project && opts.project !== config?.projectId) {\n saveConfig({ ...config, projectId: opts.project }, opts.config);\n }\n\n spin.succeed('Rules pulled');\n\n const ruleCount = Object.keys(rules).length;\n\n if (isJsonMode()) {\n json(rules);\n } else {\n success(`Pulled rules for ${ruleCount} collection(s)`);\n info('Rules file updated');\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to pull rules');\n process.exitCode = 1;\n }\n });\n}\n"],"mappings":"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","names":["import_commander","pc","ora","crypto","fs","path","open","resolve","import_commander","import_commander","path","import_commander","import_commander","resolve","fs","path","import_commander","path","import_commander","fs","path","resolve","archiver","resolve","import_commander","import_commander","import_commander","import_commander","import_commander"]}
1
+ {"version":3,"sources":["../../../../libs/cli/src/index.ts","../../../../libs/cli/src/lib/output.ts","../../../../libs/cli/src/commands/login.ts","../../../../libs/cli/src/lib/auth.ts","../../../../libs/cli/src/lib/config.ts","../../../../libs/cli/src/commands/logout.ts","../../../../libs/cli/src/commands/whoami.ts","../../../../libs/cli/src/lib/api-client.ts","../../../../libs/cli/src/commands/projects.ts","../../../../libs/cli/src/commands/use.ts","../../../../libs/cli/src/lib/prompt.ts","../../../../libs/cli/src/commands/init.ts","../../../../libs/cli/src/commands/deploy.ts","../../../../libs/cli/src/lib/zip.ts","../../../../libs/cli/src/commands/db/index.ts","../../../../libs/cli/src/commands/db/indexes-deploy.ts","../../../../libs/cli/src/commands/db/indexes-pull.ts","../../../../libs/cli/src/commands/db/rules-deploy.ts","../../../../libs/cli/src/commands/db/rules-pull.ts","../../../../libs/cli/src/commands/functions.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { setOutputMode } from './lib/output';\nimport { createLoginCommand } from './commands/login';\nimport { createLogoutCommand } from './commands/logout';\nimport { createWhoamiCommand } from './commands/whoami';\nimport { createProjectsCommand } from './commands/projects';\nimport { createUseCommand } from './commands/use';\nimport { createInitCommand } from './commands/init';\nimport { createDeployCommand } from './commands/deploy';\nimport { createDbCommand } from './commands/db';\nimport { createFunctionsCommand } from './commands/functions';\n\nconst program = new Command();\n\nprogram\n .name('spacelr')\n .description('CLI tool for the Spacelr platform')\n .version('0.1.0')\n .option('--api-url <url>', 'Override API URL')\n .option('--token <token>', 'Explicit auth token (CI mode)')\n .option('--json', 'Output as JSON')\n .option('--verbose', 'Verbose logging')\n .hook('preAction', (thisCommand) => {\n const opts = thisCommand.optsWithGlobals();\n setOutputMode({\n json: opts['json'] as boolean | undefined,\n verbose: opts['verbose'] as boolean | undefined,\n });\n });\n\nprogram.addCommand(createLoginCommand());\nprogram.addCommand(createLogoutCommand());\nprogram.addCommand(createWhoamiCommand());\nprogram.addCommand(createProjectsCommand());\nprogram.addCommand(createUseCommand());\nprogram.addCommand(createInitCommand());\nprogram.addCommand(createDeployCommand());\nprogram.addCommand(createDbCommand());\nprogram.addCommand(createFunctionsCommand());\n\nprogram.parse();\n","import ora, { type Ora } from 'ora';\nimport pc from 'picocolors';\n\nlet jsonMode = false;\nlet verboseMode = false;\n\nexport function setOutputMode(options: {\n json?: boolean;\n verbose?: boolean;\n}): void {\n jsonMode = options.json ?? false;\n verboseMode = options.verbose ?? false;\n}\n\nexport function isJsonMode(): boolean {\n return jsonMode;\n}\n\nexport function success(message: string): void {\n if (!jsonMode) {\n console.log(pc.green(`\\u2713 ${message}`));\n }\n}\n\nexport function error(message: string): void {\n if (!jsonMode) {\n console.error(pc.red(`\\u2717 ${message}`));\n }\n}\n\nexport function warn(message: string): void {\n if (!jsonMode) {\n console.warn(pc.yellow(`! ${message}`));\n }\n}\n\nexport function info(message: string): void {\n if (!jsonMode) {\n console.log(pc.cyan(`\\u2139 ${message}`));\n }\n}\n\nexport function verbose(message: string): void {\n if (verboseMode && !jsonMode) {\n console.log(pc.dim(` ${message}`));\n }\n}\n\nexport function json(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n}\n\nexport function table(\n headers: string[],\n rows: string[][],\n): void {\n if (jsonMode) return;\n\n const colWidths = headers.map((h, i) => {\n const maxRow = rows.reduce(\n (max, row) => Math.max(max, (row[i] ?? '').length),\n 0,\n );\n return Math.max(h.length, maxRow);\n });\n\n const headerLine = headers\n .map((h, i) => pc.bold(h.padEnd(colWidths[i] ?? 0)))\n .join(' ');\n const separator = colWidths.map((w) => '-'.repeat(w)).join(' ');\n\n console.log(headerLine);\n console.log(separator);\n for (const row of rows) {\n console.log(\n row.map((cell, i) => cell.padEnd(colWidths[i] ?? 0)).join(' '),\n );\n }\n}\n\nexport function spinner(text: string): Ora {\n if (jsonMode) {\n return ora({ text, isSilent: true });\n }\n return ora(text).start();\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n const units = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(1024));\n const value = bytes / Math.pow(1024, i);\n return `${value.toFixed(i === 0 ? 0 : 1)} ${units[i]}`;\n}\n","import * as http from 'node:http';\nimport * as crypto from 'node:crypto';\nimport { Command } from 'commander';\nimport open from 'open';\nimport { generatePKCE, storeCredentials } from '../lib/auth';\nimport { resolveApiUrl, loadConfig } from '../lib/config';\nimport { success, error, info, spinner, json, isJsonMode } from '../lib/output';\nimport type { GlobalOptions, TokenResponse, StoredCredentials } from '../lib/types';\n\nconst CLI_CLIENT_ID = 'spacelr-cli';\n\nexport function createLoginCommand(): Command {\n return new Command('login')\n .description('Authenticate with Spacelr via browser')\n .option('--auth-url <url>', 'OAuth server URL (defaults to --api-url)')\n .action(async (opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n const authUrl = (opts.authUrl as string | undefined) ?? apiUrl;\n\n try {\n const credentials = await performLogin(authUrl, apiUrl);\n storeCredentials(credentials);\n\n if (isJsonMode()) {\n json({ success: true, expiresAt: credentials.expiresAt });\n } else {\n success('Logged in successfully');\n info(`Credentials stored in ~/.spacelr/credentials.json`);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Login failed');\n process.exitCode = 1;\n }\n });\n}\n\nasync function performLogin(authUrl: string, apiUrl: string): Promise<StoredCredentials> {\n const { codeVerifier, codeChallenge } = generatePKCE();\n const state = crypto.randomBytes(16).toString('base64url');\n\n // Start local HTTP server on a random port\n const { port, waitForCode, close } = await startCallbackServer(state);\n\n const authorizeUrl = buildAuthorizeUrl(authUrl, port, codeChallenge, state);\n\n info(`Opening browser for authentication...`);\n info(`If the browser doesn't open, visit: ${authorizeUrl}`);\n\n await open(authorizeUrl);\n\n const spin = spinner('Waiting for authentication...');\n\n try {\n const code = await waitForCode;\n spin.text = 'Exchanging authorization code...';\n\n const tokenResponse = await exchangeCode(\n authUrl,\n code,\n codeVerifier,\n port,\n );\n\n spin.succeed('Authentication complete');\n\n return {\n accessToken: tokenResponse.access_token,\n refreshToken: tokenResponse.refresh_token,\n expiresAt: Date.now() + tokenResponse.expires_in * 1000,\n apiUrl,\n };\n } catch (err) {\n spin.fail('Authentication failed');\n throw err;\n } finally {\n close();\n }\n}\n\nfunction buildAuthorizeUrl(\n apiUrl: string,\n port: number,\n codeChallenge: string,\n state: string,\n): string {\n const params = new URLSearchParams({\n client_id: CLI_CLIENT_ID,\n redirect_uri: `http://127.0.0.1:${port}/callback`,\n response_type: 'code',\n code_challenge: codeChallenge,\n code_challenge_method: 'S256',\n scope: 'openid profile email',\n state,\n });\n return `${apiUrl}/auth/authorize?${params.toString()}`;\n}\n\nasync function startCallbackServer(expectedState: string): Promise<{\n port: number;\n waitForCode: Promise<string>;\n close: () => void;\n}> {\n return new Promise((resolveServer) => {\n let resolveCode: (code: string) => void;\n let rejectCode: (err: Error) => void;\n\n const waitForCode = new Promise<string>((resolve, reject) => {\n resolveCode = resolve;\n rejectCode = reject;\n });\n\n const server = http.createServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://127.0.0.1`);\n\n if (url.pathname === '/callback') {\n const code = url.searchParams.get('code');\n const errorParam = url.searchParams.get('error');\n const returnedState = url.searchParams.get('state');\n\n if (errorParam) {\n const description =\n url.searchParams.get('error_description') ?? errorParam;\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(errorPage(description));\n rejectCode(new Error(`OAuth error: ${description}`));\n return;\n }\n\n // CSRF protection: verify state matches\n if (returnedState !== expectedState) {\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(errorPage('Invalid state parameter (possible CSRF attack)'));\n rejectCode(new Error('OAuth state mismatch'));\n return;\n }\n\n if (!code) {\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(errorPage('No authorization code received'));\n rejectCode(new Error('No authorization code received'));\n return;\n }\n\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(successPage());\n resolveCode(code);\n } else {\n res.writeHead(404);\n res.end();\n }\n });\n\n // Timeout after 5 minutes\n const timeout = setTimeout(() => {\n rejectCode(new Error('Login timed out after 5 minutes'));\n server.close();\n }, 5 * 60 * 1000);\n\n server.listen(0, '127.0.0.1', () => {\n const address = server.address();\n const port =\n typeof address === 'object' && address ? address.port : 0;\n\n resolveServer({\n port,\n waitForCode,\n close: () => {\n clearTimeout(timeout);\n server.close();\n },\n });\n });\n });\n}\n\nasync function exchangeCode(\n apiUrl: string,\n code: string,\n codeVerifier: string,\n port: number,\n): Promise<TokenResponse> {\n const response = await fetch(`${apiUrl}/auth/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n code_verifier: codeVerifier,\n client_id: CLI_CLIENT_ID,\n redirect_uri: `http://127.0.0.1:${port}/callback`,\n }),\n });\n\n if (!response.ok) {\n let message: string;\n try {\n const body = (await response.json()) as { message?: string; error?: string };\n message = body.message ?? body.error ?? response.statusText;\n } catch {\n message = response.statusText;\n }\n throw new Error(`Token exchange failed: ${message}`);\n }\n\n return (await response.json()) as TokenResponse;\n}\n\nfunction successPage(): string {\n return `<!DOCTYPE html>\n<html><head><title>Spacelr CLI</title>\n<style>body{font-family:system-ui,sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#f8f9fa;}\n.box{text-align:center;padding:2rem;}.check{font-size:3rem;color:#22c55e;}</style></head>\n<body><div class=\"box\"><div class=\"check\">&#10003;</div><h1>Authenticated</h1><p>You can close this window and return to the terminal.</p></div></body></html>`;\n}\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nfunction errorPage(message: string): string {\n return `<!DOCTYPE html>\n<html><head><title>Spacelr CLI</title>\n<style>body{font-family:system-ui,sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#f8f9fa;}\n.box{text-align:center;padding:2rem;}.x{font-size:3rem;color:#ef4444;}</style></head>\n<body><div class=\"box\"><div class=\"x\">&#10007;</div><h1>Authentication Failed</h1><p>${escapeHtml(message)}</p></div></body></html>`;\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as crypto from 'node:crypto';\nimport type { StoredCredentials, PKCEChallenge, TokenResponse } from './types';\nimport { verbose } from './output';\n\nfunction getCredentialsDir(): string {\n return path.join(\n process.env['HOME'] ?? process.env['USERPROFILE'] ?? '~',\n '.spacelr',\n );\n}\n\nfunction getCredentialsFile(): string {\n return path.join(getCredentialsDir(), 'credentials.json');\n}\n\nexport function getStoredCredentials(): StoredCredentials | null {\n try {\n const file = getCredentialsFile();\n if (!fs.existsSync(file)) return null;\n const content = fs.readFileSync(file, 'utf-8');\n return JSON.parse(content) as StoredCredentials;\n } catch {\n return null;\n }\n}\n\nexport function storeCredentials(credentials: StoredCredentials): void {\n const dir = getCredentialsDir();\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n fs.writeFileSync(\n getCredentialsFile(),\n JSON.stringify(credentials, null, 2),\n { mode: 0o600 },\n );\n}\n\nexport function clearCredentials(): void {\n try {\n const file = getCredentialsFile();\n if (fs.existsSync(file)) {\n fs.unlinkSync(file);\n }\n } catch {\n // Ignore errors during cleanup\n }\n}\n\nexport function isTokenExpired(credentials: StoredCredentials): boolean {\n // Add 60 second buffer\n return Date.now() >= credentials.expiresAt - 60_000;\n}\n\nexport async function resolveToken(flagToken?: string): Promise<string | null> {\n if (flagToken) return flagToken;\n if (process.env['SPACELR_TOKEN']) return process.env['SPACELR_TOKEN'];\n const credentials = getStoredCredentials();\n if (!credentials) return null;\n if (!isTokenExpired(credentials)) return credentials.accessToken;\n // Token expired — only refresh against the stored issuer URL\n if (credentials.refreshToken && credentials.apiUrl) {\n const newToken = await refreshStoredToken(credentials);\n if (newToken) return newToken;\n }\n return null;\n}\n\nconst REFRESH_TIMEOUT_MS = 10_000;\n\n/**\n * Refreshes the access token using the stored refresh token.\n * Always uses credentials.apiUrl (issuer-bound) to prevent\n * sending refresh tokens to untrusted URLs.\n */\nexport async function refreshStoredToken(\n credentials: StoredCredentials,\n): Promise<string | null> {\n const apiUrl = credentials.apiUrl.replace(/\\/+$/, '');\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), REFRESH_TIMEOUT_MS);\n\n try {\n verbose('Refreshing access token...');\n const response = await fetch(`${apiUrl}/auth/refresh`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ refreshToken: credentials.refreshToken ?? '' }),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n verbose(`Token refresh failed (HTTP ${response.status})`);\n return null;\n }\n\n const data = (await response.json()) as TokenResponse;\n const newCredentials: StoredCredentials = {\n accessToken: data.access_token,\n refreshToken: data.refresh_token ?? credentials.refreshToken,\n expiresAt: Date.now() + (data.expires_in ?? 3600) * 1000,\n apiUrl: credentials.apiUrl,\n };\n storeCredentials(newCredentials);\n verbose('Token refreshed successfully');\n return data.access_token;\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n verbose('Token refresh timed out');\n } else {\n verbose('Token refresh error');\n }\n return null;\n } finally {\n clearTimeout(timer);\n }\n}\n\nexport class AuthRequiredError extends Error {\n constructor() {\n super('Not logged in. Run \"spacelr login\" to authenticate.');\n this.name = 'AuthRequiredError';\n }\n}\n\n/**\n * Resolves a token or throws AuthRequiredError.\n * Use in commands that require authentication.\n */\nexport async function requireAuth(flagToken?: string): Promise<string> {\n const token = await resolveToken(flagToken);\n if (!token) {\n throw new AuthRequiredError();\n }\n return token;\n}\n\nexport function generatePKCE(): PKCEChallenge {\n const codeVerifier = crypto.randomBytes(32).toString('base64url');\n const codeChallenge = crypto\n .createHash('sha256')\n .update(codeVerifier)\n .digest('base64url');\n return { codeVerifier, codeChallenge };\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { SpacelrConfig, DatabaseRules, DatabaseIndexes } from './types';\n\nconst CONFIG_FILENAME = 'spacelr.json';\nexport const RULES_FILENAME = 'spacelr.rules.json';\nexport const INDEXES_FILENAME = 'spacelr.indexes.json';\n\nfunction readJsonFile<T>(filePath: string, label: string): T {\n const content = fs.readFileSync(filePath, 'utf-8');\n try {\n return JSON.parse(content) as T;\n } catch (err) {\n const detail = err instanceof Error ? `: ${err.message}` : '';\n throw new Error(\n `Invalid JSON in ${label}: ${filePath}${detail}\\nPlease check the file for syntax errors.`,\n );\n }\n}\n\nfunction writeJsonFile(filePath: string, data: unknown): void {\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\\n', 'utf-8');\n}\n\nfunction resolveSiblingPath(filename: string, configPath?: string): string {\n const resolved = configPath ?? findConfigPath();\n const dir = resolved ? path.dirname(resolved) : process.cwd();\n return path.join(dir, filename);\n}\n\nexport function findConfigPath(startDir?: string): string | null {\n let dir = startDir ?? process.cwd();\n\n while (true) {\n const candidate = path.join(dir, CONFIG_FILENAME);\n if (fs.existsSync(candidate)) {\n return candidate;\n }\n const parent = path.dirname(dir);\n if (parent === dir) {\n return null;\n }\n dir = parent;\n }\n}\n\nexport function loadConfig(configPath?: string): SpacelrConfig | null {\n const resolved = configPath ?? findConfigPath();\n if (!resolved || !fs.existsSync(resolved)) return null;\n return readJsonFile<SpacelrConfig>(resolved, 'config file');\n}\n\nexport function saveConfig(\n config: SpacelrConfig,\n configPath?: string,\n): void {\n const resolved = configPath ?? findConfigPath() ?? path.join(process.cwd(), CONFIG_FILENAME);\n writeJsonFile(resolved, config);\n}\n\nexport function resolveProjectId(\n flagValue?: string,\n config?: SpacelrConfig | null,\n): string {\n const projectId = flagValue ?? config?.projectId;\n if (!projectId) {\n throw new Error(\n 'Project ID is required. Provide --project <id> or set \"projectId\" in spacelr.json',\n );\n }\n return projectId;\n}\n\nexport function resolveApiUrl(\n flagValue?: string,\n config?: SpacelrConfig | null,\n): string {\n return (\n flagValue ??\n config?.apiUrl ??\n process.env['SPACELR_API_URL'] ??\n 'https://api.spacelr.com/api/v1'\n );\n}\n\nexport function loadRules(configPath?: string): DatabaseRules | null {\n const filePath = resolveSiblingPath(RULES_FILENAME, configPath);\n if (!fs.existsSync(filePath)) return null;\n return readJsonFile<DatabaseRules>(filePath, 'rules file');\n}\n\nexport function saveRules(rules: DatabaseRules, configPath?: string): void {\n writeJsonFile(resolveSiblingPath(RULES_FILENAME, configPath), rules);\n}\n\nexport function loadIndexes(configPath?: string): DatabaseIndexes | null {\n const filePath = resolveSiblingPath(INDEXES_FILENAME, configPath);\n if (!fs.existsSync(filePath)) return null;\n return readJsonFile<DatabaseIndexes>(filePath, 'indexes file');\n}\n\nexport function saveIndexes(indexes: DatabaseIndexes, configPath?: string): void {\n writeJsonFile(resolveSiblingPath(INDEXES_FILENAME, configPath), indexes);\n}\n","import { Command } from 'commander';\nimport { clearCredentials, getStoredCredentials } from '../lib/auth';\nimport { success, warn, json, isJsonMode } from '../lib/output';\nimport type { GlobalOptions } from '../lib/types';\n\nexport function createLogoutCommand(): Command {\n return new Command('logout')\n .description('Clear stored credentials')\n .action(async (_opts, cmd: Command) => {\n cmd.optsWithGlobals<GlobalOptions>();\n\n const existing = getStoredCredentials();\n clearCredentials();\n\n if (isJsonMode()) {\n json({ success: true, hadCredentials: !!existing });\n } else if (existing) {\n success('Logged out successfully');\n } else {\n warn('No credentials found');\n }\n });\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../lib/api-client';\nimport { resolveApiUrl, loadConfig } from '../lib/config';\nimport { requireAuth } from '../lib/auth';\nimport { success, error, info, json, isJsonMode } from '../lib/output';\nimport type { GlobalOptions, UserInfo } from '../lib/types';\n\nexport function createWhoamiCommand(): Command {\n return new Command('whoami')\n .description('Show current authenticated user')\n .action(async (_opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const client = new ApiClient({ apiUrl, token });\n const response = await client.get<{ user: UserInfo }>('/auth/me');\n const user = response.user;\n\n if (isJsonMode()) {\n json(user);\n } else {\n success(`Logged in as ${user.email ?? user.username ?? user.id}`);\n if (user.displayName) info(`Name: ${user.displayName}`);\n if (user.roles?.length) info(`Roles: ${user.roles.join(', ')}`);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to get user info');\n process.exitCode = 1;\n }\n });\n}\n","import {\n getStoredCredentials,\n isTokenExpired,\n refreshStoredToken,\n} from './auth';\nimport { verbose } from './output';\nimport type { StoredCredentials } from './types';\n\ninterface ApiClientOptions {\n apiUrl: string;\n token?: string;\n clientId?: string;\n projectId?: string;\n}\n\ninterface RequestOptions {\n method?: string;\n body?: BodyInit | Record<string, unknown>;\n headers?: Record<string, string>;\n timeout?: number;\n}\n\nexport class ApiClient {\n private readonly apiUrl: string;\n private readonly clientId: string;\n private readonly projectId?: string;\n private explicitToken?: string;\n private refreshing: Promise<string | null> | null = null;\n\n constructor(options: ApiClientOptions) {\n this.apiUrl = options.apiUrl.replace(/\\/+$/, '');\n this.explicitToken = options.token;\n this.clientId = options.clientId ?? 'spacelr-cli';\n this.projectId = options.projectId;\n }\n\n private async getToken(): Promise<string | null> {\n if (this.explicitToken) return this.explicitToken;\n\n const envToken = process.env['SPACELR_TOKEN'];\n if (envToken) return envToken;\n\n const credentials = getStoredCredentials();\n if (!credentials) return null;\n\n if (!isTokenExpired(credentials)) {\n return credentials.accessToken;\n }\n\n // Token expired, try refreshing\n if (credentials.refreshToken) {\n return this.refreshAccessToken(credentials);\n }\n\n return null;\n }\n\n private async refreshAccessToken(\n credentials: StoredCredentials,\n ): Promise<string | null> {\n // Deduplicate concurrent refreshes\n if (this.refreshing) return this.refreshing;\n\n this.refreshing = refreshStoredToken(credentials).finally(() => {\n this.refreshing = null;\n });\n\n return this.refreshing;\n }\n\n private serializeBody(\n body: RequestOptions['body'],\n contentType: string | undefined,\n ): BodyInit | undefined {\n if (!body) return undefined;\n if (contentType === 'application/json') {\n return JSON.stringify(body);\n }\n // Buffer, string, URLSearchParams, etc. are already valid BodyInit\n return body as BodyInit;\n }\n\n private async request<T>(\n path: string,\n options: RequestOptions = {},\n ): Promise<T> {\n const { method = 'GET', body, headers = {}, timeout = 30_000 } = options;\n const url = `${this.apiUrl}${path}`;\n\n const token = await this.getToken();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n if (body && !headers['Content-Type']) {\n headers['Content-Type'] = 'application/json';\n }\n\n headers['x-client-id'] = this.clientId;\n if (this.projectId) {\n headers['x-project-id'] = this.projectId;\n }\n\n const serializedBody = this.serializeBody(body, headers['Content-Type']);\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n\n verbose(`${method} ${url}`);\n\n try {\n const response = await fetch(url, {\n method,\n headers,\n body: serializedBody,\n signal: controller.signal,\n });\n\n if (response.status === 401 && !this.explicitToken) {\n // Try refresh once\n const credentials = getStoredCredentials();\n if (credentials?.refreshToken) {\n const newToken = await this.refreshAccessToken(credentials);\n if (newToken) {\n headers['Authorization'] = `Bearer ${newToken}`;\n const retryController = new AbortController();\n const retryTimer = setTimeout(() => retryController.abort(), timeout);\n const retryResponse = await fetch(url, {\n method,\n headers,\n body: serializedBody,\n signal: retryController.signal,\n });\n clearTimeout(retryTimer);\n if (!retryResponse.ok) {\n await this.throwApiError(retryResponse);\n }\n return (await retryResponse.json()) as T;\n }\n }\n throw new Error(\n 'Authentication required. Run \"spacelr login\" to authenticate.',\n );\n }\n\n if (!response.ok) {\n await this.throwApiError(response);\n }\n\n const contentType = response.headers.get('content-type');\n if (contentType?.includes('application/json')) {\n return (await response.json()) as T;\n }\n return (await response.text()) as unknown as T;\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n throw new Error(`Request timed out: ${method} ${path}`);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async throwApiError(response: Response): Promise<never> {\n let message: string;\n try {\n const body = (await response.json()) as { message?: string; error?: string };\n message = body.message ?? body.error ?? response.statusText;\n } catch {\n message = response.statusText;\n }\n throw new Error(`API error (${response.status}): ${message}`);\n }\n\n async get<T>(path: string, timeout?: number): Promise<T> {\n return this.request<T>(path, { timeout });\n }\n\n async post<T>(path: string, body?: Record<string, unknown> | BodyInit, timeout?: number): Promise<T> {\n return this.request<T>(path, { method: 'POST', body, timeout });\n }\n\n async put<T>(path: string, body?: Record<string, unknown> | BodyInit, timeout?: number): Promise<T> {\n return this.request<T>(path, { method: 'PUT', body, timeout });\n }\n\n async patch<T>(path: string, body?: Record<string, unknown> | BodyInit, timeout?: number): Promise<T> {\n return this.request<T>(path, { method: 'PATCH', body, timeout });\n }\n\n async delete<T>(path: string, timeout?: number): Promise<T> {\n return this.request<T>(path, { method: 'DELETE', timeout });\n }\n\n async uploadFile(\n path: string,\n fileBuffer: Buffer,\n filename: string,\n ): Promise<DeploymentUploadResponse> {\n const boundary = `----spacelr${Date.now()}`;\n const parts: Buffer[] = [];\n\n // Build multipart body manually (no form-data dependency needed)\n const header = Buffer.from(\n `--${boundary}\\r\\n` +\n `Content-Disposition: form-data; name=\"file\"; filename=\"${filename}\"\\r\\n` +\n `Content-Type: application/zip\\r\\n\\r\\n`,\n );\n const footer = Buffer.from(`\\r\\n--${boundary}--\\r\\n`);\n parts.push(header, fileBuffer, footer);\n const body = Buffer.concat(parts);\n\n return this.request<DeploymentUploadResponse>(path, {\n method: 'POST',\n body,\n headers: {\n 'Content-Type': `multipart/form-data; boundary=${boundary}`,\n },\n timeout: 300_000, // 5 minutes for uploads\n });\n }\n}\n\ninterface DeploymentUploadResponse {\n deploymentId: string;\n status: string;\n fileCount: number;\n totalSizeBytes: number;\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../lib/api-client';\nimport { resolveApiUrl, loadConfig } from '../lib/config';\nimport { requireAuth } from '../lib/auth';\nimport { error, spinner, json, isJsonMode, table, info } from '../lib/output';\nimport type { GlobalOptions, ProjectInfo } from '../lib/types';\n\nexport function createProjectsCommand(): Command {\n return new Command('projects')\n .description('List your projects')\n .action(async (_opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const client = new ApiClient({ apiUrl, token });\n const spin = spinner('Fetching projects...');\n const result = await client.get<{ projects: ProjectInfo[] }>('/projects');\n spin.stop();\n\n const projects = result.projects;\n\n if (projects.length === 0) {\n info('No projects found');\n return;\n }\n\n const activeProjectId = config?.projectId;\n\n if (isJsonMode()) {\n json(projects);\n } else {\n table(\n ['', 'ID', 'Name', 'Slug'],\n projects.map((p) => [\n p.id === activeProjectId ? '*' : ' ',\n p.id,\n p.name,\n p.slug,\n ]),\n );\n if (activeProjectId) {\n info(`\\n* = active project (from spacelr.json)`);\n }\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to list projects');\n process.exitCode = 1;\n }\n });\n}\n\nexport async function fetchProjects(\n client: ApiClient,\n): Promise<ProjectInfo[]> {\n const result = await client.get<{ projects: ProjectInfo[] }>('/projects');\n return result.projects;\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../lib/api-client';\nimport { resolveApiUrl, loadConfig, saveConfig } from '../lib/config';\nimport { requireAuth } from '../lib/auth';\nimport { success, error, spinner, json, isJsonMode, info } from '../lib/output';\nimport { promptChoice } from '../lib/prompt';\nimport { fetchProjects } from './projects';\nimport type { GlobalOptions, ProjectInfo } from '../lib/types';\n\nexport function createUseCommand(): Command {\n return new Command('use')\n .description('Set the active project')\n .argument('[project]', 'Project ID or slug')\n .action(async (project: string | undefined, _opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const client = new ApiClient({ apiUrl, token });\n const spin = spinner('Fetching projects...');\n const projects = await fetchProjects(client);\n spin.stop();\n\n if (projects.length === 0) {\n error('No projects found. Create a project first.');\n process.exitCode = 1;\n return;\n }\n\n let selected: ProjectInfo;\n\n if (project) {\n // Find by ID or slug\n const match = projects.find(\n (p) => p.id === project || p.slug === project,\n );\n if (!match) {\n error(`Project \"${project}\" not found`);\n info('Available projects:');\n for (const p of projects) {\n info(` ${p.slug} (${p.id})`);\n }\n process.exitCode = 1;\n return;\n }\n selected = match;\n } else {\n // Interactive selection\n selected = await promptChoice(\n 'Select a project:',\n projects.map((p) => ({\n ...p,\n label: `${p.name} (${p.slug})`,\n })),\n );\n }\n\n // Update config\n const updatedConfig = { ...config, projectId: selected.id };\n saveConfig(updatedConfig);\n\n if (isJsonMode()) {\n json({ projectId: selected.id, name: selected.name, slug: selected.slug });\n } else {\n success(`Now using project \"${selected.name}\" (${selected.slug})`);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to select project');\n process.exitCode = 1;\n }\n });\n}\n","import * as readline from 'node:readline';\n\nexport async function promptChoice<T extends { label: string }>(\n message: string,\n choices: T[],\n): Promise<T> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n\n console.error(`\\n${message}\\n`);\n choices.forEach((choice, i) => {\n console.error(` ${i + 1}) ${choice.label}`);\n });\n console.error();\n\n return new Promise((resolve, reject) => {\n rl.question(' Enter number: ', (answer) => {\n rl.close();\n const index = parseInt(answer, 10) - 1;\n if (isNaN(index) || index < 0 || index >= choices.length) {\n reject(new Error('Invalid selection'));\n return;\n }\n resolve(choices[index]);\n });\n });\n}\n\nexport async function promptConfirm(message: string): Promise<boolean> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n\n return new Promise((resolve) => {\n rl.question(`${message} (y/N) `, (answer) => {\n rl.close();\n resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');\n });\n });\n}\n\nexport async function promptInput(message: string, defaultValue?: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n\n const suffix = defaultValue ? ` (${defaultValue})` : '';\n\n return new Promise((resolve) => {\n rl.question(`${message}${suffix}: `, (answer) => {\n rl.close();\n resolve(answer.trim() || defaultValue || '');\n });\n });\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { Command } from 'commander';\nimport { ApiClient } from '../lib/api-client';\nimport { resolveApiUrl, loadConfig, saveConfig } from '../lib/config';\nimport { requireAuth } from '../lib/auth';\nimport { success, error, warn, spinner, json, isJsonMode, info } from '../lib/output';\nimport { promptChoice, promptInput } from '../lib/prompt';\nimport { fetchProjects } from './projects';\nimport type { GlobalOptions, SpacelrConfig } from '../lib/types';\n\nexport function createInitCommand(): Command {\n return new Command('init')\n .description('Initialize a spacelr.json config in the current directory')\n .action(async (_opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const existingConfig = loadConfig();\n\n const configPath = path.join(process.cwd(), 'spacelr.json');\n if (fs.existsSync(configPath)) {\n warn(`spacelr.json already exists in ${process.cwd()}`);\n info('Use \"spacelr use\" to change the active project');\n return;\n }\n\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, existingConfig);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const client = new ApiClient({ apiUrl, token });\n const spin = spinner('Fetching projects...');\n const projects = await fetchProjects(client);\n spin.stop();\n\n if (projects.length === 0) {\n error('No projects found. Create a project in the admin panel first.');\n process.exitCode = 1;\n return;\n }\n\n // Select project\n const selected = await promptChoice(\n 'Select a project:',\n projects.map((p) => ({\n ...p,\n label: `${p.name} (${p.slug})`,\n })),\n );\n\n // Ask for hosting directory\n const hostingDir = await promptInput(\n 'Hosting directory',\n './dist',\n );\n\n const config: SpacelrConfig = {\n projectId: selected.id,\n apiUrl: apiUrl !== 'https://api.spacelr.com/api/v1' ? apiUrl : undefined,\n hosting: {\n directory: hostingDir,\n },\n };\n\n saveConfig(config, configPath);\n\n if (isJsonMode()) {\n json(config);\n } else {\n success(`Created spacelr.json for \"${selected.name}\"`);\n info(`Project: ${selected.slug} (${selected.id})`);\n info(`Hosting directory: ${hostingDir}`);\n info('');\n info('Next steps:');\n info(' spacelr deploy Deploy your site');\n info(' spacelr db indexes pull Pull database indexes');\n info(' spacelr db rules pull Pull database rules');\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Initialization failed');\n process.exitCode = 1;\n }\n });\n}\n","import * as path from 'node:path';\nimport { Command } from 'commander';\nimport { ApiClient } from '../lib/api-client';\nimport {\n resolveApiUrl,\n resolveProjectId,\n loadConfig,\n} from '../lib/config';\nimport { requireAuth } from '../lib/auth';\nimport { createZipBuffer, countFiles } from '../lib/zip';\nimport {\n error,\n info,\n spinner,\n json,\n isJsonMode,\n formatBytes,\n verbose,\n} from '../lib/output';\nimport type {\n GlobalOptions,\n DeploymentResponse,\n} from '../lib/types';\n\nexport function createDeployCommand(): Command {\n return new Command('deploy')\n .description('Deploy a directory to Spacelr hosting')\n .argument('[directory]', 'Directory to deploy')\n .option('--project <id>', 'Project ID')\n .option('--description <text>', 'Deployment description')\n .option('--no-wait', 'Do not wait for processing to complete')\n .option('--dry-run', 'Show what would be deployed without uploading')\n .action(async (directory: string | undefined, opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n const deployDir = directory ?? config?.hosting?.directory ?? '.';\n const absDir = path.resolve(deployDir);\n\n const client = new ApiClient({ apiUrl, token, projectId });\n await deploy(client, projectId, absDir, {\n description: opts.description,\n wait: opts.wait !== false,\n dryRun: opts.dryRun === true,\n });\n } catch (err) {\n error(err instanceof Error ? err.message : 'Deployment failed');\n process.exitCode = 1;\n }\n });\n}\n\ninterface DeployOptions {\n description?: string;\n wait: boolean;\n dryRun: boolean;\n}\n\nasync function deploy(\n client: ApiClient,\n projectId: string,\n directory: string,\n options: DeployOptions,\n): Promise<void> {\n // Step 1: Count files and create ZIP\n const spin = spinner('Preparing deployment...');\n\n const fileCount = countFiles(directory);\n verbose(`Found ${fileCount} files in ${directory}`);\n\n spin.text = 'Creating archive...';\n const zipBuffer = await createZipBuffer(directory);\n verbose(`Archive size: ${formatBytes(zipBuffer.length)}`);\n\n if (options.dryRun) {\n spin.succeed('Dry run complete');\n if (isJsonMode()) {\n json({ dryRun: true, fileCount, archiveSize: zipBuffer.length, directory });\n } else {\n info(`Directory: ${directory}`);\n info(`Files: ${fileCount}`);\n info(`Archive size: ${formatBytes(zipBuffer.length)}`);\n }\n return;\n }\n\n // Step 2: Create deployment\n spin.text = 'Creating deployment...';\n const deployment = await client.post<DeploymentResponse>(\n `/hosting/${projectId}/deployments`,\n {\n description: options.description,\n },\n );\n verbose(`Deployment ID: ${deployment.deploymentId}`);\n\n // Step 3: Upload ZIP\n spin.text = `Uploading ${formatBytes(zipBuffer.length)}...`;\n await client.uploadFile(\n `/hosting/${projectId}/deployments/${deployment.deploymentId}/upload`,\n zipBuffer,\n 'deployment.zip',\n );\n\n if (!options.wait) {\n spin.succeed('Upload complete');\n info(`Deployment ${deployment.deploymentId} is processing`);\n if (isJsonMode()) {\n json({ deploymentId: deployment.deploymentId, status: 'processing' });\n }\n return;\n }\n\n // Step 4: Poll for status\n spin.text = 'Processing deployment...';\n const result = await pollDeploymentStatus(\n client,\n projectId,\n deployment.deploymentId,\n spin,\n );\n\n if (result.status === 'active') {\n spin.succeed('Deployment active');\n if (isJsonMode()) {\n json(result);\n } else {\n info(`Deployment ID: ${result.deploymentId}`);\n info(`Files: ${result.fileCount}`);\n info(`Size: ${formatBytes(result.totalSizeBytes)}`);\n }\n } else if (result.status === 'failed') {\n spin.fail('Deployment failed');\n error(result.errorMessage ?? 'Unknown error');\n process.exitCode = 1;\n } else {\n spin.warn(`Deployment status: ${result.status}`);\n if (isJsonMode()) {\n json(result);\n }\n }\n}\n\nasync function pollDeploymentStatus(\n client: ApiClient,\n projectId: string,\n deploymentId: string,\n spin: { text: string },\n): Promise<DeploymentResponse> {\n const maxAttempts = 120; // 10 minutes (5s intervals)\n for (let i = 0; i < maxAttempts; i++) {\n await sleep(5000);\n const status = await client.get<DeploymentResponse>(\n `/hosting/${projectId}/deployments/${deploymentId}/status`,\n );\n\n verbose(`Poll ${i + 1}: status=${status.status}`);\n spin.text = `Processing deployment... (${status.status})`;\n\n if (\n status.status === 'active' ||\n status.status === 'failed'\n ) {\n return status;\n }\n }\n\n throw new Error('Deployment timed out after 10 minutes');\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport archiver from 'archiver';\n\nexport async function createZipBuffer(directory: string): Promise<Buffer> {\n const absDir = path.resolve(directory);\n if (!fs.existsSync(absDir)) {\n throw new Error(`Directory not found: ${absDir}`);\n }\n if (!fs.statSync(absDir).isDirectory()) {\n throw new Error(`Not a directory: ${absDir}`);\n }\n\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n const archive = archiver('zip', { zlib: { level: 9 } });\n\n archive.on('data', (chunk: Buffer) => chunks.push(chunk));\n archive.on('end', () => resolve(Buffer.concat(chunks)));\n archive.on('error', reject);\n\n archive.directory(absDir, false);\n archive.finalize();\n });\n}\n\nexport function countFiles(directory: string): number {\n const absDir = path.resolve(directory);\n let count = 0;\n\n function walk(dir: string): void {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isFile()) {\n count++;\n } else if (entry.isDirectory()) {\n walk(path.join(dir, entry.name));\n }\n }\n }\n\n walk(absDir);\n return count;\n}\n","import { Command } from 'commander';\nimport { createIndexesDeployCommand } from './indexes-deploy';\nimport { createIndexesPullCommand } from './indexes-pull';\nimport { createRulesDeployCommand } from './rules-deploy';\nimport { createRulesPullCommand } from './rules-pull';\n\nexport function createDbCommand(): Command {\n const indexes = new Command('indexes')\n .description('Manage database indexes');\n\n indexes.addCommand(createIndexesDeployCommand());\n indexes.addCommand(createIndexesPullCommand());\n\n const rules = new Command('rules')\n .description('Manage database rules');\n\n rules.addCommand(createRulesDeployCommand());\n rules.addCommand(createRulesPullCommand());\n\n const db = new Command('db')\n .description('Database management commands');\n\n db.addCommand(indexes);\n db.addCommand(rules);\n\n return db;\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../../lib/api-client';\nimport {\n resolveApiUrl,\n resolveProjectId,\n loadConfig,\n loadIndexes,\n} from '../../lib/config';\nimport { requireAuth } from '../../lib/auth';\nimport { success, error, info, spinner, json, isJsonMode, warn } from '../../lib/output';\nimport { promptConfirm } from '../../lib/prompt';\nimport type { GlobalOptions, IndexRuleEntry, RemoteIndexEntry } from '../../lib/types';\n\nexport function createIndexesDeployCommand(): Command {\n return new Command('deploy')\n .description('Deploy indexes from spacelr.indexes.json to remote')\n .option('--project <id>', 'Project ID')\n .option('--config <path>', 'Config file path')\n .option('--yes', 'Skip confirmation')\n .action(async (opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig(opts.config);\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n const indexes = loadIndexes(opts.config);\n\n if (!indexes || Object.keys(indexes).length === 0) {\n warn('No indexes found in spacelr.indexes.json');\n return;\n }\n\n // Convert index format: config uses 1/-1, API expects asc/desc\n const indexRules = convertIndexFormat(indexes);\n\n const collectionCount = Object.keys(indexRules).length;\n const totalIndexes = Object.values(indexRules).reduce(\n (sum, arr) => sum + arr.length,\n 0,\n );\n\n if (!opts.yes) {\n info(\n `Will deploy ${totalIndexes} index(es) across ${collectionCount} collection(s)`,\n );\n const confirmed = await promptConfirm('Proceed with deployment?');\n if (!confirmed) {\n info('Aborted');\n return;\n }\n }\n\n const spin = spinner('Deploying indexes...');\n const client = new ApiClient({ apiUrl, token, projectId });\n const result = await client.put<{ message: string }>(\n `/databases/${projectId}/index-rules`,\n { indexRules },\n );\n\n spin.succeed('Indexes deployed');\n\n if (isJsonMode()) {\n json(result);\n } else {\n success(result.message ?? 'Indexes synced successfully');\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to deploy indexes');\n process.exitCode = 1;\n }\n });\n}\n\nfunction convertIndexFormat(\n indexes: Record<string, IndexRuleEntry[]>,\n): Record<string, RemoteIndexEntry[]> {\n const result: Record<string, RemoteIndexEntry[]> = {};\n\n for (const [collection, entries] of Object.entries(indexes)) {\n result[collection] = entries.map((entry) => {\n const fields: Record<string, 'asc' | 'desc'> = {};\n for (const [field, direction] of Object.entries(entry.fields)) {\n fields[field] = direction === 1 ? 'asc' : 'desc';\n }\n return {\n fields,\n ...(entry.unique !== undefined && { unique: entry.unique }),\n ...(entry.sparse !== undefined && { sparse: entry.sparse }),\n ...(entry.ttlSeconds !== undefined && { ttlSeconds: entry.ttlSeconds }),\n };\n });\n }\n\n return result;\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../../lib/api-client';\nimport {\n resolveApiUrl,\n resolveProjectId,\n loadConfig,\n saveConfig,\n saveIndexes,\n} from '../../lib/config';\nimport { requireAuth } from '../../lib/auth';\nimport { success, error, spinner, json, isJsonMode, info } from '../../lib/output';\nimport type { GlobalOptions, IndexRuleEntry, RemoteIndexEntry } from '../../lib/types';\n\nexport function createIndexesPullCommand(): Command {\n return new Command('pull')\n .description('Pull current indexes from remote to spacelr.indexes.json')\n .option('--project <id>', 'Project ID')\n .option('--config <path>', 'Config file path')\n .action(async (opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig(opts.config);\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n\n const spin = spinner('Pulling indexes...');\n const client = new ApiClient({ apiUrl, token, projectId });\n const response = await client.get<Record<string, unknown>>(\n `/databases/${projectId}/index-rules`,\n );\n\n // The API may return the indexes directly or wrapped in { indexRules }\n const remoteIndexes: Record<string, RemoteIndexEntry[]> =\n response && 'indexRules' in response\n ? (response['indexRules'] as Record<string, RemoteIndexEntry[]>)\n : (response as Record<string, RemoteIndexEntry[]>) ?? {};\n\n // Convert from API format (asc/desc) to config format (1/-1)\n const indexes = convertFromRemoteFormat(remoteIndexes);\n\n saveIndexes(indexes, opts.config);\n\n if (opts.project && opts.project !== config?.projectId) {\n saveConfig({ ...config, projectId: opts.project }, opts.config);\n }\n\n spin.succeed('Indexes pulled');\n\n const collectionCount = Object.keys(indexes).length;\n const totalIndexes = Object.values(indexes).reduce(\n (sum, arr) => sum + arr.length,\n 0,\n );\n\n if (isJsonMode()) {\n json(indexes);\n } else {\n success(\n `Pulled ${totalIndexes} index(es) from ${collectionCount} collection(s)`,\n );\n info('Indexes file updated');\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to pull indexes');\n process.exitCode = 1;\n }\n });\n}\n\nfunction convertFromRemoteFormat(\n remoteIndexes: Record<string, RemoteIndexEntry[]>,\n): Record<string, IndexRuleEntry[]> {\n const result: Record<string, IndexRuleEntry[]> = {};\n\n for (const [collection, entries] of Object.entries(remoteIndexes)) {\n result[collection] = entries.map((entry) => {\n const fields: Record<string, 1 | -1> = {};\n for (const [field, direction] of Object.entries(entry.fields)) {\n fields[field] = direction === 'asc' ? 1 : -1;\n }\n return {\n fields,\n ...(entry.unique !== undefined && { unique: entry.unique }),\n ...(entry.sparse !== undefined && { sparse: entry.sparse }),\n ...(entry.ttlSeconds !== undefined && {\n ttlSeconds: entry.ttlSeconds,\n }),\n };\n });\n }\n\n return result;\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../../lib/api-client';\nimport {\n resolveApiUrl,\n resolveProjectId,\n loadConfig,\n loadRules,\n} from '../../lib/config';\nimport { requireAuth } from '../../lib/auth';\nimport { success, error, info, spinner, json, isJsonMode, warn } from '../../lib/output';\nimport { promptConfirm } from '../../lib/prompt';\nimport type { GlobalOptions } from '../../lib/types';\n\nexport function createRulesDeployCommand(): Command {\n return new Command('deploy')\n .description('Deploy rules from spacelr.rules.json to remote')\n .option('--project <id>', 'Project ID')\n .option('--config <path>', 'Config file path')\n .option('--yes', 'Skip confirmation')\n .action(async (opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig(opts.config);\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n const rules = loadRules(opts.config);\n\n if (!rules || Object.keys(rules).length === 0) {\n warn('No rules found in spacelr.rules.json');\n return;\n }\n\n const ruleCount = Object.keys(rules).length;\n\n if (!opts.yes) {\n info(`Will deploy rules for ${ruleCount} collection(s)`);\n const confirmed = await promptConfirm('Proceed with deployment?');\n if (!confirmed) {\n info('Aborted');\n return;\n }\n }\n\n // Validate first\n const spin = spinner('Validating rules...');\n const client = new ApiClient({ apiUrl, token, projectId });\n\n await client.post<{ valid: boolean }>(\n `/databases/${projectId}/rules/validate`,\n { rules },\n );\n\n // Deploy\n spin.text = 'Deploying rules...';\n const result = await client.put<{ message: string }>(\n `/databases/${projectId}/rules`,\n { rules },\n );\n\n spin.succeed('Rules deployed');\n\n if (isJsonMode()) {\n json(result);\n } else {\n success(result.message ?? 'Rules deployed successfully');\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to deploy rules');\n process.exitCode = 1;\n }\n });\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../../lib/api-client';\nimport {\n resolveApiUrl,\n resolveProjectId,\n loadConfig,\n saveConfig,\n saveRules,\n} from '../../lib/config';\nimport { requireAuth } from '../../lib/auth';\nimport { success, error, spinner, json, isJsonMode, info } from '../../lib/output';\nimport type { GlobalOptions } from '../../lib/types';\n\nexport function createRulesPullCommand(): Command {\n return new Command('pull')\n .description('Pull current rules from remote to spacelr.rules.json')\n .option('--project <id>', 'Project ID')\n .option('--config <path>', 'Config file path')\n .action(async (opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig(opts.config);\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n\n const spin = spinner('Pulling rules...');\n const client = new ApiClient({ apiUrl, token, projectId });\n const result = await client.get<{ rules: Record<string, unknown> }>(\n `/databases/${projectId}/rules`,\n );\n\n const rules = result.rules;\n\n saveRules(rules, opts.config);\n\n if (opts.project && opts.project !== config?.projectId) {\n saveConfig({ ...config, projectId: opts.project }, opts.config);\n }\n\n spin.succeed('Rules pulled');\n\n const ruleCount = Object.keys(rules).length;\n\n if (isJsonMode()) {\n json(rules);\n } else {\n success(`Pulled rules for ${ruleCount} collection(s)`);\n info('Rules file updated');\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to pull rules');\n process.exitCode = 1;\n }\n });\n}\n","import * as path from 'node:path';\nimport { Command } from 'commander';\nimport { ApiClient } from '../lib/api-client';\nimport {\n resolveApiUrl,\n resolveProjectId,\n loadConfig,\n} from '../lib/config';\nimport { requireAuth } from '../lib/auth';\nimport { createZipBuffer, countFiles } from '../lib/zip';\nimport {\n error,\n info,\n spinner,\n json,\n isJsonMode,\n formatBytes,\n verbose,\n} from '../lib/output';\nimport type { GlobalOptions } from '../lib/types';\n\ninterface FunctionEntry {\n id: string;\n name: string;\n enabled: boolean;\n cronExpression?: string;\n environmentVariables?: Record<string, string>;\n}\n\ninterface FunctionListResponse {\n data?: FunctionEntry[];\n}\n\ninterface FunctionCreateResponse {\n id?: string;\n data?: { id: string };\n}\n\ninterface ExecutionLogEntry {\n timestamp: string;\n level: string;\n message: string;\n}\n\ninterface ExecutionEntry {\n status: string;\n startedAt: string;\n duration?: number;\n triggeredBy: string;\n error?: string;\n logs?: ExecutionLogEntry[];\n}\n\ninterface ExecutionsResponse {\n items?: ExecutionEntry[];\n data?: { items?: ExecutionEntry[] };\n}\n\nexport function createFunctionsCommand(): Command {\n const functions = new Command('functions')\n .description('Manage serverless functions');\n\n functions\n .command('deploy [directory]')\n .description('Deploy a function')\n .requiredOption('--name <name>', 'Function name')\n .option('--entry <file>', 'Entry point (default: index.js)')\n .option('--cron <expression>', 'Cron schedule expression')\n .option('--timezone <tz>', 'Timezone for cron (default: UTC)')\n .option('--timeout <ms>', 'Execution timeout in ms')\n .option('--memory <mb>', 'Memory limit in MB')\n .option('--env <KEY=VALUE...>', 'Environment variables', collectEnvVars, {})\n .option('--project <id>', 'Project ID')\n .action(async (directory: string | undefined, opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n const deployDir = directory ?? '.';\n const absDir = path.resolve(deployDir);\n\n const client = new ApiClient({ apiUrl, token, projectId });\n\n // Create zip\n const spin = spinner('Preparing deployment...');\n const fileCount = countFiles(absDir);\n verbose(`Found ${fileCount} files in ${absDir}`);\n\n spin.text = 'Creating archive...';\n const zipBuffer = await createZipBuffer(absDir);\n verbose(`Archive size: ${formatBytes(zipBuffer.length)}`);\n\n // Check if function already exists\n spin.text = 'Checking for existing function...';\n const envVars = opts.env as Record<string, string>;\n const existingFns = await client.get<\n FunctionEntry[] | FunctionListResponse\n >(`/projects/${projectId}/functions`);\n const fnList: FunctionEntry[] = Array.isArray(existingFns)\n ? existingFns\n : (existingFns as FunctionListResponse).data || [];\n const existing = fnList.find(\n (f: FunctionEntry) => f.name === opts.name,\n );\n\n let functionId: string;\n const functionBody = {\n entryPoint: opts.entry,\n cronExpression: opts.cron,\n cronTimezone: opts.timezone,\n timeout: opts.timeout ? parseInt(opts.timeout, 10) : undefined,\n memoryLimitMb: opts.memory ? parseInt(opts.memory, 10) : undefined,\n environmentVariables:\n Object.keys(envVars).length > 0 ? envVars : undefined,\n };\n\n if (existing) {\n // Update existing function\n spin.text = 'Updating function...';\n await client.patch(\n `/projects/${projectId}/functions/${existing.id}`,\n functionBody,\n );\n functionId = existing.id;\n } else {\n // Create new function\n spin.text = 'Creating function...';\n const createResult = await client.post<FunctionCreateResponse>(\n `/projects/${projectId}/functions`,\n { name: opts.name, ...functionBody },\n );\n const createdId = createResult.id || createResult.data?.id;\n if (!createdId) {\n throw new Error('Failed to create function');\n }\n functionId = createdId;\n }\n\n // Upload code\n spin.text = 'Uploading code...';\n await client.uploadFile(\n `/projects/${projectId}/functions/${functionId}/deploy`,\n zipBuffer,\n 'code.zip',\n );\n\n spin.succeed(\n `Function \"${opts.name}\" deployed (${formatBytes(zipBuffer.length)}, ${fileCount} files)`,\n );\n\n if (opts.cron) {\n info(`Cron schedule: ${opts.cron}`);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Deploy failed');\n process.exitCode = 1;\n }\n });\n\n functions\n .command('list')\n .description('List functions')\n .option('--project <id>', 'Project ID')\n .action(async (opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n const client = new ApiClient({ apiUrl, token, projectId });\n\n const result = await client.get<FunctionEntry[] | FunctionListResponse>(\n `/projects/${projectId}/functions`,\n );\n\n const fns: FunctionEntry[] = Array.isArray(result)\n ? result\n : (result as FunctionListResponse).data || [];\n\n if (isJsonMode()) {\n json(fns);\n return;\n }\n\n if (fns.length === 0) {\n info('No functions found');\n return;\n }\n\n for (const fn of fns) {\n const status = fn.enabled ? 'enabled' : 'disabled';\n const cron = fn.cronExpression ? ` [${fn.cronExpression}]` : '';\n info(`${fn.name} (${fn.id}) - ${status}${cron}`);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to list functions');\n process.exitCode = 1;\n }\n });\n\n functions\n .command('delete <name>')\n .description('Delete a function')\n .option('--project <id>', 'Project ID')\n .action(async (name: string, opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n const client = new ApiClient({ apiUrl, token, projectId });\n\n const fn = await findFunctionByName(client, projectId, name);\n\n await client.delete(\n `/projects/${projectId}/functions/${fn.id}`,\n );\n\n info(`Function \"${name}\" deleted`);\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to delete function');\n process.exitCode = 1;\n }\n });\n\n functions\n .command('trigger <name>')\n .description('Trigger a function execution')\n .option('--project <id>', 'Project ID')\n .action(async (name: string, opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n const client = new ApiClient({ apiUrl, token, projectId });\n\n const fn = await findFunctionByName(client, projectId, name);\n\n const spin = spinner('Triggering function...');\n await client.post(\n `/projects/${projectId}/functions/${fn.id}/trigger`,\n );\n spin.succeed(`Function \"${name}\" triggered`);\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to trigger function');\n process.exitCode = 1;\n }\n });\n\n functions\n .command('logs <name>')\n .description('View function execution logs')\n .option('--limit <n>', 'Number of executions to show', '10')\n .option('--project <id>', 'Project ID')\n .action(async (name: string, opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n const client = new ApiClient({ apiUrl, token, projectId });\n\n const fn = await findFunctionByName(client, projectId, name);\n\n const limit = parseInt(opts.limit, 10);\n const result = await client.get<ExecutionsResponse>(\n `/projects/${projectId}/functions/${fn.id}/executions?limit=${limit}`,\n );\n\n const executions = result.items || result.data?.items || [];\n\n if (isJsonMode()) {\n json(executions);\n return;\n }\n\n if (executions.length === 0) {\n info('No executions found');\n return;\n }\n\n for (const exec of executions) {\n const date = new Date(exec.startedAt).toLocaleString();\n const duration = exec.duration ? `${exec.duration}ms` : '-';\n info(\n `[${exec.status}] ${date} (${duration}) - ${exec.triggeredBy}${exec.error ? ` - ${exec.error}` : ''}`,\n );\n\n if (exec.logs && exec.logs.length > 0) {\n for (const log of exec.logs) {\n const logTime = new Date(log.timestamp).toLocaleTimeString();\n info(` ${logTime} [${log.level}] ${log.message}`);\n }\n }\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to get logs');\n process.exitCode = 1;\n }\n });\n\n const envCmd = functions\n .command('env')\n .description('Manage function environment variables');\n\n envCmd\n .command('set <name> <keyValue>')\n .description('Set an environment variable (KEY=VALUE)')\n .option('--project <id>', 'Project ID')\n .action(async (name: string, keyValue: string, opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n const client = new ApiClient({ apiUrl, token, projectId });\n\n const eqIndex = keyValue.indexOf('=');\n if (eqIndex === -1) {\n throw new Error('Format must be KEY=VALUE');\n }\n const key = keyValue.substring(0, eqIndex);\n const value = keyValue.substring(eqIndex + 1);\n\n const fn = await findFunctionByName(client, projectId, name);\n\n // Merge with current env vars\n const currentVars = fn.environmentVariables || {};\n const updatedVars = { ...currentVars, [key]: value };\n\n await client.patch(\n `/projects/${projectId}/functions/${fn.id}`,\n { environmentVariables: updatedVars },\n );\n\n info(`Set ${key} for function \"${name}\"`);\n } catch (err) {\n error(err instanceof Error ? err.message : 'Failed to set env var');\n process.exitCode = 1;\n }\n });\n\n envCmd\n .command('list <name>')\n .description('List environment variables for a function')\n .option('--project <id>', 'Project ID')\n .action(async (name: string, opts, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GlobalOptions>();\n const config = loadConfig();\n const apiUrl = resolveApiUrl(globalOpts.apiUrl, config);\n\n try {\n const token = await requireAuth(globalOpts.token);\n const projectId = resolveProjectId(opts.project, config);\n const client = new ApiClient({ apiUrl, token, projectId });\n\n const fn = await findFunctionByName(client, projectId, name);\n\n const vars = fn.environmentVariables || {};\n const keys = Object.keys(vars);\n\n if (isJsonMode()) {\n json(vars);\n return;\n }\n\n if (keys.length === 0) {\n info('No environment variables set');\n return;\n }\n\n for (const key of keys) {\n info(`${key}=${vars[key]}`);\n }\n } catch (err) {\n error(\n err instanceof Error ? err.message : 'Failed to list env vars',\n );\n process.exitCode = 1;\n }\n });\n\n return functions;\n}\n\n/** Look up a function by name from the list endpoint. */\nasync function findFunctionByName(\n client: ApiClient,\n projectId: string,\n name: string,\n): Promise<FunctionEntry> {\n const result = await client.get<FunctionEntry[] | FunctionListResponse>(\n `/projects/${projectId}/functions`,\n );\n\n const fnList: FunctionEntry[] = Array.isArray(result)\n ? result\n : (result as FunctionListResponse).data || [];\n\n const fn = fnList.find((f) => f.name === name);\n if (!fn) {\n throw new Error(`Function \"${name}\" not found`);\n }\n return fn;\n}\n\nfunction collectEnvVars(\n value: string,\n previous: Record<string, string>,\n): Record<string, string> {\n const eqIndex = value.indexOf('=');\n if (eqIndex === -1) return previous;\n const key = value.substring(0, eqIndex);\n const val = value.substring(eqIndex + 1);\n return { ...previous, [key]: val };\n}\n"],"mappings":"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","names":["import_commander","pc","ora","crypto","fs","path","open","resolve","import_commander","import_commander","path","import_commander","import_commander","resolve","fs","path","import_commander","path","import_commander","fs","path","resolve","archiver","resolve","import_commander","import_commander","import_commander","import_commander","import_commander","path","import_commander"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spacelr/cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "CLI tool for the Spacelr platform - deploy hosting sites and manage databases",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",