From c229fb071eb0d60ff6252b9524400698167a12c9 Mon Sep 17 00:00:00 2001 From: Fathy Boundjadj Date: Tue, 25 Sep 2018 23:15:53 +0200 Subject: [PATCH] refactor(integration): port code-generator to ts --- packages/core/tsconfig.json | 9 +-- packages/integrations/package.json | 10 ++- ...en-integrations.js => gen-integrations.ts} | 74 +++++++++++-------- .../src/{gen-readme.js => gen-readme.ts} | 10 +-- packages/integrations/src/integration-list.js | 28 ------- packages/integrations/src/integration-list.ts | 65 ++++++++++++++++ packages/integrations/src/module.d.ts | 2 + packages/integrations/tsconfig.json | 10 +++ tsconfig.json | 10 +++ yarn.lock | 33 ++++++++- 10 files changed, 173 insertions(+), 78 deletions(-) rename packages/integrations/src/{gen-integrations.js => gen-integrations.ts} (68%) rename packages/integrations/src/{gen-readme.js => gen-readme.ts} (79%) delete mode 100644 packages/integrations/src/integration-list.js create mode 100644 packages/integrations/src/integration-list.ts create mode 100644 packages/integrations/src/module.d.ts create mode 100644 packages/integrations/tsconfig.json create mode 100644 tsconfig.json diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 04b86021e..ff02f1b22 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -1,13 +1,8 @@ { + "extends": "../../tsconfig.json", "compilerOptions": { - "strict": true, - "lib": ["es5", "es2015.promise", "dom"], - "target": "es5", - - "sourceMap": true, - "declaration": true, "outDir": "build", - "moduleResolution": "node" + "lib": ["es5", "es2015.promise", "dom"] }, "include": ["src/**/*.ts"] } diff --git a/packages/integrations/package.json b/packages/integrations/package.json index 1863df98a..9d1083c4e 100644 --- a/packages/integrations/package.json +++ b/packages/integrations/package.json @@ -4,8 +4,9 @@ "private": true, "scripts": { "clean": "rimraf build", - "generate:integrations": "node src/gen-integrations", - "generate:readme": "node src/gen-readme", + "ts": "ts-node -P tsconfig.json --files --pretty", + "generate:integrations": "yarn ts src/gen-integrations", + "generate:readme": "yarn ts src/gen-readme", "generate": "run-p generate:*", "build": "run-s clean generate" }, @@ -14,5 +15,10 @@ "markdown-table": "^1.1.2", "mustache": "^3.0.0", "yaml": "^1.0.0-rc.7" + }, + "devDependencies": { + "@types/mustache": "^0.8.31", + "@types/yaml": "^1.0.0", + "ts-node": "^7.0.1" } } diff --git a/packages/integrations/src/gen-integrations.js b/packages/integrations/src/gen-integrations.ts similarity index 68% rename from packages/integrations/src/gen-integrations.js rename to packages/integrations/src/gen-integrations.ts index 72fffc3f8..6f9a3574a 100644 --- a/packages/integrations/src/gen-integrations.js +++ b/packages/integrations/src/gen-integrations.ts @@ -1,36 +1,44 @@ -const fs = require('fs-extra') -const path = require('path') -const mustache = require('mustache') -const pkg = require('../package.json') +import fs from 'fs-extra' +import path from 'path' +import mustache from 'mustache' +import pkg from '../package.json' + +import integrations, { Integration } from './integration-list' + +interface Context extends Integration { + nativeModule: string + out: string + template: (template: string, view: {}, dest?: string) => Promise +} const root = path.resolve(__dirname, '..') -const integrations = require('./integration-list') -const safeWrite = async (file, contents) => { +const safeWrite = async (file: string, contents: string) => { await fs.mkdirp(path.dirname(file)) await fs.writeFile(file, contents) } -function prepareAndroid({ template, name, android, nativeModule, slug }) { +async function prepareAndroid({ template, name, android, nativeModule, slug }: Context) { const identifier = slug('.').toLowerCase() + const classSlug = `${slug()}Integration` const { maven: { - repo, + repo = undefined, name: depName = `com.segment.analytics.android.integrations:${slug( '-' ).toLowerCase()}`, version = '+@aar' } = {}, factory: { - class: factoryClass = `${slug()}Integration`, - import: factoryImport = `com.segment.analytics.android.integrations.${identifier}.${factoryClass}` + class: factoryClass = classSlug, + import: factoryImport = `com.segment.analytics.android.integrations.${identifier}.${classSlug}` } = {} } = android const classpath = `com.segment.analytics.reactnative.integration.${identifier}` const dependency = `${depName}:${version}` const root = 'android/src/main' - return Promise.all([ + await Promise.all([ template('android/build.gradle', { dependency, maven: repo }), template(`${root}/AndroidManifest.xml`, { classpath }), @@ -45,22 +53,25 @@ function prepareAndroid({ template, name, android, nativeModule, slug }) { ]) } -function prepareiOS({ template, name, out, ios, nativeModule, slug }) { +async function prepareiOS({ template, name, out, ios, nativeModule, slug }: Context) { const xcodeProject = 'ios/RNAnalyticsIntegration.xcodeproj' const targetXcodeProject = `ios/${nativeModule}.xcodeproj` const pod_name = `RNAnalyticsIntegration-${slug('-')}` const { pod: { name: pod_dependency = `Segment-${slug()}`, - version: pod_version + version: pod_version = undefined } = {}, - prefix = 'SEG', - className = `${prefix}${slug()}IntegrationFactory`, + prefix = 'SEG' + } = ios + const classSlug = `${prefix}${slug()}IntegrationFactory` + const { + className = classSlug, framework = pod_dependency, - header = className + header = classSlug } = ios - return Promise.all([ + await Promise.all([ fs.copy( path.resolve(root, 'template', xcodeProject, 'project.xcworkspace'), path.resolve(out, targetXcodeProject, 'project.xcworkspace') @@ -90,7 +101,7 @@ function prepareiOS({ template, name, out, ios, nativeModule, slug }) { ]) } -function prepareJs({ +async function prepareJs({ name, npm, nativeModule, @@ -99,8 +110,8 @@ function prepareJs({ ios, android, slug -}) { - return Promise.all([ +}: Context) { + await Promise.all([ safeWrite( path.resolve(out, 'package.json'), JSON.stringify( @@ -124,26 +135,25 @@ function prepareJs({ ]) } -function genIntegration({ name, ios, android, npm, slug }) { +function genIntegration({ name, ios, android, npm, slug }: Integration) { const out = path.resolve(root, 'build', npm.package) const nativeModule = `RNAnalyticsIntegration_${slug('_')}` - const template = async (template, view, dest = template) => - safeWrite( - path.resolve(out, dest), - mustache.render( - await fs.readFile(path.resolve(root, 'template', template), 'utf-8'), - view - ) - ) - const ctx = { + const ctx: Context = { name, out, nativeModule, npm, - template, ios, android, - slug + slug, + template: async (template, view, dest = template) => + await safeWrite( + path.resolve(out, dest), + mustache.render( + await fs.readFile(path.resolve(root, 'template', template), 'utf-8'), + view + ) + ) } const tasks = [prepareJs(ctx)] diff --git a/packages/integrations/src/gen-readme.js b/packages/integrations/src/gen-readme.ts similarity index 79% rename from packages/integrations/src/gen-readme.js rename to packages/integrations/src/gen-readme.ts index 2af51a316..06326b1a3 100644 --- a/packages/integrations/src/gen-readme.js +++ b/packages/integrations/src/gen-readme.ts @@ -1,13 +1,13 @@ -const mdtable = require('markdown-table') -const fs = require('fs') -const path = require('path') +import mdtable from 'markdown-table' +import fs from 'fs' +import path from 'path' -const integrations = require('./integration-list') +import integrations from './integration-list' const YES = ':white_check_mark:' const NO = ':x:' -const table = mdtable([ +const table: string = mdtable([ ['Name', 'iOS', 'Android', 'npm package'], ...integrations .sort((a, b) => a.name.localeCompare(b.name)) diff --git a/packages/integrations/src/integration-list.js b/packages/integrations/src/integration-list.js deleted file mode 100644 index 5c6ea04dc..000000000 --- a/packages/integrations/src/integration-list.js +++ /dev/null @@ -1,28 +0,0 @@ -const { parse } = require('yaml').default -const { readFileSync } = require('fs') -const { resolve } = require('path') - -module.exports = parse( - readFileSync(resolve(__dirname, '../integrations.yml'), 'utf-8') -) - .map(({ name, ios = {}, android = {} }) => { - if (ios.disabled && android.disabled) { - return null - } - - const slug = (sep = '') => name.replace(/-|_| /g, sep) - const suffix = ios.disabled ? '-android' : android.disabled ? '-ios' : '' - - return { - name, - slug, - ios, - android, - npm: { - package: `@segment/analytics-react-native-${slug( - '-' - ).toLowerCase()}${suffix}` - } - } - }) - .filter(integration => integration !== null) diff --git a/packages/integrations/src/integration-list.ts b/packages/integrations/src/integration-list.ts new file mode 100644 index 000000000..bbfae711f --- /dev/null +++ b/packages/integrations/src/integration-list.ts @@ -0,0 +1,65 @@ +import {parse} from 'yaml' +import { readFileSync } from 'fs' +import { resolve } from 'path' + +export interface IntegrationDeclaration { + name: string + ios: { + disabled?: boolean + pod?: { + name?: string + version?: string + } + prefix?: string + className?: string + framework?: string + header?: string + } + android: { + disabled?: boolean + factory?: { + class?: string + import?: string + } + maven?: { + repo?: string + name?: string + version?: string + } + } +} + +export interface Integration extends IntegrationDeclaration { + name: string + slug(separator?: string): string + npm: { + package: string + } +} + +const integrations: IntegrationDeclaration[] = parse( + readFileSync(resolve(__dirname, '../integrations.yml'), 'utf-8') +) + +export default integrations + .map(({ name, ios = {}, android = {} }) => { + if (ios.disabled && android.disabled) { + return null! + } + + const slug = (sep = '') => name.replace(/-|_| /g, sep) + const suffix = ios.disabled ? '-android' : android.disabled ? '-ios' : '' + + return { + name, + slug, + ios, + android, + npm: { + package: `@segment/analytics-react-native-${slug( + '-' + ).toLowerCase()}${suffix}` + } + } + }) + .filter(integration => integration !== null) diff --git a/packages/integrations/src/module.d.ts b/packages/integrations/src/module.d.ts new file mode 100644 index 000000000..d7b675970 --- /dev/null +++ b/packages/integrations/src/module.d.ts @@ -0,0 +1,2 @@ +declare module 'markdown-table' +declare module '*.json' diff --git a/packages/integrations/tsconfig.json b/packages/integrations/tsconfig.json new file mode 100644 index 000000000..8badc0a56 --- /dev/null +++ b/packages/integrations/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "target": "es6", + "outDir": "build", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true + }, + "include": ["src/**/*.ts"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..8689c4f17 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "strict": true, + "noImplicitAny": true, + "target": "es5", + "sourceMap": true, + "declaration": true, + "moduleResolution": "node" + } +} diff --git a/yarn.lock b/yarn.lock index 177a0a7da..c1401e07f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -214,6 +214,10 @@ version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" +"@types/mustache@^0.8.31": + version "0.8.31" + resolved "https://registry.yarnpkg.com/@types/mustache/-/mustache-0.8.31.tgz#7c86cbf74f7733f9e3bdc28817623927eb386616" + "@types/node@*": version "10.11.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.11.0.tgz#ddd0d67a3b6c3810dd1a59e36675fa82de5e19ae" @@ -225,6 +229,10 @@ "@types/glob" "*" "@types/node" "*" +"@types/yaml@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/yaml/-/yaml-1.0.0.tgz#4bd87eb73fcb25ac0a8510eede6251ada2d91369" + JSONStream@^1.0.4: version "1.3.4" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.4.tgz#615bb2adb0cd34c8f4c447b5f6512fa1d8f16a2e" @@ -388,7 +396,7 @@ array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" -arrify@^1.0.1: +arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -691,7 +699,7 @@ btoa-lite@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" -buffer-from@1.x, buffer-from@^1.0.0: +buffer-from@1.x, buffer-from@^1.0.0, buffer-from@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -1261,7 +1269,7 @@ detox@^8.1.4: tempfile "^2.0.0" ws "^1.1.1" -diff@3.5.0, diff@^3.2.0: +diff@3.5.0, diff@^3.1.0, diff@^3.2.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -3111,7 +3119,7 @@ macos-release@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-1.1.0.tgz#831945e29365b470aa8724b0ab36c8f8959d10fb" -make-error@1.x: +make-error@1.x, make-error@^1.1.1: version "1.3.5" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" @@ -4764,6 +4772,19 @@ ts-jest@^23.1.3: semver "5.x" yargs-parser "10.x" +ts-node@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" + dependencies: + arrify "^1.0.0" + buffer-from "^1.1.0" + diff "^3.1.0" + make-error "^1.1.1" + minimist "^1.2.0" + mkdirp "^0.5.1" + source-map-support "^0.5.6" + yn "^2.0.0" + tslib@^1.7.1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" @@ -5135,3 +5156,7 @@ yargs@^11.0.0: which-module "^2.0.0" y18n "^3.2.1" yargs-parser "^9.0.2" + +yn@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a"