@lizard-build/sdk 0.1.73 → 0.1.74

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.d.mts CHANGED
@@ -967,7 +967,11 @@ declare class GitReposAPI {
967
967
  /** Who moved which branch, when. */
968
968
  reflog(repo: RepoRef, ref?: string): Promise<unknown[]>;
969
969
  archive(repo: RepoRef, ref: string, format?: 'zip' | 'tar.gz'): Promise<Uint8Array>;
970
- /** The HTTPS clone URL. With `withKey`, it carries the API key, so plain `git clone` works without a helper. */
970
+ /**
971
+ * The HTTPS clone URL. With `withKey`, it carries the API key, so plain `git clone` works
972
+ * without a helper; git then keeps it in .git/config. For anything shared or logged, use a
973
+ * limited Lizard Git token (`tokens.create`) as `apiKey` instead of the account's key.
974
+ */
971
975
  cloneUrl(repo: RepoRef, opts?: {
972
976
  withKey?: boolean;
973
977
  }): string;
package/dist/index.d.ts CHANGED
@@ -967,7 +967,11 @@ declare class GitReposAPI {
967
967
  /** Who moved which branch, when. */
968
968
  reflog(repo: RepoRef, ref?: string): Promise<unknown[]>;
969
969
  archive(repo: RepoRef, ref: string, format?: 'zip' | 'tar.gz'): Promise<Uint8Array>;
970
- /** The HTTPS clone URL. With `withKey`, it carries the API key, so plain `git clone` works without a helper. */
970
+ /**
971
+ * The HTTPS clone URL. With `withKey`, it carries the API key, so plain `git clone` works
972
+ * without a helper; git then keeps it in .git/config. For anything shared or logged, use a
973
+ * limited Lizard Git token (`tokens.create`) as `apiKey` instead of the account's key.
974
+ */
971
975
  cloneUrl(repo: RepoRef, opts?: {
972
976
  withKey?: boolean;
973
977
  }): string;
package/dist/index.js CHANGED
@@ -559,9 +559,14 @@ function qs(path, values) {
559
559
  for (const [k, v] of Object.entries(values)) if (v !== void 0 && v !== "") q.set(k, String(v));
560
560
  return q.size ? `${path}?${q}` : path;
561
561
  }
562
+ function segs(p) {
563
+ const parts = p.split("/");
564
+ if (parts.some((x) => x === "" || x === "." || x === "..")) throw new Error(`bad path: "${p}"`);
565
+ return parts.map(seg).join("/");
566
+ }
562
567
  function repoPath(repo) {
563
568
  const m = /^([^/\s]+)\/([^/\s]+?)(\.git)?$/.exec(repo);
564
- if (!m) throw new Error(`repository must be "owner/name", got "${repo}"`);
569
+ if (!m || [m[1], m[2]].some((x) => x === "." || x === "..")) throw new Error(`repository must be "owner/name", got "${repo}"`);
565
570
  return `/api/repos/${seg(m[1])}/${seg(m[2])}`;
566
571
  }
567
572
  var GitClient = class {
@@ -574,6 +579,8 @@ var GitClient = class {
574
579
  method,
575
580
  body,
576
581
  headers: { "X-API-Key": this.config.apiKey, ...headers },
582
+ redirect: "error",
583
+ // a redirect would carry the key to wherever it points
577
584
  signal: AbortSignal.timeout(this.config.requestTimeoutMs)
578
585
  });
579
586
  if (!res.ok) await handleApiError(res);
@@ -650,7 +657,7 @@ var GitReposAPI = class {
650
657
  return this.c.post(`${repoPath(repo)}/branches`, { name, from });
651
658
  }
652
659
  deleteBranch(repo, name) {
653
- return this.c.delete(`${repoPath(repo)}/branches/${name.split("/").map(seg).join("/")}`);
660
+ return this.c.delete(`${repoPath(repo)}/branches/${segs(name)}`);
654
661
  }
655
662
  tree(repo, opts = {}) {
656
663
  return this.c.get(qs(`${repoPath(repo)}/tree`, opts));
@@ -661,8 +668,9 @@ var GitReposAPI = class {
661
668
  }
662
669
  /** A file's bytes, whatever its size or type. */
663
670
  raw(repo, path, ref) {
671
+ repoPath(repo);
664
672
  const [owner, name] = repo.split("/");
665
- return this.c.bytes(`/raw/${seg(owner)}/${seg(name)}/${ref.split("/").map(seg).join("/")}/${path.split("/").map(seg).join("/")}`);
673
+ return this.c.bytes(`/raw/${seg(owner)}/${seg(name)}/${segs(ref)}/${segs(path)}`);
666
674
  }
667
675
  /** Every file path at a ref. */
668
676
  files(repo, ref) {
@@ -696,7 +704,11 @@ var GitReposAPI = class {
696
704
  archive(repo, ref, format = "tar.gz") {
697
705
  return this.c.bytes(`${repoPath(repo)}/archive/${seg(ref)}.${format}`);
698
706
  }
699
- /** The HTTPS clone URL. With `withKey`, it carries the API key, so plain `git clone` works without a helper. */
707
+ /**
708
+ * The HTTPS clone URL. With `withKey`, it carries the API key, so plain `git clone` works
709
+ * without a helper; git then keeps it in .git/config. For anything shared or logged, use a
710
+ * limited Lizard Git token (`tokens.create`) as `apiKey` instead of the account's key.
711
+ */
700
712
  cloneUrl(repo, opts = {}) {
701
713
  repoPath(repo);
702
714
  const u = new URL(`${this.c.url}/${repo.replace(/\.git$/, "")}.git`);
package/dist/index.mjs CHANGED
@@ -489,9 +489,14 @@ function qs(path, values) {
489
489
  for (const [k, v] of Object.entries(values)) if (v !== void 0 && v !== "") q.set(k, String(v));
490
490
  return q.size ? `${path}?${q}` : path;
491
491
  }
492
+ function segs(p) {
493
+ const parts = p.split("/");
494
+ if (parts.some((x) => x === "" || x === "." || x === "..")) throw new Error(`bad path: "${p}"`);
495
+ return parts.map(seg).join("/");
496
+ }
492
497
  function repoPath(repo) {
493
498
  const m = /^([^/\s]+)\/([^/\s]+?)(\.git)?$/.exec(repo);
494
- if (!m) throw new Error(`repository must be "owner/name", got "${repo}"`);
499
+ if (!m || [m[1], m[2]].some((x) => x === "." || x === "..")) throw new Error(`repository must be "owner/name", got "${repo}"`);
495
500
  return `/api/repos/${seg(m[1])}/${seg(m[2])}`;
496
501
  }
497
502
  var GitClient = class {
@@ -504,6 +509,8 @@ var GitClient = class {
504
509
  method,
505
510
  body,
506
511
  headers: { "X-API-Key": this.config.apiKey, ...headers },
512
+ redirect: "error",
513
+ // a redirect would carry the key to wherever it points
507
514
  signal: AbortSignal.timeout(this.config.requestTimeoutMs)
508
515
  });
509
516
  if (!res.ok) await handleApiError(res);
@@ -580,7 +587,7 @@ var GitReposAPI = class {
580
587
  return this.c.post(`${repoPath(repo)}/branches`, { name, from });
581
588
  }
582
589
  deleteBranch(repo, name) {
583
- return this.c.delete(`${repoPath(repo)}/branches/${name.split("/").map(seg).join("/")}`);
590
+ return this.c.delete(`${repoPath(repo)}/branches/${segs(name)}`);
584
591
  }
585
592
  tree(repo, opts = {}) {
586
593
  return this.c.get(qs(`${repoPath(repo)}/tree`, opts));
@@ -591,8 +598,9 @@ var GitReposAPI = class {
591
598
  }
592
599
  /** A file's bytes, whatever its size or type. */
593
600
  raw(repo, path, ref) {
601
+ repoPath(repo);
594
602
  const [owner, name] = repo.split("/");
595
- return this.c.bytes(`/raw/${seg(owner)}/${seg(name)}/${ref.split("/").map(seg).join("/")}/${path.split("/").map(seg).join("/")}`);
603
+ return this.c.bytes(`/raw/${seg(owner)}/${seg(name)}/${segs(ref)}/${segs(path)}`);
596
604
  }
597
605
  /** Every file path at a ref. */
598
606
  files(repo, ref) {
@@ -626,7 +634,11 @@ var GitReposAPI = class {
626
634
  archive(repo, ref, format = "tar.gz") {
627
635
  return this.c.bytes(`${repoPath(repo)}/archive/${seg(ref)}.${format}`);
628
636
  }
629
- /** The HTTPS clone URL. With `withKey`, it carries the API key, so plain `git clone` works without a helper. */
637
+ /**
638
+ * The HTTPS clone URL. With `withKey`, it carries the API key, so plain `git clone` works
639
+ * without a helper; git then keeps it in .git/config. For anything shared or logged, use a
640
+ * limited Lizard Git token (`tokens.create`) as `apiKey` instead of the account's key.
641
+ */
630
642
  cloneUrl(repo, opts = {}) {
631
643
  repoPath(repo);
632
644
  const u = new URL(`${this.c.url}/${repo.replace(/\.git$/, "")}.git`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lizard-build/sdk",
3
- "version": "0.1.73",
3
+ "version": "0.1.74",
4
4
  "description": "TypeScript SDK for Lizard: Firecracker microVM sandboxes, code execution and cloud apps.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",