@straitlink/cli 0.3.6 → 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,7 +51,7 @@ From a checkout of this repo: `node bin/strait.mjs init ../my-app`, or `npm link
51
51
 
52
52
  | Option | |
53
53
  |---|---|
54
- | `--key` | Publishable key (Dashboard → Get started). Env: `STRAIT_PUBLISHABLE_KEY` |
54
+ | `--key` | Publishable key (Dashboard → Setup → Your keys). Env: `STRAIT_PUBLISHABLE_KEY` |
55
55
  | `--host` | Link domain, e.g. `acme.strait.link`. A pasted link works too. Env: `STRAIT_LINK_HOST` |
56
56
  | `--scheme` | Custom scheme: the one you typed in Dashboard → Apps & stores. Taken from `app.json`, or guessed from the package name (`com.acme.shop` → `acmeshop`); a guess is marked "(guessed from …)" in the output |
57
57
  | `--framework` | `react-native`, `expo`, `flutter` or `android`, to skip detection |
@@ -90,7 +90,7 @@ Exit codes: `0` no errors (warnings allowed), `1` a check failed, `2` usage prob
90
90
  ## Manage links: `strait links`
91
91
 
92
92
  ```bash
93
- export STRAIT_SECRET_KEY=st_live_… # Dashboard → Settings → Secret keys
93
+ export STRAIT_SECRET_KEY=st_live_… # Dashboard → Settings → Keys
94
94
  npx @straitlink/cli links create summer https://acme.com/summer --campaign sale --tag email
95
95
  npx @straitlink/cli links list --status active --limit 20
96
96
  npx @straitlink/cli links qr summer --size 512 # writes summer.png
@@ -104,7 +104,7 @@ Exit codes: `0` done, `1` the API said no or can't be reached (its message on st
104
104
  ## Am I set up right? `strait test`
105
105
 
106
106
  ```bash
107
- export STRAIT_SECRET_KEY=st_live_… # Dashboard → Settings → Secret keys
107
+ export STRAIT_SECRET_KEY=st_live_… # Dashboard → Settings → Keys
108
108
  npx @straitlink/cli test
109
109
  ```
110
110
 
@@ -126,7 +126,7 @@ One read-only pass: the engine answers (`GET /healthz`), the secret key is valid
126
126
  ## What's wrong with my setup? `strait app verify`
127
127
 
