text:
<repo_name>NicholasMing/mall<file_sep>/generator/src/main/java/com/ming/templates/serviceImpl.ftl
package ${packageName};

import ${entityPackageName}.${ClassName};
import ${mapperPackageName}.${ClassName}Mapper;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;

@Service
public class ${ClassName}${classLastName} implements ${ClassName}Service{
	@Autowired
	private ${ClassName}Mapper ${ClassName?uncap_first}Mapper;

	public ${ClassName} select${ClassName}ById(Long ${PrimaryKey?uncap_first}){
		return ${ClassName?uncap_first}Mapper.select${ClassName}ById(${PrimaryKey?uncap_first});
	}

	public List<${ClassName}> select${ClassName}List(){
		return ${ClassName?uncap_first}Mapper.select${ClassName}List();
	}

	public int deleteBy${PrimaryKey}(Long ${PrimaryKey?uncap_first}){
		return ${ClassName?uncap_first}Mapper.deleteBy${PrimaryKey?cap_first}(${PrimaryKey?uncap_first});
	}

	public int save${ClassName}(${ClassName} ${ClassName?uncap_first}){
		return ${ClassName?uncap_first}Mapper.save${ClassName}(${ClassName?uncap_first});
	}

	public int update${ClassName}By${PrimaryKey}(${ClassName} ${ClassName?uncap_first}){
		return ${ClassName?uncap_first}Mapper.update${ClassName}By${PrimaryKey}(${ClassName?uncap_first});
	}

	public ${ClassName} selectByCondition(${ClassName} ${ClassName?uncap_first}){
		return ${ClassName?uncap_first}Mapper.selectByCondition(${ClassName?uncap_first});
	}
}<file_sep>/generator/src/main/java/com/ming/util/StringUtil.java
package com.ming.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtil {
    public static final char UNDERLINE = '_';

    /**
     * 下划线格式字符串转换为驼峰格式字符串,首字母大写
     *
     * @param param
     */
    public static String underlineToCamel(String param, boolean isUp) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        StringBuilder sb = new StringBuilder(param);

        Matcher mc = Pattern.compile("_").matcher(param);
        int i = 0;
        while (mc.find()) {
            int position = mc.end() - (i++);
            sb.replace(position - 1, position + 1, sb.substring(position, position + 1).toUpperCase());
        }
        param = sb.toString();
        if (isUp) param = param.substring(0, 1).toUpperCase() + param.substring(1);
        return param;
    }
}
<file_sep>/generator/src/main/java/com/ming/templates/entity.ftl
package ${packageName};
<#list columnList as list>
    <#if list.dataType=='timestamp' >
import java.util.Date;
    </#if>
</#list>

public class ${ClassName} {
    <#list columnList as list>
    private <#if list.dataType=='int' >Integer <#elseif list.dataType='timestamp'>Date <#else>String </#if>${list.columnName};//${list.comment}
    </#list>

    <#list columnList as list>
    public <#if list.dataType=='int' >Integer <#elseif list.dataType='timestamp'>Date <#else>String </#if> get${list.columnName?cap_first}() {
    return ${list.columnName};
    }

    public void set${list.columnName?cap_first}(<#if list.dataType=='int' >Integer <#elseif list.dataType='timestamp'>Date <#else>String </#if> ${list.columnName}) {
    this.${list.columnName} = ${list.columnName};
    }

</#list>
}
<file_sep>/mall-web/src/main/webapp/index.jsp
<% request.setAttribute("base",request.getContextPath());%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>

    <title>粉丝</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

    <link rel="stylesheet" href="${base}/css/dpl-min.css" type="text/css"/>
    <link rel="stylesheet" href="${base}/css/bui-min.css" type="text/css"/>
    <link rel="stylesheet" href="${base}/css/main.css" type="text/css"/>

手机商城

                    jianlaifu

退出

微信

<file_sep>/generator/src/main/java/com/ming/templates/service.ftl
package ${packageName};

import ${entityPackageName}.${ClassName};

import java.util.List;

public interface ${ClassName}${classLastName} {

	${ClassName} select${ClassName}ById(Long ${PrimaryKey?uncap_first});

	List<${ClassName}> select${ClassName}List();

	int deleteBy${PrimaryKey}(Long ${PrimaryKey?uncap_first});

	int save${ClassName}(${ClassName} ${ClassName?uncap_first});

	int update${ClassName}By${PrimaryKey}(${ClassName} ${ClassName?uncap_first});

	${ClassName} selectByCondition(${ClassName} ${ClassName?uncap_first});
}<file_sep>/generator/src/main/java/com/ming/templates/mapper.ftl
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="${packageName}.${ClassName}${classLastName}" >
    <resultMap id="BaseResultMap" type="${entityPackageName}.${ClassName}" >
<#list columnList as list>
    <#if primaryKey==list.nativeColumnName>
    <id column="${list.nativeColumnName}" property="${list.columnName}" jdbcType="${list.jdbcType!}"/>
    <#else>
    <result column="${list.nativeColumnName}" property="${list.columnName}" jdbcType="${list.jdbcType!}"/>
</#if>
</#list>
    </resultMap>
    <sql id="Base_Column_List" >
            <#list columnList as list>
                <#if list_has_next>${list.nativeColumnName},<#else>${list.nativeColumnName}</#if>
            </#list>
    </sql>
    <select id="select${ClassName}ById" resultMap="BaseResultMap" parameterType="java.lang.Long" >
        select
        <include refid="Base_Column_List" />
        from ${tableName}
        where ${primaryKey}=${"#"}{${PrimaryKey?uncap_first},jdbcType=INTEGER}
    </select>

    <select id="select${ClassName}List" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from ${tableName}
    </select>

    <delete id="deleteBy${PrimaryKey}" parameterType="java.lang.Long">
        delete from ${tableName}
        where ${primaryKey} =${"#"}{${PrimaryKey?uncap_first},jdbcType=INTEGER}
    </delete>

    <insert id="save${ClassName}" parameterType="${entityPackageName}.${ClassName}">

        insert into ${tableName}
        <trim prefix="(" suffix=")" suffixOverrides="," >
            <#list columnList as list>
            <if test="${list.columnName} != null" >
               ${list.nativeColumnName},
            </if>
            </#list>
        </trim>
        values
        <trim prefix="(" suffix=")" suffixOverrides="," >
    <#list columnList as list>
    <if test="${list.columnName} != null" >
        ${"#"}{${list.columnName},jdbcType=${list.jdbcType!}},
    </if>
        </#list>
        </trim>
    </insert>

    <update id="update${ClassName}By${PrimaryKey}" parameterType="${entityPackageName}.${ClassName}" >
        update ${tableName}
        <set >
        <#list columnList as list>
            <#if primaryKey!=list.nativeColumnName>
        <if test="${list.columnName} != null" >
         ${list.nativeColumnName} = ${"#"}{${list.columnName},jdbcType=${list.jdbcType!}},
        </if>
            </#if>
        </#list>
        </set>
        where ${primaryKey} =${"#"}{${PrimaryKey?uncap_first},jdbcType=INTEGER}
    </update>

    <select id="selectByCondition" parameterType="${entityPackageName}.${ClassName}" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from ${tableName}
        <where>
            <trim prefix="(" suffix=")" suffixOverrides="," >
            <#list columnList as list>
                <if test="${list.columnName} != null" >
                ${list.nativeColumnName} = ${"#"}{${list.columnName},jdbcType=${list.jdbcType!}},
                </if>
            </#list>
            </trim>
        </where>
    </select>
</mapper><file_sep>/mall-web/src/main/resources/properties/config.properties
validation_query=SELECT 1
data_source_url=jdbc:mysql://127.0.0.1/store?autoReconnect=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
data_source_username=root
data_source_password=<PASSWORD>
<file_sep>/generator/src/main/java/com/ming/util/DbUtil.java
package com.ming.util;

