-
Strongly Typed Analytics: Generates strongly-typed Segment analytics clients from arbitrary JSON Schema.
-
Cross-Language Support: Supports native clients in JavaScript, TypeScript, Node.js, Android and iOS.
-
Segment Protocols: Built-in support to sync your Typewriter clients with your centralized Tracking Plans.
$ yarn add -D typewriter| Language | Build-Time | Run-Time |
|---|---|---|
| JavaScript | ❌ Types ❌ Naming ❌ Required Properties ✅ Intellisense |
✅ Types ✅ Naming ✅ Required Properties N/A |
| TypeScript | ✅ Types ✅ Naming ✅ Required Properties ✅ Intellisense |
✅ Types ✅ Naming ✅ Required Properties N/A |
| Android (Java) | ✅ Types ✅ Naming ❌ Required Properties ✅ Intellisense |
✅ Types ✅ Naming ✅ Required Properties N/A |
| iOS (Objective C) | ✅ Types ✅ Naming ❌ Required Properties ✅ Intellisense |
✅ Types ✅ Naming ✅ Required Properties N/A |
Using Segment Protocols? You can download a JSON Schema version of your Tracking Plan directly from the Segment Platform API. See the instructions below.
Typewriter supports generating clients from multiple events without collisions, where each event is validated by its own JSON Schema. A minimal example might look like:
{
"events": [
{
"name": "Viewed Typewriter",
"description": "Fired when a user views the Typewriter landing page",
"rules": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"properties": {
"type": "object",
"properties": {
"user_id": {
"type": "string",
"description": "The user viewing Typewriter"
}
}
}
},
"required": ["properties"]
}
}
]
}Typewriter supports JSON Schema draft-04 through draft-07.
First, generate a Typewriter client from your schema:
$ typewriter gen-js \
--inputPath ./schema.json \
--outputPath ./generated \
--declarations tsBy default, the JavaScript client is generated as ES6. To customize the language target (and module format), use the
--targetand--moduleflags (runtypewriter gen-js --helpto see all available module formats and target syntaxes)
Then, import analytics.js and the generated Typewriter client to start making type-safe calls!
import TypewriterAnalytics from './generated'
// Pass in your analytics.js instance to Typewriter
const analytics = new TypewriterAnalytics(analyticsJS)
analytics.viewedTypewriter({
profile_id: '1234'
})To see a full working example, see the JavaScript example here or the TypeScript example here.
We recommend that you add client generation as a package.json command:
// package.json
{
"scripts": {
"typewriter": "typewriter gen-js --inputPath ./schema.json --outputPath ./generated"
}
}First, generate a Typewriter client from your schema:
$ typewriter gen-js \
--inputPath ./schema.json \
--outputPath ./generated \
--client node \
--target "ES2017" \
--module "CommonJS" \
--declarations tsThen, import analytics-node and the generated Typewriter client to start making type-safe calls!
const TypewriterAnalytics = require('./generated')
// Pass in your analytics-node instance to Typewriter
const analytics = new TypewriterAnalytics(analyticsNode)
analytics.viewedTypewriter({
properties: {
user_id: '1234'
}
})To see a full working example, see the Node.js example here.
We recommend that you add client generation as a package.json command.
First, generate a Typewriter client from your schema:
$ typewriter gen-android \
--inputPath ./schema.json \
--outputPath ./generated \
--language "java"Then, configure a new analytics-android instance:
import com.segment.analytics.Analytics;
// Your generated Typewriter client
import com.segment.analytics.KicksAppAnalytics;
// ...
Analytics analytics = new Analytics.Builder(this, SEGMENT_WRITE_KEY)
.trackApplicationLifecycleEvents()
.recordScreenViews()
.build();
this.kicksAppAnalytics = new KicksAppAnalytics(analytics);Finally, start making type-safe calls!
OrderCompleted order = new OrderCompleted.Builder()
.currency("USD")
.orderID(UUID.randomUUID().toString())
.total(13.37)
.build();
this.kicksAppAnalytics.orderCompleted(order);To see a full working example, see the Android Java example here.
First, generate a Typewriter client from your schema:
$ typewriter gen-ios \
--inputPath ./schema.json \
--outputPath ./generated \
--language "objectivec"Then, configure a new analytics-ios instance:
#import <Analytics/SEGAnalytics.h>
// Your generated Typewriter client
#import "Analytics/SEGKicksAppAnalytics.h"
// ...
self.kicksAppAnalytics = [[SEGKicksAppAnalytics alloc] initWithAnalytics:[SEGAnalytics sharedAnalytics]];Finally, start making type-safe calls!
SEGOrderCompleted *order = [SEGOrderCompletedBuilder initWithBlock:^(SEGOrderCompletedBuilder *builder) {
builder.currency = @"USD";
builder.orderID = [[NSUUID UUID] UUIDString];
builder.total = productPrice;
}];
[self.kicksAppAnalytics orderCompleted:order];To see a full working example, see the iOS Objective C example here.
If you use Segment Protocols, you can automatically generate clients from your Tracking Plan for any supported language.
To do so, you'll need your workspace slug and Tracking Plan id. You can find both in the URL when viewing your Tracking Plan: https://app.segment.com/<WORKSPACE_SLUG>/protocols/tracking-plans/<TRACKING_PLAN_ID>
- First, you'll want to generate a personal API token:
$ USER=me@example.com
$ PASS=foobar
$ WORKSPACE_SLUG=your_slug
$ curl \
-d "{'access_token': {'description': 'Typewriter Personal Access Token', 'scopes': 'workspace:read', 'workspaceNames': [ 'workspaces/${WORKSPACE_SLUG}' ] }}" \
-u "$USER:$PASS" \
https://platform.segmentapis.com/v1beta/access-tokens- Then, you can download a Tracking Plan with the
synccommand:
$ TRACKING_PLAN_ID=rs_foobar
$ PERSONAL_ACCESS_TOKEN=1234.4321
$ WORKSPACE_SLUG=your_slug
$ typewriter sync \
--trackingPlanId ${TRACKING_PLAN_ID} \
--token ${PERSONAL_ACCESS_TOKEN} \
--workspaceSlug ${WORKSPACE_SLUG} \
--outputPath ./generated/tracking-plan.json- Great! You're now setup to follow any of the quickstarts above!
- To submit a bug report or feature request, file an issue here.
- To develop on Typewriter or propose a new language, see CONTRIBUTING.md.
