From da038b4033c880a489cda0877853ad8c059ff1df Mon Sep 17 00:00:00 2001 From: campionfellin Date: Fri, 25 Jan 2019 20:03:59 -0800 Subject: [PATCH] Make urls.ts file and refactor Signed-off-by: campionfellin --- src/apis.ts | 2 ++ src/auth.ts | 3 ++- src/commands.ts | 2 +- src/commands/clone.ts | 29 ++++++++--------------------- src/urls.ts | 39 +++++++++++++++++++++++++++++++++++++++ src/utils.ts | 13 +------------ tests/test.ts | 15 +++++++++++++-- 7 files changed, 66 insertions(+), 37 deletions(-) create mode 100644 src/urls.ts diff --git a/src/apis.ts b/src/apis.ts index 6ce618e8..03157093 100644 --- a/src/apis.ts +++ b/src/apis.ts @@ -182,3 +182,5 @@ export const PUBLIC_ADVANCED_SERVICES: AdvancedService[] = [ version: 'v3', }, ]; + +export const SCRIPT_ID_LENGTH = 57; \ No newline at end of file diff --git a/src/auth.ts b/src/auth.ts index aa127f6b..91a453db 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -10,7 +10,8 @@ import { discovery_v1, drive_v3, google, logging_v2, script_v1, serviceusage_v1 import { prompt } from 'inquirer'; import { ClaspToken, DOTFILE } from './dotfile'; import { enableExecutionAPI, readManifest } from './manifest'; -import { ClaspCredentials, ERROR, LOG, URL, checkIfOnline, getOAuthSettings, logError } from './utils'; +import { URL } from './urls'; +import { ClaspCredentials, ERROR, LOG,checkIfOnline, getOAuthSettings, logError } from './utils'; import open = require('opn'); import readline = require('readline'); diff --git a/src/commands.ts b/src/commands.ts index 2bc26267..ff6e98db 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -36,12 +36,12 @@ import { manifestExists, readManifest, } from './manifest'; +import { URL } from './urls'; import { ERROR, LOG, PROJECT_MANIFEST_BASENAME, PROJECT_MANIFEST_FILENAME, - URL, checkIfOnline, getDefaultProjectName, getProjectId, diff --git a/src/commands/clone.ts b/src/commands/clone.ts index 17c0f706..0a20cf4f 100644 --- a/src/commands/clone.ts +++ b/src/commands/clone.ts @@ -3,6 +3,10 @@ import { loadAPICredentials, } from './../auth'; +import { + extractScriptId, +} from './../urls'; + import { checkIfOnline, ERROR, @@ -20,7 +24,6 @@ import { const padEnd = require('string.prototype.padend'); const prompt = require('inquirer').prompt; -const scriptIdStandardLength = 57; /** * Fetches an Apps Script project. @@ -33,11 +36,7 @@ const scriptIdStandardLength = 57; export default async (scriptId: string, versionNumber: number, cmd: { rootDir: string }) => { await checkIfOnline(); if (hasProject()) return logError(null, ERROR.FOLDER_EXISTS); - if (!scriptId) { - scriptId = await getScriptId(); - } else { - scriptId = extractScriptId(scriptId); - } + scriptId = scriptId ? extractScriptId(scriptId) : await getScriptId(); spinner.setSpinnerTitle(LOG.CLONING); const rootDir = cmd.rootDir; saveProject({ @@ -48,6 +47,9 @@ export default async (scriptId: string, versionNumber: number, cmd: { rootDir: s await writeProjectFiles(files, rootDir); }; +/** + * Lists a user's AppsScripts and prompts them to choose one to clone. + */ const getScriptId = async () => { await loadAPICredentials(); const list = await drive.files.list({ @@ -76,19 +78,4 @@ const getScriptId = async () => { }, ]); return answers.scriptId; -}; - -// We have a scriptId or URL -// If we passed a URL, extract the scriptId from that. For example: -// https://script.google.com/a/DOMAIN/d/1Ng7bNZ1K95wNi2H7IUwZzM68FL6ffxQhyc_ByV42zpS6qAFX8pFsWu2I/edit -const extractScriptId = (scriptId: string) => { - if (scriptId.length !== scriptIdStandardLength) { - const ids = scriptId.split('/').filter(s => { - return s.length === scriptIdStandardLength; - }); - if (ids.length) { - scriptId = ids[0]; - } - } - return scriptId; }; \ No newline at end of file diff --git a/src/urls.ts b/src/urls.ts new file mode 100644 index 00000000..fc97e4f0 --- /dev/null +++ b/src/urls.ts @@ -0,0 +1,39 @@ +import { + SCRIPT_ID_LENGTH, +} from './apis'; + +/** + * Extracts scriptId from URL if given in URL form. + * @param scriptId {string} either a scriptId or URL containing the scriptId + * @example + * extractScriptId( + * 'https://script.google.com/a/DOMAIN/d/1Ng7bNZ1K95wNi2H7IUwZzM68FL6ffxQhyc_ByV42zpS6qAFX8pFsWu2I/edit' + * ) + * returns '1Ng7bNZ1K95wNi2H7IUwZzM68FL6ffxQhyc_ByV42zpS6qAFX8pFsWu2I' + * @example + * extractScriptId('1Ng7bNZ1K95wNi2H7IUwZzM68FL6ffxQhyc_ByV42zpS6qAFX8pFsWu2I') + * returns '1Ng7bNZ1K95wNi2H7IUwZzM68FL6ffxQhyc_ByV42zpS6qAFX8pFsWu2I' + */ +export const extractScriptId = (scriptId: string) => { + if (scriptId.length !== SCRIPT_ID_LENGTH) { + const ids = scriptId.split('/').filter(s => { + return s.length === SCRIPT_ID_LENGTH; + }); + if (ids.length) { + scriptId = ids[0]; + } + } + return scriptId; +}; + +// Helpers to get Apps Script project URLs +export const URL = { + APIS: (projectId: string) => `https://console.developers.google.com/apis/dashboard?project=${projectId}`, + CREDS: (projectId: string) => `https://console.developers.google.com/apis/credentials?project=${projectId}`, + LOGS: (projectId: string) => + `https://console.cloud.google.com/logs/viewer?project=${projectId}&resource=app_script_function`, + SCRIPT_API_USER: 'https://script.google.com/home/usersettings', + // It is too expensive to get the script URL from the Drive API. (Async/not offline) + SCRIPT: (scriptId: string) => `https://script.google.com/d/${scriptId}/edit`, + DRIVE: (driveId: string) => `https://drive.google.com/open?id=${driveId}`, +}; \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts index ba33f40f..721256ed 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -6,6 +6,7 @@ import { prompt } from 'inquirer'; import * as pluralize from 'pluralize'; import { ClaspToken, DOT, DOTFILE, ProjectSettings } from './dotfile'; import {Manifest} from './manifest'; +import { URL } from './urls'; const ucfirst = require('ucfirst'); const isOnline = require('is-online'); @@ -57,18 +58,6 @@ export function getOAuthSettings(local: boolean): Promise { }); } -// Helpers to get Apps Script project URLs -export const URL = { - APIS: (projectId: string) => `https://console.developers.google.com/apis/dashboard?project=${projectId}`, - CREDS: (projectId: string) => `https://console.developers.google.com/apis/credentials?project=${projectId}`, - LOGS: (projectId: string) => - `https://console.cloud.google.com/logs/viewer?project=${projectId}&resource=app_script_function`, - SCRIPT_API_USER: 'https://script.google.com/home/usersettings', - // It is too expensive to get the script URL from the Drive API. (Async/not offline) - SCRIPT: (scriptId: string) => `https://script.google.com/d/${scriptId}/edit`, - DRIVE: (driveId: string) => `https://drive.google.com/open?id=${driveId}`, -}; - // Error messages (some errors take required params) export const ERROR = { ACCESS_TOKEN: `Error retrieving access token: `, diff --git a/tests/test.ts b/tests/test.ts index e3c0646e..f1deafaf 100644 --- a/tests/test.ts +++ b/tests/test.ts @@ -7,13 +7,12 @@ import { getAppsScriptFileName, getFileType } from './../src/files'; import { ERROR, LOG, - URL, getAPIFileType, getDefaultProjectName, getWebApplicationURL, hasOauthClientSettings, saveProject, -} from './../src/utils.js'; +} from './../src/utils'; import { backupSettings, @@ -36,6 +35,11 @@ import { TEST_CODE_JS, } from './constants'; +import { + extractScriptId, + URL, +} from './../src/urls'; + const { spawnSync } = require('child_process'); describe('Test --help for each function', () => { @@ -158,6 +162,13 @@ describe('Test clasp clone function', () => { after(cleanup); }); +describe('Test extractScriptId function', () => { + it('should return scriptId correctly', () => { + expect(extractScriptId(SCRIPT_ID)).to.equal(SCRIPT_ID); + expect(extractScriptId(URL.SCRIPT(SCRIPT_ID))).to.equal(SCRIPT_ID); + }); +}); + describe('Test clasp pull function', () => { before(function () { if (IS_PR) {