import com.ming.entity.Table;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class DbUtil {
    /**
     * 数据库连接
     */
    public static Connection getCon() throws Exception {

        String driverName = "com.mysql.jdbc.Driver";

        String dbURL = PropertiesUtil.getConfig("db_url");

        String username = PropertiesUtil.getConfig("db_username");

        String password = PropertiesUtil.getConfig("db_password");

        Connection dbConn;

        Class.forName(driverName);

        dbConn = DriverManager.getConnection(dbURL, username, password);
        return dbConn;

    }

    /**
     * 加载字段
     */
    public static List getTableColumnList() {
        List
 columnList = new ArrayList<>();
        try {
            Connection con = DbUtil.getCon();
            String sql = "select COLUMN_NAME as columnName,DATA_TYPE as dataType,column_comment as comment from information_schema.columns where TABLE_NAME=? and table_schema=?";
            PreparedStatement pstm = con.prepareStatement(sql);
            pstm.setString(1, PropertiesUtil.getConfig("tableName"));
            pstm.setString(2, PropertiesUtil.getConfig("dataBaseName"));
            ResultSet rs = pstm.executeQuery();

            while (rs.next()) {
                String columnName = rs.getString("columnName");
                String dataType = rs.getString("dataType");
                String comment = rs.getString("comment");
                columnList.add(new Table(columnName, dataType, comment));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return columnList;
    }
    /**
     * 主键id
     */
    public static String primaryKey() {
        String primarKey = "";
        try {
            Connection con = DbUtil.getCon();
            String sql = "select COLUMN_NAME as columnName from information_schema.columns where TABLE_NAME=? and table_schema=? and column_key='PRI'";
            PreparedStatement pstm = con.prepareStatement(sql);
            pstm.setString(1, PropertiesUtil.getConfig("tableName"));
            pstm.setString(2, PropertiesUtil.getConfig("dataBaseName"));
            ResultSet rs = pstm.executeQuery();
            if (rs.next()) {
                primarKey = rs.getString("columnName");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return primarKey;
    }
}
<file_sep>/generator/src/main/java/com/ming/service/Main.java
package com.ming.service;

/**
 * Created by Nicholas on 2017/1/16.
 */
public class Main {
    public static void main(String[] args) {
        Generator generator = new Generator();
        generator.createFile("gen");
    }
}
<file_sep>/generator/src/main/java/com/ming/service/DataModel.java
package com.ming.service;

import com.ming.util.DbUtil;
import com.ming.util.PropertiesUtil;
import com.ming.util.StringUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Nicholas on 2017/1/18.
 */
public class DataModel {
    public static Map<String, Object> getDataModel(String module, List columnList) {
        Map<String, Object> model = new HashMap<>();

        model.put("templateName", PropertiesUtil.getConfig(module + ".templateName"));
        model.put("packageName", PropertiesUtil.getConfig(module + ".packageName"));
        model.put("extName", PropertiesUtil.getConfig(module + ".extName"));

        String extName = PropertiesUtil.getConfig(module + ".extName");
        String classLastName = extName.substring(0, extName.indexOf("."));
        model.put("classLastName", classLastName);

        model.put("tableName", PropertiesUtil.getConfig("tableName"));
        model.put("className", PropertiesUtil.getConfig("tableName").replace(PropertiesUtil.getConfig("prefix"), ""));
        model.put("ClassName", StringUtil.underlineToCamel(PropertiesUtil.getConfig("tableName").replace(PropertiesUtil.getConfig("prefix"), ""), true));
        model.put("primaryKey", DbUtil.primaryKey());
        model.put("PrimaryKey", StringUtil.underlineToCamel(DbUtil.primaryKey(), true));
        model.put("columnList", columnList);
        model.put("entityPackageName", PropertiesUtil.getConfig("entity.packageName"));
        model.put("mapperPackageName", PropertiesUtil.getConfig("mapper.packageName"));
        return model;
    }
}
<file_sep>/generator/src/main/java/com/ming/service/Generator.java
package com.ming.service;

import com.ming.util.DbUtil;
import com.ming.util.FreeMarkerUtil;
import com.ming.util.PropertiesUtil;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by Nicholas on 2017/1/21.
 */
public class Generator {
    public void createFile(String propertiesName) {
        //加载配置文件
        PropertiesUtil.getProperties(propertiesName);

        //从数据库中获取表字段
        List columnList = DbUtil.getTableColumnList();

        //需要生成的模块
        List<String> switchList = getSwitchList();

        System.out.println("=========================开始生成========================");
        for (String module : switchList) {
            //准备数据
            Map<String, Object> dataModel = DataModel.getDataModel(module, columnList);

            FreeMarkerUtil.processTemplate(dataModel, columnList);
        }
        System.out.println("=========================生成结束========================");
    }

    /**
     * 需要生成的代码
     *
     * @return
     */
    public List<String> getSwitchList() {
        List<String> switchList = new ArrayList();
        Map map = PropertiesUtil.getMap();
        Iterator keys = map.keySet().iterator();
        while (keys.hasNext()) {
            String key = (String) keys.next();
            if (key.contains("switch.") && map.get(key).equals("true")) {
                switchList.add(key.substring(7, key.length()));
            }
        }
        return switchList;
    }
}

branch_name: refs/heads/master

languages:
INI
Java Server Pages
Java
FreeMarker
Fluent

repo_language: INI

repo_name: NicholasMing/mall


text:
<file_sep>default_run_options[:pty] = true

set :application, 'storyboardr'

set :scm,         :git
set :repository,  '<EMAIL>:theworkinggroup/storyboardr.git'
set :deploy_via,  :remote_cache

set :user,      'deploy'
set :use_sudo,  false

set :keep_releases, 5

task :production do
  set :rails_env, 'production'
  set :domain,    'rails2.twg.ca'
  set :deploy_to, "/web/#{application}"
  set :branch,    'master'
  set :keep_releases, 5

  role :web,  domain
  role :app,  domain
  role :db,   domain, :primary => true
end

namespace :deploy do

  task :start do ; end
  task :stop  do ; end
  task :restart, :roles => :app, :except => { :no_release => true } do
    run "touch #{release_path}/tmp/restart.txt"
  end

end

after 'deploy', 'deploy:cleanup'<file_sep>%form.upload{:action => '/', :method => 'post', :enctype => 'multipart/form-data'}
  %input.file{:type => 'file', :name => 'file'}
  %input{:type => 'submit', :value => 'Upload CSV', :class => 'submit'}

- if @stories
  #stories
    - @stories.each_with_index do |story, index|
      .story{:class => story[:color]}
        .header
          .index
            = "##{index + 1}"
          .project
            = story[:project]
          .category
            = story[:category]
          .estimate
            = story[:estimate]
        .description
          = story[:description]
          <file_sep>!!!
%html
  %head
    %title StoryPrinter - Let's make some stories to work on
    %script{:type => 'text/javascript', :src => '/javascripts/jquery-1.4.2.min.js'}
    %script{:type => 'text/javascript', :src => '/javascripts/jquery-ui-1.8.2.custom.min.js'}
    %script{:type => 'text/javascript', :src => '/javascripts/application.js'}

    %style
      :sass
        body
          background: #000 url(/css_images/body_bg.jpg)
          font: 14px Arial, sans-serif
          padding: 0px
        h1
          text-align: center
          font: 80px/80px Arial, sans-serif
          color: #fff
          margin: 0px
          padding: 0px
          text-transform: uppercase
          text-shadow: 0px 0px 5px #000
          span
            color: #ff0000
            font-weight: bold
        .body_container
          margin: auto
          width: 750px
          padding: 25px
          background: #fff
          -moz-border-radius: 10px
          -moz-box-shadow: 0px 0px 5px #000
          form.upload
            text-align: right
            background: -moz-linear-gradient(top, #373737, #555)
            padding: 10px
            -moz-border-radius-topleft: 10px
            -moz-border-radius-topright: 10px
            margin-bottom: 5px
            input
              margin-right: 10px

          #stories
            position: relative
            .story
              margin-bottom: 5px
              position: relative
              border: 1px solid #e5e5e5
              .header
                overflow: hidden
                .index, .project, .category, .estimate
                  float: left
                  padding: 5px 10px
                  color: #fff
                  text-shadow: 0 1px 0 #000
                .index
                  padding: 5px
                  cursor: move
                .estimate
                  float: right
                  text-shadow: none
                  font-weight: bold
              .description
                padding: 20px 50px 20px 20px
                background-color: rgba(255, 255, 255, 0.3)

            $red:     #ed1c24
            $orange:  #f7941d
            $green:   #39b54a
            $teal:    #00a99d
            $blue:    #0054a6
            $purple:  #662d91
            $pink:    #ec008c
            $brown:   #603913

            .story.red
              background-color: rgba($red, 0.2)
              border-color: rgba($red, 0.2)
              .index
                background-color: rgba($red, 1)
              .project
                background-color: rgba($red, 0.8)
              .category
                background-color: rgba($red, 0.6)
              .estimate
                color: rgba($red, 1)
            .story.orange
              background-color: rgba($orange, 0.2)
              border-color: rgba($orange, 0.2)
              .index
                background-color: rgba($orange, 1)
              .project
                background-color: rgba($orange, 0.8)
              .category
                background-color: rgba($orange, 0.6)
              .estimate
                color: rgba($orange, 1)
            .story.green
              background-color: rgba($green, 0.2)
              border-color: rgba($green, 0.2)
              .index
                background-color: rgba($green, 1)
              .project
                background-color: rgba($green, 0.8)
              .category
                background-color: rgba($green, 0.6)
              .estimate
                color: rgba($green, 1)
            .story.teal
              background-color: rgba($teal, 0.2)
              border-color: rgba($teal, 0.2)
              .index
                background-color: rgba($teal, 1)
              .project
                background-color: rgba($teal, 0.8)
              .category
                background-color: rgba($teal, 0.6)
              .estimate
                color: rgba($teal, 1)
            .story.blue
              background-color: rgba($blue, 0.2)
              border-color: rgba($blue, 0.2)
              .index
                background-color: rgba($blue, 1)
              .project
                background-color: rgba($blue, 0.8)
              .category
                background-color: rgba($blue, 0.6)
              .estimate
                color: rgba($blue, 1)
            .story.purple
              background-color: rgba($purple, 0.2)
              border-color: rgba($purple, 0.2)
              .index
                background-color: rgba($purple, 1)
              .project
                background-color: rgba($purple, 0.8)
              .category
                background-color: rgba($purple, 0.6)
              .estimate
                color: rgba($purple, 1)
            .story.pink
              background-color: rgba($pink, 0.2)
              border-color: rgba($pink, 0.2)
              .index
                background-color: rgba($pink, 1)
              .project
                background-color: rgba($pink, 0.8)
              .category
                background-color: rgba($pink, 0.6)
              .estimate
                color: rgba($pink, 1)
            .story.brown
              background-color: rgba($brown, 0.2)
              border-color: rgba($brown, 0.2)
              .index
                background-color: rgba($brown, 1)
              .project
                background-color: rgba($brown, 0.8)
              .category
                background-color: rgba($brown, 0.6)
              .estimate
                color: rgba($brown, 1)

  %body
    %h1
      Storyprinter
    .body_container
      = yield<file_sep>require 'sinatra/base'
require 'haml'
require 'lib/extensions'
require 'fastercsv'
require 'pdfkit'

class Storyboardr < Sinatra::Base

  COLORS = %w( red orange green teal blue purple pink brown )

  get '/' do
    haml :index
  end

  post '/' do
    # reading from CSV file...
    file = params[:file][:tempfile]
    data = FasterCSV.parse(file)
    @stories = data.collect do |project, category, description, estimate|
      {
        :project      => project.to_s,
        :category     => category.to_s,
        :description  => description.to_s,
        :estimate     => estimate.to_s,
        :color        => nil
      }
    end

    # assigning colors
    index = 0
    @stories.collect{|s| s[:project].downcase }.uniq.each do |uniq_project|
      index = 0 if index == COLORS.size
      @stories.select{|s| s[:project].downcase == uniq_project}.each{|s| s[:color] = COLORS[index]}
      index += 1
    end

    haml :index

    # kit = PDFKit.new(haml(:index))

    # content_type 'application/pdf'
    # attachment 'stories.pdf'
    # kit.to_pdf
  end

end

languages: Ruby Haml

repo_language: Ruby

repo_name: theworkinggroup/storyboardr


text:
<repo_name>sonacy/react-js-convert-ts<file_sep>/src/extension.ts
import * as path from 'path'
import * as vscode from 'vscode'

import { convert } from './compile'

const warn = (message: string) => {
  vscode.window.showWarningMessage(message)
}

export function activate(context: vscode.ExtensionContext) {
  let disposable = vscode.commands.registerCommand(
    'extension.convertToTs',
    () => {
      if (vscode.window.activeTextEditor) {
        const file = vscode.window.activeTextEditor.document.fileName
        const ext = path.extname(file)
        if (ext.indexOf('.js') < 0) {
          warn('only support js file convert to ts!')
          return
        }
        const tsFile = convert(file)

        vscode.workspace.openTextDocument(tsFile).then(document => {
          vscode.window.showTextDocument(document)
        })
      } else {
        warn('You need to open the page you want to convert!')
      }
    }
  )

  context.subscriptions.push(disposable)
}

export function deactivate() {}
<file_sep>/src/transform/removeStaticPropTypes.ts
import {
  createNodeArray,
  isClassDeclaration,
  isGetAccessorDeclaration,
  isPropertyDeclaration,
  Node,
  SourceFile,
  TransformationContext,
  TypeChecker,
  updateClassDeclaration,
  visitEachChild,
} from 'typescript'

import { isPropTypesMember, isReactClassComponent, isStaticMember } from '../utils/react'

export const removeStaticPropTypes = (typeChecker: TypeChecker) => (
  context: TransformationContext
) => (sourceFile: SourceFile) => {
  const visitor = (node: Node) => {
    if (isClassDeclaration(node) && isReactClassComponent(node, typeChecker)) {
      return updateClassDeclaration(
        node,
        node.decorators,
        node.modifiers,
        node.name,
        node.typeParameters,
        createNodeArray(node.heritageClauses),
        node.members.filter(m => {
          if (
            isPropertyDeclaration(m) &&
            isStaticMember(m) &&
            isPropTypesMember(m)
          ) {
            // static and propTypes
            return false
          }

          if (
            isGetAccessorDeclaration(m) &&
            isStaticMember(m) &&
            isPropTypesMember(m)
          ) {
            // static and propTypes
            return false
          }

          return true
        })
      )
    }
    return node
  }

  return visitEachChild(sourceFile, visitor, context)
}
<file_sep>/src/transform/generateGenericPropAndState.ts
import {
  ClassDeclaration,
  ConstructorDeclaration,
  createInterfaceDeclaration,
  createKeywordTypeNode,
  createProperty,
  createTypeLiteralNode,
  createTypeReferenceNode,
  createUnionOrIntersectionTypeNode,
  forEachChild,
  GetAccessorDeclaration,
  isBinaryExpression,
  isCallExpression,
  isClassDeclaration,
  isExpressionStatement,
  isGetAccessorDeclaration,
  isIntersectionTypeNode,
  isMethodDeclaration,
  isObjectLiteralExpression,
  isPropertyAccessExpression,
  isPropertyDeclaration,
  isReturnStatement,
  isTypeLiteralNode,
  isUnionTypeNode,
  Node,
  NodeBuilderFlags,
  ObjectLiteralExpression,
  SourceFile,
  SyntaxKind,
  TypeChecker,
  TypeElement,
  TypeLiteralNode,
  TypeNode,
  updateClassDeclaration,
  updateExpressionWithTypeArguments,
  updateHeritageClause,
  updateSourceFileNode,
} from 'typescript'

import { buildInterfaceFromPropTypes } from '../utils/interface'
import {
  insertBefore,
  isPropTypesMember,
  isReactClassComponent,
  isStaticMember,
  removeItem,
  replaceItem,
} from '../utils/react'

const visitReactClassComponent = (
  cls: ClassDeclaration,
  sourceFile: SourceFile,
  typeChecker: TypeChecker
) => {
  const className = cls && cls.name && cls.name.getText(sourceFile)
  const propType = getPropTypeOfComponent(cls)
  const stateType = getStateTypeOfComponent(cls, typeChecker)

  const shouldMakePropType = propType.members.length > 0
  const shouldMakeStateType = !isStateTypeMemberEmpty(stateType)
  const propName = `I${className}Props`
  const stateName = `I${className}State`
  const propInterface = createInterfaceDeclaration(
    [],
    [],
    propName,
    [],
    [],
    propType.members
  )

  const stateMembers: TypeElement[] = []
  if (isUnionTypeNode(stateType) || isIntersectionTypeNode(stateType)) {
    stateType.types.forEach(t => {
      stateMembers.push(...(t as TypeLiteralNode).members)
    })
  }

  const stateInterface = createInterfaceDeclaration(
    [],
    [],
    stateName,
    [],
    [],
    stateMembers
  )

  const PropTypeRef = createTypeReferenceNode(propName, [])
  const StateTypeRef = createTypeReferenceNode(stateName, [])

  let newCls = getNewCls(
    cls,
    shouldMakePropType ? PropTypeRef : propType,
    shouldMakeStateType ? StateTypeRef : stateType
  )
  newCls = findConstructorThis(newCls)
  const allTypes = []

  if (shouldMakePropType) {
    allTypes.push(propInterface)
  }
  if (shouldMakeStateType) {
    allTypes.push(stateInterface)
  }

  let statements = insertBefore(sourceFile.statements, cls, allTypes)
  statements = replaceItem(statements, cls, newCls)

  return updateSourceFileNode(sourceFile, statements)
}

const getNewCls = (
  cls: ClassDeclaration,
  propType: TypeNode,
  stateType: TypeNode
) => {
  if (!cls.heritageClauses || !cls.heritageClauses.length) {
    return cls
  }

  const superComponent = cls.heritageClauses[0]

  const newSuperComponentType = replaceItem(
    superComponent.types,
    superComponent.types[0],
    updateExpressionWithTypeArguments(
      superComponent.types[0],
      [propType, stateType],
      superComponent.types[0].expression
    )
  )

  const newSuperComponent = replaceItem(
    cls.heritageClauses,
    superComponent,
    updateHeritageClause(superComponent, newSuperComponentType)
  )

  return updateClassDeclaration(
    cls,
    cls.decorators,
    cls.modifiers,
    cls.name,
    cls.typeParameters,
    newSuperComponent,
    cls.members
  )
}

const getStateTypeOfComponent = (
  cls: ClassDeclaration,
  typeChecker: TypeChecker
) => {
  const initState = getInitialStateFromClass(cls, typeChecker)
  const isVoid = initState.kind === SyntaxKind.VoidKeyword

  if (isVoid) {
    return createTypeLiteralNode([])
  }

  return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, [
    initState,
  ])
}

export const getStateFromSetState = (
  cls: ClassDeclaration,
  typeChecker: TypeChecker
) => {
  const typeNodes: TypeNode[] = []
  for (const member of cls.members) {
    if (member && isMethodDeclaration(member) && member.body) {
      findSetState(member.body)
    }
  }

  return typeNodes

  function findSetState(node: Node) {
    forEachChild(node, findSetState)
    if (
      isExpressionStatement(node) &&
      isCallExpression(node.expression) &&
      node.expression.expression.getText().match(/setState/)
    ) {
      const type = typeChecker.getTypeAtLocation(node.expression.arguments[0])
      typeNodes.push(
        typeChecker.typeToTypeNode(
          type,
          undefined,
          NodeBuilderFlags.NoTruncation
        )!
      )
    }
  }
}

const getInitialStateFromClass = (
  cls: ClassDeclaration,
  typeChecker: TypeChecker
): TypeNode => {
  // state = {}
  const stateMember = cls.members.find(
    m => isPropertyDeclaration(m) && m.name && m.name.getText() === 'state'
  )

  if (
    stateMember &&
    isPropertyDeclaration(stateMember) &&
    stateMember.initializer
  ) {
    const type = typeChecker.getTypeAtLocation(stateMember.initializer)
    return typeChecker.typeToTypeNode(
      type,
      undefined,
      NodeBuilderFlags.NoTruncation
    )!
  }

  // constructor
  const constructor = cls.members.find(
    m => m.kind === SyntaxKind.Constructor
  ) as ConstructorDeclaration | undefined
  if (constructor && constructor.body) {
    for (const statement of constructor.body.statements) {
      if (
        isExpressionStatement(statement) &&
        isBinaryExpression(statement.expression) &&
        statement.expression.left.getText() === 'this.state'
      ) {
        const right = statement.expression.right as ObjectLiteralExpression
        const type = typeChecker.getTypeAtLocation(right)
        return typeChecker.typeToTypeNode(
          type,
          undefined,
          NodeBuilderFlags.NoTruncation
        )!
      }
    }
  }

  return createKeywordTypeNode(SyntaxKind.VoidKeyword)
}

const findConstructorThis = (cls: ClassDeclaration) => {
  const constructor = cls.members.find(
    m => m.kind === SyntaxKind.Constructor
  ) as ConstructorDeclaration
  if (constructor && constructor.body) {
    const properties = []
    for (const statement of constructor.body.statements) {
      if (
        isExpressionStatement(statement) &&
        isBinaryExpression(statement.expression)
      ) {
        if (isPropertyAccessExpression(statement.expression.left)) {
          const name = statement.expression.left.name.getText()

          const property = createProperty(
            undefined,
            undefined,
            name,
            undefined,
            undefined,
            statement.expression.right
          )

          properties.push(property)
        }
      }
    }
    let members = insertBefore(cls.members, constructor, properties)
    members = removeItem(members, constructor)
    return updateClassDeclaration(
      cls,
      cls.decorators,
      cls.modifiers,
      cls.name,
      cls.typeParameters,
      cls.heritageClauses,
      members
    )
  }

  return cls
}

const getPropTypeOfComponent = (cls: ClassDeclaration) => {
  const staticPropTypes = cls.members.find(
    m => isPropertyDeclaration(m) && isStaticMember(m) && isPropTypesMember(m)
  )

  if (
    staticPropTypes !== undefined &&
    isPropertyDeclaration(staticPropTypes) &&
    staticPropTypes.initializer &&
    isObjectLiteralExpression(staticPropTypes.initializer)
  ) {
    return buildInterfaceFromPropTypes(staticPropTypes.initializer)
  }

  const staticGetterPropTypes = cls.members.find(
    m =>
      isGetAccessorDeclaration(m) && isStaticMember(m) && isPropTypesMember(m)
  )

  if (staticGetterPropTypes !== undefined) {
    const returnStatement = (staticGetterPropTypes as GetAccessorDeclaration).body!.statements.find(
      s => isReturnStatement(s)
    )

    if (
      returnStatement !== undefined &&
      isReturnStatement(returnStatement) &&
      returnStatement.expression &&
      isObjectLiteralExpression(returnStatement.expression)
    ) {
      return buildInterfaceFromPropTypes(returnStatement.expression)
    }
  }

  return createTypeLiteralNode([])
}

export const generateGenericPropAndState = (typeChecker: TypeChecker) => () => (
  sourceFile: SourceFile
) => {
  let newSourceFile = sourceFile
  for (const statement of sourceFile.statements) {
    if (
      isClassDeclaration(statement) &&
      isReactClassComponent(statement, typeChecker)
    ) {
      // react class component
      newSourceFile = visitReactClassComponent(
        statement,
        newSourceFile,
        typeChecker
      )
    }
  }

  return newSourceFile
}

function isStateTypeMemberEmpty(stateType: TypeNode): boolean {
  if (isTypeLiteralNode(stateType)) {
    return stateType.members.length === 0
  }

  if (!isIntersectionTypeNode(stateType)) {
    return true
  }

  return stateType.types.every(isStateTypeMemberEmpty)
}
<file_sep>/src/transform/removeImportPropTypes.ts
import { isImportDeclaration, isStringLiteral, SourceFile, updateSourceFileNode } from 'typescript'

export const removeImportPropTypes = () => () => (sourceFile: SourceFile) => {
  const statements = sourceFile.statements.filter(
    s =>
      !(
        isImportDeclaration(s) &&
        isStringLiteral(s.moduleSpecifier) &&
        s.moduleSpecifier.text === 'prop-types'
      )
  )
  return updateSourceFileNode(sourceFile, statements)
}
<file_sep>/src/compile.ts
import * as fs from 'fs'
import * as path from 'path'
import * as prettier from 'prettier'
import {
  CompilerOptions,
  createPrinter,
  createProgram,
  EmitHint,
  JsxEmit,
  ModuleKind,
  ScriptTarget,
  transform,
} from 'typescript'

import { rcDecoratorToHoc } from './transform/decoratorToHoc'
import { generateGenericPropAndState } from './transform/generateGenericPropAndState'
import { parseTsFunc } from './transform/parseTsFunc'
import { removeImportPropTypes } from './transform/removeImportPropTypes'
import { removeStaticPropTypes } from './transform/removeStaticPropTypes'

export const compile = (realPath: string, compileOptions: CompilerOptions) => {
  const program = createProgram([realPath], compileOptions)

  const sourceFiles = program
    .getSourceFiles()
    .filter(s => s.fileName === realPath)

  const typeChecker = program.getTypeChecker()

  const result = transform(sourceFiles, [
    generateGenericPropAndState(typeChecker),
    rcDecoratorToHoc(typeChecker),
    removeImportPropTypes(),
    removeStaticPropTypes(typeChecker),
    parseTsFunc(typeChecker),
  ])

  const printer = createPrinter()

  const printed = printer.printNode(
    EmitHint.SourceFile,
    result.transformed[0],
    sourceFiles[0]
  )

  const res = prettier.format(printed, {
    semi: true,
    singleQuote: true,
    trailingComma: 'es5',
    bracketSpacing: true,
    parser: 'typescript',
  })
  return res
}

export const convert = (realPath: string) => {
  const compileOptions: CompilerOptions = {
    target: ScriptTarget.ES2017,
    module: ModuleKind.ES2015,
    allowJs: true,
    jsx: JsxEmit.Preserve,
  }
  const res = compile(realPath, compileOptions)

  const name = realPath.slice(0, realPath.lastIndexOf('.'))
  const ext = path.extname(realPath).replace('j', 't')
  const retPath = `${name}${ext}`
  fs.writeFileSync(retPath, res, {
    encoding: 'utf8',
  })
  return retPath
}
<file_sep>/src/utils/react.ts
import { ClassDeclaration, ClassElement, isIdentifier, SyntaxKind, TypeChecker } from 'typescript'

// extends React.Component | Component | PureComponent | React.PureComponent
export const isReactClassComponent = (
  classes: ClassDeclaration,
  checker: TypeChecker
) => {
  if (!classes.heritageClauses) {
    return false
  }

  if (classes.heritageClauses.length !== 1) {
    return false
  }
  const firstHeritageClause = classes.heritageClauses[0]
  if (firstHeritageClause.token !== SyntaxKind.ExtendsKeyword) {
    return false
  }

  const firstArgumentTypes = firstHeritageClause.types[0]
  if (!firstArgumentTypes) {
    return false
  }

  const type = checker.getTypeAtLocation(firstArgumentTypes)
  let name = type && type.symbol && type.symbol.name
  if (!name) {
    name = firstArgumentTypes.expression.getText()
  }

  if (
    !/React\.Component|Component|PureComponent|React\.PureComponent/.test(name)
  ) {
    return false
  }

  return true
}

// static propTypes
export const isStaticMember = (member: ClassElement) => {
  if (!member.modifiers) {
    return false
  }
  const staticModifier = member.modifiers.find(modifier => {
    return modifier.kind === SyntaxKind.StaticKeyword
  })
  return staticModifier !== undefined
}

// static propTypes
export const isPropTypesMember = (member: ClassElement) => {
  try {
    const name =
      member.name !== undefined && isIdentifier(member.name)
        ? member.name.escapedText
        : null
    return name === 'propTypes'
  } catch (e) {
    return false
  }
}

export const insertAfter = <T>(
  collection: ArrayLike<T>,
  afterItem: T,
  newItem: T
) => {
  const arr = Array.from(collection)
  const index = arr.indexOf(afterItem) + 1
  return arr
    .slice(0, index)
    .concat(newItem)
    .concat(arr.slice(index))
}

export const insertBefore = <T>(
  collection: ArrayLike<T>,
  beforeItem: T,
  newItem: T | T[]
) => {
  const arr = Array.from(collection)
  const index = arr.indexOf(beforeItem)
  return arr
    .slice(0, index)
    .concat(newItem)
    .concat(arr.slice(index))
}

export const replaceItem = <T>(
  collection: ArrayLike<T>,
  item: T,
  newItem: T
) => {
  const arr = Array.from(collection)
  const index = arr.indexOf(item)
  return arr
    .slice(0, index)
    .concat(newItem)
    .concat(arr.slice(index + 1))
}

export const removeItem = <T>(collection: ArrayLike<T>, item: T) => {
  const arr = Array.from(collection)
  const index = arr.indexOf(item)
  return arr.slice(0, index).concat(arr.slice(index + 1))
}
<file_sep>/README.md
# react-js-convert-ts README

> simple way to tranlate react js classComponent to ts

## Features

- `Cmd+Shift+P`, convert js to ts
<file_sep>/src/utils/interface.ts
import {
  createArrayTypeNode,
  createFunctionTypeNode,
  createIndexSignature,
  createKeywordTypeNode,
  createLiteralTypeNode,
  createParameter,
  createPropertySignature,
  createToken,
  createTypeLiteralNode,
  createTypeReferenceNode,
  createUnionOrIntersectionTypeNode,
  createUnionTypeNode,
  Expression,
  isArrayLiteralExpression,
  isCallExpression,
  isNumericLiteral,
  isObjectLiteralExpression,
  isPropertyAccessExpression,
  isPropertyAssignment,
  isStringLiteral,
  NodeArray,
  NumericLiteral,
  ObjectLiteralExpression,
  PropertyAccessExpression,
  StringLiteral,
  SyntaxKind,
  TypeNode,
} from 'typescript'

const isPropTypeRequired = (node: Expression) => {
  if (!isPropertyAccessExpression(node)) {
    return false
  }
  const text = node.getText()
  return text.includes('.isRequired')
}

const getTypeFromReactPropTypeExpression = (node: Expression): TypeNode => {
  let result = null

  if (isPropertyAccessExpression(node)) {
    // array bool func number object string symbol node element any
    const text = node.getText()

    if (/.string/.test(text)) {
      result = createKeywordTypeNode(SyntaxKind.StringKeyword)
    } else if (/.any/.test(text)) {
      result = createKeywordTypeNode(SyntaxKind.AnyKeyword)
    } else if (/.array/.test(text)) {
      result = createArrayTypeNode(createKeywordTypeNode(SyntaxKind.AnyKeyword))
    } else if (/.bool/.test(text)) {
      result = createKeywordTypeNode(SyntaxKind.BooleanKeyword)
    } else if (/.number/.test(text)) {
      result = createKeywordTypeNode(SyntaxKind.NumberKeyword)
    } else if (/.object/.test(text)) {
      result = createKeywordTypeNode(SyntaxKind.ObjectKeyword)
    } else if (/.node/.test(text)) {
      result = createTypeReferenceNode('React.ReactNode', [])
    } else if (/.element/.test(text)) {
      result = createTypeReferenceNode('JSX.Element', [])
    } else if (/.func/.test(text)) {
      const arrayOfAny = createParameter(
        [],
        [],
        createToken(SyntaxKind.DotDotDotToken),
        'args',
        undefined,
        createArrayTypeNode(createKeywordTypeNode(SyntaxKind.AnyKeyword)),
        undefined
      )
      result = createFunctionTypeNode(
        [],
        [arrayOfAny],
        createKeywordTypeNode(SyntaxKind.AnyKeyword)
      )
    }
  } else if (isCallExpression(node)) {
    // oneOf oneOfType arrayOf objectOf shape
    const text = node.expression.getText()
    const args = node.arguments[0]
    if (/.oneOf/.test(text)) {
      if (isArrayLiteralExpression(args)) {
        if (
          args.elements.every(
            elm => isStringLiteral(elm) || isNumericLiteral(elm)
          )
        ) {
          result = createUnionTypeNode(
            (args.elements as NodeArray<StringLiteral | NumericLiteral>).map(
              elm => createLiteralTypeNode(elm)
            )
          )
        }
      }
    } else if (/.oneOfType/.test(text)) {
      if (isArrayLiteralExpression(args)) {
        result = createUnionOrIntersectionTypeNode(
          SyntaxKind.UnionType,
          args.elements.map(getTypeFromReactPropTypeExpression)
        )
      }
    } else if (/.arrayOf/.test(text)) {
      if (args) {
        result = createArrayTypeNode(getTypeFromReactPropTypeExpression(args))
      }
    } else if (/.objectOf/.test(text)) {
      if (args) {
        result = createTypeLiteralNode([
          createIndexSignature(
            undefined,
            undefined,
            [
              createParameter(
                undefined,
                undefined,
                undefined,
                'key',
                undefined,
                createKeywordTypeNode(SyntaxKind.StringKeyword)
              ),
            ],
            getTypeFromReactPropTypeExpression(args)
          ),
        ])
      }
    } else if (/.shapeOf/.test(text)) {
      if (isObjectLiteralExpression(args)) {
        return buildInterfaceFromPropTypes(args)
      }
    }
  }

  if (!result) {
    result = createKeywordTypeNode(SyntaxKind.AnyKeyword)
  }

  return result
}

export const buildInterfaceFromPropTypes = (exp: ObjectLiteralExpression) => {
  const members = exp.properties
    // only a: 1
    .filter(isPropertyAssignment)
    // no need for children
    .filter(p => p.name.getText() !== 'children')
    .map(property => {
      const name = property.name.getText()
      const initializer = property.initializer
      const isRequired = isPropTypeRequired(initializer)
      const typeExpression = isRequired
        ? (initializer as PropertyAccessExpression).expression
        : initializer
      const typeValue = getTypeFromReactPropTypeExpression(typeExpression)

      return createPropertySignature(
        [],
        name,
        isRequired ? undefined : createToken(SyntaxKind.QuestionToken),
        typeValue,
        undefined
      )
    })

  return createTypeLiteralNode(members)
}
<file_sep>/src/transform/parseTsFunc.ts
import {
  addSyntheticTrailingComment,
  isArrowFunction,
  isFunctionDeclaration,
  isVariableStatement,
  Node,
  NodeBuilderFlags,
  ParameterDeclaration,
  SourceFile,
  SyntaxKind,
  TransformationContext,
  TypeChecker,
  updateFunctionDeclaration,
  updateVariableDeclaration,
  updateVariableDeclarationList,
  updateVariableStatement,
  visitEachChild,
} from 'typescript'

export const parseTsFunc = (typeChecker: TypeChecker) => (
  context: TransformationContext
) => (sourceFile: SourceFile) => {
  const visitor = (node: Node) => {
    if (isFunctionDeclaration(node)) {
      const type = typeChecker.getTypeAtLocation(node)

      const nodeType = typeChecker.typeToTypeNode(type) as any
      const parameters = nodeType.parameters.map((p: ParameterDeclaration) => {
        return addSyntheticTrailingComment(
          p,
          SyntaxKind.SingleLineCommentTrivia,
          ' TODO:',
          true
        )
      })
      return updateFunctionDeclaration(
        node,
        node.decorators,
        node.modifiers,
        node.asteriskToken,
        node.name,
        node.typeParameters,
        parameters,
        node.type,
        node.body
      )
    }

    if (
      isVariableStatement(node) &&
      node.declarationList &&
      node.declarationList.declarations
    ) {
      const exp = node.declarationList.declarations[0]
      if (exp.initializer && isArrowFunction(exp.initializer)) {
        const aFunc = exp.initializer
        const type = typeChecker.getTypeAtLocation(exp)

        const nodeType = typeChecker.typeToTypeNode(
          type,
          undefined,
          NodeBuilderFlags.NoTruncation
        ) as any

        const newVD = updateVariableDeclaration(exp, exp.name, nodeType, aFunc)

        const newDList = updateVariableDeclarationList(node.declarationList, [
          newVD,
        ])
        return updateVariableStatement(node, node.modifiers, newDList)
      }
    }

    return node
  }

  return visitEachChild(sourceFile, visitor, context)
}
<file_sep>/src/transform/decoratorToHoc.ts
import {
  addSyntheticLeadingComment,
  ArrowFunction,
  Block,
  CallExpression,
  ClassDeclaration,
  createCall,
  createExportAssignment,
  createIdentifier,
  createIntersectionTypeNode,
  createTypeQueryNode,
  createTypeReferenceNode,
  createVariableDeclaration,
  createVariableDeclarationList,
  createVariableStatement,
  Decorator,
  Expression,
  isArrowFunction,
  isCallExpression,
  isClassDeclaration,
  isExportAssignment,
  isInterfaceDeclaration,
  isObjectLiteralExpression,
  isReturnStatement,
  NodeArray,
  NodeBuilderFlags,
  NodeFlags,
  SourceFile,
  Statement,
  SyntaxKind,
  TypeChecker,
  TypeReferenceNode,
  updateCall,
  updateClassDeclaration,
  updateExpressionWithTypeArguments,
  updateHeritageClause,
  updateInterfaceDeclaration,
  updateSourceFileNode,
} from 'typescript'

import { insertAfter, isReactClassComponent, removeItem, replaceItem } from '../utils/react'

export const rcDecoratorToHoc = (typeChecker: TypeChecker) => () => (
  sourceFile: SourceFile
) => {
  let statements = Array.from(sourceFile.statements)
  for (const statement of sourceFile.statements) {
    if (
      isClassDeclaration(statement) &&
      isReactClassComponent(statement, typeChecker) &&
      statement.decorators &&
      statement.decorators.length > 0
    ) {
      let decorators: NodeArray<Decorator> | undefined = statement.decorators
      let hocs: Expression[] = statement.decorators.map(d => d.expression)
      const res = generateFromConnect(hocs, statements, typeChecker, statement)
      hocs = res.hocs
      statements = res.statements
      const cls = res.newCls
      if (
        cls.modifiers &&
        cls.modifiers.find(m => m.kind === SyntaxKind.ExportKeyword) &&
        cls.modifiers.find(m => m.kind === SyntaxKind.DefaultKeyword) &&
        cls.name
      ) {
        // statement
        const exportNode = createExport(cls.name.getText(), hocs)
        statements = insertAfter(
          statements,
          statements[statements.length - 1],
          exportNode
        )
        decorators = undefined
      } else {
        const exportAssignment = sourceFile.statements.find(
          s =>
            isExportAssignment(s) && s.getText().includes(cls.name!.getText())
        )
        if (exportAssignment && isExportAssignment(exportAssignment)) {
          decorators = undefined
          if (isCallExpression(exportAssignment.expression)) {
            hocs = getHocFromExport(exportAssignment.expression, hocs)
          }
          const exportNode = createExport(cls.name!.getText(), hocs)
          statements = removeItem(statements, exportAssignment)
          statements = insertAfter(
            statements,
            statements[statements.length - 1],
            exportNode
          )
        }
      }

      const newcls = updateClassDeclaration(
        cls,
        decorators,
        undefined,
        cls.name,
        cls.typeParameters,
        cls.heritageClauses,
        cls.members
      )

      statements = replaceItem(statements, cls, newcls)
    }
  }

  return updateSourceFileNode(sourceFile, statements)
}

const getHocFromExport = (
  exp: CallExpression,
  hocs: Expression[]
): Expression[] => {
  hocs = [exp.expression, ...hocs]
  if (exp.arguments && exp.arguments.length > 0) {
    const argExp = exp.arguments[0]
    if (isCallExpression(argExp)) {
      return getHocFromExport(argExp, hocs)
    }
  }

  return hocs
}

const createExport = (name: string, hocs: Expression[]) => {
  let call: Expression = createIdentifier(name)
  for (const hoc of hocs) {
    call = createCall(hoc, undefined, [call])
  }
  return createExportAssignment(undefined, undefined, false, call)
}

const generateFromConnect = (
  hocs: Expression[],
  statements: Statement[],
  typeChecker: TypeChecker,
  cls: ClassDeclaration
) => {
  const connectIndex = hocs.findIndex(s => {
    if (isCallExpression(s)) {
      return s.expression.getText() === 'connect'
    }
    return false
  })

  let newCls = cls

  if (connectIndex > -1) {
    let connect = hocs[connectIndex] as CallExpression
    let args = connect.arguments
    const types: TypeReferenceNode[] = []

    const props: string[] = []
    const exp0 = args[0]
    const exp1 = args[1]

    if (exp0 && exp0.getText() !== 'null') {
      // mapStateToProps
      const mapStateToProps = createVarFunc(
        'mapStateToProps',
        exp0,
        typeChecker
      )

      if (isArrowFunction(exp0)) {
        props.push(...getPropStrFromConnect(exp0))
      }

      statements = insertAfter(
        statements,
        statements[statements.length - 1],
        mapStateToProps as any
      )

      hocs = replaceItem(
        hocs,
        connect,
        updateCall(
          connect,
          connect.expression,
          connect.typeArguments,
          replaceItem(args, args[0], createIdentifier('mapStateToProps'))
        )
      )

      types.push(
        createTypeReferenceNode(createIdentifier('ReturnType'), [
          createTypeQueryNode(createIdentifier('mapStateToProps')),
        ])
      )
    }

    if (exp1 && exp1.getText() !== 'null') {
      // mapDispatchToProps

      const mapDispatchToProps = createVarFunc(
        'mapDispatchToProps',
        exp1,
        typeChecker
      )

      if (isArrowFunction(exp1)) {
        props.push(...getPropStrFromConnect(exp1))
      }

      statements = insertAfter(
        statements,
        statements[statements.length - 1],
        mapDispatchToProps as any
      )
      connect = hocs[connectIndex] as CallExpression
      args = connect.arguments
      hocs = replaceItem(
        hocs,
        connect,
        updateCall(
          connect,
          connect.expression,
          connect.typeArguments,
          replaceItem(args, args[1], createIdentifier('mapDispatchToProps'))
        )
      )

      types.push(
        createTypeReferenceNode(createIdentifier('ReturnType'), [
          createTypeQueryNode(createIdentifier('mapDispatchToProps')),
        ])
      )
    }
    // remove duplicated props
    if (props.length > 0) {
      const className = cls.name!.getText()
      const propsInterface = statements.find(
        s =>
          isInterfaceDeclaration(s) &&
          s.name.escapedText === `I${className}Props`
      )
      if (propsInterface && isInterfaceDeclaration(propsInterface)) {
        const newMembers = propsInterface.members.filter((m: any) => {
          return !props.includes(m.name.escapedText)
        })
        const newPropsInterface = updateInterfaceDeclaration(
          propsInterface,
          propsInterface.decorators,
          propsInterface.modifiers,
          propsInterface.name,
          propsInterface.typeParameters,
          propsInterface.heritageClauses,
          newMembers
        )
        statements = replaceItem(statements, propsInterface, newPropsInterface)
      }
    }

    // set ReturnType
    if (types.length > 0) {
      const baseType = cls.heritageClauses![0].types![0].typeArguments![0]
      const type = createIntersectionTypeNode([baseType, ...types])

      const superComponent = cls.heritageClauses![0]

      const newSuperComponentType = replaceItem(
        superComponent.types,
        superComponent.types[0],
        updateExpressionWithTypeArguments(
          superComponent.types[0],
          [type, superComponent.types[0].typeArguments![1]],
          superComponent.types[0].expression
        )
      )

      const newSuperComponent = replaceItem(
        cls.heritageClauses!,
        superComponent,
        updateHeritageClause(superComponent, newSuperComponentType)
      )

      newCls = updateClassDeclaration(
        cls,
        cls.decorators,
        cls.modifiers,
        cls.name,
        cls.typeParameters,
        newSuperComponent,
        cls.members
      )

      statements = replaceItem(statements, cls, newCls)
    }
  }

  return { hocs, statements, newCls }
}

const createVarFunc = (
  name: string,
  exp: Expression,
  typeChecker: TypeChecker
) => {
  const node = typeChecker.getTypeAtLocation(exp)

  const declaration = createVariableDeclaration(
    name,
    typeChecker.typeToTypeNode(node, undefined, NodeBuilderFlags.NoTruncation),
    exp
  )
  const varS = createVariableStatement(
    undefined,
    createVariableDeclarationList([declaration], NodeFlags.Const)
  )
  return addSyntheticLeadingComment(
    varS,
    SyntaxKind.SingleLineCommentTrivia,
    ' TODO:'
  )
}

const getPropStrFromConnect = (exp: ArrowFunction) => {
  let properties: string[] = []
  const body = exp.body as Block

  // get from return
  if (body && body.statements) {
    body.statements.forEach(s => {
      if (
        isReturnStatement(s) &&
        s.expression &&
        isObjectLiteralExpression(s.expression)
      ) {
        properties = [
          ...properties,
          ...s.expression.properties.map(p => p.name!.getText()),
        ]
      }
    })
  }

  // get from direct
  const nextContainer = (exp as any).nextContainer
  if (nextContainer && nextContainer.properties) {
    properties = [
      ...properties,
      ...nextContainer.properties.map((a: any) => a.name.getText()),
    ]
  }

  return properties
}

languages: Markdown TypeScript

repo_language: Markdown

repo_name: sonacy/react-js-convert-ts


text:
<repo_name>jcmorais-araujo/exercicioMySQL<file_sep>/exercicio_postgre.sql
--create database secao03;

-- create table tipos_produto(
--	id SERIAL PRIMARY KEY,
--	descricao character varying(50) not null
-- );

-- create table produtos(
--	id SERIAL PRIMARY KEY,
--	descricao character varying(50) not null,
--	preco money not null,
--	id_tipo_produto int references tipos_produto(id) not null
-- );

create table pacientes(
id SERIAL PRIMARY KEY,
nome character varying(50) not null,
endereco character varying(50) not null,
bairro varchar(50) not null,
cidade varchar(50) not null,
estado char(2) not null,
cep varchar(9) not null,
data_nascimento date not null
);

CREATE TABLE professores(
id serial primary key,
telefone int not null,
nome varchar(50) not null
);

create table turmas(
id serial primary key,
capacidade int not null,
id_professor int references professores(id) not null
);<file_sep>/consultarEstados.sql
-- select * from estados;

-- select nome, sigla from estados;

-- SELECT sigla, nome AS 'Nome do Estado' from estados
-- WHERE regiao = 'Nordeste';

-- SELECT nome, regiao FROM estados WHERE populacao >= 10;

SELECT nome, regiao FROM estados WHERE populacao >= 10
ORDER BY populacao DESC;

<file_sep>/README.md
# exercicioMySQL
Exercícios para praticar os principais bancos de dados relacionais e não relacionais.
<file_sep>/excluirEstados.sql
-- DELETE  FROM `estados` WHERE sigla = 'MN';

-- select * from `estados`;

-- delete from `estados` WHERE id='1000';

select * from `estados`;<file_sep>/inserirCidades.sql
-- SELECT  * from estados
select * from cidades;
-- insert into cidades (nome, area, estado_id)
-- values('Campinas', 795, 29);<file_sep>/atualizarEstados.sql
-- UPDATE `estados`
-- SET nome = 'Maranhão'
-- WHERE sigla = 'MA';

-- SELECT nome from estados WHERE sigla = 'MA';

-- UPDATE estados
-- SET nome = 'Paraná', populacao = 11.32
-- WHERE sigla = 'PR';

SELECT nome, sigla, populacao FROM `estados`
WHERE sigla = 'PR';

branch_name: refs/heads/main

languages: Markdown SQL

repo_name: jcmorais-araujo/exercicioMySQL


text:
<file_sep>#!/usr/bin/python
#
# Script to add missing tables in the MS to conform with CASA standards and
# to make a fix in the MeasInfo in the spectral window table.
#
# Explanation by <NAME>:
#
# The LOFAR Measurement Set is written in a manner inconsistent with the
# MS definition v2.
# Two additional tables (STATE,PROCESSOR) need to be added because since
# release a check is done by CASA causing a failure.
#
# Explanation by <NAME>:
#
# The TableMesRefDesc problem is caused by a change in the coordinates
# by NRAO some time ago; a type Undefined has been added.
# Basically it means that an MS produced with a newer casacore
# is not readable by old CASA. I must confess I'm not exactly sure
# in which casacore release it was introduced.
# Later I've changed casacore such that it did not stumble anymore on
# this issue, so the upcoming CASA release should be fine.
# The CASA group had never merged back my change into their (old) casacore
# repository used for the previous CASA release.
#
# Authors: <NAME>, <NAME>
#
# Date: Aug 25, 2015
#

import os,sys
import pyrap.tables as pt

if (len(sys.argv) <= 1):
  print "This script will add a line in the STATE and PROCESSOR tables, fix an issue"
  print "in the SPECTRAL_WINDOW tabel that causes backward incompatibility with"
  print "Casacore versions < 2, and adapt the PROCESSOR table."
  print "To use it, please provide an MS name"
  exit(0)

msin=sys.argv[1]
msin_state=msin+"/STATE"
t_state=pt.table(msin_state,ack=False);
if t_state.nrows() == 0:
  try:
    pt.taql('insert into '+str(msin)+'/STATE set SIG=True, REF=False, CAL=0, LOAD=0, SUB_SCAN=0, OBS_MODE="", FLAG_ROW=False')
  except:
    print "Error in adding a row in the empty STATE table"
    exit(1)

msin_proc=msin+"/PROCESSOR"
t_proc=pt.table(msin_proc,ack=False);
if t_proc.nrows() == 0:
  try:
    pt.taql('insert into '+str(msin)+'/PROCESSOR set TYPE="CORRELATOR", SUB_TYPE="LOFAR-COBALT", TYPE_ID=-1, MODE_ID=-1, FLAG_ROW=False')
  except:
    print "Error in adding a row in the empty PROCESSOR table"
  exit(1)

msin_spw=msin+"/SPECTRAL_WINDOW"
try:
   t=pt.table(msin_spw, readonly=False,ack=False)
except:
   print "Cannot find or open",msin_spw
   exit(1)

for colnm in ['CHAN_FREQ','REF_FREQUENCY']:
  tc=t.col(colnm)
  meas=tc.getkeyword('MEASINFO')
  tc.putkeyword('MEASINFO-sav', meas) #save the original keywords
  TabRefTypes_indx=[] ; TabRefCodes_indx=[]
  for indx in range(len(meas)):
    if meas.items()[indx][0] == 'TabRefTypes': TabRefTypes_indx.append(indx)
    if meas.items()[indx][0] == 'TabRefCodes': TabRefCodes_indx.append(indx)
  if len(TabRefTypes_indx) != 0: meas.__delitem__('TabRefTypes') ; print 'Column %s: Deleted TabRefTypes' % colnm
  if len(TabRefCodes_indx) != 0: meas.__delitem__('TabRefCodes') ; print 'Column %s: Deleted TabRefCodes' % colnm
  tc.putkeyword('MEASINFO', meas)

try:
  t.flush()
  t.close()
except:
  print "Failed to update", msin
  exit(1)

if len(TabRefTypes_indx) != 0 or len(TabRefCodes_indx) != 0:
  print "Done fixing",msin
else:
  print "None fixing",msin
<file_sep># LOFAR-datarepair-tools
Repository that will contain repair tools for incorrect LOFAR data products

languages: Markdown Python

repo_name: lofar-astron/LOFAR-datarepair-tools


text:
<file_sep># About: School project - Web design
#### School: LERNIA Javascript developer, YHJUST16, HTML/CSS/JS and web standards, ( Stockholm, Sweden )
#### Purpose: Showcase one's ability with different technologies
##### Technologies: HTML5, CSS3, Javascript, JQuery, Bootstrap 3

###### Installation example:

git clone https://github.com/mow-github/course_htmlcssjs_finalproject.git

###### Instructions:

1. Open index.html

###### Requirements:
* Everything is implemented by me
* Code is explained where necessary
* It's a SPA ( Single Page Application )
* Bootstrap 3 is implemented and it has support for mobile -> desktop sizes ( col-xs-12 col-sm-6 col-md-4 on the main content )
* JQuery is used for at least two tasks + manipulates the DOM and CSS + animate / effects some objects
* Javascript is used for at least 1 DOM manipulation
* Added a custom.css with some styling
* Added a custom.js with some styling
* A styled form is implemented
* HTML5 semantics is implemented in combination with bootstrap 3 syntax
* Design and functionality goes hand in hand

###### Workflow:
* JS_Skolan.pdf (sv) inside the root folder

> _"Failure is just a symptom for success"_
[link to my homepage - bviking.se ](https://www.bviking.se)
[link to my LinkedIn profile ](https://www.linkedin.com/in/mats-wikmar)


text:
<repo_name>megbrown/chinook<file_sep>/README.md
# chinook

## 01-chinook-erd

### Introduction
Before we move on to shiny, new things we are going to ramp up the difficulty a bit, and introduce you to the [Chinook Database](https://chinookdatabase.codeplex.com/), a sample db that countless back end devs have used for practicing their SQL skills. As the site tells us, "The Chinook data model represents a digital media store, including tables for artists, albums, media tracks, invoices and customers."

### Instructions
1. Hit the link above to download and unzip the file.
1. Open up DB Broswer for SQLite again, click 'open database', and select from the Chinook Database labeled `Chinook_Sqlite.sqlite`.
1. Be a good, honest, upstanding citizen and don't click the link on the Chinook home page to view the data model or search Google images for "Chinook database". Do your best to glean the relationships from the tables and make a complete ERD before peeking to see if you've hit the mark.

## 02-sql_queries-chinook

### Requirements
Use the [Chinook Database](https://chinookdatabase.codeplex.com/) and the [DB Browser for SQLite](http://sqlitebrowser.org/) we downloaded in the ERD exercise.

For each of the following exercises, provide the appropriate query.

Keep your successful queries in a `chinook-queries.sql` file.

#### Other Resources
* http://www.sqlcourse.com/
* https://github.com/treehouse/cheatsheets/blob/master/sql_basics/cheatsheet.md
* [SQL Cheatsheet](https://zeroturnaround.com/wp-content/uploads/2016/06/RebelLabs-SQL-cheat-sheet.png)
* http://www.sqlite.org/lang_select.html
* https://www.sololearn.com/Course/SQL/
<file_sep>/02-sql_queries-chinook/chinook-queries.sql
-- 1. Provide a query showing Customers (just their full names, customer ID and
-- country) who are not in the US.

-- SELECT FirstName || ' ' || LastName AS Name, CustomerId, Country
-- FROM Customer
-- WHERE Country
-- NOT IN ('USA')

-- 2. Provide a query only showing the Customers from Brazil.

-- SELECT *
-- FROM Customer
-- WHERE Country
-- IS ('Brazil')

-- 3. Provide a query showing the Invoices of customers who are from Brazil.
-- The resultant table should show the customer's full name, Invoice ID, Date
-- of the invoice and billing country.

-- SELECT c.FirstName || ' ' || c.LastName AS Name, i.InvoiceId, i.InvoiceDate, i.BillingCountry
-- FROM Customer c, Invoice i
-- WHERE c.Country IS ('Brazil')
-- AND c.CustomerId IS i.CustomerId

-- 4. Provide a query showing only the Employees who are Sales Agents.

-- SELECT *
-- FROM Employee
-- WHERE Title IS ('Sales Support Agent')

-- 5. Provide a query showing a unique list of billing countries from the
-- Invoice table.

-- SELECT DISTINCT BillingCountry
-- FROM Invoice

-- 6. Provide a query that shows the invoices associated with each sales agent.
-- The resultant table should include the Sales Agent's full name.

-- SELECT e.FirstName || ' ' || e.LastName AS SalesAgentName, i.*
-- FROM Employee e, Invoice i, Customer c
-- WHERE e.EmployeeId IS c.SupportRepId
-- AND c.CustomerId IS i.CustomerId

-- 7. Provide a query that shows the Invoice Total, Customer name, Country and
-- Sale Agent name for all invoices and customers.

-- SELECT  c.FirstName || ' ' || c.LastName As CustomerName, i.Total, c.Country, e.FirstName || ' ' || e.LastName AS SalesAgentName
-- FROM Invoice i, Customer c, Employee e
-- WHERE i.CustomerId IS c.CustomerId
-- AND c.SupportRepId IS e.EmployeeId

-- 8. How many Invoices were there in 2009 and 2011? What are the respective
-- total sales for each of those years?

-- SELECT COUNT(*) AS InvoiceTotal
-- FROM Invoice
-- WHERE InvoiceDate LIKE ('2009%')
-- OR InvoiceDate LIKE ('2011%')

-- SELECT SUM(Total) AS Total2009
-- FROM Invoice
-- WHERE InvoiceDate LIKE ('2009%')

-- SELECT SUM(Total) AS Total2011
-- FROM Invoice
-- WHERE InvoiceDate LIKE ('2011%')

-- 9. Looking at the InvoiceLine table, provide a query that COUNTs the number
-- of line items for Invoice ID 37.

-- SELECT COUNT(InvoiceId) AS TOTAL37
-- FROM InvoiceLine
-- WHERE InvoiceId IS 37

-- 10. Looking at the InvoiceLine table, provide a query that COUNTs the number
-- of line items for each Invoice. HINT:
-- [GROUP BY](http://www.sqlite.org/lang_select.html#resultset)

-- SELECT InvoiceId, COUNT(InvoiceId) AS Total
-- FROM InvoiceLine
-- GROUP BY InvoiceID

-- 11. Provide a query that includes the track name with each invoice line item.

-- SELECT l.*, t.name
-- FROM Track t, InvoiceLine l
-- WHERE t.TrackId IS l.TrackId

-- 12. Provide a query that includes the purchased track name AND artist name
-- with each invoice line item.

-- SELECT l.*, t.name AS TrackName, r.Name AS ArtistName
-- FROM Track t, InvoiceLine l, Album a, Artist r
-- WHERE t.TrackId IS l.TrackId
-- AND t.AlbumId IS a.AlbumId
-- AND a.ArtistId IS r.ArtistId

-- 13. Provide a query that shows the # of invoices per country.
-- HINT: [GROUP BY](http://www.sqlite.org/lang_select.html#resultset)

-- SELECT BillingCountry, COUNT(*) AS TotalInvoice
-- FROM Invoice
-- GROUP BY BillingCountry

-- 14. Provide a query that shows the total number of tracks in each playlist.
-- The Playlist name should be included on the resultant table.

-- SELECT p.name, COUNT(l.PlaylistId) AS TotalTracks
-- FROM Playlist p, PlaylistTrack l
-- WHERE p.PlaylistId IS l.PlaylistId
-- GROUP BY p.PlaylistId

-- 15. Provide a query that shows all the Tracks, but displays no IDs. The
-- resultant table should include the Album name, Media type and Genre.

-- SELECT a.Title AS AlbumName, g.Name AS Genre,  m.Name As MediaType
-- FROM Album a, Genre g, MediaType m, Track t
-- WHERE a.AlbumId IS t.AlbumId
-- AND g.GenreId IS t.GenreId
-- AND m.MediaTypeId IS t.MediaTypeId

-- 16. Provide a query that shows all Invoices but includes the # of invoice
-- line items.

-- SELECT i.*, COUNT(l.InvoiceId) AS TotalInvoice
-- FROM Invoice i, InvoiceLine l
-- Where i.invoiceId IS l.invoiceId
-- GROUP BY l.InvoiceId

-- 17. Provide a query that shows total sales made by each sales agent.

-- SELECT e.EmployeeId AS SalesAgentId, round(SUM(i.Total), 2) AS TotalSales
-- FROM Employee e, Invoice i, Customer c
-- WHERE e.EmployeeId IS c.SupportRepId
-- AND c.CustomerId IS i.CustomerId
-- GROUP BY e.EmployeeId

-- 18. Which sales agent made the most in sales in 2009?

-- SELECT SalesAgentId, MAX(TotalSales)
-- FROM
-- (SELECT e.EmployeeId AS SalesAgentId, round(SUM(i.Total), 2) AS TotalSales
-- FROM Employee e, Invoice i, Customer c
-- WHERE e.EmployeeId IS c.SupportRepId
-- AND c.CustomerId IS i.CustomerId
-- AND i.InvoiceDate LIKE ('2009%')
-- GROUP BY e.EmployeeId)

-- 19. Which sales agent made the most in sales in 2010?

-- SELECT SalesAgentId, MAX(TotalSales)
-- FROM
-- (SELECT e.EmployeeId AS SalesAgentId, round(SUM(i.Total), 2) AS TotalSales
-- FROM Employee e, Invoice i, Customer c
-- WHERE e.EmployeeId IS c.SupportRepId
-- AND c.CustomerId IS i.CustomerId
-- AND i.InvoiceDate LIKE ('2010%')
-- GROUP BY e.EmployeeId)

-- 20. Which sales agent made the most in sales over all?

-- SELECT SalesAgentId, MAX(TotalSales)
-- FROM
-- (SELECT e.EmployeeId AS SalesAgentId, round(SUM(i.Total), 2) AS TotalSales
-- FROM Employee e, Invoice i, Customer c
-- WHERE e.EmployeeId IS c.SupportRepId
-- AND c.CustomerId IS i.CustomerId
-- GROUP BY e.EmployeeId)

-- 21. Provide a query that shows the # of customers assigned to each sales
-- agent.

-- SELECT COUNT(CustomerId) AS NumberCust, SupportRepId AS SalesAgent
-- FROM Customer
-- GROUP BY SalesAgent

-- 22. Provide a query that shows the total sales per country. Which country's
-- customers spent the most?

-- SELECT BillingCountry, SUM(Total) AS TotalSales
-- FROM Invoice
-- GROUP BY BillingCountry

-- SELECT BillingCountry, MAX(TotalSales) AS TotalSales
-- FROM
-- (SELECT BillingCountry, SUM(Total) AS TotalSales
-- FROM Invoice
-- GROUP BY BillingCountry)

-- 23. Provide a query that shows the most purchased track of 2013.

-- SELECT t.Name, COUNT(l.TrackId) AS TrackTotal, i.InvoiceDate
-- FROM Track t, InvoiceLine l, Invoice i
-- WHERE t.TrackId IS l.TrackId
-- AND l.InvoiceId IS i.InvoiceId
-- AND i.InvoiceDate LIKE ('2013%')
-- GROUP BY l.TrackId
-- ORDER BY TrackTotal DESC

-- 24. Provide a query that shows the top 5 most purchased tracks over all.

-- SELECT t.Name, COUNT(l.TrackId) AS TrackTotal
-- FROM Track t, InvoiceLine l
-- WHERE t.TrackId IS l.TrackId
-- GROUP BY l.TrackId
-- ORDER BY TrackTotal DESC
-- LIMIT 5

-- 25. Provide a query that shows the top 3 best selling artists.

-- SELECT a.Name, SUM(i.Total) AS TotalSales
-- FROM Artist a, Album b, Track t, InvoiceLine l, Invoice i
-- WHERE a.ArtistId IS b.ArtistId
-- AND b.AlbumId IS t.AlbumId
-- AND t.TrackId IS l.TrackId
-- AND l.InvoiceId IS i.InvoiceId
-- GROUP BY i.Total
-- ORDER BY i.Total DESC
-- LIMIT 3

-- 26. Provide a query that shows the most purchased Media Type.

-- 27. Provide a query that shows the number tracks purchased in all invoices
-- that contain more than one genre.

repo_name: megbrown/chinook