@google/clasp
Version:
Develop Apps Script Projects locally
145 lines (144 loc) • 4.52 kB
JavaScript
import Debug from 'debug';
import { GaxiosError } from 'googleapis-common';
const debug = Debug('clasp:core');
export function assertAuthenticated(options) {
if (!options.credentials) {
debug('Credentials not set in options: %O', options);
throw new Error('No credentials found.', {
cause: {
code: 'NO_CREDENTIALS',
},
});
}
}
export function assertScriptConfigured(options) {
var _a;
if (!((_a = options.project) === null || _a === void 0 ? void 0 : _a.scriptId) ||
!options.files.projectRootDir ||
!options.configFilePath ||
!options.files.contentDir) {
debug('Script configuration not found in options: %O', options);
throw new Error('Project settings not found.', {
cause: {
code: 'MISSING_SCRIPT_CONFIGURATION',
},
});
}
}
export function assertGcpProjectConfigured(options) {
var _a;
assertScriptConfigured(options);
if (!((_a = options.project) === null || _a === void 0 ? void 0 : _a.projectId)) {
debug('Script configuration not found in options: %O', options);
throw new Error('Project ID not found.', {
cause: {
code: 'MISSING_PROJECT_ID',
},
});
}
}
function pageOptionsWithDefaults(options) {
return {
pageSize: 100,
maxPages: 10,
maxResults: Number.MAX_SAFE_INTEGER,
...(options !== null && options !== void 0 ? options : {}),
};
}
export async function fetchWithPages(fn, options) {
const { pageSize, maxPages, maxResults } = pageOptionsWithDefaults(options);
let pageToken = undefined;
let pageCount = 0;
const results = [];
do {
debug('Fetching page %d', pageCount + 1);
const page = await fn(pageSize, pageToken);
if (page.results) {
results.push(...page.results);
}
++pageCount;
pageToken = page.pageToken;
} while (pageToken && pageCount < maxPages && results.length < maxResults);
if (pageToken) {
debug('Returning partial results, page limit exceeded');
}
if (results.length > maxResults) {
debug('Trimming results to %d', maxResults);
return {
results: results.slice(0, maxResults),
partialResults: true,
};
}
return {
results,
partialResults: pageToken !== undefined,
};
}
function isDetailedError(error) {
if (!error) {
return false;
}
const detailedError = error;
if (detailedError.errors === undefined) {
return false;
}
if (detailedError.errors.length === 0) {
return false;
}
return true;
}
const ERROR_CODES = {
400: 'INVALID_ARGUMENT',
401: 'NOT_AUTHENTICATED',
403: 'NOT_AUTHORIZED',
404: 'NOT_FOUND',
};
export function handleApiError(error) {
var _a;
debug('Handling API error: %O', error);
if (!(error instanceof GaxiosError)) {
throw new Error('Unexpected error', {
cause: {
code: 'UNEPECTED_ERROR',
message: new String(error),
error: error,
},
});
}
const status = error.status;
let message = error.message;
if (isDetailedError(error)) {
message = error.errors[0].message;
}
const code = (_a = ERROR_CODES[status !== null && status !== void 0 ? status : 0]) !== null && _a !== void 0 ? _a : 'UNEXPECTED_API_ERROR';
throw new Error(message, {
cause: {
code: code,
message: message,
error: error,
},
});
}
export function ensureStringArray(value) {
if (typeof value === 'string') {
return [value];
}
else if (Array.isArray(value)) {
// Ensure all elements in the array are strings.
if (value.every(item => typeof item === 'string')) {
return value;
}
else {
// Handle cases where the array contains non-string elements.
// You could throw an error, filter out non-strings, or convert them to strings.
// Example: filter out non-strings
return value.filter(item => typeof item === 'string');
}
}
else {
// Handle cases where the value is neither a string nor an array of strings.
// You could throw an error or return an empty array.
// Example: return an empty array
return [];
}
}