Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/cli #572

Open
wants to merge 25 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6d00746
Initial Setup
JayaKrishnaNamburu May 14, 2021
2e214f2
refactor(cli): setup cli for development
JayaKrishnaNamburu May 14, 2021
78e2e5e
Adding missing @types for packages
JayaKrishnaNamburu May 14, 2021
ccd1edd
fix(mapper): disable watcher for cli and improve cli worklflow
JayaKrishnaNamburu May 15, 2021
bf64ae4
DIsabling validator in project temporarly
JayaKrishnaNamburu May 15, 2021
4446724
refactor(mapper): improving project validator error messages and bug …
JayaKrishnaNamburu May 16, 2021
1c44ccc
(feat): Parsing abilitites to generate links
JayaKrishnaNamburu May 16, 2021
f979ae8
refactor(cli): by default fallback to project generation
JayaKrishnaNamburu May 21, 2021
4f24a34
Refacotring code generator
JayaKrishnaNamburu May 21, 2021
130e4a2
Merge branch 'development' into feat/cli-beta
JayaKrishnaNamburu May 21, 2021
0a52ce9
refactor(proj-plugin): improvements in handling project plugins
JayaKrishnaNamburu May 21, 2021
b48bfa5
name bug fixes for generated projects
JayaKrishnaNamburu May 22, 2021
fc31206
Merge branch 'development' into feat/cli-beta
JayaKrishnaNamburu May 24, 2021
6c176e7
Merging development and changes for build for cli and mapper
JayaKrishnaNamburu May 26, 2021
7f17a43
Merge branch 'development' into feat/cli-beta
JayaKrishnaNamburu Jun 8, 2021
16e0c09
Merge branch 'development' into feat/cli-beta
JayaKrishnaNamburu Feb 5, 2022
e1a82af
Bringing cli to working state
JayaKrishnaNamburu Feb 6, 2022
a15ef4f
Extracting few packages and access to editorcc env too
JayaKrishnaNamburu Feb 8, 2022
4717bdd
Fixing lint errors
JayaKrishnaNamburu Feb 9, 2022
24b0d95
Plugin workflow setup for using teleport-cli
JayaKrishnaNamburu Feb 11, 2022
d543dab
Merge branch 'development' into feat/cli-beta
JayaKrishnaNamburu Apr 14, 2022
0f6bcf9
Merge branch 'development' into feat/cli-beta
JayaKrishnaNamburu Jul 28, 2022
3a3efa4
Update lock file
JayaKrishnaNamburu Jul 28, 2022
080e5b4
Update correction for component detection andd upgraded to generators
JayaKrishnaNamburu Jul 28, 2022
859f7e6
Merge branch 'development' into feat/cli-beta
JayaKrishnaNamburu Jul 28, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
"@types/jszip": "^3.1.7",
"@types/prettier": "^2.1.6",
"@types/rimraf": "^2.0.3",
"@types/diff": "^5.0.0",
"@types/fs-extra": "^9.0.11",
"@types/minimist": "^1.2.1",
"@types/node-fetch": "^2.5.10",
"all-contributors-cli": "^6.13.0",
"chalk": "^2.4.2",
"chokidar": "^3.0.2",
Expand Down
63 changes: 63 additions & 0 deletions packages/teleport-cli/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
## @teleporthq/teleport-cli

### Clone a Project

```shell
teleport clone --link <link-to-project> --path <sys-path>

teleport clone -l https://repl.teleporthq.io/project/2c5878e9-1bbc-4f7c-a27a-b8822dd39571

teleport clone --link https://teleport-gui-git-development-teleport-team.vercel.app/projects/new-project-zan7
```

### Clone a Component

```shell
teleport clone --link <link-to-component> --path <sys-path>

teleport clone --link https://repl.teleporthq.io/\?uidlLink\=35c82f1c-d272-4f8b-8a3f-5fa44702a1e6\&flavor\=React\&style\=CSS-Modules
JayaKrishnaNamburu marked this conversation as resolved.
Show resolved Hide resolved

teleport clone --link https://teleport-gui-git-development-teleport-team.vercel.app/projects/new-project-zan7/editor/5c3c97d9-98e9-4649-b654-b9103a99c200 --path /components
```

### Format
After cloning and resolving merge conflicts. If we want to format, please run

```shell
teleport format --path <sys-path>

teleport format -p /components

teleport format
```

### Sync

Using `teleport.config.json` and sync's the project and component's used.

```shell
teleport sync
```

We can use `--force` to `overwrite` local files with remote changes.

```shell
teleport sync --force
```

### Init

Creates a `teleport.config.json` in a existing project

```shell
teleport init
```

### Dev Workflow

- Install `dependencies` using `yarn` in the root folder. Under `teleport-code-generator`.
- Run `yarn build` to build the project.
- Run `yarn link` to create a `sym-link`.
- Now go to the required folder and run `yarn link "@teleporthq/teleport-cli"`where we want to use the command line.
- To run the `cli` in watch mode, please run `yarn dev`. This will re-complie the `.ts` files every-time we make changes.

