Skip to content

Commit

Permalink
feat(pull-components): add option to resolve datasource for single/mu…
Browse files Browse the repository at this point in the history
…ltiple option field
  • Loading branch information
RKcode committed Apr 8, 2024
1 parent 71d5c4a commit 78943d7
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 6 deletions.
5 changes: 3 additions & 2 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,12 @@ program
.option("--sf, --separate-files [value]", "Argument to create a single file for each component")
.option("-p, --path <path>", "Path to save the component files")
.option("-f, --file-name <fileName>", "custom name to be used in file(s) name instead of space id")
.option("--rd, --resolve-datasources", "Fill options for single/multiple option field with the linked datasource")
.description("Download your space's components schema as json")
.action(async (options) => {
console.log(`${chalk.blue("-")} Executing pull-components task`);
const space = program.space;
const { separateFiles, path } = options;
const { separateFiles, path, resolveDatasources } = options;
if (!space) {
console.log(chalk.red("X") + " Please provide the space as argument --space YOUR_SPACE_ID.");
process.exit(0);
Expand All @@ -160,7 +161,7 @@ program
}

api.setSpaceId(space);
await tasks.pullComponents(api, { fileName, separateFiles, path });
await tasks.pullComponents(api, { fileName, separateFiles, path, resolveDatasources });
} catch (e) {
errorHandler(e, COMMANDS.PULL_COMPONENTS);
}
Expand Down
35 changes: 32 additions & 3 deletions src/tasks/pull-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,51 @@ const getNameFromComponentGroups = (groups, uuid) => {
return ''
}

const resolveDatasourceOptions = async (api, components) => {
const datasources = await api.getDatasources()

for (const datasource of datasources) {
const datasourceEntries = await api.getDatasourceEntries(datasource.id)
datasource.entries = datasourceEntries
}

return components.map(component => {
const schema = component.schema

for (const field in schema) {
if (schema[field].source === 'internal' && schema[field].datasource_slug) {
const datasource = datasources.find(ds => ds.slug === schema[field].datasource_slug)

if (datasource) {
schema[field].options = datasource.entries.map(entry => ({ value: entry.value, name: entry.name }))
}
}
}

return component
})
}

/**
* @method pullComponents
* @param {Object} api
* @param {Object} options { fileName: string, separateFiles: Boolean, path: String }
* @param {Object} options { fileName: string, separateFiles: Boolean, path: String, resolveDatasources: Boolean }
* @return {Promise<Object>}
*/
const pullComponents = async (api, options) => {
const { fileName, separateFiles, path } = options
const { fileName, separateFiles, path, resolveDatasources } = options

try {
const componentGroups = await api.getComponentGroups()

const components = await api.getComponents()
let components = await api.getComponents()

const presets = await api.getPresets()

if (resolveDatasources) {
components = await resolveDatasourceOptions(api, components)
}

components.forEach(component => {
const groupUuid = component.component_group_uuid
if (groupUuid) {
Expand Down
9 changes: 9 additions & 0 deletions src/utils/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,15 @@ export default {
.catch(err => Promise.reject(err))
},

getDatasourceEntries (id) {
const client = this.getClient()

return client
.get(this.getPath(`datasource_entries?datasource_id=${id}`))
.then(data => data.data.datasource_entries || [])
.catch(err => Promise.reject(err))
},

deleteDatasource (id) {
const client = this.getClient()

Expand Down
49 changes: 49 additions & 0 deletions tests/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,55 @@ export const FAKE_COMPONENTS = () => [
preset_id: null,
real_name: 'hero',
component_group_uuid: null
},
{
name: 'meta',
display_name: null,
created_at: '2019-11-06T17:07:04.196Z',
updated_at: '2019-11-06T18:12:29.136Z',
id: 4,
schema: {
robot: {
type: "option",
source: "internal",
datasource_slug: "robots",
}
},
image: null,
preview_field: null,
is_root: false,
preview_tmpl: null,
is_nestable: true,
all_presets: [],
preset_id: null,
real_name: 'meta',
component_group_uuid: null
},
]

export const FAKE_DATASOURCES = () => [
{
id: 1,
name: "Robots",
slug: "robots",
dimensions: [],
created_at: "2019-10-15T17:00:32.212Z",
updated_at: "2019-11-15T17:00:32.212Z",
},
]

export const FAKE_DATASOURCE_ENTRIES = () => [
{
id: 1,
name: "No index",
value: "noindex",
dimension_value: ""
},
{
id: 2,
name: "No follow",
value: "nofollow",
dimension_value: ""
}
]

Expand Down
50 changes: 49 additions & 1 deletion tests/units/pull-components.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'fs'
import pullComponents from '../../src/tasks/pull-components'
import { FAKE_PRESET, FAKE_COMPONENTS } from '../constants'
import { FAKE_PRESET, FAKE_COMPONENTS, FAKE_DATASOURCES, FAKE_DATASOURCE_ENTRIES } from '../constants'
import { jest } from '@jest/globals'

jest.spyOn(fs, 'writeFile').mockImplementation(jest.fn((key, data, _) => {
Expand Down Expand Up @@ -126,6 +126,54 @@ describe('testing pullComponents', () => {
}
})

it('pull components should be call fs.writeFile correctly and return filled options from datasource entries', async () => {
const SPACE = 12345

const api = {
getComponents () {
return Promise.resolve([FAKE_COMPONENTS()[5]])
},
getComponentGroups () {
return Promise.resolve([])
},
getDatasources () {
return Promise.resolve(FAKE_DATASOURCES())
},
getDatasourceEntries () {
return Promise.resolve(FAKE_DATASOURCE_ENTRIES())
},
getPresets () {
return Promise.resolve([])
}
}

const options = {
fileName: SPACE,
resolveDatasources: true
}

const expectFileName = `components.${SPACE}.json`

await pullComponents(api, options)
const [path, data] = fs.writeFile.mock.calls[0]

expect(fs.writeFile.mock.calls.length).toBe(1)
expect(path).toBe(`./${expectFileName}`)
expect(JSON.parse(data)).toEqual({
components: [{
...FAKE_COMPONENTS()[5],
schema: {
robot: {
type: "option",
source: "internal",
datasource_slug: "robots",
options: FAKE_DATASOURCE_ENTRIES().map(entry => ({ value: entry.value, name: entry.name }))
}
}
}]
})
})

it('api.getComponents() when a error ocurred, catch the body response', async () => {
const _api = {
getComponents (_, fn) {
Expand Down

0 comments on commit 78943d7

Please sign in to comment.