diff --git a/README.md b/README.md index d2ec833..97d0f90 100644 --- a/README.md +++ b/README.md @@ -22,12 +22,13 @@ npx lexigen -u -s -p 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. diff --git a/src/generators/dart.ts b/src/generators/dart.ts new file mode 100644 index 0000000..b0692b7 --- /dev/null +++ b/src/generators/dart.ts @@ -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', +} + +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]) => { + 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: { + ${propertiesMap}, + });` +} + +const formatDescription = (event: EventSchema): string => { + return event.schemaJson.description ? `/// ${event.schemaJson.description}\n` : '' +} + +export const generate = async (events: EventSchema[]): Promise => { + 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? properties}) { + mixpanel?.track(eventName, properties: properties); + } + +${eventMethods.join('\n\n')} +} +` +} diff --git a/src/index.ts b/src/index.ts index f0c6e48..8f94779 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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 = { +const generators: Record = { typescript: generateTypescript, + dart: generateDart, } const { username, secret, project, target, filter } = yargs(hideBin(process.argv)) @@ -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', })