Skip to content

Commit

Permalink
feat: basic pull-component and save to json functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
alvarosabu committed Nov 5, 2024
1 parent 67c05b0 commit 3c47528
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 1 deletion.
16 changes: 15 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,21 @@
"request": "launch",
"name": "Debug Pull languages",
"program": "${workspaceFolder}/dist/index.mjs",
"args": ["pull-languages", "--space", "2950182323", "--path", ".storyblok"],
"args": ["pull-languages", "--space", "295018", "--path", ".storyblok"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"env": {
"STUB": "true"
}
},
{
"type": "node",
"request": "launch",
"name": "Debug Pull Components",
"program": "${workspaceFolder}/dist/index.mjs",
"args": ["pull-components", "--space", "295018", "--path", ".storyblok"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"sourceMaps": true,
Expand Down
80 changes: 80 additions & 0 deletions src/commands/pull-components/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { ofetch } from 'ofetch'
import { handleAPIError, handleFileSystemError } from '../../utils'
import { regionsDomain } from '../../constants'
import { access, constants, mkdir, writeFile } from 'node:fs/promises'
import { join, resolve } from 'node:path'

export interface SpaceComponent {
name: string
display_name: string
created_at: string
updated_at: string
id: number
schema: Record<string, unknown>
image?: string
preview_field?: string
is_root?: boolean
is_nestable?: boolean
preview_tmpl?: string
all_presets?: Record<string, unknown>
preset_id?: number
real_name?: string
component_group_uuid?: string
color: null
internal_tags_list: string[]
interntal_tags_ids: number[]
content_type_asset_preview?: string
}

export interface ComponentsSaveOptions {
path?: string
filename?: string
}

export const pullComponents = async (space: string, token: string, region: string): Promise<SpaceComponent[] | undefined> => {
try {
const response = await ofetch(`https://${regionsDomain[region]}/v1/spaces/${space}/components`, {
headers: {
Authorization: token,
},
})
return response.components
}
catch (error) {
handleAPIError('pull_components', error as Error)
}
}

export const saveComponentsToFiles = async (space: string, components: SpaceComponent[], options: ComponentsSaveOptions) => {
const { path, filename } = options

try {
const data = JSON.stringify(components, null, 2)
const resolvedPath = path ? resolve(process.cwd(), path) : process.cwd()
const filePath = join(resolvedPath, filename ? `${filename}.json` : `components.${space}.json`)

// Check if the path exists, and create it if it doesn't
try {
await access(resolvedPath, constants.F_OK)
}
catch {
try {
await mkdir(resolvedPath, { recursive: true })
}
catch (mkdirError) {
handleFileSystemError('mkdir', mkdirError as Error)
return // Exit early if the directory creation fails
}
}

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

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

export const pullComponentsCommand = program
.command('pull-components')
.description(`Download your space's components schema as json`)
.option('-s, --space <space>', 'space ID')
.option('-p, --path <path>', 'path to save the file')
.option('-f, --filename <filename>', 'custom name to be used in file(s) name instead of space id')
.action(async (options) => {
konsola.title(` ${commands.PULL_COMPONENTS} `, colorPalette.PULL_COMPONENTS, 'Pulling components...')
// Global options
const verbose = program.opts().verbose
// Command options
const { space, path, filename } = options

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

if (!state.isLoggedIn || !state.password || !state.region) {
handleError(new CommandError(`You are currently not logged in. Please login first to get your user info.`), verbose)
return
}
if (!space) {
handleError(new CommandError(`Please provide the space as argument --space YOUR_SPACE_ID.`), verbose)
return
}

try {
const components = await pullComponents(space, state.password, state.region)

if (!components || components.length === 0) {
konsola.warn(`No components found in the space ${space}`)
return
}
await saveComponentsToFiles(space, components, {
path,
filename,
})
konsola.ok(`Components schema downloaded successfully at ${chalk.hex(colorPalette.PRIMARY)(path ? `${path}/components.${space}.json` : `components.${space}.json`)}`)
}
catch (error) {
handleError(error as Error, verbose)
}
})
2 changes: 2 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ export const commands = {
LOGOUT: 'logout',
USER: 'user',
PULL_LANGUAGES: 'pull-languages',
PULL_COMPONENTS: 'pull-components',
} as const

export const colorPalette = {
PRIMARY: '#45bfb9',
LOGIN: '#8556D3',
USER: '#8BC34A',
PULL_LANGUAGES: '#FFC107',
PULL_COMPONENTS: '#FF5722',
} as const

export interface ReadonlyArray<T> {
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import './commands/login'
import './commands/logout'
import './commands/user'
import './commands/pull-languages'
import './commands/pull-components'

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

Expand Down
1 change: 1 addition & 0 deletions src/utils/error/api-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const API_ACTIONS = {
login_email_password: 'Failed to log in with email and password',
get_user: 'Failed to get user',
pull_languages: 'Failed to pull languages',
pull_components: 'Failed to pull components',
} as const

export const API_ERRORS = {
Expand Down

0 comments on commit 3c47528

Please sign in to comment.