46 changes: 46 additions & 0 deletions packages/teleport-cli/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "@teleporthq/teleport-cli",
"version": "0.16.3",
"description": "A command line utility to sync work from studio and other sources to local.",
"author": "teleportHQ",
"license": "MIT",
"homepage": "https://teleporthq.io/",
"types": "dist/src/index.d.ts",
"sideEffects": false,
"main": "dist/src/index.js",
"bin": {
"teleport": "dist/src/index.js"
},
"repository": {
"type": "git",
"url": "git+ssh://[email protected]/teleporthq/teleport-code-generators.git"
},
"bugs": {
"url": "https://github.com/teleporthq/teleport-code-generators/issues"
},
"publishConfig": {
"access": "public"
},
"scripts": {
"clean": "rimraf dist",
"dev": "tsc -p tsconfig-cjs.json --watch",
"build": "tsc -p tsconfig-cjs.json"
},
"dependencies": {
"@teleporthq/teleport-code-generator": "^0.16.3",
"@teleporthq/teleport-postprocessor-prettier-html": "^0.16.3",
"@teleporthq/teleport-postprocessor-prettier-jsx": "^0.16.3",
"@teleporthq/teleport-postprocessor-prettier-ts": "^0.16.3",
"@teleporthq/teleport-postprocessor-vue-file": "^0.16.3",
"@teleporthq/teleport-types": "^0.16.3",
"@teleporthq/teleport-mapper": "^0.16.3",
"chalk": "^4.1.1",
"commander": "^7.2.0",
"diff": "^5.0.0",
"fs-extra": "^9.1.0",
"minimist": "^1.2.5",
"node-fetch": "^2.6.1",
"ora": "^5.4.0"
}
}

126 changes: 126 additions & 0 deletions packages/teleport-cli/src/commands/clone.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { ProjectType, VComponentUIDL, VProjectUIDL } from '@teleporthq/teleport-types'
import {
fetchSnapshotFromPlayground,
fetchUIDLFromREPL,
generateComponentFromUIDL,
generateProjectFromUIDL,
} from '../services'
import { injectFilesToPath } from '../services/file'
import { getComponentType, updateConfigFile } from '../utils'
import { MapSnapshotToUIDL } from '@teleporthq/teleport-mapper'
import ora from 'ora'

/* Basic projects seems to generate
- Fonts & Assets
- Default Element Styles (Buttons)
*/

export default async function (options: { url: string; targetPath: string; force?: boolean }) {
const { url, targetPath, force = false } = options
let uidl: VComponentUIDL | VProjectUIDL
const spinner = ora()
spinner.start()
// Assuming it is coming from playground
if (url.includes('teleport') && !url.includes('repl.teleporthq.io')) {
const opts = url.split('/')
if (opts.length === 5) {
try {
spinner.text = `Fetching from studio ${opts[4]} \n`

const {
snapshot: { data },
} = await fetchSnapshotFromPlayground(opts[4])
const mapper = new MapSnapshotToUIDL(data)
uidl = mapper.toProjectUIDL()

if (!uidl) {
throw new Error('Failed in Generating Project')
}

await generateProjectFromUIDL({
uidl,
projectType: ProjectType.NEXT,
targetPath,
url,
force,
})

spinner.text = `Project Generated Successfully`
spinner.succeed()
} catch (e) {
spinner.text = `Project Generation Failed`
spinner.fail()
}
}

if (opts.length >= 7) {
try {
spinner.text = `Fetching from studio ${opts[4]} \n`

const {
snapshot: { data },
} = await fetchSnapshotFromPlayground(opts[4])
const mapper = new MapSnapshotToUIDL(data)
uidl = mapper.componentToUIDL(opts[6])

if (!uidl) {
throw new Error('Failed in Generating Project')
}

const { files } = await generateComponentFromUIDL(uidl, getComponentType())
injectFilesToPath(process.cwd(), targetPath, files, force)
updateConfigFile((content) => {
content.components[url] = { url, path: targetPath }
})

spinner.text = `Component ${files[0].name}.${files[0].fileType} generated`
spinner.succeed()
} catch (e) {
spinner.text = 'Failed in generating project'
spinner.fail()
}
}
}

if (url.includes('repl.teleporthq.io')) {
/* Generating projects */
if (url.includes('project')) {
try {
spinner.text = `Fetching project from repl \n`

uidl = (await fetchUIDLFromREPL(url)) as VProjectUIDL
await generateProjectFromUIDL({
uidl,
projectType: ProjectType.NEXT,
targetPath,
url,
force,
})

spinner.text = `Project Generated Successfully`
spinner.succeed()
} catch (e) {
spinner.text = `Project Generation Failed`
spinner.fail()
}
} else {
try {
spinner.text = `Fetching component from repl \n`

uidl = (await fetchUIDLFromREPL(url)) as VComponentUIDL
const { files } = await generateComponentFromUIDL(uidl, getComponentType())
injectFilesToPath(process.cwd(), targetPath, files, force)
updateConfigFile((content) => {
content.components[url] = { url, path: targetPath }
})

spinner.text = `Component ${files[0].name}.${files[0].fileType} generated`
spinner.succeed()
} catch (e) {
spinner.text = `Component Generation Failed`
spinner.fail()
}
}
}
spinner.stop()
}
65 changes: 65 additions & 0 deletions packages/teleport-cli/src/commands/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import ora from 'ora'
import path from 'path'
import { readdirSync, writeFileSync, readFileSync, lstatSync } from 'fs-extra'
import { FileType, PostProcessor } from '@teleporthq/teleport-types'
import processorVUE from '@teleporthq/teleport-postprocessor-vue-file'
import processorTS from '@teleporthq/teleport-postprocessor-prettier-ts'
import processorJSX from '@teleporthq/teleport-postprocessor-prettier-jsx'
import processorHTML from '@teleporthq/teleport-postprocessor-prettier-html'
import { IGNORE_EXTENSIONS, IGNORE_FOLDERS } from '../constants'

