freestyle 0.1.46 → 0.1.47

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/cli.mjs CHANGED
@@ -6,7 +6,7 @@ import { Freestyle, VmSpec } from './index.mjs';
6
6
  import * as fs from 'fs';
7
7
  import * as path from 'path';
8
8
  import * as os from 'os';
9
- import { spawn } from 'child_process';
9
+ import { spawn, spawnSync } from 'child_process';
10
10
 
11
11
  const DEFAULT_STACK_API_URL = "https://api.stack-auth.com";
12
12
  const DEFAULT_STACK_APP_URL = "https://dash.freestyle.sh";
@@ -1105,6 +1105,27 @@ const runCommand = {
1105
1105
  }
1106
1106
  };
1107
1107
 
1108
+ function spawnGit(args) {
1109
+ return new Promise((resolve, reject) => {
1110
+ const sigintHandler = () => {
1111
+ };
1112
+ process.on("SIGINT", sigintHandler);
1113
+ const child = spawn("git", args, { stdio: "inherit" });
1114
+ child.on("error", (err) => {
1115
+ process.off("SIGINT", sigintHandler);
1116
+ reject(err);
1117
+ });
1118
+ child.on("close", (code, signal) => {
1119
+ process.off("SIGINT", sigintHandler);
1120
+ if (code === 0) {
1121
+ resolve();
1122
+ } else {
1123
+ const detail = signal ? `signal ${signal}` : `exit code ${code}`;
1124
+ reject(new Error(`git ${args[0]} failed with ${detail}`));
1125
+ }
1126
+ });
1127
+ });
1128
+ }
1108
1129
  const gitCommand = {
1109
1130
  command: "git <action>",
1110
1131
  describe: "Manage Git repositories",
@@ -1224,6 +1245,99 @@ Total: ${repos.total}`);
1224
1245
  handleError(error);
1225
1246
  }
1226
1247
  }
1248
+ ).command(
1249
+ "clone <repoId> [directory]",
1250
+ "Clone a repo and persist an access token in the checkout so git push/pull work",
1251
+ (yargs2) => {
1252
+ return yargs2.positional("repoId", {
1253
+ type: "string",
1254
+ description: "Repository ID to clone",
1255
+ demandOption: true
1256
+ }).positional("directory", {
1257
+ type: "string",
1258
+ description: "Destination directory (defaults to <repoId>)"
1259
+ }).option("readonly", {
1260
+ type: "boolean",
1261
+ description: "Provision a read-only token instead of read/write",
1262
+ default: false
1263
+ });
1264
+ },
1265
+ async (argv) => {
1266
+ loadEnv();
1267
+ const args = argv;
1268
+ const permission = args.readonly ? "read" : "write";
1269
+ const destination = args.directory ?? args.repoId;
1270
+ const freestyle = await getFreestyleClient();
1271
+ let identityId;
1272
+ let tokenId;
1273
+ let cloneSucceeded = false;
1274
+ try {
1275
+ console.log(
1276
+ `Provisioning ${permission} access token for ${args.repoId}...`
1277
+ );
1278
+ const { identity, identityId: newIdentityId } = await freestyle.identities.create();
1279
+ identityId = newIdentityId;
1280
+ await identity.permissions.git.grant({
1281
+ repoId: args.repoId,
1282
+ permission
1283
+ });
1284
+ const created = await identity.tokens.create();
1285
+ tokenId = created.tokenId;
1286
+ const url = new URL(`/${args.repoId}`, "https://git.freestyle.sh");
1287
+ url.username = "x-access-token";
1288
+ url.password = created.token;
1289
+ console.log(`Cloning repository ${args.repoId} into ${destination}...`);
1290
+ await spawnGit([
1291
+ "clone",
1292
+ url.toString(),
1293
+ ...args.directory ? [args.directory] : []
1294
+ ]);
1295
+ spawnSync(
1296
+ "git",
1297
+ ["-C", destination, "config", "freestyle.identityId", identityId],
1298
+ { stdio: "ignore" }
1299
+ );
1300
+ spawnSync(
1301
+ "git",
1302
+ ["-C", destination, "config", "freestyle.tokenId", tokenId],
1303
+ { stdio: "ignore" }
1304
+ );
1305
+ spawnSync(
1306
+ "git",
1307
+ ["-C", destination, "config", "freestyle.permission", permission],
1308
+ { stdio: "ignore" }
1309
+ );
1310
+ cloneSucceeded = true;
1311
+ console.log(`
1312
+ \u2713 Clone complete (${permission} access)`);
1313
+ console.log(
1314
+ ` The access token is stored in ${destination}/.git/config;`
1315
+ );
1316
+ console.log(
1317
+ ` git push and git pull will work from inside ${destination}.`
1318
+ );
1319
+ } catch (error) {
1320
+ handleError(error);
1321
+ } finally {
1322
+ if (!cloneSucceeded) {
1323
+ if (tokenId && identityId) {
1324
+ try {
1325
+ const identity = freestyle.identities.ref({ identityId });
1326
+ await identity.tokens.revoke({ tokenId });
1327
+ } catch (err) {
1328
+ console.error("Warning: failed to revoke token:", err);
1329
+ }
1330
+ }
1331
+ if (identityId) {
1332
+ try {
1333
+ await freestyle.identities.delete({ identityId });
1334
+ } catch (err) {
1335
+ console.error("Warning: failed to delete identity:", err);
1336
+ }
1337
+ }
1338
+ }
1339
+ }
1340
+ }
1227
1341
  ).command(
1228
1342
  "delete <repoId>",
1229
1343
  "Delete a git repository",
@@ -1923,7 +2037,7 @@ const loginCommand = {
1923
2037
  if (teams.length > 1) {
1924
2038
  console.log(
1925
2039
  `
1926
- \u2139\uFE0F You have ${teams.length} teams. Use 'freestyle team switch' to change teams.`
2040
+ \u2139\uFE0F You have ${teams.length} teams.`
1927
2041
  );
