Skip to content

Commit

Permalink
feat: pull-languages cmd
Browse files Browse the repository at this point in the history
  • Loading branch information
alvarosabu committed Oct 31, 2024
1 parent 044ff92 commit ea4a3a6
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 3 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,7 @@ dist
# CLI generated files
components.*.json
presets.*.json
storyblok-component-types.d.ts
storyblok-component-types.d.ts

# storyblok folder
.storyblok/
11 changes: 11 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@
"console": "integratedTerminal",
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
},
{
"type": "node",
"request": "launch",
"name": "Debug Pull languages",
"program": "${workspaceFolder}/dist/index.mjs",
"args": ["pull-languages", "--space", "295018", "--path", ".storyblok"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
}
]
}
64 changes: 64 additions & 0 deletions src/commands/pull-languages/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { access, constants, mkdir, writeFile } from 'node:fs/promises'
import { join, resolve } from 'node:path'

import { handleAPIError, handleFileSystemError } from '../../utils'
import { ofetch } from 'ofetch'
import { regionsDomain } from '../../constants'
import { session } from '../../session'
import { apiClient } from '../../api'

export interface SpaceInternationalizationOptions {
languages: SpaceLanguage[]
default_lang_name: string
}
export interface SpaceLanguage {
code: string
name: string
}

export const pullLanguages = async (space: string): Promise<SpaceInternationalizationOptions | undefined> => {
try {
const { client } = apiClient()
if (!client) {
throw new Error('Client not initialized')
}

const { state } = session()
const response = await ofetch(`https://${regionsDomain[state.region]}/v1/spaces/${space}`, {
headers: {
Authorization: state.password,
},
})
return {
default_lang_name: response.space.default_lang_name,
languages: response.space.languages,
}
}
catch (error) {
handleAPIError('pull_languages', error as Error)
}
}

export const saveLanguagesToFile = async (space: string, internationalizationOptions: SpaceInternationalizationOptions, path?: string) => {
try {
const data = JSON.stringify(internationalizationOptions, null, 2)
const filename = `languages.${space}.json`
const resolvedPath = path ? resolve(process.cwd(), path) : process.cwd()
const filePath = join(resolvedPath, filename)

// Check if the path exists, and create it if it doesn't
try {
await access(resolvedPath, constants.F_OK)
}
catch {
await mkdir(resolvedPath, { recursive: true })
}

return await writeFile(filePath, data, {
mode: 0o600,
})
}
catch (error) {
handleFileSystemError('write', error as Error)
}
}
45 changes: 45 additions & 0 deletions src/commands/pull-languages/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { colorPalette, commands } from '../../constants'
import { CommandError, handleError, konsola } from '../../utils'
import { getProgram } from '../../program'
import { session } from '../../session'
import { pullLanguages, saveLanguagesToFile } from './actions'
import chalk from 'chalk'

const program = getProgram() // Get the shared singleton instance

export const pullLanguagesCommand = program
.command('pull-languages')
.description(`Download your space's languages schema as json`)
.option('-s, --space <space>', 'space ID')
.option('-p, --path <path>', 'path to save the file')
.action(async (options) => {
const { space, path } = options
konsola.title(` ${commands.PULL_LANGUAGES} `, colorPalette.PULL_LANGUAGES, 'Pulling languages...')

const { state, initializeSession } = session()
await initializeSession()

if (!state.isLoggedIn) {
handleError(new CommandError(`You are currently not logged in. Please login first to get your user info.`))
return
}

if (!space) {
handleError(new CommandError(`Please provide the space as argument --space YOUR_SPACE_ID.`))
return
}

try {
const internationalization = await pullLanguages(space)

if (!internationalization || !internationalization.languages) {
konsola.warn(`No languages found in the space ${space}`)
return
}
await saveLanguagesToFile(space, internationalization, path)
konsola.ok(`Languages schema downloaded successfully at ${chalk.hex(colorPalette.PRIMARY)(path ? `${path}/languages.${space}.json` : `languages.${space}.json`)}`)
}
catch (error) {
handleError(error as Error, true)
}
})
4 changes: 3 additions & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ export const commands = {
LOGIN: 'login',
LOGOUT: 'logout',
USER: 'user',
PULL_LANGUAGES: 'pull-languages',
} as const

export const colorPalette = {
PRIMARY: '#45bfb9',
LOGIN: '#8556D3',
USER: '#8BC34A', // Changed to a less saturated green color
USER: '#8BC34A',
PULL_LANGUAGES: '#FFC107',
} as const

export interface ReadonlyArray<T> {
Expand Down
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { getProgram } from './program'
import './commands/login'
import './commands/logout'
import './commands/user'
import './commands/pull-languages'

import { loginWithToken } from './commands/login/actions'

dotenv.config() // This will load variables from .env into process.env
Expand All @@ -17,7 +19,6 @@ const messageText = ` `
console.log(formatHeader(`
${introText} ${messageText}`))

program.option('-s, --space [value]', 'space ID')
program.option('-v, --verbose', 'Enable verbose output')

program.on('command:*', () => {
Expand Down

0 comments on commit ea4a3a6

Please sign in to comment.