gsheet-lvt 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +163 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +3140 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +276 -0
- package/dist/index.js +1246 -0
- package/dist/index.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/auth/oauth-flow.ts","../src/config/constants.ts","../src/utils/logger.ts","../src/auth/oauth-scopes.ts","../src/auth/token-refresh.ts","../src/config/config-manager.ts","../src/utils/json.ts","../src/config/types.ts","../src/core/google-drive.service.ts","../src/core/google-sheets.service.ts","../src/client.ts","../src/utils/csv.ts","../src/utils/formatters.ts"],"sourcesContent":["import { OAuth2Client } from 'google-auth-library';\nimport http from 'http';\nimport { GOOGLE_API_URLS, OAUTH_CONFIG, OAUTH_SCOPES } from '../config/constants';\nimport type { OAuthCredentials } from '../config/types';\nimport { Logger } from '../utils/logger';\nimport { assertRequiredOAuthScopes } from './oauth-scopes';\n\nexport interface OAuthFlowResult {\n email: string;\n credentials: OAuthCredentials;\n}\n\nexport interface OAuthFlowOptions {\n loginHint?: string;\n onAuthUrl?: (url: string) => void;\n}\n\nexport async function performOAuthFlow(\n clientId: string,\n clientSecret: string,\n options: OAuthFlowOptions = {}\n): Promise<OAuthFlowResult> {\n const port = await getRandomAvailablePort();\n const redirectUri = `http://${OAUTH_CONFIG.REDIRECT_HOST}:${port}${OAUTH_CONFIG.REDIRECT_PATH}`;\n\n const oauth2Client = new OAuth2Client(clientId, clientSecret, redirectUri);\n\n const authUrl = oauth2Client.generateAuthUrl({\n access_type: OAUTH_CONFIG.ACCESS_TYPE,\n scope: [OAUTH_SCOPES.SPREADSHEETS, OAUTH_SCOPES.DRIVE_READONLY, OAUTH_SCOPES.USERINFO_EMAIL],\n prompt: OAUTH_CONFIG.PROMPT,\n include_granted_scopes: true,\n login_hint: options.loginHint\n });\n\n if (options.onAuthUrl) {\n options.onAuthUrl(authUrl);\n } else {\n Logger.info('Opening browser for authentication...');\n Logger.info(`Visit: ${authUrl}`);\n }\n\n const authCode = await startCallbackServer(port);\n\n const { tokens } = await oauth2Client.getToken(authCode);\n oauth2Client.setCredentials(tokens);\n\n if (!tokens.access_token) {\n throw new Error('No access token received. Try re-authenticating.');\n }\n\n const tokenInfo = await oauth2Client.getTokenInfo(tokens.access_token);\n assertRequiredOAuthScopes(tokenInfo.scopes);\n\n const userInfo = await fetch(GOOGLE_API_URLS.USERINFO, {\n headers: { Authorization: `Bearer ${tokens.access_token}` }\n });\n const userData = (await userInfo.json()) as { email: string };\n\n if (!tokens.refresh_token) {\n throw new Error('No refresh token received. Try revoking app access and re-authenticating.');\n }\n\n return {\n email: userData.email,\n credentials: {\n client_id: clientId,\n client_secret: clientSecret,\n refresh_token: tokens.refresh_token,\n access_token: tokens.access_token ?? undefined,\n expiry_date: tokens.expiry_date ?? undefined\n }\n };\n}\n\nasync function getRandomAvailablePort(): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = http.createServer();\n server.listen(0, () => {\n const address = server.address();\n if (address && typeof address !== 'string') {\n const port = address.port;\n server.close(() => resolve(port));\n } else {\n reject(new Error('Failed to get port'));\n }\n });\n });\n}\n\nasync function startCallbackServer(port: number): Promise<string> {\n return new Promise((resolve, reject) => {\n const server = http.createServer((req, res) => {\n if (req.url?.startsWith(OAUTH_CONFIG.REDIRECT_PATH)) {\n const url = new URL(req.url, `http://${OAUTH_CONFIG.REDIRECT_HOST}:${port}`);\n const code = url.searchParams.get('code');\n\n if (code) {\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(`\n <html>\n <body style=\"font-family: system-ui; text-align: center; padding: 50px;\">\n <h1 style=\"color: #10b981;\">Authentication Successful</h1>\n <p>You can close this window and return to the terminal.</p>\n </body>\n </html>\n `);\n\n server.close();\n resolve(code);\n } else {\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(`\n <html>\n <body style=\"font-family: system-ui; text-align: center; padding: 50px;\">\n <h1 style=\"color: #ef4444;\">✗ Authentication Failed</h1>\n <p>No authorization code received.</p>\n </body>\n </html>\n `);\n server.close();\n reject(new Error('No authorization code received'));\n }\n }\n });\n\n server.listen(port, OAUTH_CONFIG.REDIRECT_HOST);\n });\n}\n","import { existsSync, readFileSync } from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst packageJsonPath = findPackageJsonPath(__dirname);\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n\nexport const APP_INFO = {\n name: 'gsheet',\n packageName: packageJson.name,\n display_name: 'Google Sheets CLI',\n version: packageJson.version\n};\n\nenum SupportedOS {\n Linux = 'linux',\n Mac = 'mac',\n Windows = 'windows',\n Wsl = 'wsl'\n}\n\nconst configDirectoryByOS = {\n [SupportedOS.Linux]: (homeDir: string) => path.join(homeDir, '.config', APP_INFO.name),\n [SupportedOS.Wsl]: (homeDir: string) => path.join(homeDir, '.config', APP_INFO.name),\n [SupportedOS.Mac]: (homeDir: string) => path.join(homeDir, 'Library', 'Preferences', APP_INFO.name),\n [SupportedOS.Windows]: (homeDir: string) => path.join(homeDir, 'AppData', 'Roaming', APP_INFO.name)\n} as const satisfies Record<SupportedOS, (homeDir: string) => string>;\n\nexport function getUserOS(): SupportedOS {\n const platform = os.platform();\n\n if (platform === 'linux') {\n try {\n const release = os.release().toLowerCase();\n if (release.includes('microsoft') || release.includes('wsl')) {\n return SupportedOS.Wsl;\n }\n } catch {}\n return SupportedOS.Linux;\n }\n\n if (platform === 'darwin') return SupportedOS.Mac;\n if (platform === 'win32') return SupportedOS.Windows;\n\n throw new Error(`Unsupported OS: ${platform}`);\n}\n\nexport function getConfigDirectory(): string {\n const userOS = getUserOS();\n const homeDir = os.homedir();\n\n return configDirectoryByOS[userOS](homeDir);\n}\n\nexport const CONFIG_PATHS = {\n configDir: getConfigDirectory(),\n userMetadataFile: path.join(getConfigDirectory(), 'user_metadata.json'),\n defaultConfigFile: path.join(getConfigDirectory(), 'config.json')\n};\n\nexport const OAUTH_SCOPES = {\n SPREADSHEETS: 'https://www.googleapis.com/auth/spreadsheets',\n DRIVE_READONLY: 'https://www.googleapis.com/auth/drive.readonly',\n USERINFO_EMAIL: 'https://www.googleapis.com/auth/userinfo.email'\n};\n\nexport const GOOGLE_API_URLS = {\n USERINFO: 'https://www.googleapis.com/oauth2/v2/userinfo',\n SHEETS_CREATE: 'https://sheets.google.com'\n};\n\nexport const GOOGLE_CLOUD_CONSOLE_URLS = {\n CREDENTIALS: 'https://console.cloud.google.com/apis/credentials',\n CONSENT_SCREEN: 'https://console.cloud.google.com/apis/credentials/consent',\n SCOPES: 'https://console.cloud.google.com/auth/scopes',\n TEST_USERS: 'https://console.cloud.google.com/auth/audience',\n ENABLE_SHEETS_API: 'https://console.cloud.google.com/apis/library/sheets.googleapis.com',\n ENABLE_DRIVE_API: 'https://console.cloud.google.com/apis/library/drive.googleapis.com'\n};\n\nexport const OAUTH_CONFIG = {\n REDIRECT_HOST: '127.0.0.1',\n REDIRECT_PATH: '/callback',\n ACCESS_TYPE: 'offline' as const,\n PROMPT: 'consent' as const\n};\n\nexport const TOKEN_REFRESH_THRESHOLD_MS = 5 * 60 * 1000;\n\nfunction findPackageJsonPath(startDir: string): string {\n let currentDir = startDir;\n\n while (true) {\n const candidate = path.join(currentDir, 'package.json');\n\n if (existsSync(candidate)) {\n return candidate;\n }\n\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) {\n throw new Error('Could not find package.json');\n }\n\n currentDir = parentDir;\n }\n}\n","import chalk from 'chalk';\n\nexport class Logger {\n static error(message: string, error?: unknown): void {\n if (error === undefined) {\n console.error(chalk.red(`❌ ${message}`));\n return;\n }\n\n const errorText = error instanceof Error ? error.message : 'Unknown error';\n console.error(chalk.red(`❌ ${message}: ${errorText}`));\n }\n\n static success(message: string): void {\n console.log(chalk.green(`✅ ${message}`));\n }\n\n static warning(message: string): void {\n console.log(chalk.yellow(`⚠️ ${message}`));\n }\n\n static info(message: string): void {\n console.log(`${message}`);\n }\n\n static dim(message: string): void {\n console.log(chalk.dim(message));\n }\n\n static plain(message: string): void {\n console.log(message);\n }\n\n static json(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n }\n\n static bold(message: string): void {\n console.log(chalk.bold(message));\n }\n\n static loading(message: string): void {\n console.log(`🔄 ${message}`);\n }\n\n static link(url: string, prefix?: string): void {\n const linkText = prefix ? `${prefix} ${url}` : url;\n console.log(chalk.dim(`🔗 ${linkText}`));\n }\n}\n","import { OAUTH_SCOPES } from '../config/constants';\n\nconst DRIVE_SCOPES = new Set([OAUTH_SCOPES.DRIVE_READONLY, 'https://www.googleapis.com/auth/drive']);\n\nconst REQUIRED_OAUTH_SCOPES = [OAUTH_SCOPES.SPREADSHEETS, OAUTH_SCOPES.DRIVE_READONLY] as const;\n\nfunction getMissingOAuthScopes(grantedScopes: string[]): string[] {\n return REQUIRED_OAUTH_SCOPES.filter((scope) => {\n if (scope === OAUTH_SCOPES.DRIVE_READONLY) {\n return !grantedScopes.some((grantedScope) => DRIVE_SCOPES.has(grantedScope));\n }\n\n return !grantedScopes.includes(scope);\n });\n}\n\nexport function assertRequiredOAuthScopes(grantedScopes: string[]): void {\n const missingScopes = getMissingOAuthScopes(grantedScopes);\n\n if (missingScopes.length === 0) {\n return;\n }\n\n throw new Error(\n [\n 'Google returned an access token without required scopes.',\n `Missing scopes: ${missingScopes.join(', ')}`,\n `Granted scopes: ${grantedScopes.length > 0 ? grantedScopes.join(', ') : 'none'}`,\n 'Fix: in Google Cloud Console, add the missing scopes to the OAuth consent screen, publish/save the consent screen, then run `gsheet account reauth` again.'\n ].join('\\n')\n );\n}\n","import { OAuth2Client } from 'google-auth-library';\nimport { TOKEN_REFRESH_THRESHOLD_MS } from '../config/constants';\nimport type { OAuthCredentials } from '../config/types';\nimport { assertRequiredOAuthScopes } from './oauth-scopes';\n\nexport async function refreshTokenIfNeeded(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n const now = Date.now();\n const expiryDate = credentials.expiry_date || 0;\n\n if (now >= expiryDate - TOKEN_REFRESH_THRESHOLD_MS) {\n return await refreshToken(credentials);\n }\n\n return credentials;\n}\n\nexport async function refreshToken(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n const oauth2Client = new OAuth2Client(credentials.client_id, credentials.client_secret);\n\n oauth2Client.setCredentials({\n refresh_token: credentials.refresh_token\n });\n\n const { credentials: newTokens } = await oauth2Client.refreshAccessToken();\n const accessToken = newTokens.access_token || credentials.access_token;\n\n if (!accessToken) {\n throw new Error('No access token available after refresh. Run `gsheet account reauth`.');\n }\n\n const tokenInfo = await oauth2Client.getTokenInfo(accessToken);\n assertRequiredOAuthScopes(tokenInfo.scopes);\n\n return {\n client_id: credentials.client_id,\n client_secret: credentials.client_secret,\n refresh_token: credentials.refresh_token,\n access_token: accessToken,\n expiry_date: newTokens.expiry_date || credentials.expiry_date\n };\n}\n","import * as fs from 'fs';\nimport { OAuth2Client } from 'google-auth-library';\nimport { assertRequiredOAuthScopes } from '../auth/oauth-scopes';\nimport { refreshTokenIfNeeded } from '../auth/token-refresh';\nimport { readJson, writeJson } from '../utils/json';\nimport { CONFIG_PATHS } from './constants';\nimport type { Account, OAuthCredentials, SheetsConfig, SpreadsheetConfig, UserMetadata } from './types';\nimport { sheetsConfigSchema, userMetadataSchema } from './types';\n\nexport class ConfigManager {\n private userMetadata: UserMetadata | null = null;\n private config: SheetsConfig | null = null;\n\n constructor() {\n this.ensureConfigDirectory();\n this.initializeUserMetadata();\n }\n\n private ensureConfigDirectory(): void {\n if (!fs.existsSync(CONFIG_PATHS.configDir)) {\n fs.mkdirSync(CONFIG_PATHS.configDir, { recursive: true });\n }\n }\n\n private initializeUserMetadata(): void {\n if (!fs.existsSync(CONFIG_PATHS.userMetadataFile)) {\n this.createDefaultUserMetadata();\n }\n this.loadUserMetadata();\n }\n\n private createDefaultUserMetadata(): void {\n const defaultMetadata: UserMetadata = {\n config_path: CONFIG_PATHS.defaultConfigFile,\n accounts: {}\n };\n writeJson(CONFIG_PATHS.userMetadataFile, defaultMetadata);\n }\n\n private loadUserMetadata(): void {\n try {\n const data = readJson<UserMetadata>(CONFIG_PATHS.userMetadataFile);\n const validated = userMetadataSchema.parse(data);\n this.userMetadata = validated;\n } catch (error) {\n throw new Error(`Failed to load user metadata: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n private saveUserMetadata(): void {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n writeJson(CONFIG_PATHS.userMetadataFile, this.userMetadata);\n }\n\n private getConfigPath(): string {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n return this.userMetadata.config_path;\n }\n\n private loadConfig(): SheetsConfig {\n if (this.config) {\n return this.config;\n }\n\n const configPath = this.getConfigPath();\n\n if (!fs.existsSync(configPath)) {\n this.createDefaultConfig();\n }\n\n try {\n const data = readJson<SheetsConfig>(configPath);\n const validated = sheetsConfigSchema.parse(data);\n this.config = validated;\n return this.config;\n } catch (error) {\n throw new Error(`Failed to load config: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n private createDefaultConfig(): void {\n const defaultConfig: SheetsConfig = {\n settings: {\n max_results: 50,\n default_columns: 'A:Z'\n }\n };\n\n const configPath = this.getConfigPath();\n writeJson(configPath, defaultConfig);\n }\n\n private saveConfig(): void {\n if (!this.config) {\n throw new Error('No config to save');\n }\n\n const configPath = this.getConfigPath();\n writeJson(configPath, this.config);\n }\n\n async addAccount(email: string, credentials: OAuthCredentials): Promise<void> {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n if (this.userMetadata.accounts[email]) {\n throw new Error(`Account '${email}' already exists`);\n }\n\n const account: Account = {\n email,\n oauth: credentials,\n spreadsheets: {}\n };\n\n this.userMetadata.accounts[email] = account;\n this.saveUserMetadata();\n }\n\n async removeAccount(email: string): Promise<void> {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n if (!this.userMetadata.accounts[email]) {\n throw new Error(`Account '${email}' not found`);\n }\n\n delete this.userMetadata.accounts[email];\n\n if (this.userMetadata.activeAccount === email) {\n this.userMetadata.activeAccount = undefined;\n }\n\n this.saveUserMetadata();\n }\n\n getAllAccounts(): Account[] {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n return Object.values(this.userMetadata.accounts);\n }\n\n getAccount(email: string): Account | null {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n return this.userMetadata.accounts[email] || null;\n }\n\n setActiveAccount(email: string): void {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n if (!this.userMetadata.accounts[email]) {\n throw new Error(`Account '${email}' not found`);\n }\n\n this.userMetadata.activeAccount = email;\n this.saveUserMetadata();\n }\n\n getActiveAccount(): Account | null {\n if (!this.userMetadata?.activeAccount) {\n return null;\n }\n\n return this.getAccount(this.userMetadata.activeAccount);\n }\n\n getActiveAccountEmail(): string | null {\n return this.userMetadata?.activeAccount || null;\n }\n\n async updateAccountCredentials(email: string, credentials: OAuthCredentials): Promise<void> {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n const account = this.userMetadata.accounts[email];\n if (!account) {\n throw new Error(`Account '${email}' not found`);\n }\n\n account.oauth = credentials;\n this.saveUserMetadata();\n }\n\n async getRefreshedCredentials(email: string): Promise<OAuthCredentials> {\n const account = this.getAccount(email);\n if (!account) {\n throw new Error(`Account '${email}' not found`);\n }\n\n const refreshedCredentials = await refreshTokenIfNeeded(account.oauth);\n await assertCredentialsHaveRequiredScopes(refreshedCredentials);\n\n if (refreshedCredentials !== account.oauth) {\n await this.updateAccountCredentials(email, refreshedCredentials);\n }\n\n return refreshedCredentials;\n }\n\n async addSpreadsheet(email: string, name: string, spreadsheetId: string): Promise<void> {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n const account = this.userMetadata.accounts[email];\n if (!account) {\n throw new Error(`Account '${email}' not found`);\n }\n\n if (account.spreadsheets[name]) {\n throw new Error(`Spreadsheet '${name}' already exists for account '${email}'`);\n }\n\n const spreadsheet: SpreadsheetConfig = {\n spreadsheet_id: spreadsheetId\n };\n\n account.spreadsheets[name] = spreadsheet;\n this.saveUserMetadata();\n }\n\n async removeSpreadsheet(email: string, name: string): Promise<void> {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n const account = this.userMetadata.accounts[email];\n if (!account) {\n throw new Error(`Account '${email}' not found`);\n }\n\n if (!account.spreadsheets[name]) {\n throw new Error(`Spreadsheet '${name}' not found for account '${email}'`);\n }\n\n delete account.spreadsheets[name];\n\n if (account.activeSpreadsheet === name) {\n account.activeSpreadsheet = undefined;\n }\n\n this.saveUserMetadata();\n }\n\n listSpreadsheets(email: string): Array<{ name: string; spreadsheetId: string; activeSheet?: string }> {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n const account = this.userMetadata.accounts[email];\n if (!account) {\n throw new Error(`Account '${email}' not found`);\n }\n\n return Object.entries(account.spreadsheets).map(([name, spreadsheet]) => ({\n name,\n spreadsheetId: spreadsheet.spreadsheet_id,\n activeSheet: spreadsheet.activeSheet\n }));\n }\n\n getSpreadsheet(email: string, name: string): SpreadsheetConfig | null {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n const account = this.userMetadata.accounts[email];\n if (!account) {\n return null;\n }\n\n return account.spreadsheets[name] || null;\n }\n\n getSpreadsheetById(email: string, id: string): SpreadsheetConfig | null {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n const account = this.userMetadata.accounts[email];\n if (!account) {\n return null;\n }\n\n return Object.values(account.spreadsheets).find((s) => s.spreadsheet_id === id) || null;\n }\n\n setActiveSpreadsheet(email: string, name: string): void {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n const account = this.userMetadata.accounts[email];\n if (!account) {\n throw new Error(`Account '${email}' not found`);\n }\n\n if (!account.spreadsheets[name]) {\n throw new Error(`Spreadsheet '${name}' not found for account '${email}'`);\n }\n\n account.activeSpreadsheet = name;\n this.saveUserMetadata();\n }\n\n getActiveSpreadsheet(email: string): SpreadsheetConfig | null {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n const account = this.userMetadata.accounts[email];\n if (!account || !account.activeSpreadsheet) {\n return null;\n }\n\n return account.spreadsheets[account.activeSpreadsheet] || null;\n }\n\n getActiveSpreadsheetName(email: string): string | null {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n const account = this.userMetadata.accounts[email];\n return account?.activeSpreadsheet || null;\n }\n\n setActiveSheet(email: string, spreadsheetName: string, sheetName: string): void {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n const account = this.userMetadata.accounts[email];\n if (!account) {\n throw new Error(`Account '${email}' not found`);\n }\n\n const spreadsheet = account.spreadsheets[spreadsheetName];\n if (!spreadsheet) {\n throw new Error(`Spreadsheet '${spreadsheetName}' not found for account '${email}'`);\n }\n\n spreadsheet.activeSheet = sheetName;\n this.saveUserMetadata();\n }\n\n getActiveSheetName(email: string, spreadsheetName: string): string | null {\n if (!this.userMetadata) {\n throw new Error('User metadata not loaded');\n }\n\n const account = this.userMetadata.accounts[email];\n if (!account) {\n return null;\n }\n\n const spreadsheet = account.spreadsheets[spreadsheetName];\n return spreadsheet?.activeSheet || null;\n }\n\n markCompletionInstalled(): void {\n const config = this.loadConfig();\n if (!config.settings) {\n config.settings = {\n max_results: 50,\n default_columns: 'A:Z'\n };\n }\n config.settings.completion_installed = true;\n this.saveConfig();\n }\n\n isCompletionInstalled(): boolean {\n const config = this.loadConfig();\n return config.settings?.completion_installed === true;\n }\n}\n\nasync function assertCredentialsHaveRequiredScopes(credentials: OAuthCredentials): Promise<void> {\n if (!credentials.access_token) {\n throw new Error('No access token available. Run `gsheet account reauth`.');\n }\n\n const oauth2Client = new OAuth2Client(credentials.client_id, credentials.client_secret);\n const tokenInfo = await oauth2Client.getTokenInfo(credentials.access_token);\n assertRequiredOAuthScopes(tokenInfo.scopes);\n}\n","import * as fs from 'fs';\n\nexport function readJson<T = Record<string, unknown>>(filePath: string): T {\n if (!fs.existsSync(filePath)) {\n throw new Error(`File not found: ${filePath}`);\n }\n\n try {\n const rawData = fs.readFileSync(filePath, 'utf-8');\n return JSON.parse(rawData) as T;\n } catch (error) {\n throw new Error(\n `Failed to parse JSON file: ${filePath}. Error: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n}\n\nexport function writeJson<T>(filePath: string, data: T, pretty = true): void {\n try {\n const jsonString = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);\n fs.writeFileSync(filePath, jsonString, 'utf-8');\n } catch (error) {\n throw new Error(\n `Failed to write JSON file: ${filePath}. Error: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n}\n","import { z } from 'zod';\n\nexport const oauthCredentialsSchema = z.object({\n client_id: z.string(),\n client_secret: z.string(),\n refresh_token: z.string(),\n access_token: z.string().optional(),\n expiry_date: z.number().optional()\n});\n\nexport const spreadsheetConfigSchema = z.object({\n spreadsheet_id: z.string(),\n activeSheet: z.string().optional()\n});\n\nexport const accountSchema = z.object({\n email: z.string(),\n oauth: oauthCredentialsSchema,\n activeSpreadsheet: z.string().optional(),\n spreadsheets: z.record(z.string(), spreadsheetConfigSchema)\n});\n\nexport const userMetadataSchema = z.object({\n config_path: z.string(),\n activeAccount: z.string().optional(),\n accounts: z.record(z.string(), accountSchema)\n});\n\nexport const sheetsConfigSchema = z.object({\n $schema: z.string().optional(),\n settings: z\n .object({\n max_results: z.number().default(50),\n default_columns: z.string().default('A:Z'),\n completion_installed: z.boolean().optional()\n })\n .optional()\n});\n\nexport const sheetDataSchema = z.object({\n title: z.string(),\n index: z.number()\n});\n\nexport type OAuthCredentials = z.infer<typeof oauthCredentialsSchema>;\nexport type SpreadsheetConfig = z.infer<typeof spreadsheetConfigSchema>;\nexport type Account = z.infer<typeof accountSchema>;\nexport type UserMetadata = z.infer<typeof userMetadataSchema>;\nexport type SheetsConfig = z.infer<typeof sheetsConfigSchema>;\nexport type SheetData = z.infer<typeof sheetDataSchema>;\n","import { google } from 'googleapis';\nimport { OAUTH_SCOPES } from '../config/constants';\nimport type { OAuthCredentials } from '../config/types';\nimport { Logger } from '../utils/logger';\n\nexport interface DriveSpreadsheet {\n id: string;\n name: string;\n modifiedTime: string;\n webViewLink: string;\n}\n\nexport class GoogleDriveService {\n private credentials: OAuthCredentials;\n\n constructor(oauthCredentials: OAuthCredentials) {\n this.credentials = oauthCredentials;\n }\n\n async listSpreadsheets(): Promise<DriveSpreadsheet[]> {\n const oauth2Client = new google.auth.OAuth2(this.credentials.client_id, this.credentials.client_secret);\n\n oauth2Client.setCredentials({\n access_token: this.credentials.access_token,\n refresh_token: this.credentials.refresh_token,\n expiry_date: this.credentials.expiry_date\n });\n\n Logger.info('Checking access token...');\n const tokenInfo = await oauth2Client.getTokenInfo(this.credentials.access_token || '');\n Logger.info(`Token scopes: ${tokenInfo.scopes?.join(', ') || 'none'}`);\n Logger.info(\n `Token expires at: ${this.credentials.expiry_date ? new Date(this.credentials.expiry_date).toLocaleString() : 'unknown'}`\n );\n\n const drive = google.drive({ version: 'v3', auth: oauth2Client });\n\n Logger.info('Requesting spreadsheets from Google Drive API...');\n\n try {\n const response = await drive.files.list({\n q: \"mimeType='application/vnd.google-apps.spreadsheet' and trashed=false\",\n fields: 'files(id, name, modifiedTime, webViewLink)',\n orderBy: 'modifiedTime desc',\n pageSize: 100\n });\n\n const files = response.data.files || [];\n Logger.info(`Found ${files.length} spreadsheet(s)`);\n\n return files.map((file) => ({\n id: file.id || '',\n name: file.name || 'Untitled',\n modifiedTime: file.modifiedTime || '',\n webViewLink: file.webViewLink || ''\n }));\n } catch (error: unknown) {\n Logger.error('Google Drive API error:', error);\n Logger.info('\\nRequired scopes for this operation:');\n Logger.info(` - ${OAUTH_SCOPES.SPREADSHEETS}`);\n Logger.info(` - ${OAUTH_SCOPES.DRIVE_READONLY}`);\n Logger.info('\\nTo fix this:');\n Logger.info(' 1. Add Drive API scope in OAuth Consent Screen');\n Logger.info(' 2. Run: gsheet account reauth');\n throw error;\n }\n }\n}\n","import { OAuth2Client } from 'google-auth-library';\nimport { GoogleSpreadsheet } from 'google-spreadsheet';\nimport type { OAuthCredentials } from '../config/types';\n\nexport interface GoogleSheetsConfig {\n spreadsheetId: string;\n oauthCredentials: OAuthCredentials;\n}\n\nexport class GoogleSheetsService {\n private doc: GoogleSpreadsheet | null = null;\n private auth: OAuth2Client;\n\n constructor(private config: GoogleSheetsConfig) {\n this.auth = new OAuth2Client(config.oauthCredentials.client_id, config.oauthCredentials.client_secret);\n\n this.auth.setCredentials({\n access_token: config.oauthCredentials.access_token,\n refresh_token: config.oauthCredentials.refresh_token,\n expiry_date: config.oauthCredentials.expiry_date\n });\n }\n\n private async ensureConnection(): Promise<void> {\n if (!this.doc) {\n this.doc = new GoogleSpreadsheet(this.config.spreadsheetId, this.auth);\n await this.doc.loadInfo();\n }\n }\n\n async getSheetInfo(): Promise<{\n title: string;\n sheets: Array<{ title: string; index: number; sheetId: number }>;\n }> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n return {\n title: this.doc.title,\n sheets: this.doc.sheetsByIndex.map((sheet, index) => ({\n title: sheet.title,\n index,\n sheetId: sheet.sheetId\n }))\n };\n }\n\n async getSheetData(sheetName: string, includeFormulas = false): Promise<string[][]> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n const sheet = this.doc.sheetsByTitle[sheetName];\n if (!sheet) {\n throw new Error(`Sheet '${sheetName}' not found`);\n }\n\n await sheet.loadCells();\n\n let lastRow = 0;\n let lastCol = 0;\n\n for (let row = 0; row < sheet.rowCount; row++) {\n for (let col = 0; col < sheet.columnCount; col++) {\n const cell = sheet.getCell(row, col);\n const value = includeFormulas && cell.formula ? cell.formula : (cell.formattedValue ?? '');\n\n if (value !== '') {\n lastRow = Math.max(lastRow, row);\n lastCol = Math.max(lastCol, col);\n }\n }\n }\n\n if (lastRow === 0 && lastCol === 0) {\n const firstCell = sheet.getCell(0, 0);\n const firstValue = includeFormulas && firstCell.formula ? firstCell.formula : (firstCell.formattedValue ?? '');\n\n if (firstValue === '') {\n return [];\n }\n }\n\n const data: string[][] = [];\n for (let row = 0; row <= lastRow; row++) {\n const rowData: string[] = [];\n for (let col = 0; col <= lastCol; col++) {\n const cell = sheet.getCell(row, col);\n const value = includeFormulas && cell.formula ? cell.formula : (cell.formattedValue ?? '');\n rowData.push(value);\n }\n data.push(rowData);\n }\n\n return data;\n }\n\n async addSheet(sheetName: string): Promise<void> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n await this.doc.addSheet({ title: sheetName });\n }\n\n async removeSheet(sheetName: string): Promise<void> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n const sheet = this.doc.sheetsByTitle[sheetName];\n if (!sheet) {\n throw new Error(`Sheet '${sheetName}' not found`);\n }\n\n await sheet.delete();\n }\n\n async renameSheet(oldName: string, newName: string): Promise<void> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n const sheet = this.doc.sheetsByTitle[oldName];\n if (!sheet) {\n throw new Error(`Sheet '${oldName}' not found`);\n }\n\n await sheet.updateProperties({ title: newName });\n }\n\n async copySheet(sheetName: string, newSheetName: string): Promise<void> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n const sheet = this.doc.sheetsByTitle[sheetName];\n if (!sheet) {\n throw new Error(`Sheet '${sheetName}' not found`);\n }\n\n await sheet.duplicate({ title: newSheetName });\n }\n\n async writeCell(sheetName: string, cell: string, value: string): Promise<void> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n const sheet = this.doc.sheetsByTitle[sheetName];\n if (!sheet) {\n throw new Error(`Sheet '${sheetName}' not found`);\n }\n\n await sheet.loadCells(cell);\n const targetCell = sheet.getCellByA1(cell);\n targetCell.value = value;\n await sheet.saveUpdatedCells();\n }\n\n async writeCellRange(\n sheetName: string,\n range: string,\n values: (string | number)[][],\n noPreserve?: boolean\n ): Promise<void> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n const sheet = this.doc.sheetsByTitle[sheetName];\n if (!sheet) {\n throw new Error(`Sheet '${sheetName}' not found`);\n }\n\n await sheet.loadCells(range);\n\n const [start, end] = range.split(':');\n const startCell = sheet.getCellByA1(start);\n const endCell = sheet.getCellByA1(end);\n\n let valueRowIndex = 0;\n for (let row = startCell.rowIndex; row <= endCell.rowIndex; row++) {\n let valueColIndex = 0;\n for (let col = startCell.columnIndex; col <= endCell.columnIndex; col++) {\n const cell = sheet.getCell(row, col);\n const cellWithRawData = cell as unknown as {\n _rawData?: { dataValidation?: unknown; userEnteredValue?: { formulaValue?: string } };\n };\n const hasDataValidation = cellWithRawData._rawData?.dataValidation !== undefined;\n const hasFormula = cellWithRawData._rawData?.userEnteredValue?.formulaValue !== undefined;\n const isCellEmpty = !cell.value || cell.value === '';\n\n if (values[valueRowIndex] && values[valueRowIndex][valueColIndex] !== undefined) {\n const newValue = values[valueRowIndex][valueColIndex];\n const isNewValueEmpty = newValue === '' || newValue === null;\n\n if (noPreserve) {\n cell.value = newValue;\n } else {\n if (!(hasDataValidation && isCellEmpty && isNewValueEmpty) && !hasFormula) {\n cell.value = newValue;\n }\n }\n }\n valueColIndex++;\n }\n valueRowIndex++;\n }\n\n await sheet.saveUpdatedCells();\n }\n\n async appendRow(sheetName: string, values: string[]): Promise<void> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n const sheet = this.doc.sheetsByTitle[sheetName];\n if (!sheet) {\n throw new Error(`Sheet '${sheetName}' not found`);\n }\n\n await sheet.addRow(values);\n }\n\n async getSheetDataRange(sheetName: string, range: string, includeFormulas = false): Promise<string[][]> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n const sheet = this.doc.sheetsByTitle[sheetName];\n if (!sheet) {\n throw new Error(`Sheet '${sheetName}' not found`);\n }\n\n await sheet.loadCells(range);\n\n const [start, end] = range.split(':');\n const startCell = sheet.getCellByA1(start);\n const endCell = sheet.getCellByA1(end);\n\n const data: string[][] = [];\n for (let row = startCell.rowIndex; row <= endCell.rowIndex; row++) {\n const rowData: string[] = [];\n for (let col = startCell.columnIndex; col <= endCell.columnIndex; col++) {\n const cell = sheet.getCell(row, col);\n const value = includeFormulas && cell.formula ? cell.formula : (cell.formattedValue ?? '');\n rowData.push(value);\n }\n data.push(rowData);\n }\n\n return data;\n }\n\n async insertRows(\n sheetName: string,\n range: { startIndex: number; endIndex: number },\n inheritFromBefore = false\n ): Promise<void> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n const sheet = this.doc.sheetsByTitle[sheetName];\n if (!sheet) {\n throw new Error(`Sheet '${sheetName}' not found`);\n }\n\n await sheet.insertDimension('ROWS', range, inheritFromBefore);\n }\n\n async deleteRows(sheetName: string, range: { startIndex: number; endIndex: number }): Promise<void> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n const sheet = this.doc.sheetsByTitle[sheetName];\n if (!sheet) {\n throw new Error(`Sheet '${sheetName}' not found`);\n }\n\n await sheet._makeSingleUpdateRequest('deleteDimension', {\n range: {\n sheetId: sheet.sheetId,\n dimension: 'ROWS',\n startIndex: range.startIndex,\n endIndex: range.endIndex\n }\n });\n }\n\n async getRowFormulas(sheetName: string, rowIndex: number): Promise<Map<number, string>> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n const sheet = this.doc.sheetsByTitle[sheetName];\n if (!sheet) {\n throw new Error(`Sheet '${sheetName}' not found`);\n }\n\n await sheet.loadCells(`A${rowIndex + 1}:${rowIndex + 1}`);\n\n const formulas = new Map<number, string>();\n for (let col = 0; col < sheet.columnCount; col++) {\n const cell = sheet.getCell(rowIndex, col);\n if (cell.formula) {\n formulas.set(col, cell.formula);\n }\n }\n\n return formulas;\n }\n\n async copyRowFormulas(sheetName: string, sourceRowIndex: number, targetRowIndex: number): Promise<void> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n const sheet = this.doc.sheetsByTitle[sheetName];\n if (!sheet) {\n throw new Error(`Sheet '${sheetName}' not found`);\n }\n\n const formulas = await this.getRowFormulas(sheetName, sourceRowIndex);\n\n if (formulas.size === 0) {\n return;\n }\n\n await sheet.loadCells(`A${targetRowIndex + 1}:${targetRowIndex + 1}`);\n\n const rowDiff = targetRowIndex - sourceRowIndex;\n\n for (const [col, formula] of formulas) {\n const cell = sheet.getCell(targetRowIndex, col);\n const adjustedFormula = this.adjustFormulaReferences(formula, rowDiff);\n cell.formula = adjustedFormula;\n }\n\n await sheet.saveUpdatedCells();\n }\n\n async copyRowFormulasBulk(\n sheetName: string,\n sourceRowIndex: number,\n startTargetRowIndex: number,\n count: number\n ): Promise<void> {\n await this.ensureConnection();\n\n if (!this.doc) {\n throw new Error('Failed to connect to Google Sheets');\n }\n\n const sheet = this.doc.sheetsByTitle[sheetName];\n if (!sheet) {\n throw new Error(`Sheet '${sheetName}' not found`);\n }\n\n const formulas = await this.getRowFormulas(sheetName, sourceRowIndex);\n\n if (formulas.size === 0) {\n return;\n }\n\n const endTargetRowIndex = startTargetRowIndex + count - 1;\n await sheet.loadCells(`A${startTargetRowIndex + 1}:${endTargetRowIndex + 1}`);\n\n for (let i = 0; i < count; i++) {\n const targetRowIndex = startTargetRowIndex + i;\n const rowDiff = targetRowIndex - sourceRowIndex;\n\n for (const [col, formula] of formulas) {\n const cell = sheet.getCell(targetRowIndex, col);\n const adjustedFormula = this.adjustFormulaReferences(formula, rowDiff);\n cell.formula = adjustedFormula;\n }\n }\n\n await sheet.saveUpdatedCells();\n }\n\n private adjustFormulaReferences(formula: string, rowDiff: number): string {\n return formula.replace(/([A-Z]+)(\\d+)/g, (_match, colLetter, rowNum) => {\n const newRow = parseInt(rowNum, 10) + rowDiff;\n return `${colLetter}${newRow}`;\n });\n }\n}\n","import { performOAuthFlow } from './auth/oauth-flow';\nimport { refreshToken } from './auth/token-refresh';\nimport { ConfigManager } from './config/config-manager';\nimport type { Account, OAuthCredentials, SpreadsheetConfig } from './config/types';\nimport { GoogleDriveService } from './core/google-drive.service';\nimport { type GoogleSheetsConfig, GoogleSheetsService } from './core/google-sheets.service';\n\nexport interface SheetCmdClientOptions {\n configManager?: ConfigManager;\n}\n\nexport interface LoginOptions {\n clientId: string;\n clientSecret: string;\n loginHint?: string;\n onAuthUrl?: (url: string) => void;\n setActive?: boolean;\n}\n\nexport interface ReauthOptions {\n email?: string;\n loginHint?: string;\n onAuthUrl?: (url: string) => void;\n}\n\nexport interface SheetServiceOptions {\n accountEmail?: string;\n spreadsheetName?: string;\n}\n\nexport interface DriveServiceOptions {\n accountEmail?: string;\n}\n\nexport function createSheetsService(config: GoogleSheetsConfig): GoogleSheetsService {\n return new GoogleSheetsService(config);\n}\n\nexport function createDriveService(oauthCredentials: OAuthCredentials): GoogleDriveService {\n return new GoogleDriveService(oauthCredentials);\n}\n\nexport class SheetCmdClient {\n private configManager: ConfigManager;\n\n constructor(options: SheetCmdClientOptions = {}) {\n this.configManager = options.configManager ?? new ConfigManager();\n }\n\n async login(options: LoginOptions): Promise<Account> {\n const result = await performOAuthFlow(options.clientId, options.clientSecret, {\n loginHint: options.loginHint,\n onAuthUrl: options.onAuthUrl\n });\n\n await this.configManager.addAccount(result.email, result.credentials);\n\n if (options.setActive ?? this.configManager.getAllAccounts().length === 1) {\n this.configManager.setActiveAccount(result.email);\n }\n\n const account = this.configManager.getAccount(result.email);\n if (!account) {\n throw new Error(`Account '${result.email}' not found after login`);\n }\n\n return account;\n }\n\n async reauth(options: ReauthOptions = {}): Promise<Account> {\n const account = options.email\n ? this.configManager.getAccount(options.email)\n : this.configManager.getActiveAccount();\n if (!account) {\n throw new Error(options.email ? `Account '${options.email}' not found` : 'No active account set');\n }\n\n const result = await performOAuthFlow(account.oauth.client_id, account.oauth.client_secret, {\n loginHint: options.loginHint ?? account.email,\n onAuthUrl: options.onAuthUrl\n });\n\n await this.configManager.updateAccountCredentials(account.email, result.credentials);\n\n const updatedAccount = this.configManager.getAccount(account.email);\n if (!updatedAccount) {\n throw new Error(`Account '${account.email}' not found after reauth`);\n }\n\n return updatedAccount;\n }\n\n listAccounts(): Account[] {\n return this.configManager.getAllAccounts();\n }\n\n getAccount(email: string): Account | null {\n return this.configManager.getAccount(email);\n }\n\n getActiveAccount(): Account | null {\n return this.configManager.getActiveAccount();\n }\n\n selectAccount(email: string): void {\n this.configManager.setActiveAccount(email);\n }\n\n async removeAccount(email: string): Promise<void> {\n await this.configManager.removeAccount(email);\n }\n\n async addSpreadsheet(email: string, name: string, spreadsheetId: string): Promise<void> {\n await this.configManager.addSpreadsheet(email, name, spreadsheetId);\n }\n\n async removeSpreadsheet(email: string, name: string): Promise<void> {\n await this.configManager.removeSpreadsheet(email, name);\n }\n\n listSpreadsheets(email = this.requireActiveAccount().email): Array<{\n name: string;\n spreadsheetId: string;\n activeSheet?: string;\n }> {\n return this.configManager.listSpreadsheets(email);\n }\n\n getSpreadsheet(email: string, name: string): SpreadsheetConfig | null {\n return this.configManager.getSpreadsheet(email, name);\n }\n\n selectSpreadsheet(email: string, name: string): void {\n this.configManager.setActiveSpreadsheet(email, name);\n }\n\n getActiveSpreadsheet(email = this.requireActiveAccount().email): SpreadsheetConfig | null {\n return this.configManager.getActiveSpreadsheet(email);\n }\n\n getActiveSpreadsheetName(email = this.requireActiveAccount().email): string | null {\n return this.configManager.getActiveSpreadsheetName(email);\n }\n\n selectSheet(email: string, spreadsheetName: string, sheetName: string): void {\n this.configManager.setActiveSheet(email, spreadsheetName, sheetName);\n }\n\n getActiveSheetName(email = this.requireActiveAccount().email, spreadsheetName?: string): string | null {\n return this.configManager.getActiveSheetName(email, spreadsheetName ?? this.requireActiveSpreadsheetName(email));\n }\n\n async getSheetsService(options: SheetServiceOptions = {}): Promise<GoogleSheetsService> {\n const account = options.accountEmail ? this.requireAccount(options.accountEmail) : this.requireActiveAccount();\n const spreadsheetName = options.spreadsheetName ?? this.requireActiveSpreadsheetName(account.email);\n const spreadsheet = this.requireSpreadsheet(account.email, spreadsheetName);\n const oauthCredentials = await this.configManager.getRefreshedCredentials(account.email);\n\n return createSheetsService({\n spreadsheetId: spreadsheet.spreadsheet_id,\n oauthCredentials\n });\n }\n\n async getDriveService(options: DriveServiceOptions = {}): Promise<GoogleDriveService> {\n const account = options.accountEmail ? this.requireAccount(options.accountEmail) : this.requireActiveAccount();\n const oauthCredentials = await this.configManager.getRefreshedCredentials(account.email);\n return createDriveService(oauthCredentials);\n }\n\n async refreshAccountCredentials(email: string): Promise<OAuthCredentials> {\n const account = this.requireAccount(email);\n const credentials = await refreshToken(account.oauth);\n await this.configManager.updateAccountCredentials(email, credentials);\n return credentials;\n }\n\n private requireActiveAccount(): Account {\n const account = this.configManager.getActiveAccount();\n if (!account) {\n throw new Error('No active account set');\n }\n return account;\n }\n\n private requireAccount(email: string): Account {\n const account = this.configManager.getAccount(email);\n if (!account) {\n throw new Error(`Account '${email}' not found`);\n }\n return account;\n }\n\n private requireActiveSpreadsheetName(email: string): string {\n const spreadsheetName = this.configManager.getActiveSpreadsheetName(email);\n if (!spreadsheetName) {\n throw new Error(`No active spreadsheet set for account '${email}'`);\n }\n return spreadsheetName;\n }\n\n private requireSpreadsheet(email: string, name: string): SpreadsheetConfig {\n const spreadsheet = this.configManager.getSpreadsheet(email, name);\n if (!spreadsheet) {\n throw new Error(`Spreadsheet '${name}' not found for account '${email}'`);\n }\n return spreadsheet;\n }\n}\n","export function parseCSV(content: string): string[][] {\n const lines = content.split('\\n').filter((line) => line.trim() !== '');\n const result: string[][] = [];\n\n for (const line of lines) {\n const row: string[] = [];\n let current = '';\n let inQuotes = false;\n\n for (let i = 0; i < line.length; i++) {\n const char = line[i];\n\n if (char === '\"') {\n if (inQuotes && line[i + 1] === '\"') {\n current += '\"';\n i++;\n } else {\n inQuotes = !inQuotes;\n }\n } else if (char === ',' && !inQuotes) {\n row.push(current.trim());\n current = '';\n } else {\n current += char;\n }\n }\n\n row.push(current.trim());\n result.push(row);\n }\n\n return result;\n}\n","export function formatAsMarkdown(data: string[][]): string {\n if (data.length === 0) return '';\n\n const [headers, ...rows] = data;\n const colWidths = headers.map((_, colIndex) => Math.max(...data.map((row) => (row[colIndex] || '').length)));\n\n const separator = `| ${colWidths.map((w) => '-'.repeat(w)).join(' | ')} |`;\n const formatRow = (row: string[]) => `| ${row.map((cell, i) => (cell || '').padEnd(colWidths[i])).join(' | ')} |`;\n\n return [formatRow(headers), separator, ...rows.map(formatRow)].join('\\n');\n}\n\nexport function formatAsCSV(data: string[][]): string {\n return data\n .map((row) =>\n row\n .map((cell) => {\n const value = cell || '';\n if (value.includes(',') || value.includes('\"') || value.includes('\\n')) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n })\n .join(',')\n )\n .join('\\n');\n}\n\nexport function formatAsJSON(data: string[][]): string {\n if (data.length === 0) return '[]';\n\n const [headers, ...rows] = data;\n\n const jsonData = rows.map((row) => {\n const obj: Record<string, string> = {};\n headers.forEach((header, index) => {\n obj[header] = row[index] || '';\n });\n return obj;\n });\n\n return JSON.stringify(jsonData, null, 2);\n}\n"],"mappings":"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","names":["platform","release","OAuth2Client","OAuth2Client","fs","OAuth2Client","OAuth2Client","OAuth2Client"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gsheet-lvt",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A CLI tool to interact with Google Sheets - perfect for LLM integrations",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"gs": "./dist/cli.js",
|
|
16
|
+
"gsheet": "./dist/cli.js"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"google-sheets",
|
|
23
|
+
"llm",
|
|
24
|
+
"tool",
|
|
25
|
+
"cli"
|
|
26
|
+
],
|
|
27
|
+
"author": "Lucas Vieira",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"homepage": "https://github.com/lucasvtiradentes/sheet-cmd#readme",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/lucasvtiradentes/sheet-cmd.git"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/lucasvtiradentes/sheet-cmd/issues"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@caporal/core": "^2.0.7",
|
|
39
|
+
"chalk": "^5.4.1",
|
|
40
|
+
"google-auth-library": "^9.14.2",
|
|
41
|
+
"google-spreadsheet": "^4.1.4",
|
|
42
|
+
"googleapis": "^164.1.0",
|
|
43
|
+
"inquirer": "^12.7.0",
|
|
44
|
+
"zod": "^4.0.5"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@biomejs/biome": "^2.1.2",
|
|
48
|
+
"@changesets/cli": "^2.29.7",
|
|
49
|
+
"@types/node": "^22.18.8",
|
|
50
|
+
"dotenv": "^17.2.3",
|
|
51
|
+
"husky": "^9.1.7",
|
|
52
|
+
"knip": "^6.4.1",
|
|
53
|
+
"lint-staged": "^15.4.3",
|
|
54
|
+
"tsup": "^8.5.1",
|
|
55
|
+
"tsx": "^4.19.2",
|
|
56
|
+
"typescript": "^5.7.3",
|
|
57
|
+
"vitest": "^3.2.4"
|
|
58
|
+
},
|
|
59
|
+
"scripts": {
|
|
60
|
+
"check": "biome check src/ scripts/ tests/",
|
|
61
|
+
"check:fix": "biome check --fix src/ scripts/ tests/",
|
|
62
|
+
"dev": "SHEET_CMD_PROG_NAME=gsheet tsx src/cli.ts",
|
|
63
|
+
"dev:install": "tsx scripts/install-dev-version.ts",
|
|
64
|
+
"dev:uninstall": "tsx scripts/uninstall-dev-version.ts",
|
|
65
|
+
"typecheck": "tsc --noEmit",
|
|
66
|
+
"build": "tsup",
|
|
67
|
+
"postbuild": "pnpm gen:docs",
|
|
68
|
+
"gen:docs": "tsx scripts/gen-docs.ts",
|
|
69
|
+
"start": "SHEET_CMD_PROG_NAME=gsheet node dist/cli.js",
|
|
70
|
+
"test:e2e": "vitest run --config tests/configs/e2e.vitest.config.ts",
|
|
71
|
+
"format": "biome format --write .",
|
|
72
|
+
"knip": "knip",
|
|
73
|
+
"lint": "biome check --write .",
|
|
74
|
+
"lint-staged": "lint-staged",
|
|
75
|
+
"changeset": "changeset",
|
|
76
|
+
"release": "pnpm run build && changeset publish"
|
|
77
|
+
}
|
|
78
|
+
}
|