1928
2042
  }
1929
2043
  } catch (error) {
package/index.d.cts CHANGED
@@ -5009,6 +5009,18 @@ interface PostV1VmsRequestBody {
5009
5009
  vmPort?: number | null;
5010
5010
  }[] | null;
5011
5011
  activityThresholdBytes?: number | null;
5012
+ /**
5013
+ * Optional Docker registry credentials required when using a private image
5014
+ * in `baseImage` or `template.baseImage`.
5015
+ */
5016
+ dockerCredentials?: null | {
5017
+ /** Docker registry URL (e.g., "ghcr.io", "docker.io") */
5018
+ registry: string;
5019
+ /** Username for the registry */
5020
+ username: string;
5021
+ /** Password or token for the registry */
5022
+ password: string;
5023
+ };
5012
5024
  }
5013
5025
  interface GetV1VmsSnapshotsQueryParams {
5014
5026
  includeDeleted?: boolean | null;
@@ -5375,6 +5387,18 @@ interface PostV1VmsSnapshotsRequestBody {
5375
5387
  } | {
5376
5388
  type: "persistent";
5377
5389
  });
5390
+ /**
5391
+ * Optional Docker registry credentials required when using a private image
5392
+ * in `template.baseImage`.
5393
+ */
5394
+ dockerCredentials?: null | {
5395
+ /** Docker registry URL (e.g., "ghcr.io", "docker.io") */
5396
+ registry: string;
5397
+ /** Username for the registry */
5398
+ username: string;
5399
+ /** Password or token for the registry */
5400
+ password: string;
5401
+ };
5378
5402
  }
