Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ npx lexigen -u <service-account-username> -s <service-account-secret> -p <projec
-p, --project Mixpanel project id to pull the schema definitions from.
[string] [required]
-t, --target A target API to generate.
[string] [choices: "typescript"] [default: "typescript"]
[string] [choices: "typescript", "dart"] [default: "typescript"]
-f, --filter Filters the events by a specific tag. [string]
```

## Language support
Currently supports the following generators:
- Typescript.
- Dart.

> The generator assumes that the mixpanel tracking package is already installed and setup. It only imports the package at the top of the generated file.
67 changes: 67 additions & 0 deletions src/generators/dart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { camelCase, pascalCase } from 'change-case'
import { JSONSchema } from 'json-schema-to-typescript'

import { EventSchema } from '../mixpanel'

const dartTypeMapping: { [key: string]: string } = {
string: 'String',
number: 'double',
integer: 'int',
boolean: 'bool',
array: 'List',
object: 'Map<String, dynamic>',
}

const generateDartMethod = (eventName: string, schema: JSONSchema): string => {
const requiredFields = schema.required || []
const properties = schema.properties || {}

const methodParams = Object.entries(properties)
.map(([key, value]: [string, any]) => {

Check warning on line 20 in src/generators/dart.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
const type = dartTypeMapping[value.type] || 'dynamic'
const isRequired = requiredFields === true || requiredFields.includes(key)
const paramName = camelCase(key)
return `${isRequired ? 'required ' : ''}${type}${isRequired ? '' : '?'} ${paramName}`
})
.join(', ')

const propertiesMap = Object.entries(properties)
.map(([key, _]) => `'${key}': ${camelCase(key)}`)
.join(',\n ')

if (!methodParams) {
return ` static void track${pascalCase(eventName)}Event() =>
_track('${eventName}');`
}

return ` static void track${pascalCase(eventName)}Event({
${methodParams}
}) =>
_track('${eventName}', properties: <String, dynamic>{
${propertiesMap},
});`
}

const formatDescription = (event: EventSchema): string => {
return event.schemaJson.description ? `/// ${event.schemaJson.description}\n` : ''
}

export const generate = async (events: EventSchema[]): Promise<string> => {
const eventMethods = events.map((event) => {
return `${formatDescription(event)}${generateDartMethod(event.name, event.schemaJson)}`
})

return `
import 'package:mixpanel_flutter/mixpanel_flutter.dart';

class Lexicon {
static Mixpanel? mixpanel;

static void _track(String eventName, {Map<String, dynamic>? properties}) {
mixpanel?.track(eventName, properties: properties);
}

${eventMethods.join('\n\n')}
}
`
}
8 changes: 6 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@
import yargs from 'yargs'
import { hideBin } from 'yargs/helpers'

import { generate as generateDart } from './generators/dart'
import { generate as generateTypescript } from './generators/typescripts'
import { fetchEventsSchema } from './mixpanel'

type GeneratorFunctionType = typeof generateTypescript
enum GenerationOptions {
typescript = 'typescript',
dart = 'dart',
}

const generators: Record<GenerationOptions, typeof generateTypescript> = {
const generators: Record<GenerationOptions, GeneratorFunctionType> = {
typescript: generateTypescript,
dart: generateDart,
}

const { username, secret, project, target, filter } = yargs(hideBin(process.argv))
Expand All @@ -36,7 +40,7 @@ const { username, secret, project, target, filter } = yargs(hideBin(process.argv
.option('target', {
alias: 't',
type: 'string',
choices: [GenerationOptions.typescript],
choices: [GenerationOptions.typescript, GenerationOptions.dart],
description: 'A target API to generate.',
default: 'typescript',
})
Expand Down
Loading