Skip to content

Commit 1ffb0ed

Browse files
feat: use apiKey instead of jwt for requests (#98)
* use apiKey for requests * rename jwt to apiKey * add user id to messaging * hide link/org commands, org -> workspace * workspace ids --------- Co-authored-by: Pine <[email protected]>
1 parent 85c064b commit 1ffb0ed

File tree

9 files changed

+260
-221
lines changed

9 files changed

+260
-221
lines changed

.trunk/trunk.yaml

+8-8
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,19 @@ runtimes:
1818
# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration)
1919
lint:
2020
enabled:
21-
- trivy@0.59.1
21+
- trivy@0.60.0
2222
23-
24-
- eslint@9.19.0
23+
24+
- eslint@9.22.0
2525
- git-diff-check
2626
27-
- osv-scanner@1.9.2
28-
- prettier@3.4.2
29-
- renovate@39.161.0
27+
- osv-scanner@2.0.0
28+
- prettier@3.5.3
29+
- renovate@39.207.2
3030
3131
32-
33-
- yamllint@1.35.1
32+
33+
- yamllint@1.36.2
3434
actions:
3535
enabled:
3636
- trunk-announce

.vscode/settings.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@
22
"editor.formatOnSave": true,
33
"editor.defaultFormatter": "trunk.io",
44
"editor.trimAutoWhitespace": true,
5-
"trunk.autoInit": false
5+
"trunk.autoInit": false,
6+
"[typescript]": {
7+
"editor.defaultFormatter": "esbenp.prettier-vscode"
8+
}
69
}

src/commands/link/index.ts

+145-147
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,17 @@
44
*/
55

66
import { Command } from "@oclif/core";
7-
import chalk from "chalk";
8-
import * as fs from "../../util/fs.js";
97
import * as http from "node:http";
108
import { URL } from "node:url";
119
import open from "open";
12-
import { execSync } from "child_process";
13-
import path from "path";
14-
15-
import { ciStr } from "../../util/ci.js";
16-
import { getProjectsByOrgReq, sendMapRepoAndFinishProjectCreationReq, sendCreateProjectReq, sendGetRepoIdReq } from "../../util/graphql.js";
17-
import { confirmExistingProjectLink, confirmOverwriteCiHypFile, fileExists, getCiHypFilePath, getSettingsFilePath, getGitConfigFilePath, getGitRemoteUrl, getGithubWorkflowDir, promptProjectLinkSelection, promptProjectName, readSettingsJson, writeGithubInstallationIdToSettingsFile } from "../../util/index.js";
1810