128
128
  ```bash
129
- export STRAIT_SECRET_KEY=st_live_… # Dashboard → Settings → Secret keys (read or full access)
129
+ export STRAIT_SECRET_KEY=st_live_… # Dashboard → Settings → Keys (read or full access)
130
130
  npx @straitlink/cli app # the setup Strait has: apps, link domains and their files, SDKs seen
131
131
  npx @straitlink/cli app verify # every check, with the fix for each problem
132
132
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@straitlink/cli",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "Strait deep links from the terminal: init sets them up in a React Native, Expo, Flutter or Android app, doctor checks your link host, app verify checks your whole setup with a fix for each problem, links creates and lists links and saves QR codes.",
5
5
  "keywords": [
6
6
  "strait",
package/src/cli.mjs CHANGED
@@ -78,7 +78,7 @@ Usage
78
78
  strait events add <name> [dir] [options] Print ready-to-paste code that tracks an event
79
79
 
80
80
  init options
81
- --key <st_pub_live_…> Publishable key (Dashboard → Get started)
81
+ --key <st_pub_live_…> Publishable key (Dashboard → Setup → Your keys)
82
82
  --host <host> Your link domain, e.g. acme.strait.link
83
83
  --scheme <scheme> Your app's custom scheme, the one in Dashboard → Apps & stores,
84
84
  e.g. acmeshop (guessed from the package name if left out)
@@ -102,7 +102,7 @@ doctor options (the same checks and messages as doctor() in the SDKs)
102
102
  Exit 1 when a check fails.
103
103
 
104
104
  links options
105
- --secret-key <st_live_…> Secret key (Dashboard → Settings → Secret keys). Prefer the
105
+ --secret-key <st_live_…> Secret key (Dashboard → Settings → Keys). Prefer the
106
106
  env STRAIT_SECRET_KEY: flags stay in your shell history
107
107
  --api-url <url> API base (env STRAIT_API_URL, default https://strait.link)
108
108
  --title, --campaign, --tag <tag> (repeatable) create: link details
@@ -196,7 +196,7 @@ export async function main(argv, io = {}) {
196
196
  if (canAsk && (!key || !host || !scheme)) {
197
197
  const ask = io.ask ?? (await terminalAsker(io.stdin ?? process.stdin, out));
198
198
  try {
199
- key = key ?? (await askValid(ask, 'Publishable key (Dashboard → Get started, st_pub_live_…): ', normalizeKey, err));
199
+ key = key ?? (await askValid(ask, 'Publishable key (Dashboard → Setup → Your keys, st_pub_live_…): ', normalizeKey, err));
200
200
  host = host ?? (await askValid(ask, 'Link host (e.g. acme.strait.link): ', normalizeHost, err));
201
201
  if (!scheme) {
202
202
  const guess = suggestScheme(detectProject(dir) ?? {});
@@ -248,7 +248,7 @@ async function terminalAsker(input, output) {
248
248
  async function doctor({ values: v }, { out, env, io }) {
249
249
  const hostIn = v.host ?? env.STRAIT_LINK_HOST;
250
250
  const secretIn = v['secret-key'] ?? env.STRAIT_SECRET_KEY;
251
- if (!hostIn && !secretIn) throw new UsageError('Missing --host: your link domain from Dashboard → Get started, e.g. --host acme.strait.link. Or set STRAIT_SECRET_KEY to check your whole setup.');
251
+ if (!hostIn && !secretIn) throw new UsageError('Missing --host: your link domain from Dashboard → Setup → Your keys, e.g. --host acme.strait.link. Or set STRAIT_SECRET_KEY to check your whole setup.');
252
252
  const fetchImpl = io.fetch ?? fetch;
253
253
  let result = { ok: true };
254
254
  if (hostIn) {
package/src/doctor.mjs CHANGED
@@ -51,12 +51,12 @@ export function doctorFindings(input) {
51
51
  const key = input.publishableKey ?? '';
52
52
  if (key.startsWith('st_pub_')) findings.push(ok('key.ok', 'Publishable key is set'));
53
53
  else if (key.startsWith('st_live_') || key.startsWith('st_test_'))
54
- findings.push(err('key.secret', 'This is a secret key, not the publishable key', 'Use the publishable key (st_pub_…) from Dashboard → Get started, and revoke this secret key in Dashboard → Settings → Secret keys: it has been inside your app.'));
55
- else findings.push(err('key.invalid', 'Not a publishable key', 'Copy the publishable key (st_pub_…) from Dashboard → Get started.'));
54
+ findings.push(err('key.secret', 'This is a secret key, not the publishable key', 'Use the publishable key (st_pub_…) from Dashboard → Setup → Your keys, and revoke this secret key in Dashboard → Settings → Keys: it has been inside your app.'));
55
+ else findings.push(err('key.invalid', 'Not a publishable key', 'Copy the publishable key (st_pub_…) from Dashboard → Setup → Your keys.'));
56
56
 
57
57
  const host = doctorHost(input.endpoint ?? '');
58
58
  if (!host) {
59
- findings.push(err('endpoint.invalid', "The endpoint isn't an https link domain", 'Set endpoint to your link domain from Dashboard → Get started, e.g. https://<handle>.strait.link.'));
59
+ findings.push(err('endpoint.invalid', "The endpoint isn't an https link domain", 'Set endpoint to your link domain from Dashboard → Setup → Your keys, e.g. https://<handle>.strait.link.'));
60
60
  } else if (input.file) findings.push(...hostFindings(input, host, input.file));
61
61
  return { ok: !findings.some((f) => f.severity === 'error'), findings };
62
62
  }
@@ -71,12 +71,12 @@ const notConfigured = (file) => file.status === 404 && file.body === NOT_CONFIGU
71
71
  function hostFindings(input, host, file) {
72
72
  const android = input.platform === 'android';
73
73
  if (file.status === undefined)
74
- return [err('host.unreachable', `Can't reach ${host}`, 'Check that endpoint is your link domain (Dashboard → Get started) and that this device is online.')];
74
+ return [err('host.unreachable', `Can't reach ${host}`, 'Check that endpoint is your link domain (Dashboard → Setup → Your keys) and that this device is online.')];
75
75
  const apps = file.status === 200 ? listedApps(input.platform, file.body ?? '') : null;
