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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- `strait init` writes setup for today's SDKs: Android 0.9.0 (JitPack) and iOS 0.10.0 (SwiftPM), was 0.8.4 and 0.9.5; React Native 0.10.2 and Flutter 0.9.7 unchanged. `strait events add` reads the same versions and says the iOS/Android `eventId` needs them.
- `strait test`: one pass/fail list that says you're set up right: the engine answers, the secret key is valid (which workspace, test or live), and the workspace's link domain serves apple-app-site-association and assetlinks.json. Exit 1 on any failure, `--json` for CI.
- `strait events add <name>`: prints ready-to-paste event tracking code for React Native, Flutter, iOS, Android or the web (detected from the project files, or `--platform`), using each SDK's real `trackEvent` call.
- `strait events add --platform web` prints `@straitlink/web`'s new `trackEvent` instead of a hand-written `POST /v1/event` (needs the web SDK release that adds it).
Expand Down
7 changes: 5 additions & 2 deletions src/events.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { existsSync, readdirSync } from 'node:fs';
import { join } from 'node:path';
import { detectProject } from './detect.mjs';
import { PACKAGES, VERSIONS } from './install.mjs';
import { UsageError, normalizeHost } from './validate.mjs';

export const PLATFORMS = ['react-native', 'flutter', 'ios', 'android', 'web'];
Expand Down Expand Up @@ -77,13 +78,15 @@ await links.trackEvent('${n}');
await links.trackEvent('${n}');
`,
ios: (n) => `// strait: your StraitLinks instance (strait-sdk-swift README, "Use"). Never throws.
// For revenue add value: 49.99, currency: "USD", eventId: order.id (a retry is counted once).
// For revenue add value: 49.99, currency: "USD", eventId: order.id (a retry is counted once;
// eventId needs StraitSDK ${VERSIONS.version}+: SwiftPM from: "${VERSIONS.version}").
strait.trackEvent("${n}") { ok in
// ok == false: not sent now; kept and sent later when it was the network
}
`,
android: (n) => `// It sends on the calling thread: call it off the main thread. Never throws.
// For revenue add value = 49.99, currency = "USD", eventId = order.id (a retry is counted once).
// For revenue add value = 49.99, currency = "USD", eventId = order.id (a retry is counted once;
// eventId needs ${PACKAGES.android} ${VERSIONS.androidVersion}+, what strait init installs).
val ok = StraitLinks.client.trackEvent("${n}")
`,
web: (n, { key, host }) => `import { reportWebOpen, trackEvent } from '@straitlink/web';
Expand Down
5 changes: 3 additions & 2 deletions src/install.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ export const sourceFor = (src, registry) => (typeof src.source === 'string' ? sr
/**
* SDK versions the generated code is written for. Must equal site/site.config.json `packages`
* (the one source of truth; test/install.test.mjs fails if they differ). Bump both together.
* `strait events add` reads them too: its iOS/Android eventId needs these SDKs.
*/
export const VERSIONS = {
version: '0.9.5', // Swift (Unity is not written by this CLI)
version: '0.10.0', // Swift (Unity is not written by this CLI)
rnVersion: '0.10.2',
flutterVersion: '0.9.7',
androidVersion: '0.8.4',
androidVersion: '0.9.0',
};

export const PACKAGES = {
Expand Down
4 changes: 2 additions & 2 deletions test/events.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ test('each platform prints its SDK\'s real event call with the name', async () =
const want = {
'react-native': [/import \{ links \} from '\.\/links'/, /await links\.trackEvent\('purchase'\);/, /value: 49\.99, currency: 'USD', eventId: order\.id/],
flutter: [/import 'links\.dart';/, /await links\.trackEvent\('purchase'\);/, /value: 49\.99, currency: 'USD'/],
ios: [/strait\.trackEvent\("purchase"\) \{ ok in/, /eventId: order\.id/],
android: [/StraitLinks\.client\.trackEvent\("purchase"\)/, /off the main thread/],
ios: [/strait\.trackEvent\("purchase"\) \{ ok in/, /eventId: order\.id/, /StraitSDK 0\.10\.0\+/],
android: [/StraitLinks\.client\.trackEvent\("purchase"\)/, /off the main thread/, /eventId = order\.id/, /strait-sdk-android 0\.9\.0\+/],
web: [/import \{ reportWebOpen, trackEvent \} from '@straitlink\/web'/, /await reportWebOpen\(strait\);/, /await trackEvent\(strait, 'purchase'\);/, /value: 49\.99, currency: 'USD', eventId: order\.id/],
};
for (const [platform, patterns] of Object.entries(want)) {
Expand Down
9 changes: 5 additions & 4 deletions test/install.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,22 @@ const root = fileURLToPath(new URL('..', import.meta.url));
const walk = (d) => readdirSync(d).flatMap((n) => (n === 'node_modules' || n === '.git' ? [] : statSync(join(d, n)).isDirectory() ? walk(join(d, n)) : [join(d, n)]));

test('github and registry sources', () => {
// Versions as of 3 Nov 2026 (site.config.json packages = npm / pub.dev / JitPack): RN 0.10.2, Flutter 0.9.7, Android 0.8.4.
// Versions as of 5 Nov 2026 (site.config.json packages = npm / pub.dev / JitPack): RN 0.10.2, Flutter 0.9.7, Android 0.9.0.
const gh = installSpecs({ source: 'github', githubOwner: 'strait-sdks' });
assert.equal(gh.reactNative, 'github:strait-sdks/strait-sdk-react-native#v0.10.2');
assert.equal(gh.android, 'com.github.strait-sdks:strait-sdk-android:v0.8.4');
assert.equal(gh.android, 'com.github.strait-sdks:strait-sdk-android:v0.9.0');
assert.equal(gh.androidRepository, 'https://jitpack.io');
assert.match(gh.flutterPubspec, /url: https:\/\/github\.com\/strait-sdks\/strait-sdk-flutter\n {6}ref: v0\.9\.7/);
const today = installSpecs();
assert.equal(today.reactNative, '@straitlink/react-native@0.10.2', 'npm in registry mode (16 Oct)');
assert.equal(today.flutterPubspec, ' strait_sdk: ^0.9.7', 'pub.dev in registry mode (16 Oct)');
assert.equal(today.android, `com.github.${INSTALL.githubOwner}:strait-sdk-android:v0.8.4`, 'Android stays on JitPack');
assert.equal(today.android, `com.github.${INSTALL.githubOwner}:strait-sdk-android:v0.9.0`, 'Android stays on JitPack');
const reg = installSpecs({ ...INSTALL, source: 'registry' });
assert.equal(reg.reactNative, '@straitlink/react-native@0.10.2');
assert.equal(reg.android, 'in.straitlink:strait-sdk-android:0.8.4');
assert.equal(reg.android, 'in.straitlink:strait-sdk-android:0.9.0');
assert.equal(reg.flutterPubspec, ' strait_sdk: ^0.9.7');
assert.equal(reg.androidRepository, null);
assert.equal(VERSIONS.version, '0.10.0', 'Swift tag v0.10.0 (SwiftPM)');
});

test('the owner is spelled out only in src/install.mjs', () => {
Expand Down
Loading