Skip to content

Commit 6b2ceb2

Browse files
author
Giovanni D'Andrea
committed
fix: refactored whole extension
- documented complex functions - documented all files - added License into entry point ifle - removed useless code
1 parent e18c6ac commit 6b2ceb2

File tree

11 files changed

+322
-232
lines changed

11 files changed

+322
-232
lines changed

codeishot_extension/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,18 @@
5151
}
5252
],
5353
"configuration": {
54-
"type": "string",
54+
"type": "object",
5555
"title": "Codeishot",
5656
"properties": {
5757
"jwt": {
5858
"type": "string",
5959
"default": "",
6060
"description": "Token to login into codeishot."
61+
},
62+
"Authentication": {
63+
"type": "boolean",
64+
"default": false,
65+
"description": "Choose whether to authenticate the snippets or not."
6166
}
6267
}
6368
}

codeishot_extension/src/axiosPlugin.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/**
2-
* Ported from vue axios plugin.
3-
* Needs to:
4-
* - Use the extension configuration instead of authStore
5-
* - Change the import.meta
2+
* This file is a Typescript module that uses Axios, a Promise-based HTTP client, to make HTTP requests.
3+
* It creates an Axios instance with custom configurations, such as base URL,
4+
* timeout, headers, etc. It also defines an interceptor to add a bearer token
5+
* to the request headers if the user is authenticated.
6+
* Finally, it exports the configured Axios instance as a default export.
67
*/
7-
88
import axios from "axios";
9-
import { getTokenFromConfiguration } from "./login";
9+
import { getTokenFromConfiguration } from "./utils";
10+
import { isAuthApproved } from "./preferences";
1011