76
76
  if (!apps && !notConfigured(file))
77
- return [err('host.file_missing', `${host} doesn't serve ${android ? 'assetlinks.json' : 'apple-app-site-association'}`, 'Use your Strait link domain as endpoint (Dashboard → Get started); Strait serves this file there.')];
77
+ return [err('host.file_missing', `${host} doesn't serve ${android ? 'assetlinks.json' : 'apple-app-site-association'}`, 'Use your Strait link domain as endpoint (Dashboard → Setup → Your keys); Strait serves this file there.')];
78
78
  if (!apps?.size)
79
- return [err('app.none', `No ${android ? 'Android' : 'iOS'} app is set up for ${host}`, `Fill in Dashboard → Apps & stores (${android ? 'package name and SHA-256 fingerprint' : 'Team ID and bundle ID'}), wait a minute, then check again. Already done? Make sure ${host} is your link domain from Dashboard → Get started.`)];
79
+ return [err('app.none', `No ${android ? 'Android' : 'iOS'} app is set up for ${host}`, `Fill in Dashboard → Apps & stores (${android ? 'package name and SHA-256 fingerprint' : 'Team ID and bundle ID'}), wait a minute, then check again. Already done? Make sure ${host} is your link domain from Dashboard → Setup → Your keys.`)];
80
80
 
81
81
  const listed = [...apps.keys()].join(', ');
82
82
  const app = input.appId?.trim();