1911
export default class LinkIndex extends Command {
12+
static override hidden = true;
13+
2014
static override args = {};
2115

22-
static override description = "Link a repo with a Modus App to a Hypermode Project";
16+
// static override description = "Link a repo with a Modus App to a Hypermode Project";
17+
static override description = "Temporarily disabled during migration";
2318

2419
static override examples = ["<%= config.bin %> <%= command.id %>"];
2520

@@ -100,135 +95,138 @@ export default class LinkIndex extends Command {
10095
}
10196

10297
public async run(): Promise<void> {
103-
// check if the directory has a .git/config with a remote named 'origin', if not, throw an error and ask them to set that up
104-
const gitConfigFilePath = getGitConfigFilePath();
105-
106-
if (!(await fileExists(gitConfigFilePath))) {
107-
throw new Error(chalk.red("No .git found in this directory. Please initialize a git repository with `git init`."));
108-
}
109-
110-
// Check if the current branch is 'main'
111-
let currentBranch = "";
112-
try {
113-
currentBranch = execSync("git symbolic-ref --short HEAD", { encoding: "utf-8" }).trim();
114-
} catch (error) {
115-
this.log(chalk.red("Unable to determine the current branch."));
116-
throw error;
117-
}
118-
119-
if (currentBranch !== "main") {
120-
this.log(chalk.red("You must be on the 'main' branch to link your repository."));
121-
this.log("Please switch to the 'main' branch:");
122-
this.log(` > ${chalk.blue("git checkout main")}`);
123-
this.log("or rename your current branch to 'main'.");
124-
this.log(` > ${chalk.blue("git branch -m main")}`);
125-
this.exit(1);
126-
}
127-
128-
const remoteUrl = await getGitRemoteUrl(gitConfigFilePath);
129-
130-
if (!remoteUrl) {
131-
this.log(chalk.red("`hyp link` requires a git remote to work"));
132-
const gitRoot = execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
133-
const projectName = path.basename(gitRoot);
134-
this.log(`Please create a GitHub repository: https://github.com/new?name=${projectName}`);
135-
this.log(`And push your code:`);
136-
this.log(` > ${chalk.blue("git remote add origin <GIT_URL>)")}`);
137-
this.log(` > ${chalk.blue("git push -u origin main")}`);
138-
139-
this.exit(1);
140-
}
141-
142-
// check the .hypermode/settings.json and see if there is a installationId with a key for the github owner. if there is,
143-
// continue, if not send them to github app installation page, and then go to callback server, and add installation id to settings.json
144-
145-
const settingsFilePath = getSettingsFilePath();
146-
if (!(await fileExists(settingsFilePath))) {
147-
this.log(chalk.red("Not logged in.") + " Log in with `hyp login`.");
148-
return;
149-
}
150-
151-
const settings = await readSettingsJson(settingsFilePath);
152-
153-
if (!settings.email || !settings.jwt || !settings.orgId) {
154-
this.log(chalk.red("Not logged in.") + " Log in with `hyp login`.");
155-
return;
156-
}
157-
158-
const { gitOwner, repoName } = parseGitUrl(remoteUrl);
159-
160-
const repoFullName = `${gitOwner}/${repoName}`;
161-
162-
let installationId = null;
163-
164-
if (!settings.installationIds || !settings.installationIds[gitOwner]) {
165-
installationId = await this.getUserInstallationThroughAuthFlow();
166-
await writeGithubInstallationIdToSettingsFile(gitOwner, installationId);
167-
} else {
168-
installationId = settings.installationIds[gitOwner];
169-
}
170-
171-
// call hypermode getRepoId with the installationId and the git url, if it returns a repoId, continue, if not, throw an error
172-
const repoId = await sendGetRepoIdReq(settings.jwt, installationId, remoteUrl);
173-
174-
if (!repoId) {
175-
throw new Error("No repoId found for the given installationId and gitUrl");
176-
}
177-
178-
// get list of the projects for the user in this org, if any have no repoId, ask if they want to link it, or give option of none.
179-
// If they pick an option, connect repo. If none, ask if they want to create a new project, prompt for name, and connect repoId to project
180-
const projects = await getProjectsByOrgReq(settings.jwt, settings.orgId);
181-
182-
const projectsNoRepoId = projects.filter((project) => !project.repoId);
183-
184-
let selectedProject = null;
185-
186-
if (projectsNoRepoId.length > 0) {
187-
const confirmExistingProject = await confirmExistingProjectLink();
188-
189-
if (confirmExistingProject) {
190-
selectedProject = await promptProjectLinkSelection(projectsNoRepoId);
191-
const completedProject = await sendMapRepoAndFinishProjectCreationReq(settings.jwt, selectedProject.id, repoId, repoFullName);
192-
193-
this.log(chalk.green("Successfully linked project " + completedProject.name + " to repo " + repoName + "! 🎉"));
194-
} else {
195-
const projectName = await promptProjectName(projects);
196-
const newProject = await sendCreateProjectReq(settings.jwt, settings.orgId, projectName, repoId, repoFullName);
197-
198-
this.log(chalk.green("Successfully created project " + newProject.name + " and linked it to repo " + repoName + "! 🎉"));
199-
}
200-
} else {
201-
const projectName = await promptProjectName(projects);
202-
const newProject = await sendCreateProjectReq(settings.jwt, settings.orgId, projectName, repoId, repoFullName);
203-
204-
this.log(chalk.blueBright("Successfully created project " + newProject.name + " and linked it to repo " + repoFullName + "! Setting up CI workflow..."));
205-
}
206-
207-
// add ci workflow to the repo if it doesn't already exist
208-
const githubWorkflowDir = getGithubWorkflowDir();
209-
const ciHypFilePath = getCiHypFilePath();
210-
211-
if (!(await fileExists(githubWorkflowDir))) {
212-
// create the directory
213-
await fs.mkdir(githubWorkflowDir, { recursive: true });
214-
}
215-
216-
let shouldCreateCIFile = true;
217-
if (await fileExists(ciHypFilePath)) {
218-
// prompt if they want to replace it
219-
const confirmOverwrite = await confirmOverwriteCiHypFile();
220-
if (!confirmOverwrite) {
221-
this.log(chalk.yellow("Skipping ci-modus-build.yml creation."));
222-
shouldCreateCIFile = false;
223-
}
224-
}
98+
this.error("Temporarily disabled during migration");
99+
return;
100+
101+
// // check if the directory has a .git/config with a remote named 'origin', if not, throw an error and ask them to set that up
102+
// const gitConfigFilePath = getGitConfigFilePath();
103+
104+
// if (!(await fileExists(gitConfigFilePath))) {
105+
// throw new Error(chalk.red("No .git found in this directory. Please initialize a git repository with `git init`."));
106+
// }
107+
108+
// // Check if the current branch is 'main'
109+
// let currentBranch = "";
110+
// try {
111+
// currentBranch = execSync("git symbolic-ref --short HEAD", { encoding: "utf-8" }).trim();
112+
// } catch (error) {
113+
// this.log(chalk.red("Unable to determine the current branch."));
114+
// throw error;
115+
// }
116+
117+
// if (currentBranch !== "main") {
118+
// this.log(chalk.red("You must be on the 'main' branch to link your repository."));
119+
// this.log("Please switch to the 'main' branch:");
120+
// this.log(` > ${chalk.blue("git checkout main")}`);
121+
// this.log("or rename your current branch to 'main'.");
122+
// this.log(` > ${chalk.blue("git branch -m main")}`);
123+
// this.exit(1);
124+
// }
125+
126+
// const remoteUrl = await getGitRemoteUrl(gitConfigFilePath);
127+
128+
// if (!remoteUrl) {
129+
// this.log(chalk.red("`hyp link` requires a git remote to work"));
130+
// const gitRoot = execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
131+
// const projectName = path.basename(gitRoot);
132+
// this.log(`Please create a GitHub repository: https://github.com/new?name=${projectName}`);
133+
// this.log(`And push your code:`);
134+
// this.log(` > ${chalk.blue("git remote add origin <GIT_URL>)")}`);
135+
// this.log(` > ${chalk.blue("git push -u origin main")}`);
136+
137+
// this.exit(1);
138+
// }
139+
140+
// // check the .hypermode/settings.json and see if there is a installationId with a key for the github owner. if there is,
141+
// // continue, if not send them to github app installation page, and then go to callback server, and add installation id to settings.json
142+
143+
// const settingsFilePath = getSettingsFilePath();
144+
// if (!(await fileExists(settingsFilePath))) {
145+
// this.log(chalk.red("Not logged in.") + " Log in with `hyp login`.");
146+
// return;
147+
// }
148+
149+
// const settings = await readSettingsJson(settingsFilePath);
150+
151+
// if (!settings.email || !settings.apiKey || !settings.orgId) {
152+
// this.log(chalk.red("Not logged in.") + " Log in with `hyp login`.");
153+
// return;
154+
// }
155+
156+
// const { gitOwner, repoName } = parseGitUrl(remoteUrl);
157+
158+
// const repoFullName = `${gitOwner}/${repoName}`;
159+
160+
// let installationId = null;
161+
162+
// if (!settings.installationIds || !settings.installationIds[gitOwner]) {
163+
// installationId = await this.getUserInstallationThroughAuthFlow();
164+
// await writeGithubInstallationIdToSettingsFile(gitOwner, installationId);
165+
// } else {
166+
// installationId = settings.installationIds[gitOwner];
167+
// }
168+
169+
// // call hypermode getRepoId with the installationId and the git url, if it returns a repoId, continue, if not, throw an error
170+
// const repoId = await sendGetRepoIdReq(settings.apiKey, installationId, remoteUrl);
171+
172+
// if (!repoId) {
173+
// throw new Error("No repoId found for the given installationId and gitUrl");
174+
// }
175+
176+
// // get list of the projects for the user in this org, if any have no repoId, ask if they want to link it, or give option of none.
177+
// // If they pick an option, connect repo. If none, ask if they want to create a new project, prompt for name, and connect repoId to project
178+
// const projects = await getProjectsByOrgReq(settings.apiKey, settings.orgId);
179+
180+
// const projectsNoRepoId = projects.filter((project) => !project.repoId);
181+
182+
// let selectedProject = null;
183+
184+
// if (projectsNoRepoId.length > 0) {
185+
// const confirmExistingProject = await confirmExistingProjectLink();
186+
187+
// if (confirmExistingProject) {
188+
// selectedProject = await promptProjectLinkSelection(projectsNoRepoId);
189+
// const completedProject = await sendMapRepoAndFinishProjectCreationReq(settings.apiKey, selectedProject.id, repoId, repoFullName);
190+
191+
// this.log(chalk.green("Successfully linked project " + completedProject.name + " to repo " + repoName + "! 🎉"));
192+
// } else {
193+
// const projectName = await promptProjectName(projects);
194+
// const newProject = await sendCreateProjectReq(settings.apiKey, settings.orgId, projectName, repoId, repoFullName);
195+
196+
// this.log(chalk.green("Successfully created project " + newProject.name + " and linked it to repo " + repoName + "! 🎉"));
197+
// }
198+
// } else {
199+
// const projectName = await promptProjectName(projects);
200+
// const newProject = await sendCreateProjectReq(settings.apiKey, settings.orgId, projectName, repoId, repoFullName);
201+
202+
// this.log(chalk.blueBright("Successfully created project " + newProject.name + " and linked it to repo " + repoFullName + "! Setting up CI workflow..."));
203+
// }
204+
205+
// // add ci workflow to the repo if it doesn't already exist
206+
// const githubWorkflowDir = getGithubWorkflowDir();
207+
// const ciHypFilePath = getCiHypFilePath();
208+
209+
// if (!(await fileExists(githubWorkflowDir))) {
210+
// // create the directory
211+
// await fs.mkdir(githubWorkflowDir, { recursive: true });
212+
// }
213+
214+
// let shouldCreateCIFile = true;
215+
// if (await fileExists(ciHypFilePath)) {
216+
// // prompt if they want to replace it
217+
// const confirmOverwrite = await confirmOverwriteCiHypFile();
218+
// if (!confirmOverwrite) {
219+
// this.log(chalk.yellow("Skipping ci-modus-build.yml creation."));
220+
// shouldCreateCIFile = false;
221+
// }
222+
// }
225223

226-
if (shouldCreateCIFile) {
227-
await fs.writeFile(ciHypFilePath, ciStr, { flag: "w" });
228-
this.log(chalk.green("Modus CI workflow added to your project. Commit this change to initiate a deployment to Hypermode."));
229-
}
230-
231-
this.log(chalk.green("Linking complete! 🎉"));
224+
// if (shouldCreateCIFile) {
225+
// await fs.writeFile(ciHypFilePath, ciStr, { flag: "w" });
226+
// this.log(chalk.green("Modus CI workflow added to your project. Commit this change to initiate a deployment to Hypermode."));
227+
// }
228+
229+
// this.log(chalk.green("Linking complete! 🎉"));
232230
}
233231
}
234232

@@ -284,16 +282,16 @@ const linkHTML = `<!-- src/commands/login/login.html -->
284282
</html>
285283
`;
286284

287-
function parseGitUrl(gitUrl: string) {
288-
const regex = /^(?:git@|https:\/\/)([^:/]+)[:/]([^/]+)\/([^/]+?)(?:\.git)?$/;
289-
const match = gitUrl.match(regex);
285+
// function parseGitUrl(gitUrl: string) {
286+
// const regex = /^(?:git@|https:\/\/)([^:/]+)[:/]([^/]+)\/([^/]+?)(?:\.git)?$/;
287+
// const match = gitUrl.match(regex);
290288

291-
if (!match) {
292-
throw new Error(`Invalid Git URL: ${gitUrl}`);
293-
}
289+
// if (!match) {
290+
// throw new Error(`Invalid Git URL: ${gitUrl}`);
291+
// }
294292

295-
const gitOwner = match[2];
296-
const repoName = match[3];
293+
// const gitOwner = match[2];
294+
// const repoName = match[3];
297295

298-
return { gitOwner, repoName };
299-
}
296+
// return { gitOwner, repoName };
297+
// }

0 commit comments

Comments
 (0)