1112
const fetch = axios.create({
1213
baseURL: process.env.API_BASE_URL || "https://api.codeishot.com",
@@ -25,8 +26,9 @@ fetch.interceptors.request.use(
2526
// Check if the user tokens are stored to apply the bearer on the headers,
2627
// Otherwise the request is not authenticated.
2728
const token = getTokenFromConfiguration();
29+
const isAuthApprvd = isAuthApproved();
2830

29-
if (token) {
31+
if (token && isAuthApprvd) {
3032
config.headers.Authorization = `Bearer ${token}`;
3133
}
3234
return config;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* This file is a TypeScript module for a Visual Studio Code extension.
3+
* It imports various components from the VS Code API and other custom modules.
4+
* It defines two commands: one for logging in and another for creating a code snippet.
5+
* The createSnippetCommand retrieves the selected text from the editor, creates a snippet
6+
* object with metadata, posts it to a server, and handles the response.
7+
*/
8+
9+
import { commands, window, type Disposable } from "vscode";
10+
import {
11+
getSelectedText,
12+
getCurrentFileName,
13+
getLanguageIdentifier,
14+
type PostData,
15+
postSnippet,
16+
handlePostResponse,
17+
} from "./snippets";
18+
import { login } from "./login";
19+
20+
export const loginCommand: Disposable = commands.registerCommand(
21+
"extension.login",
22+
() => {
23+
login();
24+
}
25+
);
26+
27+
/**
28+
* Defines a command called "extension.postSnippet" in a Visual Studio Code extension.
29+
* When executed, it retrieves the currently active text editor, checks if there is text selected,
30+
* constructs a snippet object with metadata like title, code, language, and style,
31+
* then posts this data to a server asynchronously. If successful, it handles the response;
32+
* otherwise, it shows an error message.
33+
*/
34+
export const createSnippetCommand: Disposable = commands.registerCommand(
35+
"extension.postSnippet",
36+
async () => {
37+
const editor = window.activeTextEditor;
38+
if (!editor) {
39+
window.showErrorMessage("No editor found");
40+
return;
41+
}
42+
43+
const text = getSelectedText(editor); // get the selected buffer text
44+
if (!text) {
45+
return;
46+
}
47+
48+
const postData: PostData = {
49+
title: getCurrentFileName() || "untitled",
50+
code: text,
51+
language: getLanguageIdentifier() || "python",
52+
style: "androidstudio",
53+
};
54+
55+
try {
56+
const data = await postSnippet(postData);
57+
await handlePostResponse(data);
58+
} catch (error: any) {
59+
window.showErrorMessage("Error: " + error.message);
60+
}
61+
}
62+
);

codeishot_extension/src/config.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1+
/**
2+
* This file handles all configurations for the extension
3+
*/
4+
15
const headers = {
26
accept: "application/json",
37
contentType: "application/json",
48
userAgent: "codeishot/1.0.0",
59
// 'X-CSRFTOKEN': csrfToken,
610
};
711

8-
export { headers };
12+
const UI_BASE_URL: string = process.env.UI_BASE_URL || "https://codeishot.com";
13+
const UI_BASE_URL_LOGIN: string =
14+
process.env.UI_BASE_URL || "https://codeishot.com/login?type=vscode";
15+
16+
export { headers, UI_BASE_URL, UI_BASE_URL_LOGIN };

codeishot_extension/src/customs.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/**
2+
* Defines Custom data types and some of their implementations.
3+
*/
4+
15
import type {
26
AxiosResponse,
37
InternalAxiosRequestConfig,

codeishot_extension/src/extension.ts

Lines changed: 33 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -1,166 +1,37 @@
1-
import * as vscode from "vscode";
2-
import * as path from "path";
3-
import { createSnippet } from "./services/codeishotServices";
4-
import { saveToken, login } from "./login";
5-
6-
const UI_BASE_URL: string = process.env.UI_BASE_URL || "https://codeishot.com";
7-
8-
interface PostData {
9-
title: string;
10-
code: string;
11-
style: string;
12-
language: string;
13-
}
14-
15-
interface Snippet {
16-
id: string;
17-
title: string;
18-
language: string;
19-
style: string;
20-
code: string;
21-
createdAt: string;
22-
editedAt: string;
23-
}
24-
25-
function getSelectedText(editor: vscode.TextEditor): string | null {
26-
const selection = editor.selection;
27-
const text = editor.document.getText(selection);
28-
29-
if (!text) {
30-
vscode.window.showErrorMessage("No text selected");
31-
return null;
32-
}
33-
34-
return text;
35-
}
36-
37-
function getCurrentFileName(): string | null {
38-
const editor = vscode.window.activeTextEditor;
39-
if (editor) {
40-
const document = editor.document;
41-
const fullPath = document.fileName;
42-
return path.basename(fullPath);
43-
}
44-
return null;
45-
}
46-
47-
function getLanguageIdentifier(): string | null {
48-
const editor = vscode.window.activeTextEditor;
49-
if (editor) {
50-
const languageId = editor.document.languageId;
51-
return languageId;
52-
}
53-
return null;
54-
}
55-
56-
function checkCreateSnippetStatusCode(status: number, data: PostData) {
57-
switch (status) {
58-
case 400:
59-
vscode.window.showWarningMessage(
60-
"This language is not available, sending snippet as a Plain Text"
61-
);
62-
const newRes = postSnippetWithValidatedData(data);
63-
return newRes;
64-
case 429:
65-
vscode.window.showErrorMessage("Too many requests!");
66-
break;
67-
default:
68-
break;
69-
}
70-
}
71-
72-
async function postSnippet(data: PostData): Promise<Snippet> {
73-
let res = await createSnippet(data);
74-
if (res.status_code) checkCreateSnippetStatusCode(res.status_code, data);
75-
return res.data as Promise<Snippet>;
76-
}
77-
78-
async function postSnippetWithValidatedData(data: PostData): Promise<Snippet> {
79-
let plainTextData: PostData = { ...data };
80-
plainTextData.language = "plaintext";
81-
82-
return await createSnippet(plainTextData)
83-
.then((res) => res.data)
84-
.catch(() => {
85-
vscode.window.showWarningMessage("Please try again!");
86-
});
87-
}
88-
89-
async function handlePostResponse(data: Snippet) {
90-
if (data && data.id) {
91-
const snippetUrl = `${UI_BASE_URL}/${data.id}`;
92-
try {
93-
await vscode.env.clipboard.writeText(snippetUrl);
94-
vscode.window.showInformationMessage("URL copied to clipboard");
95-
} catch (error) {
96-
vscode.window.showErrorMessage("Error copying URL: " + error);
97-
}
98-
99-
const infoMessage = await vscode.window.showInformationMessage(
100-
snippetUrl,
101-
"Open URL"
102-
);
103-
if (infoMessage === "Open URL") {
104-
vscode.env.openExternal(vscode.Uri.parse(snippetUrl));
105-
}
106-
}
107-
}
108-
109-
function activate(context: vscode.ExtensionContext) {
110-
let disposable = vscode.commands.registerCommand(
111-
"extension.postSnippet",
112-
async () => {
113-
const editor = vscode.window.activeTextEditor;
114-
if (!editor) {
115-
vscode.window.showErrorMessage("No editor found");
116-
return;
117-
}
118-
119-
const text = getSelectedText(editor);
120-
if (!text) {
121-
return;
122-
}
123-
124-
const postData: PostData = {
125-
title: getCurrentFileName() || "untitled",
126-
code: text,
127-
language: getLanguageIdentifier() || "python",
128-
style: "androidstudio",
129-
};
130-
131-
try {
132-
const data = await postSnippet(postData);
133-
await handlePostResponse(data);
134-
} catch (error: any) {
135-
vscode.window.showErrorMessage("Error: " + error.message);
136-
}
137-
}
138-
);
139-
140-
const loginCommand = vscode.commands.registerCommand(
141-
"extension.login",
142-
() => {
143-
login();
144-
}
145-
);
146-
147-
context.subscriptions.push(disposable);
1+
/**
2+
* MIT License
3+
* Copyright (c) [2024] [Codeishot]
4+
* Giovanni D'Andrea => @gdjohn4s
5+
* Flavio Adamo => @FlavioAdamo
6+
* Gianluca Andretta => @gnlca
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in all
16+
* copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24+
* SOFTWARE.
25+
*/
26+
27+
import { loginCommand, createSnippetCommand } from "./commands";
28+
import { type ExtensionContext } from "vscode";
29+
import { loginUriHandler } from "./handlers";
30+
31+
function activate(context: ExtensionContext) {
32+
context.subscriptions.push(createSnippetCommand);
14833
context.subscriptions.push(loginCommand);
149-
context.subscriptions.push(
150-
// vscode://codeishot.codeishot/login?jwt=<token>
151-
// TODO: @Cleanup => Move to another file, maybe `handlers.ts`?
152-
vscode.window.registerUriHandler({
153-
handleUri(uri: vscode.Uri) {
154-
if (uri.path === "/login") {
155-
const jwtParam = uri.query.split("=")[1];
156-
if (jwtParam) {
157-
vscode.window.showInformationMessage("Logged Successfully! ✨");
158-
saveToken(jwtParam);
159-
}
160-
}
161-
},
162-
})
163-
);
34+
context.subscriptions.push(loginUriHandler);
16435
}
16536

16637
function deactivate() {}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* Defines various handlers for this vscode extension.
3+
*/
4+
5+
import { window, Uri, type Disposable } from "vscode";
6+
import { updateUserConfiguration } from "./utils";
7+
8+
export const loginUriHandler: Disposable = window.registerUriHandler({
9+
handleUri(uri: Uri) {
10+
if (uri.path === "/login") {
11+
const jwtParam = uri.query.split("=")[1];
12+
if (jwtParam) {
13+
window.showInformationMessage("Logged Successfully! ✨");
14+
updateUserConfiguration(jwtParam);
15+
}
16+
}
17+
},
18+
});

0 commit comments

Comments
 (0)