Commit e0c5854f authored by Caner Candan's avatar Caner Candan

feat(assembler): add assembler pretty printer init function to project-builder

parent 30ef9627
Pipeline #19920796 skipped with stages
......@@ -121,7 +121,8 @@
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/.jest/fileTransform.js"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\](?!\\@4geit[/\\\\]).+\\.(js|jsx)$"
"[/\\\\]node_modules[/\\\\](?!\\@4geit[/\\\\]).+\\.(js|jsx)$",
"[/\\\\]utils[/\\\\].+[/\\\\]lib[/\\\\]template"
]
}
}
......@@ -48,32 +48,121 @@ import GridItemComponentRaw from '!raw-loader!./grid-item.component'
const debug = buildDebug('react-packages:packages:rct-assembler-component:components')
const components = {
RctDummyComponent: { component: RctDummyComponent, meta: parse(RctDummyComponentRaw) },
DivComponent: { component: DivComponent, meta: parse(DivComponentRaw) },
IconComponent: { component: IconComponent, meta: parse(IconComponentRaw) },
Grid: { component: Grid, meta: parse(GridRaw) },
RctDummyComponent: {
component: RctDummyComponent,
meta: parse(RctDummyComponentRaw),
imports: [{ default: 'RctDummyComponent', from: '@4geit/rct-dummy-component' }],
},
DivComponent: {
component: DivComponent,
meta: parse(DivComponentRaw),
imports: [{ named: ['DivComponent'], from: '@4geit/rct-assembler-component' }],
},
IconComponent: {
component: IconComponent,
meta: parse(IconComponentRaw),
imports: [{ named: ['IconComponent'], from: '@4geit/rct-assembler-component' }],
},
Grid: {
component: Grid,
meta: parse(GridRaw),
imports: [{ default: 'Grid', from: 'material-ui/Grid' }],
},
GridContainerComponent: {
component: GridContainerComponent,
meta: parse(GridContainerComponentRaw),
imports: [{ named: ['GridContainerComponent'], from: '@4geit/rct-assembler-component' }],
},
GridItemComponent: {
component: GridItemComponent,
meta: parse(GridItemComponentRaw),
imports: [{ named: ['GridItemComponent'], from: '@4geit/rct-assembler-component' }],
},
AppBar: {
component: AppBar,
meta: parse(AppBarRaw),
imports: [{ default: 'AppBar', from: 'material-ui/AppBar' }],
},
ToolBar: {
component: Toolbar,
meta: parse(ToolbarRaw),
imports: [{ default: 'Toolbar', from: 'material-ui/Toolbar' }],
},
Typography: {
component: Typography,
meta: parse(TypographyRaw),
imports: [{ default: 'Typography', from: 'material-ui/Typography' }],
},
Button: {
component: Button,
meta: parse(ButtonRaw),
imports: [{ default: 'Button', from: 'material-ui/Button' }],
},
Card: {
component: Card,
meta: parse(CardRaw),
imports: [{ default: 'Card', from: 'material-ui/Card' }],
},
CardHeader: {
component: CardHeader,
meta: parse(CardHeaderRaw),
imports: [{ named: ['CardHeader'], from: 'material-ui/Card' }],
},
CardActions: {
component: CardActions,
meta: parse(CardActionsRaw),
imports: [{ named: ['CardActions'], from: 'material-ui/Card' }],
},
CardContent: {
component: CardContent,
meta: parse(CardContentRaw),
imports: [{ named: ['CardContent'], from: 'material-ui/Card' }],
},
Divider: {
component: Divider,
meta: parse(DividerRaw),
imports: [{ default: 'Divider', from: 'material-ui/Divider' }],
},
List: {
component: List,
meta: parse(ListRaw),
imports: [{ default: 'List', from: 'material-ui/List' }],
},
ListItem: {
component: ListItem,
meta: parse(ListItemRaw),
imports: [{ named: ['ListItem'], from: 'material-ui/List' }],
},
ListItemText: {
component: ListItemText,
meta: parse(ListItemTextRaw),
imports: [{ named: ['ListItemText'], from: 'material-ui/List' }],
},
Paper: {
component: Paper,
meta: parse(PaperRaw),
imports: [{ default: 'Paper', from: 'material-ui/Paper' }],
},
CircularProgress: {
component: CircularProgress,
meta: parse(CircularProgressRaw),
imports: [{ named: ['CircularProgress'], from: 'material-ui/Progress' }],
},
LinearProgress: {
component: LinearProgress,
meta: parse(LinearProgressRaw),
imports: [{ named: ['LinearProgress'], from: 'material-ui/Progress' }],
},
Checkbox: {
component: Checkbox,
meta: parse(CheckboxRaw),
imports: [{ default: 'Checkbox', from: 'material-ui/Checkbox' }],
},
TextField: {
component: TextField,
meta: parse(TextFieldRaw),
imports: [{ default: 'TextField', from: 'material-ui/TextField' }],
},
GridItemComponent: { component: GridItemComponent, meta: parse(GridItemComponentRaw) },
AppBar: { component: AppBar, meta: parse(AppBarRaw) },
ToolBar: { component: Toolbar, meta: parse(ToolbarRaw) },
Typography: { component: Typography, meta: parse(TypographyRaw) },
Button: { component: Button, meta: parse(ButtonRaw) },
Card: { component: Card, meta: parse(CardRaw) },
CardHeader: { component: CardHeader, meta: parse(CardHeaderRaw) },
CardActions: { component: CardActions, meta: parse(CardActionsRaw) },
CardContent: { component: CardContent, meta: parse(CardContentRaw) },
Divider: { component: Divider, meta: parse(DividerRaw) },
List: { component: List, meta: parse(ListRaw) },
ListItem: { component: ListItem, meta: parse(ListItemRaw) },
ListItemText: { component: ListItemText, meta: parse(ListItemTextRaw) },
Paper: { component: Paper, meta: parse(PaperRaw) },
CircularProgress: { component: CircularProgress, meta: parse(CircularProgressRaw) },
LinearProgress: { component: LinearProgress, meta: parse(LinearProgressRaw) },
Checkbox: { component: Checkbox, meta: parse(CheckboxRaw) },
TextField: { component: TextField, meta: parse(TextFieldRaw) },
}
const sortedComponents = Object
......
......@@ -27,10 +27,11 @@ export const mutation = AssemblerGql`
`
export const config = {
props: ({ ownProps: { sessionId, session: { focusedOccurrence } }, mutate }) => ({
createOccurrence: async ({ component, componentProps }) => {
createOccurrence: async ({ component, componentProps, imports }) => {
debug('mutation:createOccurrence()')
debug(component)
debug(componentProps)
debug(imports)
// check if any occurrence focused and if so pass it to the mutation
const variablesFields = {}
const optimisticFields = {
......@@ -83,7 +84,9 @@ export const config = {
}
debug(variablesFields)
await mutate({
variables: { sessionId, component, ...variablesFields },
variables: {
sessionId, component, imports, ...variablesFields,
},
optimisticResponse: {
__typename: 'Mutation',
createOccurrence: {
......
......@@ -122,14 +122,17 @@ export default class RctAssemblerComponent extends Component {
}
}
handleOnAddComponentToCanvasClick = ({ type, component, meta }) => async () => {
handleOnAddComponentToCanvasClick = ({
type, component, meta, imports,
}) => async () => {
debug('handleAddComponentToCanvas()')
debug(type)
debug(component)
debug(meta)
debug(imports)
const { createOccurrence } = this.props
const { props } = meta
await createOccurrence({ component: type, componentProps: props })
await createOccurrence({ component: type, componentProps: props, imports })
}
render() {
......
......@@ -18,6 +18,7 @@ async function start() {
.option('-a, --authorName <author_name>', 'the name of the author stored in the `package.json` generated when creating a new project', '')
.option('-e, --authorEmail <author_email>', 'the name of the author stored in the `package.json` generated when creating a new project', '')
.option('-R, --dry-run', 'dry run mode')
.option('-i, --assemblerId', 'the ID of the assembler session', '')
.version(version)
.parse(process.argv)
......@@ -27,17 +28,19 @@ async function start() {
description: pDescription,
authorName: pAuthorName,
authorEmail: pAuthorEmail,
assemblerId: pAssemblerId,
dryRun,
} = program
const {
iGroup, iName, iDescription, iAuthorName, iAuthorEmail,
iGroup, iName, iDescription, iAuthorName, iAuthorEmail, iAssemblerId,
} = await inquirer.prompt([
{ name: 'iGroup', message: 'Project group?', when: () => !pGroup },
{ name: 'iName', message: 'Project name?', when: () => !pName },
{ name: 'iDescription', message: 'Project description?', when: () => !pDescription },
{ name: 'iAuthorName', message: 'Author name?', when: () => !pAuthorName && !process.env.AUTHOR_NAME },
{ name: 'iAuthorEmail', message: 'Author email?', when: () => !pAuthorEmail && !process.env.AUTHOR_EMAIL },
{ name: 'iAssemblerId', message: 'Assembler ID?', when: () => !pAssemblerId },
])
const group = iGroup || pGroup
......@@ -45,9 +48,10 @@ async function start() {
const description = iDescription || pDescription
const authorName = iAuthorName || pAuthorName || process.env.AUTHOR_NAME
const authorEmail = iAuthorEmail || pAuthorEmail || process.env.AUTHOR_EMAIL
const assemblerId = iAssemblerId || pAssemblerId
await lib({
group, name, description, authorName, authorEmail, dryRun,
group, name, description, authorName, authorEmail, assemblerId, dryRun,
})
}
......
const debug = require('debug')('react-packages:utils:rct-project-builder:lib:assembler')
const { GraphQLClient } = require('graphql-request')
const Mustache = require('mustache')
const fs = require('fs')
const util = require('util')
const { SessionQuery } = require('./graphql')
const readFile = util.promisify(fs.readFile)
const writeFile = util.promisify(fs.writeFile)
async function getSession({ client, sessionId }) {
debug('getSession()')
const data = await client.request(SessionQuery, { sessionId })
debug(data)
return data
}
async function prettyPrinter({ apiEndpoint, sessionId }) {
debug('prettyPrinter()')
const client = new GraphQLClient(apiEndpoint)
const { session: { occurrences } } = await getSession({ client, sessionId })
debug(occurrences)
return {}
}
module.exports = {
SessionQuery,
getSession,
prettyPrinter,
}
const OccurrenceFieldsFragment = require('./occurrence-fields.fragment')
const OccurrenceRecursiveFragment = require('./occurrence-recursive.fragment')
const PropFieldsFragment = require('./prop-fields.fragment')
const SessionFieldsFragment = require('./session-fields.fragment')
module.exports = {
OccurrenceFieldsFragment,
OccurrenceRecursiveFragment,
PropFieldsFragment,
SessionFieldsFragment,
}
const AssemblerGql = require('graphql-tag')
const PropFieldsFragment = require('./prop-fields.fragment')
module.exports = AssemblerGql`
fragment OccurrenceFieldsFragment on Occurrence {
id
__typename
component
parent {
id
__typename
}
props {
...PropFieldsFragment
}
}
${PropFieldsFragment}
`
const AssemblerGql = require('graphql-tag')
const OccurrenceFieldsFragment = require('./occurrence-fields.fragment')
const PropFieldsFragment = require('./prop-fields.fragment')
module.exports = AssemblerGql`
fragment OccurrenceRecursiveFragment on Occurrence {
...OccurrenceFieldsFragment
props {
...PropFieldsFragment
children {
...OccurrenceFieldsFragment
props {
...PropFieldsFragment
children {
...OccurrenceFieldsFragment
props {
...PropFieldsFragment
children {
...OccurrenceFieldsFragment
props {
...PropFieldsFragment
children {
...OccurrenceFieldsFragment
}
}
}
}
}
}
}
}
}
${OccurrenceFieldsFragment}
${PropFieldsFragment}
`
const AssemblerGql = require('graphql-tag')
module.exports = AssemblerGql`
fragment PropFieldsFragment on Prop {
id
__typename
name
type
oneOf
value
children {
id
__typename
}
}`
const AssemblerGql = require('graphql-tag')
const OccurrenceRecursiveFragment = require('./occurrence-recursive.fragment')
module.exports = AssemblerGql`
fragment SessionFieldsFragment on Session {
id
occurrences {
...OccurrenceRecursiveFragment
}
}
${OccurrenceRecursiveFragment}
`
const fragments = require('./fragments')
const queries = require('./queries')
module.exports = {
...fragments,
...queries,
}
const SessionQuery = require('./session.query')
module.exports = {
SessionQuery,
}
const AssemblerGql = require('graphql-tag')
const SessionFieldsFragment = require('../fragments/session-fields.fragment')
module.exports = AssemblerGql`
query($sessionId: ID!) {
session(id: $sessionId) {
...SessionFieldsFragment
}
}
${SessionFieldsFragment}
`
......@@ -102,7 +102,7 @@ async function usage({ group, name }) {
}
module.exports = async ({
group, name, description, authorName, authorEmail, dryRun,
group, name, description, authorName, authorEmail, assemblerId, dryRun,
}) => {
try {
// debug
......@@ -111,6 +111,7 @@ module.exports = async ({
debug(`description: ${description}`)
debug(`authorName: ${authorName}`)
debug(`authorEmail: ${authorEmail}`)
debug(`assemblerId: ${assemblerId}`)
debug(`dryRun: ${dryRun}`)
// define variables
......@@ -120,6 +121,7 @@ module.exports = async ({
description,
authorName,
authorEmail,
assemblerId,
_class: _.upperFirst(_.camelCase(name)),
_function: _.camelCase(name),
}
......
/* eslint-disable no-console */
const debug = require('debug')('react-packages:utils:rct-project-builder:lib:test')
const Swagger = require('swagger-client')
const yaml = require('js-yaml')
const fs = require('fs')
const util = require('util')
const path = require('path')
const Mustache = require('mustache')
const { request, GraphQLClient } = require('graphql-request')
const { getSession, prettyPrinter } = require('./assembler')
const readFile = util.promisify(fs.readFile)
const writeFile = util.promisify(fs.writeFile)
async function buildSwaggerClient({ token }) {
const { apis: { default: { ...operations } } } = await new Swagger({
......@@ -12,7 +19,7 @@ async function buildSwaggerClient({ token }) {
return operations
}
test('build swagger client', async () => {
xtest('build swagger client', async () => {
const { getNamespaces, createProject, enableRunner } = await buildSwaggerClient({
token: process.env.GITLAB_PRIVATE_TOKEN,
})
......@@ -20,9 +27,8 @@ test('build swagger client', async () => {
expect(createProject).toBeDefined()
expect(enableRunner).toBeDefined()
})
test('create dummy project', async () => {
const { getNamespaces/*, createProject*/ } = await buildSwaggerClient({
xtest('create dummy project', async () => {
const { getNamespaces /* , createProject */ } = await buildSwaggerClient({
token: process.env.GITLAB_PRIVATE_TOKEN,
})
const { body: [{ id: groupNamespaceId }] } = await getNamespaces({ search: 'canercandan' })
......@@ -34,8 +40,92 @@ test('create dummy project', async () => {
// path: 'ccc1234',
// description: 'fake description',
// })
// console.log(obj)
// debug(obj)
// } catch (err) {
// console.error(err)
// debug(err)
// }
})
test('connect to the backend', async () => {
const query = `
query {
session(id: "cjephcodp5n5z0104v8ooxdfm") {
id
occurrences {
id
}
focusedOccurrence {
id
}
}
}`
const data = await request('http://localhost:4000', query)
debug(data)
expect(data).toEqual({
session: {
id: 'cjephcodp5n5z0104v8ooxdfm',
occurrences: [],
focusedOccurrence: null,
},
})
})
test('getSession() should return session data', async () => {
const client = new GraphQLClient('http://localhost:4000')
const data = await getSession({ client, sessionId: 'cjepcfkwr5mg301049wfi4xvl' })
expect(data).toHaveProperty('session')
expect(data).toHaveProperty('session.id')
expect(data).toHaveProperty('session.occurrences')
expect(data.session.occurrences).toHaveLength(4)
const [firstOccurrence] = data.session.occurrences
expect(firstOccurrence).toHaveProperty('id')
expect(firstOccurrence).toHaveProperty('component')
expect(firstOccurrence).toHaveProperty('props')
expect(firstOccurrence.props).toHaveLength(1)
const [firstProp] = firstOccurrence.props
expect(firstProp).toHaveProperty('id')
expect(firstProp).toHaveProperty('name')
expect(firstProp).toHaveProperty('type')
expect(firstProp).toHaveProperty('oneOf')
expect(firstProp).toHaveProperty('value')
expect(firstProp).toHaveProperty('children')
expect(firstProp.children).toHaveLength(3)
const [firstChildOccurrence] = firstProp.children
expect(firstChildOccurrence).toHaveProperty('id')
})
test('call the prettyPrinter function', async () => {
const obj = await prettyPrinter({
apiEndpoint: 'http://localhost:4000',
sessionId: 'cjepcfkwr5mg301049wfi4xvl',
})
expect(obj).toEqual({})
})
test('mustache with a loop', async () => {
const tpl = '<(#mylist)>* <(name)>\n<(/mylist)>'
Mustache.parse(tpl, ['<(', ')>'])
const output = Mustache.render(tpl, {
mylist: [
{ name: 'aaa' },
{ name: 'bbb' },
{ name: 'ccc' },
],
})
debug(output)
})
test('pretty print imports', async () => {
const client = new GraphQLClient('http://localhost:4000')
const data = await getSession({ client, sessionId: 'cjepcfkwr5mg301049wfi4xvl' })
// const tpl = `
// <(#occurrences)>
// <(#imports)>
// import <(#default)><(.)><(/default)>{ <(#named)><(.)>, <(/named)> } from '<(from)>'
// <(/imports)>
// <(/occurrences)>
// `
const tpl = `
<(#session.occurrences)>
<(imports)>
<(/session.occurrences)>
`
Mustache.parse(tpl, ['<(', ')>'])
const output = Mustache.render(tpl, data)
debug(output)
})
......@@ -5,6 +5,11 @@ import { Switch, Route, withRouter, Link } from 'react-router-dom'
// eslint-disable-next-line
import { inject, observer } from 'mobx-react'
import { Redirect } from 'react-router'
<(#occurrences)>
<(#imports)>
import <(#default)><(.)><(/default)>{ <(#named)><(.)>, <(/named)> } from '<(from)>'
<(/imports)>
<(/occurrences)>
function PrivateRoute({ component: RouteComponent, authed, ...rest }) {
if (authed) {
......