5379
5403
  interface DeleteV1VmsSnapshotsSnapshotIdPathParams {
5380
5404
  /**
@@ -13361,6 +13385,10 @@ declare const VmBuilder: typeof VmWith;
13361
13385
  type RawBaseImage = {
13362
13386
  dockerfileContent: string;
13363
13387
  };
13388
+ /**
13389
+ * Docker registry credentials for pulling private images.
13390
+ */
13391
+ type DockerCredentials = NonNullable<PostV1VmsRequestBody["dockerCredentials"]>;
13364
13392
  /**
13365
13393
  * The raw systemd service type from the generated API
13366
13394
  */
@@ -13852,4 +13880,4 @@ declare class Freestyle {
13852
13880
  declare const freestyle: Freestyle;
13853
13881
 
13854
13882
  export { CronNamespace, Deployment, errors as Errors, FileSystem, Freestyle, GitRepo, Identity, requests as Requests, responses as Responses, Systemd, SystemdService, Vm, VmBaseImage, VmBuilder, VmService, VmSpec, VmTemplate, VmWith, VmWithInstance, debugCreateRequests, freestyle, readFiles };
13855
- export type { BackgroundRequestLogger, CreateVmOptions, CronSchedule, FreestyleOptions, GitCommitSearchEntry, GitCommitSearchResult, GitDiffFileMatch, GitDiffLineMatch, GitDiffSearchCommit, GitDiffSearchResult, GitFilenameEntry, GitFilenameSearchResult, GitSearchFileResult, GitSearchLineMatch, GitSearchResult, SystemdServiceInput, VmWaitForConfig, VmWithDefaultFieldRecord };
13883
+ export type { BackgroundRequestLogger, CreateVmOptions, CronSchedule, DockerCredentials, FreestyleOptions, GitCommitSearchEntry, GitCommitSearchResult, GitDiffFileMatch, GitDiffLineMatch, GitDiffSearchCommit, GitDiffSearchResult, GitFilenameEntry, GitFilenameSearchResult, GitSearchFileResult, GitSearchLineMatch, GitSearchResult, SystemdServiceInput, VmWaitForConfig, VmWithDefaultFieldRecord };
package/index.d.mts CHANGED
@@ -5009,6 +5009,18 @@ interface PostV1VmsRequestBody {
5009
5009
  vmPort?: number | null;
5010
5010
  }[] | null;
5011
5011
  activityThresholdBytes?: number | null;
5012
+ /**
5013
+ * Optional Docker registry credentials required when using a private image
5014
+ * in `baseImage` or `template.baseImage`.
5015
+ */
5016
+ dockerCredentials?: null | {
5017
+ /** Docker registry URL (e.g., "ghcr.io", "docker.io") */
5018
+ registry: string;
5019
+ /** Username for the registry */
5020
+ username: string;
5021
+ /** Password or token for the registry */
5022
+ password: string;
5023
+ };
5012
5024
  }
5013
5025
  interface GetV1VmsSnapshotsQueryParams {
5014
5026
  includeDeleted?: boolean | null;
@@ -5375,6 +5387,18 @@ interface PostV1VmsSnapshotsRequestBody {
5375
5387
  } | {
5376
5388
  type: "persistent";
5377
5389
  });
5390
+ /**
5391
+ * Optional Docker registry credentials required when using a private image
5392
+ * in `template.baseImage`.
5393
+ */
5394
+ dockerCredentials?: null | {
5395
+ /** Docker registry URL (e.g., "ghcr.io", "docker.io") */
5396
+ registry: string;
5397
+ /** Username for the registry */
5398
+ username: string;
5399
+ /** Password or token for the registry */
5400
+ password: string;
5401
+ };
5378
5402
  }
5379
5403
  interface DeleteV1VmsSnapshotsSnapshotIdPathParams {
5380
5404
  /**
@@ -13361,6 +13385,10 @@ declare const VmBuilder: typeof VmWith;
13361
13385
  type RawBaseImage = {
13362
13386
  dockerfileContent: string;
13363
13387
  };
13388
+ /**
13389
+ * Docker registry credentials for pulling private images.
13390
+ */
13391
+ type DockerCredentials = NonNullable<PostV1VmsRequestBody["dockerCredentials"]>;
13364
13392
  /**
13365
13393
  * The raw systemd service type from the generated API
13366
13394
  */
@@ -13852,4 +13880,4 @@ declare class Freestyle {
13852
13880
  declare const freestyle: Freestyle;
13853
13881
 
13854
13882
  export { CronNamespace, Deployment, errors as Errors, FileSystem, Freestyle, GitRepo, Identity, requests as Requests, responses as Responses, Systemd, SystemdService, Vm, VmBaseImage, VmBuilder, VmService, VmSpec, VmTemplate, VmWith, VmWithInstance, debugCreateRequests, freestyle, readFiles };
13855
- export type { BackgroundRequestLogger, CreateVmOptions, CronSchedule, FreestyleOptions, GitCommitSearchEntry, GitCommitSearchResult, GitDiffFileMatch, GitDiffLineMatch, GitDiffSearchCommit, GitDiffSearchResult, GitFilenameEntry, GitFilenameSearchResult, GitSearchFileResult, GitSearchLineMatch, GitSearchResult, SystemdServiceInput, VmWaitForConfig, VmWithDefaultFieldRecord };
13883
+ export type { BackgroundRequestLogger, CreateVmOptions, CronSchedule, DockerCredentials, FreestyleOptions, GitCommitSearchEntry, GitCommitSearchResult, GitDiffFileMatch, GitDiffLineMatch, GitDiffSearchCommit, GitDiffSearchResult, GitFilenameEntry, GitFilenameSearchResult, GitSearchFileResult, GitSearchLineMatch, GitSearchResult, SystemdServiceInput, VmWaitForConfig, VmWithDefaultFieldRecord };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "freestyle",
3
- "version": "0.1.46",
3
+ "version": "0.1.47",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "require": {