Skip to content

Commit e031512

Browse files
authored
Fix incompatibilities with pre-OAuth2 version of Server Manager (#1820)
1 parent 0838515 commit e031512

50 files changed

Lines changed: 800 additions & 698 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1718,7 +1718,7 @@
17181718
},
17191719
"devDependencies": {
17201720
"@eslint/js": "^9.39.2",
1721-
"@intersystems-community/intersystems-servermanager": "^3.14.0",
1721+
"@intersystems-community/intersystems-servermanager": "^3.14.1",
17221722
"@types/istextorbinary": "2.3.1",
17231723
"@types/minimatch": "6.0.0",
17241724
"@types/mocha": "^10.0.10",

src/api/index.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import axios from "axios";
22
import * as httpsModule from "https";
33
import * as vscode from "vscode";
44
import * as semver from "semver";
5-
import {
5+
import BasicAuthorization, {
66
getResolvedConnectionSpec,
77
config,
88
extensionContext,
@@ -57,7 +57,7 @@ export interface ConnectionSettings {
5757
port: number;
5858
superserverPort?: number;
5959
pathPrefix?: string;
60-
ns: string;
60+
ns: string | undefined;
6161
auth: Authorization;
6262
docker?: boolean;
6363
dockerService?: string;
@@ -171,7 +171,7 @@ export class AtelierAPI {
171171
webServer: { scheme, host, port, pathPrefix = "" },
172172
auth,
173173
} = connSpec;
174-
this._config.auth = auth;
174+
this._config.auth = auth ?? new BasicAuthorization();
175175
this._config.https = scheme == "https";
176176
this._config.host = host;
177177
this._config.port = port;
@@ -200,7 +200,7 @@ export class AtelierAPI {
200200

201201
public terminalUrl(): string {
202202
const { host, https, port, apiVersion, pathPrefix } = this.config;
203-
return apiVersion >= 7
203+
return apiVersion! >= 7
204204
? `${https ? "wss" : "ws"}://${host}:${port}${pathPrefix}/api/atelier/v${apiVersion}/%25SYS/terminal`
205205
: "";
206206
}
@@ -232,7 +232,11 @@ export class AtelierAPI {
232232

233233
private setConnection(workspaceFolderName: string, namespace?: string): void {
234234
this.configName = workspaceFolderName;
235-
const conn = config("conn", workspaceFolderName);
235+
const rawConn = config("conn", workspaceFolderName);
236+
const conn = {
237+
...rawConn,
238+
auth: new BasicAuthorization(rawConn.username, rawConn.password),
239+
};
236240
let serverName = workspaceFolderName.toLowerCase();
237241
if (config("intersystems.servers", workspaceFolderName).has(serverName)) {
238242
this.externalServer = true;
@@ -254,7 +258,7 @@ export class AtelierAPI {
254258
webServer: { scheme, host, port, pathPrefix = "" },
255259
auth,
256260
superServer,
257-
} = getResolvedConnectionSpec(serverName, config("intersystems.servers", workspaceFolderName).get(serverName));
261+
} = getResolvedConnectionSpec(serverName, config("intersystems.servers", workspaceFolderName).get(serverName))!;
258262
this._config = {
259263
serverName,
260264
active: this.externalServer ? !inactiveServerIds.has(serverName) : conn.active,
@@ -333,7 +337,7 @@ export class AtelierAPI {
333337
if (!active || !port || !host) {
334338
return Promise.reject();
335339
}
336-
if (minVersion > apiVersion) {
340+
if (minVersion > apiVersion!) {
337341
return Promise.reject(`${path} not supported by API version ${apiVersion}`);
338342
}
339343
const originalPath = path;
@@ -348,7 +352,7 @@ export class AtelierAPI {
348352
if (!params) {
349353
return "";
350354
}
351-
const result = [];
355+
const result: string[] = [];
352356
Object.keys(params).forEach((key) => {
353357
const value = params[key];
354358
if (typeof value === "boolean") {
@@ -379,7 +383,7 @@ export class AtelierAPI {
379383

380384
const cookies = this.cookies;
381385
const mapKey = this.mapKey();
382-
let auth: Promise<any>;
386+
let auth: Promise<any> | undefined;
383387
let authRequest = authRequestMap.get(mapKey);
384388
if (cookies.length || (method === "HEAD" && !originalPath)) {
385389
// Only send basic authorization if username and password specified (including blank, for unauthenticated access)
@@ -417,7 +421,7 @@ export class AtelierAPI {
417421
}
418422
};
419423
try {
420-
cookie = await auth;
424+
cookie = await auth!;
421425
reqTs = new Date();
422426
const response = await axios.request({
423427
method,
@@ -598,7 +602,7 @@ export class AtelierAPI {
598602
.slice(data.version.indexOf(") ") + 2)
599603
.split(" ")
600604
.shift()
601-
).version;
605+
)!.version;
602606
if (this.ns && this.ns.length && !data.namespaces.includes(this.ns) && checkNs) {
603607
throw {
604608
code: "WrongNamespace",
@@ -649,7 +653,7 @@ export class AtelierAPI {
649653
const params: Record<string, string> = {};
650654
name = this.transformNameIfCsp(name);
651655
if (
652-
this.config.apiVersion >= 4 &&
656+
this.config.apiVersion! >= 4 &&
653657
vscode.workspace
654658
.getConfiguration(
655659
"objectscript",

src/commands/addServerNamespaceToWorkspace.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ import { isfsConfig, IsfsUriParam } from "../utils/FileProviderUtil";
1717
* @param message The prefix of the message to show when the server manager API can't be found.
1818
* @returns An object containing `serverName` and `namespace`, or `undefined`.
1919
*/
20-
async function pickServerAndNamespace(message?: string): Promise<{ serverName: string; namespace: string }> {
20+
async function pickServerAndNamespace(
21+
message?: string
22+
): Promise<{ serverName: string; namespace: string } | undefined> {
2123
if (!serverManagerApi) {
2224
vscode.window.showErrorMessage(
2325
`${
@@ -29,7 +31,7 @@ async function pickServerAndNamespace(message?: string): Promise<{ serverName: s
2931
}
3032
// Get user's choice of server
3133
const options: vscode.QuickPickOptions = { ignoreFocusOut: true };
32-
const serverName: string = await serverManagerApi.pickServer(undefined, options);
34+
const serverName: string | undefined = await serverManagerApi.pickServer(undefined, options);
3335
if (!serverName) {
3436
return;
3537
}
@@ -40,13 +42,13 @@ async function pickServerAndNamespace(message?: string): Promise<{ serverName: s
4042
return { serverName, namespace };
4143
}
4244

43-
async function pickNamespaceOnServer(serverName: string): Promise<string> {
45+
async function pickNamespaceOnServer(serverName: string): Promise<string | undefined> {
4446
// Get its namespace list
4547
const uri = vscode.Uri.parse(`isfs://${serverName}:%sys/`);
4648
await resolveConnectionSpec(serverName);
4749
// Prepare a displayable form of its connection spec as a hint to the user.
4850
// This will never return the default value (second parameter) because we only just resolved the connection spec.
49-
const connSpec = getResolvedConnectionSpec(serverName, undefined);
51+
const connSpec = getResolvedConnectionSpec(serverName, undefined)!;
5052
const connDisplayString = `${connSpec.webServer.scheme}://${connSpec.webServer.host}:${connSpec.webServer.port}/${connSpec.webServer.pathPrefix}`;
5153
// Connect and fetch namespaces
5254
const api = new AtelierAPI(uri);
@@ -81,9 +83,9 @@ async function pickNamespaceOnServer(serverName: string): Promise<string> {
8183
export async function addServerNamespaceToWorkspace(resource?: vscode.Uri): Promise<void> {
8284
const TITLE = "Add server namespace to workspace";
8385
let serverName = "";
84-
let namespace = "";
85-
if (filesystemSchemas.includes(resource?.scheme)) {
86-
serverName = resource.authority.split(":")[0];
86+
let namespace: string | undefined = "";
87+
if (filesystemSchemas.includes(resource?.scheme as string)) {
88+
serverName = resource!.authority.split(":")[0];
8789
if (serverName) {
8890
const ANOTHER = "Choose another server";
8991
const choice = await vscode.window.showQuickPick([`Add a '${serverName}' namespace`, ANOTHER], {
@@ -111,7 +113,7 @@ export async function addServerNamespaceToWorkspace(resource?: vscode.Uri): Prom
111113
}
112114
}
113115
const wsFolders = vscode.workspace.workspaceFolders ?? [];
114-
let scheme: string;
116+
let scheme: string | undefined;
115117
if (wsFolders.length && wsFolders.some((wf) => notIsfs(wf.uri))) {
116118
// Don't allow the creation of an editable ISFS folder
117119
// if the workspace contains non-ISFS folders already
@@ -221,7 +223,7 @@ async function modifyWsFolderUri(uri: vscode.Uri): Promise<vscode.Uri | undefine
221223
}
222224

223225
let newParams = "";
224-
let newPath = uri.path;
226+
let newPath: string | undefined = uri.path;
225227
if (filterType == "csp") {
226228
// Prompt for a specific web app
227229
let cspApps = cspAppsForUri(uri);
@@ -243,7 +245,7 @@ async function modifyWsFolderUri(uri: vscode.Uri): Promise<vscode.Uri | undefine
243245
}
244246
}
245247
newPath = await new Promise<string | undefined>((resolve) => {
246-
let result: string;
248+
let result: string | undefined;
247249
const allItem: vscode.QuickPickItem = { label: "All" };
248250
const quickPick = vscode.window.createQuickPick();
249251
quickPick.title = "Pick a specific web application to show, or show all";
@@ -352,7 +354,7 @@ async function modifyWsFolderUri(uri: vscode.Uri): Promise<vscode.Uri | undefine
352354
}
353355

354356
export async function modifyWsFolder(wsFolderUri?: vscode.Uri): Promise<void> {
355-
let wsFolder: vscode.WorkspaceFolder;
357+
let wsFolder: vscode.WorkspaceFolder | null | undefined;
356358
if (!wsFolderUri) {
357359
// Select a workspace folder to modify
358360
wsFolder = await getWsFolder("Pick the workspace folder to modify", false, true);

src/commands/compile.ts

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export async function importFile(
8989
if (!file) return;
9090
const api = new AtelierAPI(file.uri);
9191
if (!api.active) return Promise.reject();
92-
if (file.name.split(".").pop().toLowerCase() === "cls" && !skipDeplCheck) {
92+
if (file.name.split(".").pop()!.toLowerCase() === "cls" && !skipDeplCheck) {
9393
if (await isClassDeployed(file.name, api)) {
9494
vscode.window.showErrorMessage(`Cannot import ${file.name} because it is deployed on the server.`, "Dismiss");
9595
return Promise.reject();
@@ -207,10 +207,10 @@ function updateOthers(others: string[], baseUri: vscode.Uri) {
207207
}
208208
others.forEach((item) => {
209209
const uri = DocumentContentProvider.getUri(item, undefined, undefined, undefined, workspaceFolder?.uri);
210-
if (filesystemSchemas.includes(uri.scheme)) {
211-
fileSystemProvider.fireFileChanged(uri);
212-
} else if (uri.scheme == OBJECTSCRIPT_FILE_SCHEMA) {
213-
documentContentProvider.update(uri);
210+
if (filesystemSchemas.includes(uri!.scheme)) {
211+
fileSystemProvider.fireFileChanged(uri!);
212+
} else if (uri!.scheme == OBJECTSCRIPT_FILE_SCHEMA) {
213+
documentContentProvider.update(uri!);
214214
}
215215
});
216216
}
@@ -234,7 +234,7 @@ export async function loadChanges(
234234
Promise.allSettled(
235235
data.result.content.map(async (doc) => {
236236
if (doc.status.length) return;
237-
const file = files.find((f) => f.name == doc.name);
237+
const file = files.find((f) => f.name == doc.name)!;
238238
const mtime = Number(new Date(doc.ts + "Z"));
239239
workspaceState.update(`${file.uniqueId}:mtime`, mtime > 0 ? mtime : undefined);
240240
if (notIsfs(file.uri)) {
@@ -312,8 +312,8 @@ function updateStorage(content: string[], storage: string[]): string[] {
312312

313313
function storageToMap(storage: string[]): Map<string, string> {
314314
const map: Map<string, string> = new Map();
315-
let k: string;
316-
let v = [];
315+
let k: string | undefined;
316+
let v: string[] = [];
317317
for (const line of storage) {
318318
if (line.startsWith("Storage ")) {
319319
k = line.slice("Storage ".length, line.length);
@@ -412,7 +412,7 @@ export async function importAndCompile(document?: vscode.TextDocument, askFlags
412412
}
413413
}
414414

415-
export async function compileOnly(document?: vscode.TextDocument, askFlags = false): Promise<any> {
415+
export async function compileOnly(document?: vscode.TextDocument | null, askFlags = false): Promise<any> {
416416
document =
417417
document ||
418418
(vscode.window.activeTextEditor && vscode.window.activeTextEditor.document
@@ -468,7 +468,7 @@ export async function namespaceCompile(): Promise<any> {
468468
.then(() => {
469469
// Always fetch server changes, even when compile failed or got cancelled
470470
const file = currentFile();
471-
return loadChanges([file]);
471+
return loadChanges([file!]);
472472
})
473473
);
474474
}
@@ -526,7 +526,7 @@ export async function compileExplorerItems(nodes: NodeBase[]): Promise<any> {
526526
const conf = vscode.workspace.getConfiguration("objectscript", wsFolder);
527527
const api = new AtelierAPI(wsFolder.uri);
528528
if (namespace) api.setNamespace(namespace);
529-
const docs = [];
529+
const docs: string[] = [];
530530
for (const node of nodes) {
531531
if (node instanceof PackageNode) {
532532
switch (node.category) {
@@ -659,7 +659,7 @@ export async function importArbitraryFiles(): Promise<any> {
659659
});
660660
if (!uris?.length) return;
661661
// Filter out non-importable files
662-
uris = uris.filter((uri) => supportedExts.includes(uri.path.split(".").pop().toLowerCase()));
662+
uris = uris.filter((uri) => supportedExts.includes(uri.path.split(".").pop()!.toLowerCase()));
663663
if (uris.length == 0) {
664664
vscode.window.showErrorMessage("No selected files are importable.", "Dismiss");
665665
return;
@@ -689,6 +689,7 @@ export async function importArbitraryFiles(): Promise<any> {
689689
}
690690
})
691691
.filter(notNull)
692+
.map((f) => f!)
692693
);
693694
if (filesToList.length == 0) {
694695
vscode.window.showErrorMessage("Failed to read the text of every selected file.", "Dismiss");
@@ -754,9 +755,9 @@ export async function importArbitraryFiles(): Promise<any> {
754755
}
755756
});
756757
if (readOnly.length) {
757-
docsToImport = docsToImport.filter((qpi) => {
758+
docsToImport = docsToImport!.filter((qpi) => {
758759
const nameSplit = qpi.label.split(".");
759-
return !readOnly.includes(`${nameSplit.slice(0, -1).join(".")}.${nameSplit.pop().toUpperCase()}`);
760+
return !readOnly.includes(`${nameSplit.slice(0, -1).join(".")}.${nameSplit.pop()!.toUpperCase()}`);
760761
});
761762
}
762763
});

0 commit comments

Comments
 (0)