/* Fromat is currently broken, please check */
const processors: Record<string, PostProcessor> = {
[FileType.JS]: processorJSX,
[FileType.HTML]: processorHTML,
[FileType.VUE]: processorVUE,
[FileType.TS]: processorTS,
}
/* We can extend the prettier config, ignore folders, ignore extensions */
const format = async ({ targetPath }: { targetPath: string }) => {
formatFilesFromFolder(targetPath)
}

const formatFilesFromFolder = (folderPath: string) => {
try {
const files: string[] = readdirSync(path.join(process.cwd(), folderPath))
if (files.length === 0) {
return
}

files.forEach((fileName) => {
if (
IGNORE_FOLDERS.includes(fileName) ||
IGNORE_EXTENSIONS.some((ext) => fileName.endsWith(ext)) ||
fileName.startsWith('.')
) {
return
}

const fileStatus = ora(fileName)
try {
const filePath = path.join(process.cwd(), folderPath, fileName)
const isDirectory = lstatSync(filePath).isDirectory()
if (!isDirectory) {
const file = readFileSync(filePath)
const fileExtension = path.extname(filePath)?.substring(1)
const processor = processors[fileExtension]
if (processor) {
const formattedCode = processor({ [fileExtension]: file.toString('utf-8') })
writeFileSync(filePath, formattedCode[fileExtension])
fileStatus.succeed()
}
return
}
formatFilesFromFolder(path.join(folderPath, fileName))
} catch (e) {
fileStatus.text = `Failed in formatting file ${fileName}`
fileStatus.fail()
}
})
} catch (e) {
console.warn(e)
}
}

export default format
17 changes: 17 additions & 0 deletions packages/teleport-cli/src/commands/init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import chalk from 'chalk'
import { writeFileSync } from 'fs-extra'
import path from 'path'
import { DEFAULT_CONFIG_FILE_NAME, DEFALT_CONFIG_TEMPLATE } from '../constants'
import { findFileByName } from '../services/file'

export default function () {
const isFileExists = findFileByName(DEFAULT_CONFIG_FILE_NAME)
if (!isFileExists) {
writeFileSync(
path.join(process.cwd(), DEFAULT_CONFIG_FILE_NAME),
JSON.stringify(DEFALT_CONFIG_TEMPLATE, null, 2)
)
return
}
console.warn(chalk.yellow(`${DEFAULT_CONFIG_FILE_NAME} already exists`))
}
23 changes: 23 additions & 0 deletions packages/teleport-cli/src/commands/sync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import chalk from 'chalk'
import { DefaultConfigTemplate, DEFAULT_CONFIG_FILE_NAME } from '../constants'
import { findFileByName } from '../services/file'
import clone from './clone'

/* By default sync only components specified ? */
export default async function sync({ force }: { force: boolean }) {
const config = findFileByName(DEFAULT_CONFIG_FILE_NAME)
if (!config) {
console.warn(chalk.yellow(`${DEFAULT_CONFIG_FILE_NAME} is missing from project.`))
}

const { components = {}, project } = JSON.parse(config) as DefaultConfigTemplate

if (project?.url) {
clone({ url: project.url, targetPath: '../', force })
}

Object.values(components).forEach((comp) => {
const { url, path: targetPath } = comp
clone({ url, targetPath, force })
})
}
21 changes: 21 additions & 0 deletions packages/teleport-cli/src/commands/watch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import ora from 'ora'
import { findFileByName } from '../services/file'
import { DEFAULT_CONFIG_FILE_NAME } from '../constants'
import { extractCompIdsFromURls } from '../utils'

/* Watch takes a set of components defined and tried to observe for changes.
And loads then on request */

export default async function () {
const content = JSON.parse(findFileByName(DEFAULT_CONFIG_FILE_NAME))
const { components = [] } = content || {}
if (components.length === 0) {
return
}
const compIds = extractCompIdsFromURls(components)
const spinner = ora(`Watching components \n ${JSON.stringify(compIds)}`)
spinner.start()
setTimeout(() => {
spinner.stop()
}, 1000)
}
Loading