package/src/install.mjs CHANGED
@@ -23,10 +23,10 @@ export const sourceFor = (src, registry) => (typeof src.source === 'string' ? sr
23
23
  * `strait events add` reads them too: its iOS/Android eventId needs these SDKs.
24
24
  */
25
25
  export const VERSIONS = {
26
- version: '0.11.4', // Swift (Unity is not written by this CLI)
27
- rnVersion: '0.11.3',
28
- flutterVersion: '0.10.6',
29
- androidVersion: '0.10.4',
26
+ version: '0.11.6', // Swift (Unity is not written by this CLI)
27
+ rnVersion: '0.11.5',
28
+ flutterVersion: '0.10.8',
29
+ androidVersion: '0.10.6',
30
30
  };
31
31
 
32
32
  export const PACKAGES = {
package/src/links.mjs CHANGED
@@ -14,7 +14,7 @@ export class ApiError extends Error {}
14
14
  /** The secret key for the link API, or a UsageError that says where to get one. Never echoes the value. */
15
15
  export function secretKey(value) {
16
16
  const k = String(value ?? '').trim().replace(/^['"]+|['"]+$/g, '').replace(/^Bearer\s+/i, '');
17
- const where = 'Create one in Dashboard → Settings → Secret keys and set STRAIT_SECRET_KEY (or pass --secret-key).';
17
+ const where = 'Create one in Dashboard → Settings → Keys (https://app.straitlink.in/settings#keys) and set STRAIT_SECRET_KEY (or pass --secret-key).';
18
18
  if (!k) throw new UsageError(`The link API needs a secret key (st_live_…). ${where}`);
19
19
  if (k.startsWith('st_pub_')) throw new UsageError(`That is the publishable key (st_pub_…), which only works inside apps. The link API needs a secret key (st_live_…). ${where}`);
20
20
  if (!SECRET.test(k)) throw new UsageError(`That is not a secret key (st_live_… or st_test_…). ${where}`);
package/src/selftest.mjs CHANGED
@@ -48,7 +48,7 @@ export async function runSelfTest({ call, apiUrl, key, fetch: fetchImpl }) {
48
48
  checks.push(pass('key', 'Key', `valid ${mode} key${prefix ? ` ${prefix}…` : ''} for workspace "${workspace.name ?? '?'}"${access}`));
49
49
  } catch (e) {
50
50
  if (!(e instanceof ApiError)) throw e;
51
- checks.push(fail('key', 'Key', e.message, 'Create a secret key in Dashboard → Settings → Secret keys and set STRAIT_SECRET_KEY.'));
51
+ checks.push(fail('key', 'Key', e.message, 'Create a secret key in Dashboard → Settings → Keys (https://app.straitlink.in/settings#keys) and set STRAIT_SECRET_KEY.'));
52
52
  checks.push(...DOMAIN_CHECKS.map(([id, l]) => skip(id, l, 'needs a valid key')));
53
53
  return done();
54
54
  }
package/src/validate.mjs CHANGED
@@ -15,15 +15,15 @@ const EXAMPLE_BODIES = new Set(['8fK2mQx7Lp4RtZ']);
15
15
  */
16
16
  export function normalizeKey(value) {
17
17
  let k = String(value ?? '').trim().replace(/^['"]+|['"]+$/g, '');
18
- if (!k) throw new UsageError('A publishable key is required (--key st_pub_live_…). Find it in Dashboard → Get started.');
18
+ if (!k) throw new UsageError('A publishable key is required (--key st_pub_live_…). Find it in Dashboard → Setup → Your keys (https://app.straitlink.in/setup#keys).');
19
19
  if (SECRET_KEY.test(k)) {
20
20
  throw new UsageError(
21
- 'That is a secret key (st_live_…). Apps must use the publishable key (st_pub_live_…) from Dashboard → Get started. ' +
22
- 'If the secret key was pasted somewhere public, rotate it in Dashboard → Settings → Secret keys.',
21
+ 'That is a secret key (st_live_…). Apps must use the publishable key (st_pub_live_…) from Dashboard → Setup → Your keys. ' +
22
+ 'If the secret key was pasted somewhere public, rotate it in Dashboard → Settings → Keys.',
23
23
  );
24
24
  }
25
25
  const m = /^st_pub_(live|test)_(.*)$/.exec(k);
26
- const where = (mode = 'live') => `Copy your real one from Dashboard → Get started (the Publishable key box): st_pub_${mode}_ followed by 32 letters and numbers.`;
26
+ const where = (mode = 'live') => `Copy your real one from Dashboard → Setup → Your keys (the Publishable key box): st_pub_${mode}_ followed by 32 letters and numbers.`;
27
27
  if (!m) throw new UsageError(`That is not a publishable key. ${where()}`);
28
28
  const [, mode] = m;
29
29
  let rest = m[2].replace(/\.$/, ''); // a full stop copied from a sentence
@@ -42,7 +42,7 @@ export function normalizeKey(value) {
42
42
  /** "https://Acme.strait.link/summer" → "acme.strait.link". */
43
43
  export function normalizeHost(value) {
44
44
  let h = String(value ?? '').trim().toLowerCase();
45
- if (!h) throw new UsageError('A link host is required (--host acme.strait.link). It is your workspace link domain in Dashboard → Get started.');
45
+ if (!h) throw new UsageError('A link host is required (--host acme.strait.link). It is your workspace link domain in Dashboard → Setup → Your keys.');
46
46
  h = h.replace(/^[a-z][a-z0-9+.-]*:\/\//, '').replace(/[/?#].*$/, '').replace(/\.$/, '');
47
47
  const labels = h.split('.');
48
48
  if (h.length > 253 || labels.length < 2 || !labels.every((l) => LABEL.test(l)) || !/^[a-z]{2,}$/.test(labels.at(-1))) {
package/src/version.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
  // Kept equal to package.json version (test/links.test.mjs checks it). Sent as the API User-Agent.
2
- export const CLI_VERSION = '0.3.6';
2
+ export const CLI_VERSION = '0.3.7';