@superblocksteam/sdk 2.0.6-next.66 → 2.0.6-next.68

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/src/client.ts CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  NotFoundError,
12
12
  BadRequestError,
13
13
  unreachable,
14
+ getSuperblocksDevEnvironmentConfigJson,
14
15
  } from "@superblocksteam/util";
15
16
  import axios, { AxiosError } from "axios";
16
17
  import FormData from "form-data";
@@ -24,6 +25,10 @@ import { signingEnabled } from "./flag.js";
24
25
  import { connectToISocketRPCServer } from "./socket/index.js";
25
26
  import { AgentType } from "./types/index.js";
26
27
  import { getAgentUrl } from "./utils.js";
28
+ import {
29
+ DEFAULT_BRANCH,
30
+ getCurrentGitBranchIfGit,
31
+ } from "./version-control.mjs";
27
32
  import type { StdISocketRPCClient } from "./socket/index.js";
28
33
  import type {
29
34
  ApiWithPb,
@@ -133,6 +138,116 @@ enum ResourceType {
133
138
  BACKEND = "BACKEND",
134
139
  }
135
140
 
141
+ export enum BranchSource {
142
+ DEV_ENVIRONMENT = "dev environment config file",
143
+ COMMAND_LINE = "command line",
144
+ GIT_REPO = "current git repository",
145
+ DEFAULT = "default",
146
+ }
147
+
148
+ export class CurrentBranch {
149
+ public readonly branchName: string;
150
+ public readonly source: BranchSource;
151
+ public readonly sourcePath?: string;
152
+ public readonly userSpecifiedBranch?: string;
153
+
154
+ constructor({
155
+ branchName,
156
+ source,
157
+ sourcePath,
158
+ userSpecifiedBranch,
159
+ }: {
160
+ branchName: string;
161
+ source: BranchSource;
162
+ sourcePath?: string;
163
+ userSpecifiedBranch?: string;
164
+ }) {
165
+ this.branchName = branchName;
166
+ this.source = source;
167
+ this.sourcePath = sourcePath;
168
+ this.userSpecifiedBranch = userSpecifiedBranch;
169
+ }
170
+ isDevEnvironmentWithUserSpecifiedBranch() {
171
+ return (
172
+ this.isDefinedInDevEnvironmentConfig() &&
173
+ this.userSpecifiedBranch !== undefined
174
+ );
175
+ }
176
+ isDefinedInDevEnvironmentConfig(): boolean {
177
+ return this.source === BranchSource.DEV_ENVIRONMENT;
178
+ }
179
+ isDefaultBranch(): boolean {
180
+ return this.source === BranchSource.DEFAULT;
181
+ }
182
+ isGitBranch(): boolean {
183
+ return this.source === BranchSource.GIT_REPO;
184
+ }
185
+ }
186
+
187
+ const DEFAULT_BRANCH_INFO = new CurrentBranch({
188
+ branchName: DEFAULT_BRANCH,
189
+ source: BranchSource.DEFAULT,
190
+ });
191
+
192
+ // TODO (randall): Remove this and the 'index.ts' export when it is no longer needed in the CLI.
193
+ export function getDefaultBranchInfo(): CurrentBranch {
194
+ return DEFAULT_BRANCH_INFO;
195
+ }
196
+
197
+ /**
198
+ * Returns the current branch name, in the following order of precedence:
199
+ * 1. If a branch name is specified in the dev environment config, use that
200
+ * 2. If a branch name is specified, use that
201
+ * 3. If this is in a git repo, use the current branch
202
+ * 4. If this is not in a git repo, use the default branch
203
+ * @param userSpecifiedBranch - The branch name specified by the user
204
+ * @param pathPrefix - The path prefix to use when looking for the dev environment config
205
+ * @returns The current branch information
206
+ */
207
+ export async function getCurrentBranchInfo(
208
+ userSpecifiedBranch?: string,
209
+ pathPrefix?: string,
210
+ ): Promise<CurrentBranch> {
211
+ // First, if there is a dev environment config and a branch name is specified, use that
212
+ try {
213
+ const [devEnvironmentConfig, devEnvConfigPath] =
214
+ await getSuperblocksDevEnvironmentConfigJson(true, pathPrefix);
215
+ if (devEnvironmentConfig.branch) {
216
+ return new CurrentBranch({
217
+ branchName: devEnvironmentConfig.branch,
218
+ source: BranchSource.DEV_ENVIRONMENT,
219
+ sourcePath: devEnvConfigPath,
220
+ userSpecifiedBranch: userSpecifiedBranch,
221
+ });
222
+ }
223
+ } catch {
224
+ // Did not find or could not parse the dev environment config, so continue
225
+ }
226
+ // Second, if the user specified a branch name, use that
227
+ if (userSpecifiedBranch) {
228
+ return new CurrentBranch({
229
+ branchName: userSpecifiedBranch,
230
+ source: BranchSource.COMMAND_LINE,
231
+ userSpecifiedBranch: userSpecifiedBranch,
232
+ });
233
+ }
234
+ // Third, if this is in a git repo, use the current branch
235
+ const currentGitBranch = await getCurrentGitBranchIfGit();
236
+ if (currentGitBranch) {
237
+ return new CurrentBranch({
238
+ branchName: currentGitBranch,
239
+ source: BranchSource.GIT_REPO,
240
+ userSpecifiedBranch: userSpecifiedBranch,
241
+ });
242
+ }
243
+ // Fourth, if this is not in a git repo, use the default branch
244
+ return new CurrentBranch({
245
+ branchName: DEFAULT_BRANCH,
246
+ source: BranchSource.DEFAULT,
247
+ userSpecifiedBranch: userSpecifiedBranch,
248
+ });
249
+ }
250
+
136
251
  export async function fetchApplication({
137
252
  cliVersion,
138
253
  applicationId,
package/src/index.ts CHANGED
@@ -11,6 +11,8 @@ export {
11
11
  fetchApplicationWithComponents,
12
12
  fetchApplications,
13
13
  fetchCurrentUser,
14
+ getDefaultBranchInfo,
15
+ getCurrentBranchInfo,
14
16
  pushApi,
15
17
  pushApplication,
16
18
  registerComponents,
@@ -20,8 +22,10 @@ export {
20
22
  type ApplicationWrapper,
21
23
  type Branch,
22
24
  type Branches,
25
+ type BranchSource,
23
26
  type CodeModeApplicationWrapper,
24
27
  type CommitDto,
28
+ type CurrentBranch,
25
29
  type GetCommitsResponseBody,
26
30
  type MultiPageApplicationWrapper,
27
31
  type MultiPageApplicationWrapperWithComponents,
@@ -0,0 +1,120 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { expect } from "chai";
4
+ import { describe, it } from "mocha";
5
+ import { BranchSource, getCurrentBranchInfo } from "../src/client.js";
6
+ import { getCurrentGitBranch } from "../src/version-control.mjs";
7
+ import type { SuperblocksDevEnvironmentConfig } from "@superblocksteam/util";
8
+
9
+ // The .superblocks folder is located in the 'test' directory, so we need to prefix the path in order to find it.
10
+ const testPathPrefix = "test";
11
+ const superblocksTestFolder = path.join(
12
+ process.cwd(),
13
+ testPathPrefix,
14
+ ".superblocks",
15
+ );
16
+ const devEnvBranch = "dev-branch";
17
+ const currentGitBranch = await getCurrentGitBranch();
18
+
19
+ describe("get current branch info", () => {
20
+ let createdSuperblocksFolder = false;
21
+
22
+ before(async function () {
23
+ // Make the .superblocks folder in the test directory, if it is missing. It should be git-ignored.
24
+ if (!fs.existsSync(superblocksTestFolder)) {
25
+ fs.mkdirSync(superblocksTestFolder, { recursive: true });
26
+ createdSuperblocksFolder = true;
27
+ }
28
+ // Create a dev-environment.json file in the .superblocks folder.
29
+ const devEnvironmentJson = path.join(
30
+ superblocksTestFolder,
31
+ "dev-environment.json",
32
+ );
33
+ fs.writeFileSync(
34
+ devEnvironmentJson,
35
+ JSON.stringify({
36
+ branch: devEnvBranch,
37
+ configType: "DEV_ENVIRONMENT",
38
+ } as SuperblocksDevEnvironmentConfig),
39
+ );
40
+ });
41
+
42
+ after(async function () {
43
+ // Delete the .superblocks folder in the test directory.
44
+ if (createdSuperblocksFolder && fs.existsSync(superblocksTestFolder)) {
45
+ fs.rmSync(superblocksTestFolder, { recursive: true });
46
+ }
47
+ });
48
+
49
+ it("should find the dev environment config and return a valid branch info object", async () => {
50
+ const branchInfo = await getCurrentBranchInfo(undefined, testPathPrefix);
51
+
52
+ expect(branchInfo.branchName).to.equal(devEnvBranch);
53
+ expect(branchInfo.source).to.equal(BranchSource.DEV_ENVIRONMENT);
54
+ expect(branchInfo.userSpecifiedBranch).to.be.undefined;
55
+ expect(branchInfo.isDefinedInDevEnvironmentConfig()).to.be.true;
56
+ expect(branchInfo.isDevEnvironmentWithUserSpecifiedBranch()).to.be.false;
57
+ expect(branchInfo.isDefaultBranch()).to.be.false;
58
+
59
+ // Call it again to make sure it has the same properties
60
+ const branchInfo2 = await getCurrentBranchInfo(undefined, testPathPrefix);
61
+ expect(branchInfo).to.deep.equal(branchInfo2);
62
+ });
63
+
64
+ it("should find the dev environment config and include the user-specified branch parameter", async () => {
65
+ const userBranch = "test-user-branch";
66
+ const branchInfo = await getCurrentBranchInfo(userBranch, testPathPrefix);
67
+
68
+ expect(branchInfo.branchName).to.equal(devEnvBranch);
69
+ expect(branchInfo.source).to.equal(BranchSource.DEV_ENVIRONMENT);
70
+ expect(branchInfo.userSpecifiedBranch).to.equal(userBranch);
71
+ expect(branchInfo.isDefinedInDevEnvironmentConfig()).to.be.true;
72
+ expect(branchInfo.isDevEnvironmentWithUserSpecifiedBranch()).to.be.true;
73
+ expect(branchInfo.isDefaultBranch()).to.be.false;
74
+
75
+ // Call it again to make sure it's the same object
76
+ const branchInfo2 = await getCurrentBranchInfo(userBranch, testPathPrefix);
77
+ expect(branchInfo).to.deep.equal(branchInfo2);
78
+
79
+ // Call it again without the test path will find the user supplied branch
80
+ const branchInfo3 = await getCurrentBranchInfo(userBranch);
81
+ expect(branchInfo3.branchName).to.equal(userBranch);
82
+ expect(branchInfo3.source).to.equal(BranchSource.COMMAND_LINE);
83
+ expect(branchInfo3.userSpecifiedBranch).to.equal(userBranch);
84
+ expect(branchInfo3.isDefinedInDevEnvironmentConfig()).to.be.false;
85
+ expect(branchInfo3.isDevEnvironmentWithUserSpecifiedBranch()).to.be.false;
86
+ expect(branchInfo3.isDefaultBranch()).to.be.false;
87
+ });
88
+
89
+ it("should not find a dev environment config and return an info with our git branch", async () => {
90
+ const branchInfo = await getCurrentBranchInfo();
91
+ expect(branchInfo.branchName).to.equal(currentGitBranch);
92
+ expect(branchInfo.source).to.equal(BranchSource.GIT_REPO);
93
+ expect(branchInfo.userSpecifiedBranch).to.be.undefined;
94
+ expect(branchInfo.isDefinedInDevEnvironmentConfig()).to.be.false;
95
+ expect(branchInfo.isDevEnvironmentWithUserSpecifiedBranch()).to.be.false;
96
+ expect(branchInfo.isDefaultBranch()).to.be.false;
97
+
98
+ // Call it again to make sure it's the same object
99
+ const branchInfo2 = await getCurrentBranchInfo();
100
+ expect(branchInfo).to.deep.equal(branchInfo2);
101
+ });
102
+
103
+ it("should not find a dev environment config and return an info with the user-specified branch", async () => {
104
+ const userBranch = "test-user-branch";
105
+ expect(userBranch).to.not.equal(devEnvBranch);
106
+ expect(userBranch).to.not.equal(currentGitBranch);
107
+
108
+ const branchInfo = await getCurrentBranchInfo(userBranch);
109
+ expect(branchInfo.branchName).to.equal(userBranch);
110
+ expect(branchInfo.source).to.equal(BranchSource.COMMAND_LINE);
111
+ expect(branchInfo.userSpecifiedBranch).to.equal(userBranch);
112
+ expect(branchInfo.isDefinedInDevEnvironmentConfig()).to.be.false;
113
+ expect(branchInfo.isDevEnvironmentWithUserSpecifiedBranch()).to.be.false;
114
+ expect(branchInfo.isDefaultBranch()).to.be.false;
115
+
116
+ // Call it again to make sure it's the same object
117
+ const branchInfo2 = await getCurrentBranchInfo(userBranch);
118
+ expect(branchInfo).to.deep.equal(branchInfo2);
119
+ });
120
+ });