Repository: teleporthq/teleport-code-generators
Pull request #405 (2019-11-10 13:40:40)

feat/publishers update

codecov[bot]: # [Codecov](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405?src=pr&el=h1) Report
> Merging [#405](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405?src=pr&el=desc) into [master](https://codecov.io/gh/teleporthq/teleport-code-generators/commit/0f8f6ad7f25855e0de85bd8a7fd21d5f1959febe?src=pr&el=desc) will **increase** coverage by `0.06%`.
> The diff coverage is `56.32%`.

[![Impacted file tree graph](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405/graphs/tree.svg?width=650&token=LI2WPEFm1R&height=150&src=pr)](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #405      +/-   ##
==========================================
+ Coverage    79.1%   79.16%   +0.06%     
==========================================
  Files         144      143       -1     
  Lines        4560     4584      +24     
  Branches      968      968              
==========================================
+ Hits         3607     3629      +22     
- Misses        901      902       +1     
- Partials       52       53       +1
```


| [Impacted Files](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [packages/teleport-project-packer/src/errors.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHJvamVjdC1wYWNrZXIvc3JjL2Vycm9ycy50cw==) | `100% <ø> (ø)` | :arrow_up: |
| [...ges/teleport-github-gateway/src/github-instance.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtZ2l0aHViLWdhdGV3YXkvc3JjL2dpdGh1Yi1pbnN0YW5jZS50cw==) | `30.48% <0%> (-1.98%)` | :arrow_down: |
| [...ges/teleport-project-generator-gatsby/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHJvamVjdC1nZW5lcmF0b3ItZ2F0c2J5L3NyYy9pbmRleC50cw==) | `100% <100%> (ø)` | :arrow_up: |
| [...es/teleport-publisher-codesandbox/src/constants.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHVibGlzaGVyLWNvZGVzYW5kYm94L3NyYy9jb25zdGFudHMudHM=) | `100% <100%> (ø)` | :arrow_up: |
| [packages/teleport-publisher-now/src/errors.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHVibGlzaGVyLW5vdy9zcmMvZXJyb3JzLnRz) | `100% <100%> (ø)` | :arrow_up: |
| [packages/teleport-publisher-github/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHVibGlzaGVyLWdpdGh1Yi9zcmMvaW5kZXgudHM=) | `94.11% <100%> (+14.87%)` | :arrow_up: |
| [packages/teleport-code-generator/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtY29kZS1nZW5lcmF0b3Ivc3JjL2luZGV4LnRz) | `96.82% <100%> (-0.24%)` | :arrow_down: |
| [packages/teleport-github-gateway/src/constants.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtZ2l0aHViLWdhdGV3YXkvc3JjL2NvbnN0YW50cy50cw==) | `100% <100%> (ø)` | :arrow_up: |
| [packages/teleport-project-packer/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHJvamVjdC1wYWNrZXIvc3JjL2luZGV4LnRz) | `91.17% <100%> (ø)` | :arrow_up: |
| [packages/teleport-publisher-zip/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHVibGlzaGVyLXppcC9zcmMvaW5kZXgudHM=) | `95.83% <100%> (ø)` | :arrow_up: |
| ... and [8 more](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405?src=pr&el=footer). Last update [0f8f6ad...bbfebde](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/405?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/packages/teleport-code-generator/src/index.ts b/packages/teleport-code-generator/src/index.ts
index b46e9aba..045e0617 100644
--- a/packages/teleport-code-generator/src/index.ts
+++ b/packages/teleport-code-generator/src/index.ts
@@ -1,9 +1,7 @@
 import {
-  PublisherResponse,
-  ProjectUIDL,
+  PackProjectFunction,
+  GenerateComponentFunction,
   ComponentUIDL,
-  PackerOptions,
-  GenerateOptions,
   PublisherType,
   ProjectType,
   ComponentType,
@@ -128,15 +126,10 @@ const projectPublisherFactories = {
   [PublisherType.CODESANDBOX]: createCodesandboxPublisher,
 }
 
-export const packProject = async (
-  projectUIDL: ProjectUIDL,
-  {
-    projectType = ProjectType.NEXT,
-    publisher = PublisherType.ZIP,
-    publishOptions = {},
-    assets = [],
-  }: PackerOptions = {}
-): Promise<PublisherResponse<any>> => {
+export const packProject: PackProjectFunction = async (
+  projectUIDL,
+  { projectType = ProjectType.NEXT, publisher, publishOptions = {}, assets = [] } = {}
+) => {
   const packer = createProjectPacker()
 
   const projectGeneratorFactory = projectGeneratorFactories[projectType]
@@ -145,17 +138,14 @@ export const packProject = async (
       ? PreactCodesandBoxTemplate
       : templates[projectType]
 
-  const publisherFactory = projectPublisherFactories[publisher]
-
   if (!projectGeneratorFactory) {
     throw new Error(`Invalid ProjectType: ${projectType}`)
   }
 
-  if (!publisherFactory) {
+  if (publisher && !projectPublisherFactories[publisher]) {
     throw new Error(`Invalid PublisherType: ${publisher}`)
   }
 
-  const projectPublisher = publisherFactory(publishOptions)
   packer.setAssets({
     assets,
     path: [Constants.ASSETS_IDENTIFIER],
@@ -163,17 +153,20 @@ export const packProject = async (
 
   packer.setGenerator(projectGeneratorFactory())
   packer.setTemplate(projectTemplate)
-  packer.setPublisher(projectPublisher)
+
+  // If no publisher is provided, the packer will return the generated project
+  if (publisher) {
+    const publisherFactory = projectPublisherFactories[publisher]
+    const projectPublisher = publisherFactory(publishOptions)
+    packer.setPublisher(projectPublisher)
+  }
 
   return packer.pack(projectUIDL)
 }
 
-export const generateComponent = async (
+export const generateComponent: GenerateComponentFunction = async (
   componentUIDL: ComponentUIDL,
-  {
-    componentType = ComponentType.REACT,
-    styleVariation = ReactStyleVariation.CSSModules,
-  }: GenerateOptions = {}
+  { componentType = ComponentType.REACT, styleVariation = ReactStyleVariation.CSSModules } = {}
 ) => {
   const generator = createComponentGenerator(componentType, styleVariation)
   const projectMapping = componentGeneratorProjectMappings[componentType]
diff --git a/packages/teleport-github-gateway/src/constants.ts b/packages/teleport-github-gateway/src/constants.ts
index 1ec75ee8..53d56117 100644
--- a/packages/teleport-github-gateway/src/constants.ts
+++ b/packages/teleport-github-gateway/src/constants.ts
@@ -2,7 +2,7 @@ export const DEFAULT_REF = 'master'
 
 export const DEFAULT_COMMIT_BRANCH = 'master'
 
-export const DEFAULT_COMMIT_MESSAGE = 'Commit made using TeleportHQ'
+export const DEFAULT_COMMIT_MESSAGE = 'Commit made using teleportHQ'
 
 export const DEFAULT_PATH = ''
 
diff --git a/packages/teleport-github-gateway/src/github-instance.ts b/packages/teleport-github-gateway/src/github-instance.ts
index 3d742d09..889b94ff 100644
--- a/packages/teleport-github-gateway/src/github-instance.ts
+++ b/packages/teleport-github-gateway/src/github-instance.ts
@@ -82,7 +82,15 @@ export default class GithubInstance {
       repositoryIdentity,
       commitMessage = DEFAULT_COMMIT_MESSAGE,
     } = commitMeta
-    const { username, repo, ref = DEFAULT_REF } = repositoryIdentity
+    const { repo, ref = DEFAULT_REF } = repositoryIdentity
+
+    // Step -1: Make a separate request for the username if it is not provided
+    let username = repositoryIdentity.username
+    if (!username) {
+      const user = await this.githubApi.getUser()
+      const profile = await user.getProfile()
+      username = profile.data.login
+    }
 
     // Step 0: Create repository if it does not exist
     await this.ensureRepoExists(username, repo)
diff --git a/packages/teleport-plugin-common/src/node-handlers/node-to-html/index.ts b/packages/teleport-plugin-common/src/node-handlers/node-to-html/index.ts
index 826d7daa..1e0cf854 100644
--- a/packages/teleport-plugin-common/src/node-handlers/node-to-html/index.ts
+++ b/packages/teleport-plugin-common/src/node-handlers/node-to-html/index.ts
@@ -18,13 +18,22 @@ const generateElementNode: NodeToHTML<UIDLElementNode, HastNode> = (node, params
   const { dependencies, templateLookup } = params
   const { elementType, name, key, children, attrs, dependency, events, selfClosing } = node.content
   const tagName = elementType || 'component'
-  const safeTagName = dependency ? templateSyntax.customElementTagName(tagName) : tagName
+  const safeTagName =
+    dependency && dependency.type === 'local'
+      ? templateSyntax.customElementTagName(tagName)
+      : tagName
 
   const htmlNode = createHTMLNode(safeTagName)
 
   if (dependency && templateSyntax.dependencyHandling === 'import') {
-    const safeImportName = StringUtils.dashCaseToUpperCamelCase(safeTagName)
-    dependencies[safeImportName] = { ...dependency }
+    if (dependency.type !== 'local') {
+      // library and package dependencies are assumed to be safe
+      dependencies[tagName] = { ...dependency }
+    } else {
+      // local dependencies can be renamed based on their safety (eg: Header/header, Form/form)
+      const safeImportName = StringUtils.dashCaseToUpperCamelCase(safeTagName)
+      dependencies[safeImportName] = { ...dependency }
+    }
   }
 
   if (attrs) {
diff --git a/packages/teleport-project-generator-gatsby/package.json b/packages/teleport-project-generator-gatsby/package.json
index 56d22a43..b0e15dd8 100644
--- a/packages/teleport-project-generator-gatsby/package.json
+++ b/packages/teleport-project-generator-gatsby/package.json
@@ -28,11 +28,14 @@
   "dependencies": {
     "@babel/types": "^7.5.5",
     "@teleporthq/teleport-component-generator": "^0.10.0-alpha.6",
-    "@teleporthq/teleport-component-generator-react": "^0.10.0-alpha.6",
     "@teleporthq/teleport-plugin-common": "^0.10.0-alpha.6",
     "@teleporthq/teleport-plugin-import-statements": "^0.10.0-alpha.6",
     "@teleporthq/teleport-plugin-jsx-head-config": "^0.10.0-alpha.6",
     "@teleporthq/teleport-plugin-react-app-routing": "^0.10.0-alpha.6",
+    "@teleporthq/teleport-plugin-css-modules": "^0.10.0-alpha.6",
+    "@teleporthq/teleport-plugin-jsx-proptypes": "^0.10.0-alpha.6",
+    "@teleporthq/teleport-plugin-react-base-component": "^0.10.0-alpha.6",
+    "@teleporthq/teleport-postprocessor-prettier-jsx": "^0.10.0-alpha.6",
     "@teleporthq/teleport-postprocessor-prettier-html": "^0.10.0-alpha.6",
     "@teleporthq/teleport-postprocessor-prettier-js": "^0.10.0-alpha.6",
     "@teleporthq/teleport-project-generator": "^0.10.0-alpha.6",
diff --git a/packages/teleport-project-generator-gatsby/src/index.ts b/packages/teleport-project-generator-gatsby/src/index.ts
index 9edfe338..aac8225d 100644
--- a/packages/teleport-project-generator-gatsby/src/index.ts
+++ b/packages/teleport-project-generator-gatsby/src/index.ts
@@ -1,29 +1,29 @@
 import { createProjectGenerator } from '@teleporthq/teleport-project-generator'
-import {
-  createReactComponentGenerator,
-  ReactStyleVariation,
-} from '@teleporthq/teleport-component-generator-react'
 import { createComponentGenerator } from '@teleporthq/teleport-component-generator'
 
 import reactAppRoutingPlugin from '@teleporthq/teleport-plugin-react-app-routing'
+import reactBasePlugin from '@teleporthq/teleport-plugin-react-base-component'
+import { createCSSModulesPlugin } from '@teleporthq/teleport-plugin-css-modules'
+import reactProptypes from '@teleporthq/teleport-plugin-jsx-proptypes'
 import importStatementsPlugin from '@teleporthq/teleport-plugin-import-statements'
 import headConfigPlugin from '@teleporthq/teleport-plugin-jsx-head-config'
 import prettierJS from '@teleporthq/teleport-postprocessor-prettier-js'
+import prettierJSX from '@teleporthq/teleport-postprocessor-prettier-jsx'
 
-import { Mapping } from '@teleporthq/teleport-types'
+import { Mapping, ComponentPlugin } from '@teleporthq/teleport-types'
 
 import GatsbyProjectMapping from './gatsby-mapping.json'
 import GatsbyTemplate from './project-template'
 import { createCustomHTMLEntryFile } from './utils'
 
-const createGatsbyProjectGenerator = () => {
-  const reactComponentGenerator = createReactComponentGenerator(ReactStyleVariation.CSSModules)
-  reactComponentGenerator.addMapping(GatsbyProjectMapping as Mapping)
+const cssModulesPlugin = createCSSModulesPlugin({
+  moduleExtension: true,
+  camelCaseClassNames: true,
+})
 
-  const reactPagesGenerator = createReactComponentGenerator(ReactStyleVariation.CSSModules, {
-    plugins: [headConfigPlugin],
-    mappings: [GatsbyProjectMapping as Mapping],
-  })
+const createGatsbyProjectGenerator = () => {
+  const reactComponentGenerator = createCustomReactComponentGenerator()
+  const reactPagesGenerator = createCustomReactComponentGenerator([headConfigPlugin])
 
   const routingComponentGenerator = createComponentGenerator()
   routingComponentGenerator.addPlugin(reactAppRoutingPlugin)
@@ -60,4 +60,16 @@ const createGatsbyProjectGenerator = () => {
   return generator
 }
 
+const createCustomReactComponentGenerator = (extraPlugins: ComponentPlugin[] = []) => {
+  const reactComponentGenerator = createComponentGenerator()
+  reactComponentGenerator.addPlugin(reactBasePlugin)
+  reactComponentGenerator.addPlugin(cssModulesPlugin)
+  reactComponentGenerator.addPlugin(reactProptypes)
+  extraPlugins.forEach((plugin) => reactComponentGenerator.addPlugin(plugin))
+  reactComponentGenerator.addPlugin(importStatementsPlugin)
+  reactComponentGenerator.addMapping(GatsbyProjectMapping as Mapping)
+  reactComponentGenerator.addPostProcessor(prettierJSX)
+  return reactComponentGenerator
+}
+
 export { createGatsbyProjectGenerator, GatsbyProjectMapping, GatsbyTemplate }
diff --git a/packages/teleport-project-packer/src/errors.ts b/packages/teleport-project-packer/src/errors.ts
index 192e7300..abdf0762 100644
--- a/packages/teleport-project-packer/src/errors.ts
+++ b/packages/teleport-project-packer/src/errors.ts
@@ -1,5 +1,3 @@
 export const NO_GENERATOR_PROVIDED = 'No generator provided'
-export const NO_PUBLISHER_PROVIDED = 'No publisher provided'
-
 export const NO_GITHUB_REPO = 'No github repository provided'
 export const NO_GITHUB_OWNER = 'No github repository owner provided'
diff --git a/packages/teleport-project-packer/src/index.ts b/packages/teleport-project-packer/src/index.ts
index 79e8a4bd..0ee10dcb 100644
--- a/packages/teleport-project-packer/src/index.ts
+++ b/packages/teleport-project-packer/src/index.ts
@@ -8,7 +8,7 @@ import {
   RemoteTemplateDefinition,
 } from '@teleporthq/teleport-types'
 import { injectAssetsToProject, fetchTemplate } from './utils'
-import { NO_GENERATOR_PROVIDED, NO_PUBLISHER_PROVIDED } from './errors'
+import { NO_GENERATOR_PROVIDED } from './errors'
 import { DEFAULT_TEMPLATE } from './constants'
 
 export interface PackerFactoryParams {
@@ -64,9 +64,6 @@ export const createProjectPacker: PackerFactory = (params: PackerFactoryParams =
     }
 
     const packPublisher = packParams.publisher || publisher
-    if (!packPublisher) {
-      return { success: false, payload: NO_PUBLISHER_PROVIDED }
-    }
 
     const packAssets = packParams.assets || assets
     let templateFolder = packParams.template || template
@@ -82,7 +79,15 @@ export const createProjectPacker: PackerFactory = (params: PackerFactoryParams =
 
     const project = await injectAssetsToProject(outputFolder, packAssets, assetsPath)
 
-    return packPublisher.publish({ project })
+    if (packPublisher) {
+      return packPublisher.publish({ project })
+    }
+
+    // If no publisher is provided, return the generated project
+    return {
+      success: true,
+      payload: project,
+    }
   }
 
   return {
diff --git a/packages/teleport-publisher-codesandbox/src/constants.ts b/packages/teleport-publisher-codesandbox/src/constants.ts
index d55990e1..37e61215 100644
--- a/packages/teleport-publisher-codesandbox/src/constants.ts
+++ b/packages/teleport-publisher-codesandbox/src/constants.ts
@@ -1,1 +1,3 @@
 export const BASE_URL = 'https://codesandbox.io/api/v1/sandboxes/define'
+
+export const BASE_SANDBOX_URL = 'https://codesandbox.io/s/'
diff --git a/packages/teleport-publisher-codesandbox/src/index.ts b/packages/teleport-publisher-codesandbox/src/index.ts
index ef33d1b3..42c62ae5 100644
--- a/packages/teleport-publisher-codesandbox/src/index.ts
+++ b/packages/teleport-publisher-codesandbox/src/index.ts
@@ -5,7 +5,7 @@ import {
   PublisherFactory,
   Publisher,
 } from '@teleporthq/teleport-types'
-import { BASE_URL } from './constants'
+import { BASE_URL, BASE_SANDBOX_URL } from './constants'
 import { convertToCodesandboxStructure } from './utils'
 
 export const createCodesandboxPublisher: PublisherFactory<
@@ -36,7 +36,7 @@ export const createCodesandboxPublisher: PublisherFactory<
 
       const result = await response.json()
 
-      return { success: true, payload: result.sandbox_id }
+      return { success: true, payload: `${BASE_SANDBOX_URL}${result.sandbox_id}` }
     } catch (error) {
       return { success: false, payload: error.message }
     }
diff --git a/packages/teleport-publisher-disk/src/index.ts b/packages/teleport-publisher-disk/src/index.ts
index b86ff91f..2b11fd46 100644
--- a/packages/teleport-publisher-disk/src/index.ts
+++ b/packages/teleport-publisher-disk/src/index.ts
@@ -10,7 +10,7 @@ import { NO_PROJECT_UIDL } from './errors'
 
 export interface DiskFactoryParams extends PublisherFactoryParams {
   outputPath?: string
-  projectName?: string
+  projectSlug?: string
   createProjectFolder?: boolean
 }
 
@@ -45,11 +45,11 @@ export const createDiskPublisher: PublisherFactory<DiskFactoryParams, DiskPublis
     }
 
     const projectOutputPath = options.outputPath || outputPath
-    const overrideProjectName = options.projectName || params.projectName
+    const overrideProjectSlug = options.projectSlug || params.projectSlug
     const createProjectFolder = options.createProjectFolder || params.createProjectFolder
 
-    if (overrideProjectName) {
-      projectToPublish.name = overrideProjectName
+    if (overrideProjectSlug) {
+      projectToPublish.name = overrideProjectSlug
     }
 
     try {
diff --git a/packages/teleport-publisher-github/src/errors.ts b/packages/teleport-publisher-github/src/errors.ts
index 2c46ca20..0746d442 100644
--- a/packages/teleport-publisher-github/src/errors.ts
+++ b/packages/teleport-publisher-github/src/errors.ts
@@ -3,5 +3,3 @@ export const NO_PROJECT_UIDL = 'No project UIDL provided.'
 export const NO_AUTH = 'No auth metadata provided.'
 
 export const NO_REPO = 'No repository name provided.'
-
-export const NO_REPO_OWNER = 'No repository owner provided'
diff --git a/packages/teleport-publisher-github/src/index.ts b/packages/teleport-publisher-github/src/index.ts
index b71b94a0..e7b35f16 100644
--- a/packages/teleport-publisher-github/src/index.ts
+++ b/packages/teleport-publisher-github/src/index.ts
@@ -3,7 +3,7 @@ import { GeneratedFolder, PublisherFactory, ServiceAuth } from '@teleporthq/tele
 import { publishToGithub, generateProjectFiles } from './utils'
 import { GithubFactoryParams, GithubPublisher, GithubPublishMeta } from './types'
 
-import { NO_PROJECT_UIDL, NO_REPO, NO_AUTH, NO_REPO_OWNER } from './errors'
+import { NO_PROJECT_UIDL, NO_REPO, NO_AUTH } from './errors'
 
 export const createGithubPublisher: PublisherFactory<GithubFactoryParams, GithubPublisher> = (
   params: GithubFactoryParams = {}
@@ -58,9 +58,6 @@ export const createGithubPublisher: PublisherFactory<GithubFactoryParams, Github
     }
 
     const repoOwner = findRepositoryOwner(auth, options)
-    if (!repoOwner) {
-      return { success: false, payload: NO_REPO_OWNER }
-    }
 
     const masterBranchName = options.masterBranch || masterBranch
     const master = masterBranchName ? masterBranch : 'master'
diff --git a/packages/teleport-publisher-now/src/constants.ts b/packages/teleport-publisher-now/src/constants.ts
deleted file mode 100644
index 8648d3b3..00000000
--- a/packages/teleport-publisher-now/src/constants.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export const DEPLOY_URL = 'https://us-central1-croapp-dev.cloudfunctions.net/publishToNow'
-
-export const NOW_CONFIG = {
-  version: 2,
-  public: true,
-}
diff --git a/packages/teleport-publisher-now/src/errors.ts b/packages/teleport-publisher-now/src/errors.ts
index 90c22163..edeaa487 100644
--- a/packages/teleport-publisher-now/src/errors.ts
+++ b/packages/teleport-publisher-now/src/errors.ts
@@ -1,1 +1,5 @@
 export const NO_PROJECT_UIDL = 'No project UIDL provided.'
+
+export const NO_TOKEN = 'No access token provided.'
+
+export const GENERIC_ERROR = 'Deployment failed. Please try again later.'
diff --git a/packages/teleport-publisher-now/src/index.ts b/packages/teleport-publisher-now/src/index.ts
index 09029e57..f2f58601 100644
--- a/packages/teleport-publisher-now/src/index.ts
+++ b/packages/teleport-publisher-now/src/index.ts
@@ -4,11 +4,14 @@ import {
   PublisherFactoryParams,
   PublisherFactory,
 } from '@teleporthq/teleport-types'
-import { NO_PROJECT_UIDL } from './errors'
-import { generateProjectFiles, publishToNow, checkDeploymentStatus } from './utils'
+import { NO_PROJECT_UIDL, NO_TOKEN } from './errors'
+import { generateProjectFiles, createDeployment, checkDeploymentStatus } from './utils'
+import { NowPayload } from './types'
 
 export interface NowFactoryParams extends PublisherFactoryParams {
   accessToken: string
+  projectSlug: string
+  domainAlias?: string
 }
 
 export interface NowPublisher extends Publisher<NowFactoryParams, string> {
@@ -18,6 +21,7 @@ export interface NowPublisher extends Publisher<NowFactoryParams, string> {
 
 const defaultPublisherParams: NowFactoryParams = {
   accessToken: null,
+  projectSlug: 'teleport',
 }
 
 export const createNowPublisher: PublisherFactory<NowFactoryParams, NowPublisher> = (
@@ -42,17 +46,35 @@ export const createNowPublisher: PublisherFactory<NowFactoryParams, NowPublisher
     }
 
     const nowAccessToken = options.accessToken || accessToken
+    const projectSlug = options.projectSlug || params.projectSlug
+    const domainAlias = options.domainAlias || params.domainAlias
+
+    if (!nowAccessToken) {
+      return { success: false, payload: NO_TOKEN }
+    }
 
     try {
-      const projectFiles = generateProjectFiles(projectToPublish)
-      const deploymentURL = await publishToNow(projectFiles, nowAccessToken)
+      const productionAlias = domainAlias ? `${projectSlug}.${domainAlias}` : null
+      const nowPayload: NowPayload = {
+        files: generateProjectFiles(projectToPublish),
+        name: projectSlug,
+        public: true,
+        version: 2,
+        target: 'production',
+      }
 
-      // If the user did not provide the now token, we are using the teleport one so we wait for the deployment
-      if (!nowAccessToken) {
-        await checkDeploymentStatus(deploymentURL)
+      // send the production alias if it exists
+      if (productionAlias) {
+        nowPayload.alias = [productionAlias]
       }
 
-      return { success: true, payload: 'https://' + deploymentURL }
+      const deploymentURL = await createDeployment(nowPayload, nowAccessToken)
+
+      // Makes requests to the deployment URL until the deployment is ready
+      await checkDeploymentStatus(deploymentURL)
+
+      // If productionAlias is empty, the deploymentURL is the fallback
+      return { success: true, payload: 'https://' + (productionAlias || deploymentURL) }
     } catch (error) {
       return { success: false, payload: error }
     }
diff --git a/packages/teleport-publisher-now/src/types.ts b/packages/teleport-publisher-now/src/types.ts
new file mode 100644
index 00000000..b4bb7e8a
--- /dev/null
+++ b/packages/teleport-publisher-now/src/types.ts
@@ -0,0 +1,23 @@
+import { GeneratedFolder } from '@teleporthq/teleport-types'
+
+export interface ProjectFolderInfo {
+  folder: GeneratedFolder
+  prefix?: string
+  files?: NowFile[]
+  ignoreFolder?: boolean
+}
+
+export interface NowFile {
+  file: string
+  data: Blob | string
+  encoding?: string
+}
+
+export interface NowPayload {
+  files: NowFile[]
+  name: string
+  version: number
+  public?: boolean
+  target?: string
+  alias?: string[]
+}
diff --git a/packages/teleport-publisher-now/src/utils.ts b/packages/teleport-publisher-now/src/utils.ts
index 1c881033..d6edaaad 100644
--- a/packages/teleport-publisher-now/src/utils.ts
+++ b/packages/teleport-publisher-now/src/utils.ts
@@ -1,36 +1,18 @@
 import fetch from 'cross-fetch'
 import { GeneratedFolder, GeneratedFile } from '@teleporthq/teleport-types'
-import { NOW_CONFIG, DEPLOY_URL } from './constants'
+import { ProjectFolderInfo, NowFile, NowPayload } from './types'
+import { GENERIC_ERROR } from './errors'
 
-interface ProjectFolderInfo {
-  folder: GeneratedFolder
-  prefix?: string
-  files?: NowFile[]
-  ignoreFolder?: boolean
-}
-
-interface NowFile {
-  file: string
-  data: Blob | string
-  encoding?: string
-}
+const CREATE_DEPLOY_URL = 'https://api.zeit.co/v10/now/deployments'
+const CHECK_DEPLOY_BASE_URL = 'https://api.zeit.co/v10/now/deployments/get?url='
 
-interface NowFiles {
-  files: NowFile[]
-  name: string
-}
+type DeploymentStatus = 'READY' | 'QUEUED' | 'BUILDING' | 'ERROR'
 
-export const generateProjectFiles = (project: GeneratedFolder): NowFiles => {
-  const files = destructureProjectFiles({
+export const generateProjectFiles = (project: GeneratedFolder): NowFile[] => {
+  return destructureProjectFiles({
     folder: project,
     ignoreFolder: true,
   })
-
-  return {
-    ...NOW_CONFIG,
-    files,
-    name: project.name,
-  }
 }
 
 const destructureProjectFiles = (folderInfo: ProjectFolderInfo): NowFile[] => {
@@ -66,50 +48,62 @@ const destructureProjectFiles = (folderInfo: ProjectFolderInfo): NowFile[] => {
   return files
 }
 
-export const publishToNow = async (projectFiles: NowFiles, token?: string): Promise<string> => {
-  const response = await fetch(DEPLOY_URL, {
+export const createDeployment = async (payload: NowPayload, token: string): Promise<string> => {
+  const response = await fetch(CREATE_DEPLOY_URL, {
     method: 'POST',
     headers: {
       'content-type': 'application/json',
+      Authorization: `Bearer ${token}`,
     },
-    body: JSON.stringify({
-      projectFiles,
-      token,
-    }),
+    body: JSON.stringify(payload),
   })
 
   const result = await response.json()
   if (result.error) {
-    throw new Error(result.error)
+    throw new Error(result.error.message)
   }
 
-  return result.data
+  return result.url
 }
 
 export const checkDeploymentStatus = async (deploymentURL: string) => {
   await new Promise((resolve, reject) => {
-    let retries = 7
+    let retries = 60
 
     const clearHook = setInterval(async () => {
       retries = retries - 1
 
-      const ready = await checkDeploymentReady(deploymentURL)
-      if (ready) {
+      const readyState = await checkDeploymentReady(deploymentURL)
+      if (readyState === 'READY') {
         clearInterval(clearHook)
         return resolve()
       }
 
+      if (readyState === 'ERROR') {
+        clearInterval(clearHook)
+        reject(GENERIC_ERROR)
+      }
+
       if (retries <= 0) {
         clearInterval(clearHook)
-        reject('Deployment failed. Please try again later.')
+        reject(GENERIC_ERROR)
       }
     }, 5000)
   })
 }
 
-export const checkDeploymentReady = async (deploymentURL: string) => {
-  const nowUrl = `https://api.zeit.co/v9/now/deployments/get?url=${deploymentURL}`
-  const result = await fetch(nowUrl)
-  const jsonResult = await result.json()
-  return jsonResult.readyState === 'READY'
+export const checkDeploymentReady = async (deploymentURL: string): Promise<DeploymentStatus> => {
+  try {
+    const nowUrl = `${CHECK_DEPLOY_BASE_URL}${deploymentURL}`
+    const result = await fetch(nowUrl)
+    const jsonResult = await result.json()
+    if (jsonResult.readyState) {
+      return jsonResult.readyState
+    } else {
+      return 'ERROR'
+    }
+  } catch (err) {
+    console.warn(err)
+    return 'ERROR'
+  }
 }
diff --git a/packages/teleport-publisher-zip/src/index.ts b/packages/teleport-publisher-zip/src/index.ts
index 824f605a..9aa3f68e 100644
--- a/packages/teleport-publisher-zip/src/index.ts
+++ b/packages/teleport-publisher-zip/src/index.ts
@@ -11,7 +11,7 @@ declare type ZipPublisherResponse = string | Buffer | Blob
 
 export interface ZipFactoryParams extends PublisherFactoryParams {
   outputPath?: string
-  projectName?: string
+  projectSlug?: string
 }
 
 export interface ZipPublisher extends Publisher<ZipFactoryParams, ZipPublisherResponse> {
@@ -40,7 +40,7 @@ export const createZipPublisher: PublisherFactory<ZipFactoryParams, ZipPublisher
       return { success: false, payload: NO_PROJECT_UIDL }
     }
 
-    const zipName = options.projectName || params.projectName || projectToPublish.name
+    const zipName = options.projectSlug || params.projectSlug || projectToPublish.name
 
     try {
       const zipContent = await generateProjectZip(projectToPublish)
diff --git a/packages/teleport-shared/src/utils/uidl-utils.ts b/packages/teleport-shared/src/utils/uidl-utils.ts
index c4ab99e6..54ce1802 100644
--- a/packages/teleport-shared/src/utils/uidl-utils.ts
+++ b/packages/teleport-shared/src/utils/uidl-utils.ts
@@ -51,7 +51,13 @@ export const setFriendlyOutputOptions = (uidl: ComponentUIDL) => {
   // failsafe for invalid UIDL samples with illegal characters as element names
   // when used in projects, resolveLocalDependencies should handle this
   traverseElements(uidl.node, (element) => {
-    element.elementType = removeIllegalCharacters(element.elementType)
+    if (element.dependency) {
+      element.elementType = dashCaseToUpperCamelCase(
+        removeIllegalCharacters(element.elementType) || defaultComponentName
+      )
+    } else {
+      element.elementType = removeIllegalCharacters(element.elementType)
+    }
   })
 }
 
diff --git a/packages/teleport-types/src/generators.ts b/packages/teleport-types/src/generators.ts
index d48df648..31904aa5 100644
--- a/packages/teleport-types/src/generators.ts
+++ b/packages/teleport-types/src/generators.ts
@@ -272,8 +272,9 @@ export interface PrettierFormatOptions {
 
 interface PublisherOptions {
   accessToken?: string
-  projectName?: string
   outputPath?: string
+  projectSlug?: string
+  domainAlias?: string // used by the now publisher
   createProjectFolder?: boolean // used only by the disk publisher
 }
 
@@ -337,7 +338,7 @@ export enum ProjectType {
   ANGULAR = 'Angular',
   GATSBY = 'Gatsby',
   GRIDSOME = 'Gridsome',
-  REACTNATIVE = 'React Native',
+  REACTNATIVE = 'React-Native',
 }
 
 export enum ComponentType {
@@ -346,7 +347,7 @@ export enum ComponentType {
   PREACT = 'Preact',
   STENCIL = 'Stencil',
   ANGULAR = 'Angular',
-  REACTNATIVE = 'React Native',
+  REACTNATIVE = 'React-Native',
 }
 
 export const DefaultStyleVariation: Record<ComponentType, StyleVariation> = {
@@ -359,3 +360,15 @@ export const DefaultStyleVariation: Record<ComponentType, StyleVariation> = {
 }
 
 export type StyleVariation = ReactStyleVariation | PreactStyleVariation | ReactNativeStyleVariation
+
+// The last two types are used by the teleport-code-generator package
+
+export type PackProjectFunction = (
+  projectUIDL: ProjectUIDL,
+  options: PackerOptions
+) => Promise<PublisherResponse<any>>
+
+export type GenerateComponentFunction = (
+  componentUIDL: ComponentUIDL,
+  options: GenerateOptions
+) => Promise<CompiledComponent>


Test patch:
diff --git a/packages/teleport-component-generator-react/__tests__/integration/component-dependency.ts b/packages/teleport-component-generator-react/__tests__/integration/component-dependency.ts
index 6bf445dd..7a4c1e9c 100644
--- a/packages/teleport-component-generator-react/__tests__/integration/component-dependency.ts
+++ b/packages/teleport-component-generator-react/__tests__/integration/component-dependency.ts
@@ -157,14 +157,14 @@ describe('Component with dependency ', () => {
     it('renders code with named import ', async () => {
       const result = await generator.generateComponent(
         uidl(
-          dependencySample('write', 'library', 'fs', '', {
+          dependencySample('Card', 'library', 'react-material', '', {
             namedImport: true,
           })
         )
       )
       const jsFile = findFileByType(result.files, JS_FILE)
       expect(jsFile).toBeDefined()
-      expect(jsFile.content).toContain("import { write } from 'fs'")
+      expect(jsFile.content).toContain("import { Card } from 'react-material'")
     })
   })
 })
diff --git a/packages/teleport-component-generator-vue/__tests__/integration/component-dependency.ts b/packages/teleport-component-generator-vue/__tests__/integration/component-dependency.ts
index 95716fe1..3aef16a3 100644
--- a/packages/teleport-component-generator-vue/__tests__/integration/component-dependency.ts
+++ b/packages/teleport-component-generator-vue/__tests__/integration/component-dependency.ts
@@ -38,39 +38,39 @@ describe('Component with dependency ', () => {
     it('renders code with imported package', async () => {
       const result = await vueGenerator.generateComponent(
         uidl(
-          dependencySample('ReactDatepicker', 'package', 'react-datepicker', '', {
+          dependencySample('VueDatepicker', 'package', 'vue-datepicker', '', {
             namedImport: false,
           })
         )
       )
       const code = result.files[0].content
 
-      expect(code).toContain("import ReactDatepicker from 'react-datepicker'")
+      expect(code).toContain("import VueDatepicker from 'vue-datepicker'")
     })
 
     it('renders code with named import ', async () => {
       const result = await vueGenerator.generateComponent(
         uidl(
-          dependencySample('ReactDatepicker', 'package', 'react-datepicker', '', {
+          dependencySample('VueDatepicker', 'package', 'vue-datepicker', '', {
             namedImport: true,
           })
         )
       )
       const code = result.files[0].content
-      expect(code).toContain("import { ReactDatepicker } from 'react-datepicker'")
+      expect(code).toContain("import { VueDatepicker } from 'vue-datepicker'")
     })
 
     it('renders code with original name', async () => {
       const result = await vueGenerator.generateComponent(
         uidl(
-          dependencySample('Router', 'package', 'react-router', '', {
+          dependencySample('VuePicker', 'package', 'vue-datepicker', '', {
             namedImport: true,
-            originalName: 'BrowserRouter',
+            originalName: 'VueDatePicker',
           })
         )
       )
       const code = result.files[0].content
-      expect(code).toContain("import { BrowserRouter as Router } from 'react-router'")
+      expect(code).toContain("import { VueDatePicker as VuePicker } from 'vue-datepicker'")
     })
   })
 
@@ -78,39 +78,39 @@ describe('Component with dependency ', () => {
     it('renders code with imported package', async () => {
       const result = await vueGenerator.generateComponent(
         uidl(
-          dependencySample('ReactDatepicker', 'local', '../react-datepicker', '', {
+          dependencySample('VueDatepicker', 'local', '../vue-datepicker', '', {
             namedImport: false,
           })
         )
       )
       const code = result.files[0].content
 
-      expect(code).toContain("import ReactDatepicker from '../react-datepicker'")
+      expect(code).toContain("import VueDatepicker from '../vue-datepicker'")
     })
 
     it('renders code with named import ', async () => {
       const result = await vueGenerator.generateComponent(
         uidl(
-          dependencySample('ReactDatepicker', 'local', '../react-datepicker', '', {
+          dependencySample('VueDatepicker', 'local', '../vue-datepicker', '', {
             namedImport: true,
           })
         )
       )
       const code = result.files[0].content
-      expect(code).toContain("import { ReactDatepicker } from '../react-datepicker'")
+      expect(code).toContain("import { VueDatepicker } from '../vue-datepicker'")
     })
 
     it('renders code with original name', async () => {
       const result = await vueGenerator.generateComponent(
         uidl(
-          dependencySample('Router', 'local', 'react-router', '', {
+          dependencySample('VuePicker', 'local', 'vue-datepicker', '', {
             namedImport: true,
-            originalName: 'BrowserRouter',
+            originalName: 'VueDatepicker',
           })
         )
       )
       const code = result.files[0].content
-      expect(code).toContain("import { BrowserRouter as Router } from 'react-router'")
+      expect(code).toContain("import { VueDatepicker as VuePicker } from 'vue-datepicker'")
     })
   })
 
@@ -118,13 +118,13 @@ describe('Component with dependency ', () => {
     it('renders code with named import ', async () => {
       const result = await vueGenerator.generateComponent(
         uidl(
-          dependencySample('write', 'local', 'fs', '', {
+          dependencySample('Card', 'library', 'material', '', {
             namedImport: true,
           })
         )
       )
       const code = result.files[0].content
-      expect(code).toContain("import { write } from 'fs'")
+      expect(code).toContain("import { Card } from 'material'")
     })
   })
 })
diff --git a/packages/teleport-plugin-css-modules/__tests__/index.ts b/packages/teleport-plugin-css-modules/__tests__/index.ts
index 84c4d834..640950bb 100644
--- a/packages/teleport-plugin-css-modules/__tests__/index.ts
+++ b/packages/teleport-plugin-css-modules/__tests__/index.ts
@@ -55,7 +55,7 @@ describe('plugin-css-modules', () => {
 
     const classNameAttr = nodeReference.openingElement.attributes[0]
     expect(classNameAttr.name.name).toBe('className')
-    expect(classNameAttr.value.expression.name).toBe("styles['list-container']")
+    expect(classNameAttr.value.expression.name).toBe('styles.listContainer')
   })
 
   it('generates a string chunk out of the styles and adds the className in camel case', async () => {
@@ -73,7 +73,7 @@ describe('plugin-css-modules', () => {
 
     const classNameAttr = nodeReference.openingElement.attributes[0]
     expect(classNameAttr.name.name).toBe('className')
-    expect(classNameAttr.value.expression.name).toBe('styles.listContainer')
+    expect(classNameAttr.value.expression.name).toBe("styles['list-container']")
   })
 
   it('generates a string chunk out of the styles and adds the class attribute', async () => {
diff --git a/packages/teleport-project-packer/__tests__/index.ts b/packages/teleport-project-packer/__tests__/index.ts
index f7fa25a4..fbe3596d 100644
--- a/packages/teleport-project-packer/__tests__/index.ts
+++ b/packages/teleport-project-packer/__tests__/index.ts
@@ -15,7 +15,7 @@ import {
 } from '@teleporthq/teleport-types'
 
 import { createProjectPacker } from '../src'
-import { NO_GENERATOR_PROVIDED, NO_PUBLISHER_PROVIDED } from '../src/errors'
+import { NO_GENERATOR_PROVIDED } from '../src/errors'
 import { DEFAULT_TEMPLATE } from '../src/constants'
 
 const assetFile = readFileSync(join(__dirname, 'asset.png'))
@@ -57,7 +57,7 @@ describe('teleport generic project packer', () => {
   it('should fail to pack if no generator function is provided', async () => {
     const packer = createProjectPacker()
 
-    const { success, payload } = await packer.pack(projectJson as ProjectUIDL, {
+    const { success, payload } = await packer.pack((projectJson as unknown) as ProjectUIDL, {
       template: templateDefinition,
       remoteTemplateDefinition: { provider: 'github', username: 'test', repo: 'test' },
     })
@@ -65,15 +65,16 @@ describe('teleport generic project packer', () => {
     expect(payload).toBe(NO_GENERATOR_PROVIDED)
   })
 
-  it('should fail to pack if no publisher is provider', async () => {
+  it('should return the project folder if no publisher is specified', async () => {
     const packer = createProjectPacker({
       generator: dummyGenerator,
       template: templateDefinition,
     })
 
-    const { success, payload } = await packer.pack(projectJson as ProjectUIDL)
-    expect(success).toBeFalsy()
-    expect(payload).toBe(NO_PUBLISHER_PROVIDED)
+    const { success, payload } = await packer.pack((projectJson as unknown) as ProjectUIDL)
+    expect(success).toBeTruthy()
+
+    expect(payload)
   })
 
   it('should pack if all required data is provided', async () => {
@@ -85,7 +86,7 @@ describe('teleport generic project packer', () => {
       assets: assetsData,
     })
 
-    const { success, payload } = await packer.pack(projectJson as ProjectUIDL)
+    const { success, payload } = await packer.pack((projectJson as unknown) as ProjectUIDL)
     expect(success).toBeTruthy()
 
     const { project } = payload
@@ -111,7 +112,7 @@ describe('teleport generic project packer', () => {
       assets: assetsData,
     })
 
-    const { success, payload } = await packer.pack(projectJson as ProjectUIDL, {
+    const { success, payload } = await packer.pack((projectJson as unknown) as ProjectUIDL, {
       template: templateDefinition,
     })
     expect(success).toBeTruthy()
diff --git a/packages/teleport-publisher-github/__tests__/index.ts b/packages/teleport-publisher-github/__tests__/index.ts
index d24b10ac..e3b5e655 100644
--- a/packages/teleport-publisher-github/__tests__/index.ts
+++ b/packages/teleport-publisher-github/__tests__/index.ts
@@ -1,6 +1,6 @@
 import { createGithubPublisher } from '../src'
 
-import { NO_PROJECT_UIDL, NO_AUTH, NO_REPO, NO_REPO_OWNER } from '../src/errors'
+import { NO_PROJECT_UIDL, NO_AUTH, NO_REPO } from '../src/errors'
 
 import project from './project-files.json'
 import githubFiles from './github-files-content.json'
@@ -107,18 +107,6 @@ describe('teleport publisher github', () => {
     expect(payload).toBe(NO_REPO)
   })
 
-  it('should fail if no repository owner is provided', async () => {
-    const publisher = createGithubPublisher({
-      authMeta: { token: 'dummy-invalid-token' },
-    })
-    publisher.setProject(project)
-    publisher.setRepository('test')
-
-    const { success, payload } = await publisher.publish()
-    expect(success).toBeFalsy()
-    expect(payload).toBe(NO_REPO_OWNER)
-  })
-
   it('should generate github project files from generated folder', () => {
     const files = generateProjectFiles({ folder: project, ignoreFolder: true })
     expect(JSON.stringify(files)).toBe(JSON.stringify(githubFiles))
diff --git a/packages/teleport-publisher-zip/__tests__/index.ts b/packages/teleport-publisher-zip/__tests__/index.ts
index d71b39c3..b7f6acc3 100644
--- a/packages/teleport-publisher-zip/__tests__/index.ts
+++ b/packages/teleport-publisher-zip/__tests__/index.ts
@@ -61,7 +61,7 @@ describe('teleport publisher zip', () => {
     const publisher = createZipPublisher({ project, outputPath: projectPath })
     const zipName = 'zip-name'
 
-    const { success, payload } = await publisher.publish({ projectName: zipName })
+    const { success, payload } = await publisher.publish({ projectSlug: zipName })
     expect(success).toBeTruthy()
 
     const zipPath = join(projectPath, `${zipName}.zip`)