diff --git a/.eslintignore b/.eslintignore index 8711bfaa6..d14b2995d 100644 --- a/.eslintignore +++ b/.eslintignore @@ -122,7 +122,6 @@ src/Explorer/Notebook/NotebookComponent/types.ts src/Explorer/Notebook/NotebookContainerClient.ts src/Explorer/Notebook/NotebookContentClient.ts src/Explorer/Notebook/NotebookContentItem.ts -src/Explorer/Notebook/NotebookUtil.ts src/Explorer/OpenActions.test.ts src/Explorer/OpenActions.ts src/Explorer/OpenActionsStubs.ts diff --git a/src/Explorer/Explorer.tsx b/src/Explorer/Explorer.tsx index 41566fe63..b2450cbe3 100644 --- a/src/Explorer/Explorer.tsx +++ b/src/Explorer/Explorer.tsx @@ -49,7 +49,7 @@ import { LoadQueryPane } from "./Panes/LoadQueryPane"; import * as Logger from "../Common/Logger"; import { sendMessage, sendCachedDataMessage } from "../Common/MessageHandler"; import { NotebookContentItem, NotebookContentItemType } from "./Notebook/NotebookContentItem"; -import { NotebookUtil } from "./Notebook/NotebookUtil"; +import * as NotebookUtil from "./Notebook/NotebookUtil"; import { NotebookWorkspaceManager } from "../NotebookWorkspaceManager/NotebookWorkspaceManager"; import * as NotificationConsoleUtils from "../Utils/NotificationConsoleUtils"; import { QueriesClient } from "../Common/QueriesClient"; diff --git a/src/Explorer/Notebook/NotebookComponent/NotebookComponentBootstrapper.tsx b/src/Explorer/Notebook/NotebookComponent/NotebookComponentBootstrapper.tsx index 2dc173fc6..e76163028 100644 --- a/src/Explorer/Notebook/NotebookComponent/NotebookComponentBootstrapper.tsx +++ b/src/Explorer/Notebook/NotebookComponent/NotebookComponentBootstrapper.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { NotebookComponent } from "./NotebookComponent"; import { NotebookClientV2 } from "../NotebookClientV2"; -import { NotebookUtil } from "../NotebookUtil"; +import * as NotebookUtil from "../NotebookUtil"; // Vendor modules import { diff --git a/src/Explorer/Notebook/NotebookComponent/epics.test.ts b/src/Explorer/Notebook/NotebookComponent/epics.test.ts index ab5b7cbbe..067b5cb2e 100644 --- a/src/Explorer/Notebook/NotebookComponent/epics.test.ts +++ b/src/Explorer/Notebook/NotebookComponent/epics.test.ts @@ -8,7 +8,7 @@ import * as sinon from "sinon"; import { CdbAppState, makeCdbRecord } from "./types"; import { launchWebSocketKernelEpic } from "./epics"; -import { NotebookUtil } from "../NotebookUtil"; +import * as NotebookUtil from "../NotebookUtil"; import { sessions } from "rx-jupyter"; diff --git a/src/Explorer/Notebook/NotebookComponent/epics.ts b/src/Explorer/Notebook/NotebookComponent/epics.ts index 5b3e83ff6..39db7a7f7 100644 --- a/src/Explorer/Notebook/NotebookComponent/epics.ts +++ b/src/Explorer/Notebook/NotebookComponent/epics.ts @@ -43,7 +43,7 @@ import { Action as TelemetryAction, ActionModifiers } from "../../../Shared/Tele import { CdbAppState } from "./types"; import { decryptJWTToken } from "../../../Utils/AuthorizationUtils"; import * as TextFile from "./contents/file/text-file"; -import { NotebookUtil } from "../NotebookUtil"; +import * as NotebookUtil from "../NotebookUtil"; import { FileSystemUtil } from "../FileSystemUtil"; import * as cdbActions from "../NotebookComponent/actions"; import { Areas } from "../../../Common/Constants"; diff --git a/src/Explorer/Notebook/NotebookContentClient.ts b/src/Explorer/Notebook/NotebookContentClient.ts index dfb5ab8c5..73f805c56 100644 --- a/src/Explorer/Notebook/NotebookContentClient.ts +++ b/src/Explorer/Notebook/NotebookContentClient.ts @@ -2,7 +2,7 @@ import * as DataModels from "../../Contracts/DataModels"; import { NotebookContentItem, NotebookContentItemType } from "./NotebookContentItem"; import { StringUtils } from "../../Utils/StringUtils"; import { FileSystemUtil } from "./FileSystemUtil"; -import { NotebookUtil } from "./NotebookUtil"; +import * as NotebookUtil from "./NotebookUtil"; import { ServerConfig, IContent, IContentProvider, FileType, IEmptyContent } from "@nteract/core"; import { AjaxResponse } from "rxjs/ajax"; diff --git a/src/Explorer/Notebook/NotebookUtil.test.ts b/src/Explorer/Notebook/NotebookUtil.test.ts index 5916c9d3a..b41c926f6 100644 --- a/src/Explorer/Notebook/NotebookUtil.test.ts +++ b/src/Explorer/Notebook/NotebookUtil.test.ts @@ -1,4 +1,4 @@ -import { NotebookUtil } from "./NotebookUtil"; +import * as NotebookUtil from "./NotebookUtil"; import * as GitHubUtils from "../../Utils/GitHubUtils"; import { ImmutableNotebook, diff --git a/src/Explorer/Notebook/NotebookUtil.ts b/src/Explorer/Notebook/NotebookUtil.ts index 519cbcd4d..d32ddfd7f 100644 --- a/src/Explorer/Notebook/NotebookUtil.ts +++ b/src/Explorer/Notebook/NotebookUtil.ts @@ -7,157 +7,155 @@ import * as GitHubUtils from "../../Utils/GitHubUtils"; // Must match rx-jupyter' FileType export type FileType = "directory" | "file" | "notebook"; // Utilities for notebooks -export class NotebookUtil { - /** - * It's a notebook file if the filename ends with .ipynb. - */ - public static isNotebookFile(notebookPath: string): boolean { - const fileName = NotebookUtil.getName(notebookPath); - return !!fileName && StringUtils.endsWith(fileName, ".ipynb"); - } +/** + * It's a notebook file if the filename ends with .ipynb. + */ +export function isNotebookFile(notebookPath: string): boolean { + const fileName = getName(notebookPath); + return !!fileName && StringUtils.endsWith(fileName, ".ipynb"); +} - /** - * Note: this does not connect the item to a parent in a tree. - * @param name - * @param path - */ - public static createNotebookContentItem(name: string, path: string, type: FileType): NotebookContentItem { - return { - name, - path, - type: NotebookUtil.getType(type), - timestamp: NotebookUtil.getCurrentTimestamp(), - }; - } +/** + * Note: this does not connect the item to a parent in a tree. + * @param name + * @param path + */ +export function createNotebookContentItem(name: string, path: string, type: FileType): NotebookContentItem { + return { + name, + path, + type: getType(type), + timestamp: getCurrentTimestamp(), + }; +} - /** - * Convert rx-jupyter type to our type - * @param type - */ - public static getType(type: FileType): NotebookContentItemType { - switch (type) { - case "directory": - return NotebookContentItemType.Directory; - case "notebook": - return NotebookContentItemType.Notebook; - case "file": - return NotebookContentItemType.File; - default: - throw new Error(`Unknown file type: ${type}`); - } - } - - public static getCurrentTimestamp(): number { - return new Date().getTime(); - } - - /** - * Override from kernel-lifecycle.ts to improve kernel selection: - * Only return the kernel name persisted in the notebook - * - * @param filepath - * @param notebook - */ - public static extractNewKernel(filepath: string | null, notebook: ImmutableNotebook) { - const cwd = (filepath && path.dirname(filepath)) || "/"; - - const kernelSpecName = - notebook.getIn(["metadata", "kernelspec", "name"]) || notebook.getIn(["metadata", "language_info", "name"]); - - return { - cwd, - kernelSpecName, - }; - } - - public static getFilePath(path: string, fileName: string): string { - const contentInfo = GitHubUtils.fromContentUri(path); - if (contentInfo) { - let path = fileName; - if (contentInfo.path) { - path = `${contentInfo.path}/${path}`; - } - return GitHubUtils.toContentUri(contentInfo.owner, contentInfo.repo, contentInfo.branch, path); - } - - return `${path}/${fileName}`; - } - - public static getParentPath(filepath: string): undefined | string { - const basename = NotebookUtil.getName(filepath); - if (basename) { - const contentInfo = GitHubUtils.fromContentUri(filepath); - if (contentInfo) { - const parentPath = contentInfo.path.split(basename).shift(); - if (parentPath === undefined) { - return undefined; - } - - return GitHubUtils.toContentUri( - contentInfo.owner, - contentInfo.repo, - contentInfo.branch, - parentPath.replace(/\/$/, "") // no trailling slash - ); - } - - const parentPath = filepath.split(basename).shift(); - if (parentPath) { - return parentPath.replace(/\/$/, ""); // no trailling slash - } - } - - return undefined; - } - - public static getName(path: string): undefined | string { - let relativePath: string = path; - const contentInfo = GitHubUtils.fromContentUri(path); - if (contentInfo) { - relativePath = contentInfo.path; - } - - return relativePath.split("/").pop(); - } - - public static replaceName(path: string, newName: string): string { - const contentInfo = GitHubUtils.fromContentUri(path); - if (contentInfo) { - const contentName = contentInfo.path.split("/").pop(); - if (!contentName) { - throw new Error(`Failed to extract name from github path ${contentInfo.path}`); - } - - const basePath = contentInfo.path.split(contentName).shift(); - return GitHubUtils.toContentUri(contentInfo.owner, contentInfo.repo, contentInfo.branch, `${basePath}${newName}`); - } - - const contentName = path.split("/").pop(); - if (!contentName) { - throw new Error(`Failed to extract name from path ${path}`); - } - - const basePath = path.split(contentName).shift(); - return `${basePath}${newName}`; - } - - public static findFirstCodeCellWithDisplay(notebookObject: ImmutableNotebook): number { - let codeCellIndex = 0; - for (let i = 0; i < notebookObject.cellOrder.size; i++) { - const cellId = notebookObject.cellOrder.get(i); - if (cellId) { - const cell = notebookObject.cellMap.get(cellId); - if (cell?.cell_type === "code") { - const displayOutput = (cell as ImmutableCodeCell)?.outputs?.find( - (output) => output.output_type === "display_data" || output.output_type === "execute_result" - ); - if (displayOutput) { - return codeCellIndex; - } - codeCellIndex++; - } - } - } - throw new Error("Output does not exist for any of the cells."); +/** + * Convert rx-jupyter type to our type + * @param type + */ +export function getType(type: FileType): NotebookContentItemType { + switch (type) { + case "directory": + return NotebookContentItemType.Directory; + case "notebook": + return NotebookContentItemType.Notebook; + case "file": + return NotebookContentItemType.File; + default: + throw new Error(`Unknown file type: ${type}`); } } + +export function getCurrentTimestamp(): number { + return new Date().getTime(); +} + +/** + * Override from kernel-lifecycle.ts to improve kernel selection: + * Only return the kernel name persisted in the notebook + * + * @param filepath + * @param notebook + */ +export function extractNewKernel(filepath: string | null, notebook: ImmutableNotebook) { + const cwd = (filepath && path.dirname(filepath)) || "/"; + + const kernelSpecName = + notebook.getIn(["metadata", "kernelspec", "name"]) || notebook.getIn(["metadata", "language_info", "name"]); + + return { + cwd, + kernelSpecName, + }; +} + +export function getFilePath(path: string, fileName: string): string { + const contentInfo = GitHubUtils.fromContentUri(path); + if (contentInfo) { + let path = fileName; + if (contentInfo.path) { + path = `${contentInfo.path}/${path}`; + } + return GitHubUtils.toContentUri(contentInfo.owner, contentInfo.repo, contentInfo.branch, path); + } + + return `${path}/${fileName}`; +} + +export function getParentPath(filepath: string): undefined | string { + const basename = getName(filepath); + if (basename) { + const contentInfo = GitHubUtils.fromContentUri(filepath); + if (contentInfo) { + const parentPath = contentInfo.path.split(basename).shift(); + if (parentPath === undefined) { + return undefined; + } + + return GitHubUtils.toContentUri( + contentInfo.owner, + contentInfo.repo, + contentInfo.branch, + parentPath.replace(/\/$/, "") // no trailling slash + ); + } + + const parentPath = filepath.split(basename).shift(); + if (parentPath) { + return parentPath.replace(/\/$/, ""); // no trailling slash + } + } + + return undefined; +} + +export function getName(path: string): undefined | string { + let relativePath: string = path; + const contentInfo = GitHubUtils.fromContentUri(path); + if (contentInfo) { + relativePath = contentInfo.path; + } + + return relativePath.split("/").pop(); +} + +export function replaceName(path: string, newName: string): string { + const contentInfo = GitHubUtils.fromContentUri(path); + if (contentInfo) { + const contentName = contentInfo.path.split("/").pop(); + if (!contentName) { + throw new Error(`Failed to extract name from github path ${contentInfo.path}`); + } + + const basePath = contentInfo.path.split(contentName).shift(); + return GitHubUtils.toContentUri(contentInfo.owner, contentInfo.repo, contentInfo.branch, `${basePath}${newName}`); + } + + const contentName = path.split("/").pop(); + if (!contentName) { + throw new Error(`Failed to extract name from path ${path}`); + } + + const basePath = path.split(contentName).shift(); + return `${basePath}${newName}`; +} + +export function findFirstCodeCellWithDisplay(notebookObject: ImmutableNotebook): number { + let codeCellIndex = 0; + for (let i = 0; i < notebookObject.cellOrder.size; i++) { + const cellId = notebookObject.cellOrder.get(i); + if (cellId) { + const cell = notebookObject.cellMap.get(cellId); + if (cell?.cell_type === "code") { + const displayOutput = (cell as ImmutableCodeCell)?.outputs?.find( + (output) => output.output_type === "display_data" || output.output_type === "execute_result" + ); + if (displayOutput) { + return codeCellIndex; + } + codeCellIndex++; + } + } + } + throw new Error("Output does not exist for any of the cells."); +} diff --git a/src/Explorer/Panes/PublishNotebookPaneComponent.tsx b/src/Explorer/Panes/PublishNotebookPaneComponent.tsx index 559bf3b09..587b3b409 100644 --- a/src/Explorer/Panes/PublishNotebookPaneComponent.tsx +++ b/src/Explorer/Panes/PublishNotebookPaneComponent.tsx @@ -5,7 +5,7 @@ import { FileSystemUtil } from "../Notebook/FileSystemUtil"; import "./PublishNotebookPaneComponent.less"; import Html2Canvas from "html2canvas"; import { ImmutableNotebook } from "@nteract/commutable/src"; -import { NotebookUtil } from "../Notebook/NotebookUtil"; +import * as NotebookUtil from "../Notebook/NotebookUtil"; export interface PublishNotebookPaneProps { notebookName: string; diff --git a/src/Explorer/Tree/ResourceTreeAdapter.tsx b/src/Explorer/Tree/ResourceTreeAdapter.tsx index 46831c9de..4601a9067 100644 --- a/src/Explorer/Tree/ResourceTreeAdapter.tsx +++ b/src/Explorer/Tree/ResourceTreeAdapter.tsx @@ -17,7 +17,7 @@ import NewNotebookIcon from "../../../images/notebook/Notebook-new.svg"; import FileIcon from "../../../images/notebook/file-cosmos.svg"; import PublishIcon from "../../../images/notebook/publish_content.svg"; import { ArrayHashMap } from "../../Common/ArrayHashMap"; -import { NotebookUtil } from "../Notebook/NotebookUtil"; +import * as NotebookUtil from "../Notebook/NotebookUtil"; import _ from "underscore"; import { IPinnedRepo } from "../../Juno/JunoClient"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; diff --git a/src/GitHub/GitHubClient.ts b/src/GitHub/GitHubClient.ts index 016bca4b6..b15a28011 100644 --- a/src/GitHub/GitHubClient.ts +++ b/src/GitHub/GitHubClient.ts @@ -2,7 +2,7 @@ import { Octokit } from "@octokit/rest"; import { HttpStatusCodes } from "../Common/Constants"; import * as Logger from "../Common/Logger"; import UrlUtility from "../Common/UrlUtility"; -import { NotebookUtil } from "../Explorer/Notebook/NotebookUtil"; +import * as NotebookUtil from "../Explorer/Notebook/NotebookUtil"; import { getErrorMessage } from "../Common/ErrorHandlingUtils"; export interface IGitHubPageInfo { diff --git a/src/GitHub/GitHubContentProvider.ts b/src/GitHub/GitHubContentProvider.ts index d8f45aa97..b7ffdf628 100644 --- a/src/GitHub/GitHubContentProvider.ts +++ b/src/GitHub/GitHubContentProvider.ts @@ -5,7 +5,7 @@ import { AjaxResponse } from "rxjs/ajax"; import * as Base64Utils from "../Utils/Base64Utils"; import { HttpStatusCodes } from "../Common/Constants"; import * as Logger from "../Common/Logger"; -import { NotebookUtil } from "../Explorer/Notebook/NotebookUtil"; +import * as NotebookUtil from "../Explorer/Notebook/NotebookUtil"; import { GitHubClient, IGitHubFile, IGitHubResponse } from "./GitHubClient"; import * as GitHubUtils from "../Utils/GitHubUtils"; import UrlUtility from "../Common/UrlUtility";