Repository: teleporthq/teleport-code-generators
Pull request #362 (2019-09-17 15:20:35)

refactor: rename some fields and simplify logic for routing and paths

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

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

```diff
@@            Coverage Diff             @@
##           master     #362      +/-   ##
==========================================
+ Coverage   73.94%   74.31%   +0.37%     
==========================================
  Files         126      126              
  Lines        4037     4042       +5     
  Branches      846      846              
==========================================
+ Hits         2985     3004      +19     
+ Misses       1011      997      -14     
  Partials       41       41
```


| [Impacted Files](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/362?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [...kages/teleport-project-generator-next/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/362/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHJvamVjdC1nZW5lcmF0b3ItbmV4dC9zcmMvaW5kZXgudHM=) | `100% <ø> (ø)` | :arrow_up: |
| [packages/teleport-shared/src/constants/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/362/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtc2hhcmVkL3NyYy9jb25zdGFudHMvaW5kZXgudHM=) | `100% <ø> (ø)` | :arrow_up: |
| [...kages/teleport-project-generator-nuxt/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/362/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHJvamVjdC1nZW5lcmF0b3ItbnV4dC9zcmMvaW5kZXgudHM=) | `100% <ø> (ø)` | :arrow_up: |
| [...ckages/teleport-plugin-angular-module/src/utils.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/362/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcGx1Z2luLWFuZ3VsYXItbW9kdWxlL3NyYy91dGlscy50cw==) | `0% <ø> (ø)` | :arrow_up: |
| [...s/teleport-plugin-stencil-app-routing/src/utils.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/362/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcGx1Z2luLXN0ZW5jaWwtYXBwLXJvdXRpbmcvc3JjL3V0aWxzLnRz) | `0% <0%> (ø)` | :arrow_up: |
| [...s/teleport-plugin-stencil-app-routing/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/362/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcGx1Z2luLXN0ZW5jaWwtYXBwLXJvdXRpbmcvc3JjL2luZGV4LnRz) | `0% <0%> (ø)` | :arrow_up: |
| [...ckages/teleport-plugin-angular-module/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/362/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcGx1Z2luLWFuZ3VsYXItbW9kdWxlL3NyYy9pbmRleC50cw==) | `0% <0%> (ø)` | :arrow_up: |
| [packages/teleport-project-generator/src/utils.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/362/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHJvamVjdC1nZW5lcmF0b3Ivc3JjL3V0aWxzLnRz) | `93.49% <100%> (ø)` | :arrow_up: |
| [packages/teleport-component-generator/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/362/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtY29tcG9uZW50LWdlbmVyYXRvci9zcmMvaW5kZXgudHM=) | `90.16% <100%> (ø)` | :arrow_up: |
| [...teleport-component-generator/src/resolver/utils.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/362/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtY29tcG9uZW50LWdlbmVyYXRvci9zcmMvcmVzb2x2ZXIvdXRpbHMudHM=) | `66.14% <100%> (ø)` | :arrow_up: |
| ... and [4 more](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/362/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/362?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/362?src=pr&el=footer). Last update [4cd5007...5a346e1](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/362?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/examples/uidl-samples/project.json b/examples/uidl-samples/project.json
index 9dbedea7..b1e0a038 100644
--- a/examples/uidl-samples/project.json
+++ b/examples/uidl-samples/project.json
@@ -51,8 +51,8 @@
         "values": [
           {
             "value": "home",
-            "meta": {
-              "path": "/",
+            "pageOptions": {
+              "navLink": "/",
               "componentName": "Home"
             },
             "seo": {
@@ -61,10 +61,6 @@
           },
           {
             "value": "team",
-            "meta": {
-              "path": "/team",
-              "componentName": "Team"
-            },
             "seo": {
               "title": "About Page",
               "metaTags": [
@@ -81,8 +77,8 @@
           },
           {
             "value": "contact-us",
-            "meta": {
-              "path": "/contact-us",
+            "pageOptions": {
+              "navLink": "/about-us",
               "componentName": "ContactPage"
             },
             "seo": {
diff --git a/packages/teleport-code-generator/src/index.ts b/packages/teleport-code-generator/src/index.ts
index 76cf6854..102a2238 100644
--- a/packages/teleport-code-generator/src/index.ts
+++ b/packages/teleport-code-generator/src/index.ts
@@ -121,11 +121,17 @@ const createCodeGenerator = (factoryOptions: PackerOptions & GenerateOptions = {
     const packPublishOptions = { ...publishOptions, ...packOptions.publishOptions }
     const packAssets = packOptions.assets || assets
 
-    const projectGenerator =
-      projectGenerators[packProjectType] || projectGenerators[ProjectType.NEXT]
-    const projectTemplate = templates[packProjectType] || templates[ProjectType.NEXT]
-    const publisherFactory =
-      projectPublisherFactories[packPublisher] || projectPublisherFactories[PublisherType.ZIP]
+    const projectGenerator = projectGenerators[packProjectType]
+    const projectTemplate = templates[packProjectType]
+    const publisherFactory = projectPublisherFactories[packPublisher]
+
+    if (!projectGenerator) {
+      throw new Error(`Invalid ProjectType: ${packProjectType}`)
+    }
+
+    if (!publisherFactory) {
+      throw new Error(`Invalid PublisherType: ${packPublisher}`)
+    }
 
     const projectPublisher = publisherFactory(packPublishOptions)
 
diff --git a/packages/teleport-component-generator/src/index.ts b/packages/teleport-component-generator/src/index.ts
index 5671eb5e..8593a82c 100644
--- a/packages/teleport-component-generator/src/index.ts
+++ b/packages/teleport-component-generator/src/index.ts
@@ -146,7 +146,7 @@ const getFileName = (
   styleFileName: string,
   templateFileName: string
 ) => {
-  if (fileType === FILE_TYPE.CSS || fileType === FILE_TYPE.CSSMODULE) {
+  if (fileType === FILE_TYPE.CSS) {
     return styleFileName || fileName
   }
 
diff --git a/packages/teleport-component-generator/src/resolver/utils.ts b/packages/teleport-component-generator/src/resolver/utils.ts
index 9e969877..898f43d5 100644
--- a/packages/teleport-component-generator/src/resolver/utils.ts
+++ b/packages/teleport-component-generator/src/resolver/utils.ts
@@ -63,10 +63,18 @@ export const resolveNavlinks = (uidlNode: UIDLNode, routesDefinition: UIDLStateD
         (route) => route.value === transitionState
       )
 
-      if (transitionRoute && transitionRoute.meta && transitionRoute.meta.path) {
-        transitionAttribute.content = transitionRoute.meta.path
+      if (transitionState.startsWith('/')) {
+        // attribute was explicitly set as a custom navlink
+        return
+      }
+
+      if (transitionRoute && transitionRoute.pageOptions && transitionRoute.pageOptions.navLink) {
+        transitionAttribute.content = transitionRoute.pageOptions.navLink
       } else {
-        console.warn(`No path was defined for router state: '${transitionState}'.`)
+        transitionAttribute.content = `/${transitionState}`
+        console.warn(
+          `No navlink was defined for router state: '${transitionState}'. Falling back to '${transitionAttribute.content}'`
+        )
       }
     }
   })
diff --git a/packages/teleport-plugin-angular-module/src/index.ts b/packages/teleport-plugin-angular-module/src/index.ts
index fd5c456a..da92f94a 100644
--- a/packages/teleport-plugin-angular-module/src/index.ts
+++ b/packages/teleport-plugin-angular-module/src/index.ts
@@ -72,14 +72,14 @@ export const createPlugin: ComponentPluginFactory<AngularRoutingConfig> = (confi
           dependencies.ComponentsModule = constructRouteForComponentsModule('../..')
           dependencies.CommonModule = ANGULAR_COMMON_MODULE
           const componentName = `${uidl.name}Component`
-          dependencies[componentName] = constructLocalDependency(uidl.meta.fileName)
+          dependencies[componentName] = constructLocalDependency(uidl.outputOptions.fileName)
 
           routesAST = createPageRouteAST(componentName)
           ngModuleAST = createPageModuleModuleDecorator(componentName)
-          moduleDecoratorAST = createExportModuleAST(uidl.meta.moduleName)
+          moduleDecoratorAST = createExportModuleAST(uidl.outputOptions.moduleName)
 
           // Acording to widely followed convention module should have .module in its name
-          uidl.meta.fileName = `${uidl.meta.fileName}.module`
+          uidl.outputOptions.fileName = `${uidl.outputOptions.fileName}.module`
         }
         break
       case 'component':
diff --git a/packages/teleport-plugin-angular-module/src/utils.ts b/packages/teleport-plugin-angular-module/src/utils.ts
index 2e9c9980..d4fcf223 100644
--- a/packages/teleport-plugin-angular-module/src/utils.ts
+++ b/packages/teleport-plugin-angular-module/src/utils.ts
@@ -1,7 +1,7 @@
 import * as types from '@babel/types'
 import { UIDLDependency } from '@teleporthq/teleport-types'
 import { dashCaseToUpperCamelCase } from '@teleporthq/teleport-shared/dist/cjs/utils/string-utils'
-import { extractPageMetadata } from '@teleporthq/teleport-shared/dist/cjs/utils/uidl-utils'
+import { extractPageOptions } from '@teleporthq/teleport-shared/dist/cjs/utils/uidl-utils'
 
 export const createPageModuleModuleDecorator = (componentName: string, t = types) => {
   const imports: types.ObjectProperty = t.objectProperty(
@@ -103,13 +103,13 @@ export const createRoutesAST = (routes, stateDefinitions, t = types) => {
   // TODO: Need to generate type annotation for routes variable, currently babel throwing erro
   const routesObject = routes.map((conditionalNode) => {
     const { value: routeKey } = conditionalNode.content
-    const { fileName: pageName, path } = extractPageMetadata(
+    const { fileName: pageName, navLink } = extractPageOptions(
       stateDefinitions.route,
       routeKey.toString()
     )
 
     return t.objectExpression([
-      t.objectProperty(t.identifier('path'), t.stringLiteral(path.slice(1, path.length))),
+      t.objectProperty(t.identifier('path'), t.stringLiteral(navLink.replace('/', ''))),
       t.objectProperty(
         t.identifier('loadChildren'),
         t.stringLiteral(
diff --git a/packages/teleport-plugin-css-modules/src/index.ts b/packages/teleport-plugin-css-modules/src/index.ts
index 5f9cf6a1..5a9d0744 100644
--- a/packages/teleport-plugin-css-modules/src/index.ts
+++ b/packages/teleport-plugin-css-modules/src/index.ts
@@ -106,31 +106,37 @@ export const createPlugin: ComponentPluginFactory<CSSModulesConfig> = (config =
     })
 
     /**
-     * If no classes were added, we don't need to import anything or to alter any
-     * code
+     * If no classes were added, we don't need to import anything or to alter any code
      */
     if (!cssClasses.length) {
       return structure
     }
 
-    // create-react-app expects css modules to be in files named [filename].module.css
-    const cssFileType = moduleExtension ? FILE_TYPE.CSSMODULE : FILE_TYPE.CSS
-
     /**
      * Setup an import statement for the styles
      * The name of the file is either in the meta of the component generator
      * or we fallback to the name of the component
      */
-    const cssFileName = getStyleFileName(uidl)
+    let cssFileName = getStyleFileName(uidl)
+
+    /**
+     * In case the moduleExtension flag is passed, the file name should be in the form [fileName].module.css
+     */
+    if (moduleExtension) {
+      cssFileName = `${cssFileName}.module`
+      uidl.outputOptions = uidl.outputOptions || {}
+      uidl.outputOptions.styleFileName = cssFileName
+    }
+
     dependencies[styleObjectImportName] = {
       type: 'local',
-      path: `./${cssFileName}.${cssFileType}`,
+      path: `./${cssFileName}.${FILE_TYPE.CSS}`,
     }
 
     structure.chunks.push({
       name: styleChunkName,
       type: CHUNK_TYPE.STRING,
-      fileType: cssFileType,
+      fileType: FILE_TYPE.CSS,
       content: cssClasses.join('\n'),
       linkAfter: [],
     })
diff --git a/packages/teleport-plugin-react-app-routing/src/index.ts b/packages/teleport-plugin-react-app-routing/src/index.ts
index 6a4c81ee..0cc4d252 100644
--- a/packages/teleport-plugin-react-app-routing/src/index.ts
+++ b/packages/teleport-plugin-react-app-routing/src/index.ts
@@ -5,7 +5,7 @@ import {
   createDefaultExport,
 } from '@teleporthq/teleport-shared/dist/cjs/builders/ast-builders'
 import {
-  extractPageMetadata,
+  extractPageOptions,
   extractRoutes,
 } from '@teleporthq/teleport-shared/dist/cjs/utils/uidl-utils'
 import {
@@ -50,7 +50,7 @@ export const createPlugin: ComponentPluginFactory<AppRoutingComponentConfig> = (
     const routeJSXDefinitions = routes.map((conditionalNode) => {
       const { value: routeKey } = conditionalNode.content
 
-      const { fileName: pageName, componentName, path } = extractPageMetadata(
+      const { fileName: pageName, componentName, navLink } = extractPageOptions(
         stateDefinitions.route,
         routeKey.toString()
       )
@@ -72,7 +72,7 @@ export const createPlugin: ComponentPluginFactory<AppRoutingComponentConfig> = (
         path: `${pageDependencyPrefix}${pageName}${pageComponentSuffix}`,
       }
 
-      return constructRouteJSX(flavor, componentName, path)
+      return constructRouteJSX(flavor, componentName, navLink)
     })
 
     const rootRouterTag = createRouteRouterTag(flavor, routeJSXDefinitions)
diff --git a/packages/teleport-plugin-stencil-app-routing/src/index.ts b/packages/teleport-plugin-stencil-app-routing/src/index.ts
index 6301e22f..4d369825 100644
--- a/packages/teleport-plugin-stencil-app-routing/src/index.ts
+++ b/packages/teleport-plugin-stencil-app-routing/src/index.ts
@@ -8,7 +8,7 @@ import {
   DEFAULT_COMPONENT_CHUNK_NAME,
   DEFAULT_IMPORT_CHUNK_NAME,
 } from './constants'
-import { createClassDecleration } from './utils'
+import { createClassDeclaration } from './utils'
 
 interface StencilRouterConfig {
   componentDecoratorChunkName: string
@@ -48,7 +48,7 @@ export const createPlugin: ComponentPluginFactory<StencilRouterConfig> = (config
       linkAfter: [importChunkName],
     })
 
-    const classDeclarationAST = createClassDecleration(routes, routeDefinitions)
+    const classDeclarationAST = createClassDeclaration(routes, routeDefinitions)
 
     chunks.push({
       name: componentChunkName,
diff --git a/packages/teleport-plugin-stencil-app-routing/src/utils.ts b/packages/teleport-plugin-stencil-app-routing/src/utils.ts
index 35a25be6..c8bd836d 100644
--- a/packages/teleport-plugin-stencil-app-routing/src/utils.ts
+++ b/packages/teleport-plugin-stencil-app-routing/src/utils.ts
@@ -4,21 +4,26 @@ import {
   addChildJSXTag,
   addAttributeToJSXTag,
 } from '@teleporthq/teleport-shared/dist/cjs/utils/ast-jsx-utils'
-import { extractPageMetadata } from '@teleporthq/teleport-shared/dist/cjs/utils/uidl-utils'
+import { extractPageOptions } from '@teleporthq/teleport-shared/dist/cjs/utils/uidl-utils'
 import { camelCaseToDashCase } from '@teleporthq/teleport-shared/dist/cjs/utils/string-utils'
+import { UIDLStateDefinition, UIDLConditionalNode } from '@teleporthq/teleport-types'
 
-export const createClassDecleration = (routes, routeDefinitions, t = types) => {
+export const createClassDeclaration = (
+  routes: UIDLConditionalNode[],
+  routeDefinitions: UIDLStateDefinition,
+  t = types
+) => {
   const stencilRouterTag = createJSXTag('stencil-router')
   const stencilRouteSwitchTag = createJSXTag('stencil-route-switch')
   addChildJSXTag(stencilRouterTag, stencilRouteSwitchTag)
 
   routes.forEach((routeNode) => {
     const pageKey = routeNode.content.value.toString()
-    const { componentName, path } = extractPageMetadata(routeDefinitions, pageKey)
+    const { componentName, navLink } = extractPageOptions(routeDefinitions, pageKey)
 
     const stencilRouteTag = createJSXTag('stencil-route')
-    addAttributeToJSXTag(stencilRouteTag, 'url', path)
-    if (path === '/') {
+    addAttributeToJSXTag(stencilRouteTag, 'url', navLink)
+    if (navLink === '/') {
       addAttributeToJSXTag(stencilRouteTag, 'exact', true)
     }
     addAttributeToJSXTag(stencilRouteTag, 'component', `app-${camelCaseToDashCase(componentName)}`)
diff --git a/packages/teleport-plugin-vue-app-routing/src/index.ts b/packages/teleport-plugin-vue-app-routing/src/index.ts
index 9fcedaa6..acdee954 100644
--- a/packages/teleport-plugin-vue-app-routing/src/index.ts
+++ b/packages/teleport-plugin-vue-app-routing/src/index.ts
@@ -1,6 +1,6 @@
 import * as t from '@babel/types'
 import {
-  extractPageMetadata,
+  extractPageOptions,
   extractRoutes,
 } from '@teleporthq/teleport-shared/dist/cjs/utils/uidl-utils'
 import { ComponentPluginFactory, ComponentPlugin } from '@teleporthq/teleport-types'
@@ -56,7 +56,7 @@ export const createPlugin: ComponentPluginFactory<VueRouterConfig> = (config) =>
 
     const routesAST = routes.map((routeNode) => {
       const pageKey = routeNode.content.value.toString()
-      const { fileName, componentName, path } = extractPageMetadata(routeDefinitions, pageKey)
+      const { fileName, componentName, navLink } = extractPageOptions(routeDefinitions, pageKey)
 
       dependencies[componentName] = {
         type: 'local',
@@ -65,7 +65,7 @@ export const createPlugin: ComponentPluginFactory<VueRouterConfig> = (config) =>
 
       return t.objectExpression([
         t.objectProperty(t.identifier('name'), t.stringLiteral(pageKey)),
-        t.objectProperty(t.identifier('path'), t.stringLiteral(path)),
+        t.objectProperty(t.identifier('path'), t.stringLiteral(navLink)),
         t.objectProperty(t.identifier('component'), t.identifier(componentName)),
       ])
     })
diff --git a/packages/teleport-project-generator-next/src/index.ts b/packages/teleport-project-generator-next/src/index.ts
index 9f5de4d1..50539574 100644
--- a/packages/teleport-project-generator-next/src/index.ts
+++ b/packages/teleport-project-generator-next/src/index.ts
@@ -40,8 +40,7 @@ const createNextProjectGenerator = () => {
       generator: reactPageGenerator,
       path: ['pages'],
       options: {
-        usePathAsFileName: true,
-        convertDefaultToIndex: true,
+        useFileNameForNavigation: true,
       },
     },
     entry: {
diff --git a/packages/teleport-project-generator-nuxt/src/index.ts b/packages/teleport-project-generator-nuxt/src/index.ts
index 2e62331d..6a40cbed 100644
--- a/packages/teleport-project-generator-nuxt/src/index.ts
+++ b/packages/teleport-project-generator-nuxt/src/index.ts
@@ -28,8 +28,7 @@ const createNuxtProjectGenerator = () => {
       generator: vuePageGenerator,
       path: ['pages'],
       options: {
-        usePathAsFileName: true,
-        convertDefaultToIndex: true,
+        useFileNameForNavigation: true,
       },
     },
     entry: {
diff --git a/packages/teleport-project-generator/src/file-handlers.ts b/packages/teleport-project-generator/src/file-handlers.ts
index d199218d..9c4e2569 100644
--- a/packages/teleport-project-generator/src/file-handlers.ts
+++ b/packages/teleport-project-generator/src/file-handlers.ts
@@ -62,8 +62,8 @@ export const createComponentModule = async (uidl: ProjectUIDL, strategy: Project
     moduleComponents,
   }
 
-  root.meta = root.meta || {}
-  root.meta.fileName = 'components.module'
+  root.outputOptions = root.outputOptions || {}
+  root.outputOptions.fileName = 'components.module'
 
   const { files } = await moduleGenerator.generateComponent(root, options)
   return files[0]
@@ -74,9 +74,11 @@ export const createPageModule = async (
   strategy: ProjectStrategy,
   options: GeneratorOptions
 ) => {
-  pageUIDL.meta = pageUIDL.meta || {}
-  pageUIDL.meta.fileName = pageUIDL.meta.path[0]
-  pageUIDL.meta.moduleName = `${dashCaseToUpperCamelCase(pageUIDL.meta.path[0])}Module`
+  pageUIDL.outputOptions = pageUIDL.outputOptions || {}
+  pageUIDL.outputOptions.fileName = pageUIDL.outputOptions.folderPath[0]
+  pageUIDL.outputOptions.moduleName = `${dashCaseToUpperCamelCase(
+    pageUIDL.outputOptions.folderPath[0]
+  )}Module`
   return strategy.pages.moduleGenerator.generateComponent(pageUIDL, options)
 }
 
@@ -92,8 +94,8 @@ export const createRouterFile = async (root: ComponentUIDL, strategy: ProjectStr
     strategy,
   }
 
-  root.meta = root.meta || {}
-  root.meta.fileName = fileName || DEFAULT_ROUTER_FILE_NAME
+  root.outputOptions = root.outputOptions || {}
+  root.outputOptions.fileName = fileName || DEFAULT_ROUTER_FILE_NAME
 
   const { files } = await routerGenerator.generateComponent(root, options)
   return files[0]
diff --git a/packages/teleport-project-generator/src/index.ts b/packages/teleport-project-generator/src/index.ts
index 6184d964..e069c886 100644
--- a/packages/teleport-project-generator/src/index.ts
+++ b/packages/teleport-project-generator/src/index.ts
@@ -2,7 +2,7 @@ import {
   injectFilesToPath,
   resolveLocalDependencies,
   createPageUIDLs,
-  prepareComponentFilenamesAndPath,
+  prepareComponentOutputOptions,
 } from './utils'
 
 import {
@@ -137,8 +137,8 @@ export class ProjectGenerator {
     // Based on the routing roles, separate pages into distict UIDLs with their own file names and paths
     const pageUIDLs = createPageUIDLs(uidl, this.strategy)
 
-    // Set the filename and path for each component based on the strategy
-    prepareComponentFilenamesAndPath(components, this.strategy)
+    // Set the filename and folder path for each component based on the strategy
+    prepareComponentOutputOptions(components, this.strategy)
 
     // Set the local dependency paths based on the relative paths between files
     resolveLocalDependencies(pageUIDLs, components, this.strategy)
diff --git a/packages/teleport-project-generator/src/utils.ts b/packages/teleport-project-generator/src/utils.ts
index 59e82118..25e33d6e 100644
--- a/packages/teleport-project-generator/src/utils.ts
+++ b/packages/teleport-project-generator/src/utils.ts
@@ -3,7 +3,7 @@ import {
   getComponentFileName,
   getComponentPath,
   extractRoutes,
-  extractPageMetadata,
+  extractPageOptions,
 } from '@teleporthq/teleport-shared/dist/cjs/utils/uidl-utils'
 
 import {
@@ -32,16 +32,17 @@ const createPageUIDL = (
   const routeDefinition = uidl.root.stateDefinitions.route
   const pagesStrategyOptions = strategy.pages.options || {}
 
-  const { componentName, fileName } = extractPageMetadata(
+  const { componentName, fileName } = extractPageOptions(
     routeDefinition,
     pageName,
-    strategy.pages.options
+    pagesStrategyOptions.useFileNameForNavigation
   )
 
   // If the file name will not be used as the path (eg: next, nuxt)
   // And if the option to create each page in its folder is passed (eg: preact)
-  const createPathInOwnFile =
-    !pagesStrategyOptions.usePathAsFileName && pagesStrategyOptions.createFolderForEachComponent
+  const createFolderForEachComponent =
+    !pagesStrategyOptions.useFileNameForNavigation &&
+    pagesStrategyOptions.createFolderForEachComponent
 
   const {
     customComponentFileName,
@@ -49,19 +50,19 @@ const createPageUIDL = (
     customTemplateFileName,
   } = pagesStrategyOptions
 
-  const meta = createPathInOwnFile
+  const outputOptions = createFolderForEachComponent
     ? {
         fileName: (customComponentFileName && customComponentFileName(fileName)) || 'index',
         styleFileName: (customStyleFileName && customStyleFileName(fileName)) || 'style',
         templateFileName:
           (customTemplateFileName && customTemplateFileName(fileName)) || 'template',
-        path: [fileName],
+        folderPath: [fileName],
       }
     : {
         fileName,
         styleFileName: fileName,
         templateFileName: fileName,
-        path: [],
+        folderPath: [],
       }
 
   // Looking into the state definition, we take the seo information for the corresponding page
@@ -81,12 +82,12 @@ const createPageUIDL = (
   return {
     name: componentName,
     node: pageContent,
-    meta,
+    outputOptions,
     seo,
   }
 }
 
-export const prepareComponentFilenamesAndPath = (
+export const prepareComponentOutputOptions = (
   components: Record<string, ComponentUIDL>,
   strategy: ProjectStrategy
 ) => {
@@ -95,7 +96,7 @@ export const prepareComponentFilenamesAndPath = (
   Object.keys(components).forEach((componentKey) => {
     const component = components[componentKey]
     const fileName = getComponentFileName(component)
-    const path = getComponentPath(component)
+    const folderPath = getComponentPath(component)
 
     // If the component has its own folder, name is 'index' or an override from the strategy.
     // In this case, the file name (dash converted) is used as the folder name
@@ -106,19 +107,19 @@ export const prepareComponentFilenamesAndPath = (
         customTemplateFileName,
       } = componentStrategyOptions
 
-      component.meta = {
+      component.outputOptions = {
         fileName: (customComponentFileName && customComponentFileName(fileName)) || 'index',
         styleFileName: (customStyleFileName && customStyleFileName(fileName)) || 'style',
         templateFileName:
           (customTemplateFileName && customTemplateFileName(fileName)) || 'template',
-        path: [...path, fileName],
+        folderPath: [...folderPath, fileName],
       }
     } else {
-      component.meta = {
+      component.outputOptions = {
         fileName,
         styleFileName: fileName,
         templateFileName: fileName,
-        path,
+        folderPath,
       }
     }
   })
diff --git a/packages/teleport-shared/src/constants/index.ts b/packages/teleport-shared/src/constants/index.ts
index 571c9b24..e06ca84d 100644
--- a/packages/teleport-shared/src/constants/index.ts
+++ b/packages/teleport-shared/src/constants/index.ts
@@ -13,7 +13,6 @@ export const PRETTIER_CONFIG: PrettierFormatOptions = {
 }
 export const FILE_TYPE = {
   CSS: 'css',
-  CSSMODULE: 'module.css',
   HTML: 'html',
   JS: 'js',
   JSON: 'json',
diff --git a/packages/teleport-shared/src/utils/uidl-utils.ts b/packages/teleport-shared/src/utils/uidl-utils.ts
index 6eea0993..081cafa4 100644
--- a/packages/teleport-shared/src/utils/uidl-utils.ts
+++ b/packages/teleport-shared/src/utils/uidl-utils.ts
@@ -12,6 +12,7 @@ import {
   UIDLDynamicReference,
   UIDLRepeatContent,
   UIDLRepeatMeta,
+  UIDLPageOptions,
 } from '@teleporthq/teleport-types'
 
 /**
@@ -19,43 +20,40 @@ import {
  * In case of next/nuxt generators, the file names represent the urls of the pages
  * Also the root path needs to be represented by the index file
  */
-export const extractPageMetadata = (
+export const extractPageOptions = (
   routeDefinitions: UIDLStateDefinition,
   stateName: string,
-  options: {
-    usePathAsFileName?: boolean
-    convertDefaultToIndex?: boolean
-  } = {
-    usePathAsFileName: false,
-    convertDefaultToIndex: false,
-  }
-): { fileName: string; componentName: string; path: string } => {
+  useFileNameForNavigation = false
+): UIDLPageOptions => {
   const defaultPage = routeDefinitions.defaultValue
   const pageDefinitions = routeDefinitions.values || []
   const pageDefinition = pageDefinitions.find((stateDef) => stateDef.value === stateName)
 
-  // If not meta object is defined, the stateName is used
-  if (!pageDefinition || !pageDefinition.meta) {
-    return {
-      fileName: options.convertDefaultToIndex && stateName === defaultPage ? 'index' : stateName,
-      componentName: stateName,
-      path: '/' + stateName,
-    }
+  // If no meta object is defined, the stateName is used
+  const defaultPageMetadata: UIDLPageOptions = {
+    fileName: useFileNameForNavigation && stateName === defaultPage ? 'index' : stateName,
+    componentName: stateName,
+    navLink: '/' + stateName,
+  }
+
+  if (!pageDefinition || !pageDefinition.pageOptions) {
+    return defaultPageMetadata
   }
 
-  // In case the path is used as the url (next, nuxt), we override the filename from the path
-  const fileNameFromMeta = options.usePathAsFileName
-    ? pageDefinition.meta.path && pageDefinition.meta.path.slice(1)
-    : pageDefinition.meta.fileName
+  // The pageDefinition values have precedence, defaults are fallbacks
+  const pageMetadata = {
+    ...defaultPageMetadata,
+    ...pageDefinition.pageOptions,
+  }
 
-  return {
-    fileName:
-      options.convertDefaultToIndex && stateName === defaultPage
-        ? 'index'
-        : fileNameFromMeta || stateName,
-    componentName: pageDefinition.meta.componentName || stateName,
-    path: pageDefinition.meta.path || '/' + stateName,
+  // In case of next/nuxt, the path dictates the file name, so this is adjusted accordingly
+  // Also, the defaultPage has to be index, overriding any other value set
+  if (useFileNameForNavigation) {
+    const fileName = pageMetadata.navLink.replace('/', '')
+    pageMetadata.fileName = stateName === defaultPage ? 'index' : fileName
   }
+
+  return pageMetadata
 }
 
 export const extractRoutes = (rootComponent: ComponentUIDL) => {
@@ -69,7 +67,10 @@ export const extractRoutes = (rootComponent: ComponentUIDL) => {
 }
 
 export const getComponentFileName = (component: ComponentUIDL) => {
-  const name = component.meta && component.meta.fileName ? component.meta.fileName : component.name
+  const name =
+    component.outputOptions && component.outputOptions.fileName
+      ? component.outputOptions.fileName
+      : component.name
   return camelCaseToDashCase(name)
 }
 
@@ -77,8 +78,8 @@ export const getStyleFileName = (component: ComponentUIDL) => {
   const componentFileName = getComponentFileName(component)
 
   // If component meta style file name is not set, we default to the component file name
-  return component.meta && component.meta.styleFileName
-    ? component.meta.styleFileName
+  return component.outputOptions && component.outputOptions.styleFileName
+    ? component.outputOptions.styleFileName
     : componentFileName
 }
 
@@ -86,13 +87,13 @@ export const getTemplateFileName = (component: ComponentUIDL) => {
   const componentFileName = getComponentFileName(component)
 
   // If component meta style file name is not set, we default to the component file name
-  return component.meta && component.meta.templateFileName
-    ? component.meta.templateFileName
+  return component.outputOptions && component.outputOptions.templateFileName
+    ? component.outputOptions.templateFileName
     : componentFileName
 }
 
 export const getComponentPath = (component: ComponentUIDL) =>
-  component.meta ? component.meta.path : []
+  component.outputOptions ? component.outputOptions.folderPath : []
 
 export const getRepeatIteratorNameAndKey = (meta: UIDLRepeatMeta = {}) => {
   const iteratorName = meta.iteratorName || 'item'
diff --git a/packages/teleport-types/src/generators.ts b/packages/teleport-types/src/generators.ts
index b0e6d7c6..b57c656f 100644
--- a/packages/teleport-types/src/generators.ts
+++ b/packages/teleport-types/src/generators.ts
@@ -164,8 +164,7 @@ export interface ProjectStrategyComponentOptions {
 }
 
 export type ProjectStrategyPageOptions = ProjectStrategyComponentOptions & {
-  usePathAsFileName?: boolean
-  convertDefaultToIndex?: boolean
+  useFileNameForNavigation?: boolean
 }
 
 export interface EntryFileOptions {
@@ -219,7 +218,7 @@ export interface AssetsDefinition {
 export interface AssetInfo {
   data: string
   name: string
-  type: string
+  type?: string
 }
 
 export interface RemoteTemplateDefinition {
diff --git a/packages/teleport-types/src/uidl.ts b/packages/teleport-types/src/uidl.ts
index 68ef15f5..aaaa3ba9 100755
--- a/packages/teleport-types/src/uidl.ts
+++ b/packages/teleport-types/src/uidl.ts
@@ -32,16 +32,16 @@ export interface ComponentUIDL {
   $schema?: string
   name: string
   node: UIDLElementNode
-  meta?: {
+  propDefinitions?: Record<string, UIDLPropDefinition>
+  stateDefinitions?: Record<string, UIDLStateDefinition>
+  outputOptions?: {
     fileName?: string
     styleFileName?: string
     templateFileName?: string
     moduleName?: string
-    path?: string[]
+    folderPath?: string[]
   }
   seo?: UIDLComponentSEO
-  propDefinitions?: Record<string, UIDLPropDefinition>
-  stateDefinitions?: Record<string, UIDLStateDefinition>
 }
 
 export interface UIDLComponentSEO {
@@ -61,16 +61,15 @@ export interface UIDLStateDefinition {
   defaultValue: string | number | boolean | any[] | object | (() => void)
   values?: Array<{
     value: string | number | boolean
-    meta?: {
-      // Used when the StateDefinition is used as the router
-      componentName?: string
-      path?: string
-      fileName?: string
-    }
+    pageOptions?: UIDLPageOptions // Used when the StateDefinition is used as the router
     seo?: UIDLComponentSEO
-    transitions?: any
   }>
-  actions?: string[]
+}
+
+export interface UIDLPageOptions {
+  componentName?: string
+  navLink?: string
+  fileName?: string
 }
 
 export type ReferenceType = 'prop' | 'state' | 'local' | 'attr' | 'children'
diff --git a/packages/teleport-uidl-validator/src/uidl-schemas/component.json b/packages/teleport-uidl-validator/src/uidl-schemas/component.json
index 4c5c67ee..9b2b48cb 100644
--- a/packages/teleport-uidl-validator/src/uidl-schemas/component.json
+++ b/packages/teleport-uidl-validator/src/uidl-schemas/component.json
@@ -23,33 +23,11 @@
         "content": { "$ref": "#/definitions/elementNodeContent" }
       }
     },
-    "meta": {"type": "object"},
+    "outputOptions": {"type": "object"},
     "stateDefinitions":  { "$ref": "#/definitions/stateDefinitions" },
     "propDefinitions": { "$ref": "#/definitions/propDefinitions" }
   },
   "definitions": {
-    "dependency": {
-      "type": "object",
-      "additionalProperties": false,
-      "required": ["type"],
-      "properties": {
-        "type": {
-          "type": "string",
-          "enum": ["package", "local", "library"],
-          "examples": ["package", "local", "library"]
-        },
-        "path": {"type": "string"},
-        "version": {"type": "string", "default": "1.0.0"},
-        "meta": {
-          "type": "object", 
-          "additionalProperties": false,
-          "properties": {
-            "namedImport": {"type": "boolean", "default": false},
-            "originalName": {"type": "string"}
-          }
-        }
-      }
-    },
     "propDefinitions": {
       "type": "object",
       "patternProperties": {
@@ -103,13 +81,19 @@
                 "type": "object",
                 "properties": {
                   "value": {},
-                  "meta": { 
+                  "pageOptions": { 
                     "type": "object",
                     "additionalProperties": false,
                     "properties": {
                       "componentName": { "type": "string" },
-                      "path": { "type": "string" },
-                      "fileName": { "type": "string" },
+                      "navLink": { "type": "string" },
+                      "fileName": { "type": "string" }
+                    }
+                  },
+                  "seo": {
+                    "type": "object",
+                    "additionalProperties": false,
+                    "properties": {
                       "title": { "type": "string" },
                       "metaTags": {
                         "type": "array",
@@ -121,15 +105,27 @@
                             }
                           }
                         }
+                      },
+                      "assets": {
+                        "type": "array",
+                        "items": {
+                          "type": "object",
+                          "additionalProperties": false,
+                          "required": ["type"],
+                          "properties": {
+                            "type": { "type": "string", "enum": ["link", "script", "font", "icon", "style", "canonical"] },
+                            "path": { "type": "string" },
+                            "content": { "type": "string" },
+                            "meta": { "type": "object" }
+                          }
+                        }
                       }
                     }
-                  },
-                  "transitions": { "type": "object" }
+                  }
                 }
               }
             },
-            "defaultValue": {},
-            "actions": {"type": "array"}
+            "defaultValue": {}
           }
         }
       }
diff --git a/packages/teleport-uidl-validator/src/uidl-schemas/project.json b/packages/teleport-uidl-validator/src/uidl-schemas/project.json
index b81a442c..fabf1a28 100644
--- a/packages/teleport-uidl-validator/src/uidl-schemas/project.json
+++ b/packages/teleport-uidl-validator/src/uidl-schemas/project.json
@@ -71,7 +71,7 @@
             "additionalProperties": false,
             "required": ["type"],
             "properties": {
-              "type": { "type": "string", "enum": ["link", "script", "font", "icon", "style"] },
+              "type": { "type": "string", "enum": ["link", "script", "font", "icon", "style", "canonical"] },
               "path": { "type": "string" },
               "content": { "type": "string" },
               "meta": { "type": "object" }
diff --git a/packages/teleport-uidl-validator/src/validator/utils.ts b/packages/teleport-uidl-validator/src/validator/utils.ts
index e172826f..d079164d 100644
--- a/packages/teleport-uidl-validator/src/validator/utils.ts
+++ b/packages/teleport-uidl-validator/src/validator/utils.ts
@@ -191,12 +191,19 @@ export const checkRootComponent = (input: ProjectUIDL) => {
     }
   })
 
-  input.root.stateDefinitions.route.values
-    .filter((route) => !routeNaming.includes(route.value))
-    .forEach((route) => {
-      const errorMsg = `\nRoot Node contains routes that don't have corresponding components. Check the "value" for the following routes: ${route.meta.path}.`
-      errors.push(errorMsg)
-    })
+  const routeValues = input.root.stateDefinitions.route.values
+  if (!routeValues || routeValues.length <= 0) {
+    errors.push(
+      '\nThe `route` state definition from the root node does not contain the possible route values'
+    )
+  } else {
+    input.root.stateDefinitions.route.values
+      .filter((route) => !routeNaming.includes(route.value))
+      .forEach((route) => {
+        const errorMsg = `\nRoot Node contains a route that don't have a specified state: ${route.pageOptions.navLink}.`
+        errors.push(errorMsg)
+      })
+  }
 
   return errors
 }
diff --git a/tsconfig.json b/tsconfig.json
index 69490293..4ffc3ea7 100755
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -16,7 +16,7 @@
     "moduleResolution": "node",
     "typeRoots" : [
       "node_modules/@types"
-    ],
+    ]
   },
   "exclude": [
     "examples",


Test patch:
diff --git a/examples/test-samples/project-invalid-sample.json b/examples/test-samples/project-invalid-sample.json
index c4408ade..2dab06e1 100644
--- a/examples/test-samples/project-invalid-sample.json
+++ b/examples/test-samples/project-invalid-sample.json
@@ -83,22 +83,22 @@
         "values": [
           {
             "value": "index",
-            "meta": {
-              "path": "/",
+            "pageOptions": {
+              "navLink": "/",
               "componentName": "Home"
             }
           },
           {
             "value": "about",
-            "meta": {
-              "path": "/about",
+            "pageOptions": {
+              "navLink": "/about",
               "componentName": "About"
             }
           },
           {
             "value": "contact-us",
-            "meta": {
-              "path": "/here-we-are",
+            "pageOptions": {
+              "navLink": "/here-we-are",
               "componentName": "Us"
             }
           }
diff --git a/examples/test-samples/project-sample.json b/examples/test-samples/project-sample.json
index d301477e..8a869a1d 100644
--- a/examples/test-samples/project-sample.json
+++ b/examples/test-samples/project-sample.json
@@ -83,22 +83,22 @@
         "values": [
           {
             "value": "index",
-            "meta": {
-              "path": "/",
+            "pageOptions": {
+              "navLink": "/",
               "componentName": "Home"
             }
           },
           {
             "value": "about",
-            "meta": {
-              "path": "/about",
+            "pageOptions": {
+              "navLink": "/about",
               "componentName": "About"
             }
           },
           {
             "value": "contact-us",
-            "meta": {
-              "path": "/here-we-are",
+            "pageOptions": {
+              "navLink": "/here-we-are",
               "componentName": "Us"
             }
           }
diff --git a/packages/teleport-code-generator/__tests__/index.ts b/packages/teleport-code-generator/__tests__/index.ts
index 49cbfd0f..e947538c 100644
--- a/packages/teleport-code-generator/__tests__/index.ts
+++ b/packages/teleport-code-generator/__tests__/index.ts
@@ -43,7 +43,7 @@ afterAll(() => {
 
 describe('code generator', () => {
   const packer = createCodeGenerator()
-  it('should pack a react project', async () => {
+  it('creates a react project', async () => {
     const options: PackerOptions = {
       projectType: ProjectType.REACT,
       assets,
@@ -55,7 +55,7 @@ describe('code generator', () => {
     expect(success).toBeTruthy()
   })
 
-  it('should pack a next project', async () => {
+  it('creates a next project', async () => {
     const options: PackerOptions = {
       projectType: ProjectType.NEXT,
       assets,
@@ -67,7 +67,7 @@ describe('code generator', () => {
     expect(success).toBeTruthy()
   })
 
-  it('should pack a vue project', async () => {
+  it('creates a vue project', async () => {
     const options: PackerOptions = {
       projectType: ProjectType.VUE,
       assets,
@@ -79,7 +79,7 @@ describe('code generator', () => {
     expect(success).toBeTruthy()
   })
 
-  it('should pack a nuxt project', async () => {
+  it('creates a nuxt project', async () => {
     const options: PackerOptions = {
       projectType: ProjectType.NUXT,
       assets,
@@ -91,7 +91,7 @@ describe('code generator', () => {
     expect(success).toBeTruthy()
   })
 
-  it('should pack a nuxt project', async () => {
+  it('creates a stencil project', async () => {
     const options: PackerOptions = {
       projectType: ProjectType.STENCIL,
       assets,
@@ -103,7 +103,7 @@ describe('code generator', () => {
     expect(success).toBeTruthy()
   })
 
-  it('should pack a nuxt project', async () => {
+  it('creates a preact project', async () => {
     const options: PackerOptions = {
       projectType: ProjectType.PREACT,
       assets,
@@ -115,7 +115,7 @@ describe('code generator', () => {
     expect(success).toBeTruthy()
   })
 
-  it('should generate a react component', async () => {
+  it('creates a react component', async () => {
     const options: GenerateOptions = {
       componentType: ComponentType.REACT,
       styleVariation: ReactStyleVariation.CSSModules,
@@ -125,7 +125,7 @@ describe('code generator', () => {
     expect(files.length).toBe(2)
   })
 
-  it('should generate a preact component', async () => {
+  it('creates a preact component', async () => {
     const options: GenerateOptions = {
       componentType: ComponentType.PREACT,
       styleVariation: PreactStyleVariation.CSS,
@@ -135,7 +135,7 @@ describe('code generator', () => {
     expect(files.length).toBe(2)
   })
 
-  it('should generate a vue component', async () => {
+  it('creates a vue component', async () => {
     const options: GenerateOptions = {
       componentType: ComponentType.VUE,
     }
@@ -144,7 +144,7 @@ describe('code generator', () => {
     expect(files.length).toBe(1)
   })
 
-  it('should generate a stencil component', async () => {
+  it('creates a stencil component', async () => {
     const options: GenerateOptions = {
       componentType: ComponentType.STENCIL,
     }
@@ -153,7 +153,7 @@ describe('code generator', () => {
     expect(files.length).toBe(2)
   })
 
-  it('should generate a angular component', async () => {
+  it('creates an angular component', async () => {
     const options: GenerateOptions = {
       componentType: ComponentType.ANGULAR,
     }
@@ -162,11 +162,21 @@ describe('code generator', () => {
     expect(files.length).toBe(3)
   })
 
-  it('should resolve an element with react mapping', async () => {
+  it('resolves an element with the react mapping', async () => {
     const elementNode = element('container')
-    const result = await packer.resolveElement(elementNode)
+    const result = packer.resolveElement(elementNode)
     expect(result.elementType).toBe('div')
   })
+
+  it('throws an error when given an invalid ProjectType', async () => {
+    const result = packer.packProject(projectUIDL, { projectType: 'random' })
+    await expect(result).rejects.toThrow(Error)
+  })
+
+  it('throws an error when given an invalid Publisher', async () => {
+    const result = packer.packProject(projectUIDL, { publisher: 'random' })
+    await expect(result).rejects.toThrow(Error)
+  })
 })
 
 const removeDirectory = (dirPath: string): void => {
diff --git a/packages/teleport-component-generator-react/__tests__/integration/component-style.ts b/packages/teleport-component-generator-react/__tests__/integration/component-style.ts
index c703d05f..8f62abe7 100644
--- a/packages/teleport-component-generator-react/__tests__/integration/component-style.ts
+++ b/packages/teleport-component-generator-react/__tests__/integration/component-style.ts
@@ -67,7 +67,7 @@ describe('React Styles in Component', () => {
       const generator = createReactComponentGenerator(ReactStyleVariation.CSSModules)
       const result = await generator.generateComponent(ComponentWithStateReference)
       const jsFile = findFileByType(result.files, FILE_TYPE.JS)
-      const cssFile = findFileByType(result.files, FILE_TYPE.CSSMODULE)
+      const cssFile = findFileByType(result.files, FILE_TYPE.CSS)
 
       expect(jsFile).toBeDefined()
       expect(cssFile).toBeDefined()
@@ -321,7 +321,7 @@ describe('React Styles in Component', () => {
     it('should return code in an array of files', async () => {
       const result = await generator.generateComponent(ComponentWithValidStyle)
       const jsFile = findFileByType(result.files, FILE_TYPE.JS)
-      const cssFile = findFileByType(result.files, FILE_TYPE.CSSMODULE)
+      const cssFile = findFileByType(result.files, FILE_TYPE.CSS)
 
       expect(jsFile).toBeDefined()
       expect(cssFile).toBeDefined()
diff --git a/packages/teleport-component-generator/__tests__/resolver/utils.ts b/packages/teleport-component-generator/__tests__/resolver/utils.ts
index bc2f6a0f..48cc5d1e 100644
--- a/packages/teleport-component-generator/__tests__/resolver/utils.ts
+++ b/packages/teleport-component-generator/__tests__/resolver/utils.ts
@@ -237,8 +237,8 @@ describe('resolveNavlinks', () => {
     values: [
       {
         value: 'home-link',
-        meta: {
-          path: '/home',
+        pageOptions: {
+          navLink: '/home',
         },
       },
     ],
@@ -255,6 +255,17 @@ describe('resolveNavlinks', () => {
     expect(navlink.content.attrs.transitionTo.content).toBe('/home')
   })
 
+  it('does not change an attribute which starts with /', () => {
+    const navlink = elementNode('navlink', {
+      transitionTo: staticNode('/home-link'),
+    })
+
+    const uidlNode = elementNode('container', {}, [elementNode('div', {}, [navlink])])
+
+    resolveNavlinks(uidlNode, routeDef)
+    expect(navlink.content.attrs.transitionTo.content).toBe('/home-link')
+  })
+
   it('throws an error for dynamic attributes', () => {
     const navlink = elementNode('navlink', {
       transitionTo: dynamicNode('prop', 'path'),
@@ -274,8 +285,10 @@ describe('resolveNavlinks', () => {
 
     resolveNavlinks(navlink, routeDef)
 
-    expect(warn).toHaveBeenCalledWith("No path was defined for router state: 'non-existing-state'.")
-    expect(navlink.content.attrs.transitionTo.content).toBe('non-existing-state')
+    expect(warn).toHaveBeenCalledWith(
+      "No navlink was defined for router state: 'non-existing-state'. Falling back to '/non-existing-state'"
+    )
+    expect(navlink.content.attrs.transitionTo.content).toBe('/non-existing-state')
   })
 })
 
diff --git a/packages/teleport-plugin-angular-module/__tests__/index.ts b/packages/teleport-plugin-angular-module/__tests__/index.ts
index 9cd4ed30..372cf163 100644
--- a/packages/teleport-plugin-angular-module/__tests__/index.ts
+++ b/packages/teleport-plugin-angular-module/__tests__/index.ts
@@ -47,10 +47,10 @@ describe('Testing the functionality for Angular Modules', () => {
 
   it('Should add Angular dependencies for page module', async () => {
     const componentUIDL = projectUIDL.components.OneComponent as ComponentUIDL
-    componentUIDL.meta = componentUIDL.meta || {}
+    componentUIDL.outputOptions = componentUIDL.outputOptions || {}
     componentUIDL.name = 'One'
-    componentUIDL.meta.fileName = 'OneComponent'
-    componentUIDL.meta.moduleName = 'OneComponentModule'
+    componentUIDL.outputOptions.fileName = 'OneComponent'
+    componentUIDL.outputOptions.moduleName = 'OneComponentModule'
 
     const componentPlugin = createPlugin({ moduleType: 'page' })
     const structure: ComponentStructure = {
diff --git a/packages/teleport-plugin-css-modules/__tests__/index.ts b/packages/teleport-plugin-css-modules/__tests__/index.ts
index 70a61cd5..4736cac4 100644
--- a/packages/teleport-plugin-css-modules/__tests__/index.ts
+++ b/packages/teleport-plugin-css-modules/__tests__/index.ts
@@ -98,15 +98,17 @@ describe('plugin-css-modules', () => {
     expect(classNameAttr.value.expression.name).toBe("styles['list-container']")
   })
 
-  it('generates a string chunk of type CSSMODULE', async () => {
+  it('generates a string chunk of type CSS', async () => {
     const plugin = createPlugin({ moduleExtension: true })
     const structure = setupPluginStructure('list-container')
-    const { chunks } = await plugin(structure)
+    const { chunks, dependencies } = await plugin(structure)
 
     expect(chunks.length).toBe(2)
     expect(chunks[1].type).toBe('string')
-    expect(chunks[1].fileType).toBe(FILE_TYPE.CSSMODULE)
+    expect(chunks[1].fileType).toBe(FILE_TYPE.CSS)
     expect(chunks[1].content).toContain('height: 100px;')
+    expect(structure.uidl.outputOptions.styleFileName).toContain('.module')
+    expect(dependencies.styles.path).toContain('.module.css')
   })
 
   it('inlines dynamic style and does not generate a new chunk if no static styles are present', async () => {
diff --git a/packages/teleport-project-generator-angular/__tests__/end2end/index.ts b/packages/teleport-project-generator-angular/__tests__/end2end/index.ts
index 64bc78cb..02cad3b7 100644
--- a/packages/teleport-project-generator-angular/__tests__/end2end/index.ts
+++ b/packages/teleport-project-generator-angular/__tests__/end2end/index.ts
@@ -7,7 +7,7 @@ import template from './template-definition.json'
 import { createAngularProjectGenerator } from '../../src'
 import { FILE_TYPE } from '@teleporthq/teleport-shared/dist/cjs/constants'
 
-describe('React Next Project Generator', () => {
+describe('Angular Project Generator', () => {
   const generator = createAngularProjectGenerator()
 
   it('runs without crashing', async () => {
diff --git a/packages/teleport-project-generator/__tests__/index.ts b/packages/teleport-project-generator/__tests__/index.ts
index 55671cf0..51deff3c 100644
--- a/packages/teleport-project-generator/__tests__/index.ts
+++ b/packages/teleport-project-generator/__tests__/index.ts
@@ -57,7 +57,7 @@ describe('Generic Project Generator', () => {
 
       const routerUIDL = {
         ...uidl.root,
-        meta: {
+        outputOptions: {
           fileName: 'index',
         },
       }
@@ -104,7 +104,7 @@ describe('Generic Project Generator', () => {
     it('calls the generators according to the strategy', async () => {
       await generator.generateProject(projectUIDL)
 
-      const uidl = projectUIDL as ProjectUIDL
+      const uidl = (projectUIDL as unknown) as ProjectUIDL
 
       // This adds the local dependencies on the UIDL, so we can proper assert below
       resolveLocalDependencies([], uidl.components, strategy)
@@ -135,7 +135,7 @@ describe('Generic Project Generator', () => {
 
       const routerUIDL = {
         ...uidl.root,
-        meta: {
+        outputOptions: {
           fileName: strategy.router.fileName,
         },
       }
@@ -166,7 +166,7 @@ describe('Generic Project Generator', () => {
     it('calls the generators according to the strategy', async () => {
       const result = await generator.generateProject(projectUIDL)
 
-      const uidl = projectUIDL as ProjectUIDL
+      const uidl = (projectUIDL as unknown) as ProjectUIDL
 
       // This adds the local dependencies on the UIDL, so we can proper assert below
       resolveLocalDependencies([], uidl.components, strategy)
@@ -186,7 +186,7 @@ describe('Generic Project Generator', () => {
 
       const routerUIDL = {
         ...uidl.root,
-        meta: {
+        outputOptions: {
           fileName: 'index',
         },
       }
@@ -242,34 +242,32 @@ describe('Generic Project Generator', () => {
       generator.updatePagesStrategy({
         options: {
           createFolderForEachComponent: true,
-          convertDefaultToIndex: false,
         },
       })
 
       const strategy = generator.getStrategy()
 
       expect(strategy.pages.options.createFolderForEachComponent).toBe(true)
-      expect(strategy.pages.options.convertDefaultToIndex).toBe(false)
     })
 
     it('overrides existing options', () => {
       const initialStrategy = createStrategyWithCommonGenerator()
       initialStrategy.pages.options = {
-        convertDefaultToIndex: true,
+        useFileNameForNavigation: true,
       }
       const generator = createProjectGenerator(initialStrategy)
 
       generator.updatePagesStrategy({
         options: {
           createFolderForEachComponent: true,
-          convertDefaultToIndex: false,
+          useFileNameForNavigation: false,
         },
       })
 
       const strategy = generator.getStrategy()
 
       expect(strategy.pages.options.createFolderForEachComponent).toBe(true)
-      expect(strategy.pages.options.convertDefaultToIndex).toBe(false)
+      expect(strategy.pages.options.useFileNameForNavigation).toBe(false)
     })
   })
 })
diff --git a/packages/teleport-publisher-codesandbox/__tests__/index.ts b/packages/teleport-publisher-codesandbox/__tests__/index.ts
new file mode 100644
index 00000000..ae30f328
--- /dev/null
+++ b/packages/teleport-publisher-codesandbox/__tests__/index.ts
@@ -0,0 +1,20 @@
+import { createCodesandboxPublisher } from '../src'
+import { createProjectFolder } from './mocks'
+
+describe('codesandbox publisher', () => {
+  it('creates a new instance of the publisher', () => {
+    const publisher = createCodesandboxPublisher()
+    expect(publisher.getProject).toBeDefined()
+    expect(publisher.setProject).toBeDefined()
+    expect(publisher.publish).toBeDefined()
+  })
+
+  it('should set project', () => {
+    const publisher = createCodesandboxPublisher()
+    const project = createProjectFolder()
+    publisher.setProject(project)
+
+    const publisherProject = JSON.stringify(publisher.getProject())
+    expect(publisherProject).toBe(JSON.stringify(project))
+  })
+})
diff --git a/packages/teleport-publisher-codesandbox/__tests__/mocks.ts b/packages/teleport-publisher-codesandbox/__tests__/mocks.ts
new file mode 100644
index 00000000..e2f70e23
--- /dev/null
+++ b/packages/teleport-publisher-codesandbox/__tests__/mocks.ts
@@ -0,0 +1,29 @@
+import { GeneratedFolder } from '@teleporthq/teleport-types'
+
+export const createProjectFolder = (): GeneratedFolder => {
+  return {
+    name: 'root',
+    files: [
+      {
+        content: '<asdasd>',
+        name: 'root-file',
+      },
+    ],
+    subFolders: [
+      {
+        name: 'src',
+        files: [
+          {
+            name: 'file-1',
+            content: 'asdasd-1',
+          },
+          {
+            name: 'file-2',
+            content: 'asdasd-2',
+          },
+        ],
+        subFolders: [],
+      },
+    ],
+  }
+}
diff --git a/packages/teleport-publisher-codesandbox/__tests__/utils.ts b/packages/teleport-publisher-codesandbox/__tests__/utils.ts
new file mode 100644
index 00000000..67e52359
--- /dev/null
+++ b/packages/teleport-publisher-codesandbox/__tests__/utils.ts
@@ -0,0 +1,12 @@
+import { convertToCodesandboxStructure } from '../src/utils'
+import { createProjectFolder } from './mocks'
+
+describe('convertToCodesandboxStructure', () => {
+  it('creates a flat structure based on the given folder', () => {
+    const folder = createProjectFolder()
+    const result = convertToCodesandboxStructure(folder)
+    expect(result['root-file'].content).toBe('<asdasd>')
+    expect(result['src/file-1'].content).toBe('asdasd-1')
+    expect(result['src/file-2'].content).toBe('asdasd-2')
+  })
+})
diff --git a/packages/teleport-publisher-github/__tests__/index.ts b/packages/teleport-publisher-github/__tests__/index.ts
index 87070199..d24b10ac 100644
--- a/packages/teleport-publisher-github/__tests__/index.ts
+++ b/packages/teleport-publisher-github/__tests__/index.ts
@@ -2,9 +2,7 @@ import { createGithubPublisher } from '../src'
 
 import { NO_PROJECT_UIDL, NO_AUTH, NO_REPO, NO_REPO_OWNER } from '../src/errors'
 
-// @ts-ignore
 import project from './project-files.json'
-// @ts-ignore
 import githubFiles from './github-files-content.json'
 import { generateProjectFiles } from '../src/utils'
 
diff --git a/packages/teleport-shared/__tests__/utils/uidl-utils.ts b/packages/teleport-shared/__tests__/utils/uidl-utils.ts
index ab2f3805..74cc7716 100644
--- a/packages/teleport-shared/__tests__/utils/uidl-utils.ts
+++ b/packages/teleport-shared/__tests__/utils/uidl-utils.ts
@@ -7,16 +7,17 @@ import {
   getComponentPath,
   getComponentFileName,
   getRepeatIteratorNameAndKey,
+  extractPageOptions,
 } from '../../src/utils/uidl-utils'
-import { component, staticNode } from '../../src/builders/uidl-builders'
+import { component, staticNode, elementNode } from '../../src/builders/uidl-builders'
 import {
   UIDLStyleDefinitions,
   UIDLElementNode,
   UIDLConditionalNode,
   UIDLRepeatNode,
-  UIDLStaticValue,
   UIDLDynamicReference,
   UIDLSlotNode,
+  UIDLStateDefinition,
 } from '@teleporthq/teleport-types'
 
 // @ts-ignore
@@ -335,14 +336,14 @@ describe('traverses the UIDL and returns the first element node that is found',
 })
 
 describe('getComponentFileName', () => {
-  const testComponent = component('MyComponent', staticNode('random'))
+  const testComponent = component('MyComponent', elementNode('random'))
 
   it('returns the dashcase filename', () => {
     expect(getComponentFileName(testComponent)).toBe('my-component')
   })
 
   it('meta fileName overrides', () => {
-    testComponent.meta = {
+    testComponent.outputOptions = {
       fileName: 'my-custom-name',
     }
     expect(getComponentFileName(testComponent)).toBe('my-custom-name')
@@ -350,15 +351,15 @@ describe('getComponentFileName', () => {
 })
 
 describe('getComponentPath', () => {
-  const testComponent = component('MyComponent', staticNode('random'))
+  const testComponent = component('MyComponent', elementNode('random'))
 
   it('returns an empty array if no meta path is provided', () => {
     expect(getComponentPath(testComponent)).toHaveLength(0)
   })
 
   it('returns the input meta path', () => {
-    testComponent.meta = {
-      path: ['one', 'two'],
+    testComponent.outputOptions = {
+      folderPath: ['one', 'two'],
     }
 
     const path = getComponentPath(testComponent)
@@ -418,3 +419,69 @@ describe('getRepeatIteratorNameAndKey', () => {
     expect(iteratorKey).toBe('item.id')
   })
 })
+
+describe('extractPageOptions', () => {
+  const routeDefinitions: UIDLStateDefinition = {
+    type: 'string',
+    defaultValue: 'home',
+    values: [
+      {
+        value: 'home',
+        pageOptions: {
+          navLink: '/',
+        },
+      },
+      {
+        value: 'about',
+        pageOptions: {
+          navLink: '/about-us',
+          componentName: 'AboutUs',
+        },
+      },
+      {
+        value: 'contact-us',
+        pageOptions: {
+          navLink: '/team',
+        },
+      },
+      {
+        value: 'no-meta',
+      },
+    ],
+  }
+
+  it('uses the state for a non-declared page', () => {
+    const result = extractPageOptions(routeDefinitions, 'non-declared')
+    expect(result.navLink).toBe('/non-declared')
+    expect(result.fileName).toBe('non-declared')
+    expect(result.componentName).toBe('non-declared')
+  })
+
+  it('uses the state for a page without meta', () => {
+    const result = extractPageOptions(routeDefinitions, 'no-meta')
+    expect(result.navLink).toBe('/no-meta')
+    expect(result.fileName).toBe('no-meta')
+    expect(result.componentName).toBe('no-meta')
+  })
+
+  it('returns values from the meta with defaults from the state', () => {
+    const result = extractPageOptions(routeDefinitions, 'about')
+    expect(result.navLink).toBe('/about-us') // meta value
+    expect(result.fileName).toBe('about') // state value
+    expect(result.componentName).toBe('AboutUs') // meta value
+  })
+
+  it('converts the fileName to index', () => {
+    const result = extractPageOptions(routeDefinitions, 'home', true)
+    expect(result.navLink).toBe('/')
+    expect(result.fileName).toBe('index')
+    expect(result.componentName).toBe('home')
+  })
+
+  it('uses the path as the fileName', () => {
+    const result = extractPageOptions(routeDefinitions, 'about', true)
+    expect(result.navLink).toBe('/about-us')
+    expect(result.fileName).toBe('about-us')
+    expect(result.componentName).toBe('AboutUs')
+  })
+})
diff --git a/packages/teleport-uidl-validator/__tests__/validator/index.ts b/packages/teleport-uidl-validator/__tests__/validator/index.ts
index 572c2be4..49401b75 100644
--- a/packages/teleport-uidl-validator/__tests__/validator/index.ts
+++ b/packages/teleport-uidl-validator/__tests__/validator/index.ts
@@ -124,7 +124,7 @@ Index variable is used but the "useIndex" meta information is false.,
  - Path : should have required property 'name'. {"missingProperty":"name"},
  - Path .globals.settings: should NOT have additional properties. {"additionalProperty":"key"},
  - Path .globals.settings.language: should be string. Received number,
- - Path .globals.assets[1].type: should be equal to one of the allowed values. {"allowedValues":["link","script","font","icon","style"]}`
+ - Path .globals.assets[1].type: should be equal to one of the allowed values. {"allowedValues":["link","script","font","icon","style","canonical"]}`
       )
     })
   })
@@ -149,7 +149,7 @@ Index variable is used but the "useIndex" meta information is false.,
 The component "Navbars" is not defined in the UIDL's component section.,
 The following components have different name than their key: Navbar,OneComponent,
 Root Node contains elements of type "static". It should contain only elements of type "conditional",
-Root Node contains routes that don't have corresponding components. Check the "value" for the following routes: /about.`
+Root Node contains a route that don't have a specified state: /about.`
       )
     })
     it('returns error if route is missing from state definitions', () => {
diff --git a/packages/teleport-uidl-validator/__tests__/validator/old-project-invalid-sample.json b/packages/teleport-uidl-validator/__tests__/validator/old-project-invalid-sample.json
index c4408ade..2dab06e1 100644
--- a/packages/teleport-uidl-validator/__tests__/validator/old-project-invalid-sample.json
+++ b/packages/teleport-uidl-validator/__tests__/validator/old-project-invalid-sample.json
@@ -83,22 +83,22 @@
         "values": [
           {
             "value": "index",
-            "meta": {
-              "path": "/",
+            "pageOptions": {
+              "navLink": "/",
               "componentName": "Home"
             }
           },
           {
             "value": "about",
-            "meta": {
-              "path": "/about",
+            "pageOptions": {
+              "navLink": "/about",
               "componentName": "About"
             }
           },
           {
             "value": "contact-us",
-            "meta": {
-              "path": "/here-we-are",
+            "pageOptions": {
+              "navLink": "/here-we-are",
               "componentName": "Us"
             }
           }
diff --git a/packages/teleport-uidl-validator/__tests__/validator/project-invalid-sample-no-route.json b/packages/teleport-uidl-validator/__tests__/validator/project-invalid-sample-no-route.json
index 0651959c..39340942 100644
--- a/packages/teleport-uidl-validator/__tests__/validator/project-invalid-sample-no-route.json
+++ b/packages/teleport-uidl-validator/__tests__/validator/project-invalid-sample-no-route.json
@@ -18,22 +18,22 @@
         "values": [
           {
             "value": "index",
-            "meta": {
-              "path": "/",
+            "pageOptions": {
+              "navLink": "/",
               "componentName": "Home"
             }
           },
           {
             "value": "abouts",
-            "meta": {
-              "path": "/about",
+            "pageOptions": {
+              "navLink": "/about",
               "componentName": "About"
             }
           },
           {
             "value": "contact-us",
-            "meta": {
-              "path": "/here-we-are",
+            "pageOptions": {
+              "navLink": "/here-we-are",
               "componentName": "Us"
             }
           }
diff --git a/packages/teleport-uidl-validator/__tests__/validator/project-invalid-sample.json b/packages/teleport-uidl-validator/__tests__/validator/project-invalid-sample.json
index b4cd0cb9..f4dbfcd4 100644
--- a/packages/teleport-uidl-validator/__tests__/validator/project-invalid-sample.json
+++ b/packages/teleport-uidl-validator/__tests__/validator/project-invalid-sample.json
@@ -18,22 +18,22 @@
         "values": [
           {
             "value": "index",
-            "meta": {
-              "path": "/",
+            "pageOptions": {
+              "navLink": "/",
               "componentName": "Home"
             }
           },
           {
             "value": "abouts",
-            "meta": {
-              "path": "/about",
+            "pageOptions": {
+              "navLink": "/about",
               "componentName": "About"
             }
           },
           {
             "value": "contact-us",
-            "meta": {
-              "path": "/here-we-are",
+            "pageOptions": {
+              "navLink": "/here-we-are",
               "componentName": "Us"
             }
           }
diff --git a/packages/teleport-uidl-validator/__tests__/validator/project-sample.json b/packages/teleport-uidl-validator/__tests__/validator/project-sample.json
index 6b771afd..249dcec9 100644
--- a/packages/teleport-uidl-validator/__tests__/validator/project-sample.json
+++ b/packages/teleport-uidl-validator/__tests__/validator/project-sample.json
@@ -18,22 +18,22 @@
         "values": [
           {
             "value": "index",
-            "meta": {
-              "path": "/",
+            "pageOptions": {
+              "navLink": "/",
               "componentName": "Home"
             }
           },
           {
             "value": "about",
-            "meta": {
-              "path": "/about",
+            "pageOptions": {
+              "navLink": "/about",
               "componentName": "About"
             }
           },
           {
             "value": "contact-us",
-            "meta": {
-              "path": "/here-we-are",
+            "pageOptions": {
+              "navLink": "/here-we-are",
               "componentName": "Us"
             }
           }