-
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 ts
By default, the JavaScript client is generated as ES6. To customize the language target (and module format), use the
--target
and--module
flags (runtypewriter gen-js --help
to 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 ts
Then, 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
sync
command:
$ 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.