@goliapkg/sentori-expo 0.1.0 → 0.1.2

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/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ExpoApplicationLike, InitOptions } from './types.js';
1
+ import type { InitOptions } from './types.js';
2
2
  /**
3
3
  * Drop-in init for Expo apps. Reads bundleId / version / build from
4
4
  * `expo-application` (which is shipped in every Expo SDK) so the
@@ -23,13 +23,12 @@ import type { ExpoApplicationLike, InitOptions } from './types.js';
23
23
  */
24
24
  export declare function initSentoriExpo(options: InitOptions): void;
25
25
  /**
26
- * Build a `slug@version+build` release string from expo-application.
27
- * Returns `undefined` when the module isn't available so the caller
28
- * can fall back to a manually-supplied release.
29
- *
30
- * Exported for callers who want to use the same string outside of
31
- * init (e.g. as a tag, log prefix, or metric label).
26
+ * Re-export of `deriveRelease` (defined in `./release.ts`) for
27
+ * callers who want to use the same `slug@version+build` string outside
28
+ * of init (e.g. as a tag, log prefix, or metric label). Lives in its
29
+ * own module so it can be unit-tested without the SDK chain pulling
30
+ * in `react-native`'s Flow-typed exports.
32
31
  */
33
- export declare function deriveRelease(app: ExpoApplicationLike | undefined): string | undefined;
32
+ export { deriveRelease } from './release.js';
34
33
  export type { ExpoApplicationLike, InitOptions } from './types.js';
35
34
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAElE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAe1D;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,mBAAmB,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAOtF;AAWD,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAe1D;AAED;;;;;;GAMG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAW5C,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA"}
package/lib/index.js CHANGED
@@ -3,6 +3,7 @@
3
3
  // The Config Plugin (app.plugin.js) is loaded by Expo at prebuild
4
4
  // time; this module is what apps import from JS at runtime.
5
5
  import { init as initSentoriRN } from '@goliapkg/sentori-react-native';
6
+ import { deriveRelease } from './release.js';
6
7
  /**
7
8
  * Drop-in init for Expo apps. Reads bundleId / version / build from
8
9
  * `expo-application` (which is shipped in every Expo SDK) so the
@@ -40,21 +41,13 @@ export function initSentoriExpo(options) {
40
41
  });
41
42
  }
42
43
  /**
43
- * Build a `slug@version+build` release string from expo-application.
44
- * Returns `undefined` when the module isn't available so the caller
45
- * can fall back to a manually-supplied release.
46
- *
47
- * Exported for callers who want to use the same string outside of
48
- * init (e.g. as a tag, log prefix, or metric label).
44
+ * Re-export of `deriveRelease` (defined in `./release.ts`) for
45
+ * callers who want to use the same `slug@version+build` string outside
46
+ * of init (e.g. as a tag, log prefix, or metric label). Lives in its
47
+ * own module so it can be unit-tested without the SDK chain pulling
48
+ * in `react-native`'s Flow-typed exports.
49
49
  */
50
- export function deriveRelease(app) {
51
- if (!app)
52
- return undefined;
53
- const id = app.applicationId ?? app.nativeApplicationVersion ?? 'app';
54
- const version = app.nativeApplicationVersion ?? '0.0.0';
55
- const build = app.nativeBuildVersion ?? '0';
56
- return `${id}@${version}+${build}`;
57
- }
50
+ export { deriveRelease } from './release.js';
58
51
  function isDev() {
59
52
  // RN's __DEV__ is true under Metro dev server; bare false in
60
53
  // Hermes release builds. typeof check keeps this safe to import in
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,kEAAkE;AAClE,4DAA4D;AAE5D,OAAO,EAAE,IAAI,IAAI,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAItE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,eAAe,CAAC,OAAoB;IAClD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IACrE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,2CAA2C;YACzC,uEAAuE;YACvE,yDAAyD,CAC5D,CAAA;IACH,CAAC;IACD,aAAa,CAAC;QACZ,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9D,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,iCAAiC;QACjE,OAAO;QACP,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,GAAoC;IAChE,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAA;IAC1B,MAAM,EAAE,GACN,GAAG,CAAC,aAAa,IAAI,GAAG,CAAC,wBAAwB,IAAI,KAAK,CAAA;IAC5D,MAAM,OAAO,GAAG,GAAG,CAAC,wBAAwB,IAAI,OAAO,CAAA;IACvD,MAAM,KAAK,GAAG,GAAG,CAAC,kBAAkB,IAAI,GAAG,CAAA;IAC3C,OAAO,GAAG,EAAE,IAAI,OAAO,IAAI,KAAK,EAAE,CAAA;AACpC,CAAC;AAED,SAAS,KAAK;IACZ,6DAA6D;IAC7D,mEAAmE;IACnE,0CAA0C;IAC1C,OAAO,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAA;AAClD,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,kEAAkE;AAClE,4DAA4D;AAE5D,OAAO,EAAE,IAAI,IAAI,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAEtE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAG5C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,eAAe,CAAC,OAAoB;IAClD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IACrE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,2CAA2C;YACzC,uEAAuE;YACvE,yDAAyD,CAC5D,CAAA;IACH,CAAC;IACD,aAAa,CAAC;QACZ,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9D,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,iCAAiC;QACjE,OAAO;QACP,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;GAMG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE5C,SAAS,KAAK;IACZ,6DAA6D;IAC7D,mEAAmE;IACnE,0CAA0C;IAC1C,OAAO,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAA;AAClD,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ExpoApplicationLike } from './types.js';
2
+ /**
3
+ * Build a `slug@version+build` release string from expo-application.
4
+ * Returns `undefined` when the module isn't available so the caller
5
+ * can fall back to a manually-supplied release.
6
+ */
7
+ export declare function deriveRelease(app: ExpoApplicationLike | undefined): string | undefined;
8
+ //# sourceMappingURL=release.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAErD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,mBAAmB,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAMtF"}
package/lib/release.js ADDED
@@ -0,0 +1,19 @@
1
+ // Phase 21 sub-D — pure release-derivation helper, intentionally
2
+ // isolated from `./index.ts` so unit tests can exercise it without
3
+ // pulling in `@goliapkg/sentori-react-native` (and its transitive
4
+ // static import of `react-native`, which Bun's test runner can't
5
+ // parse — RN ships Flow-typed re-exports). Index.ts re-exports it.
6
+ /**
7
+ * Build a `slug@version+build` release string from expo-application.
8
+ * Returns `undefined` when the module isn't available so the caller
9
+ * can fall back to a manually-supplied release.
10
+ */
11
+ export function deriveRelease(app) {
12
+ if (!app)
13
+ return undefined;
14
+ const id = app.applicationId ?? app.nativeApplicationVersion ?? 'app';
15
+ const version = app.nativeApplicationVersion ?? '0.0.0';
16
+ const build = app.nativeBuildVersion ?? '0';
17
+ return `${id}@${version}+${build}`;
18
+ }
19
+ //# sourceMappingURL=release.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release.js","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,mEAAmE;AACnE,kEAAkE;AAClE,iEAAiE;AACjE,mEAAmE;AAInE;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,GAAoC;IAChE,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAA;IAC1B,MAAM,EAAE,GAAG,GAAG,CAAC,aAAa,IAAI,GAAG,CAAC,wBAAwB,IAAI,KAAK,CAAA;IACrE,MAAM,OAAO,GAAG,GAAG,CAAC,wBAAwB,IAAI,OAAO,CAAA;IACvD,MAAM,KAAK,GAAG,GAAG,CAAC,kBAAkB,IAAI,GAAG,CAAA;IAC3C,OAAO,GAAG,EAAE,IAAI,OAAO,IAAI,KAAK,EAAE,CAAA;AACpC,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@goliapkg/sentori-expo",
3
- "version": "0.1.0",
4
- "description": "Expo adapter for Sentori Config Plugin marker, expo-application auto-config, EAS post-build helper. Built on @goliapkg/sentori-react-native.",
3
+ "version": "0.1.2",
4
+ "description": "Expo adapter for Sentori \u2014 Config Plugin marker, expo-application auto-config, EAS post-build helper. Built on @goliapkg/sentori-react-native.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://sentori.golia.jp",
7
7
  "repository": {
@@ -58,8 +58,9 @@
58
58
  "@expo/config-plugins": "^9 || ^10"
59
59
  },
60
60
  "devDependencies": {
61
+ "@goliapkg/sentori-react-native": "workspace:*",
61
62
  "@types/bun": "latest",
62
- "typescript": "^5"
63
+ "typescript": "^6"
63
64
  },
64
65
  "publishConfig": {
65
66
  "access": "public"
@@ -26,10 +26,17 @@
26
26
  * node ./node_modules/@goliapkg/sentori-expo/scripts/eas-post-build.mjs \
27
27
  * --token $SENTORI_ADMIN_TOKEN --release "$EAS_BUILD_RELEASE"
28
28
  *
29
- * The script shells out to `sentori-cli` for the actual upload (Phase 22
30
- * sub-A introduces `sentori-cli upload dsym`). Until that lands this is
31
- * a stub that logs what it would have done adopt sub-D in your
32
- * pipeline now and the CLI integration arrives transparently.
29
+ * Shells out to `@goliapkg/sentori-cli upload sourcemap` for the actual
30
+ * upload. Make sure `@goliapkg/sentori-cli` is installed (or reachable
31
+ * via `npx`); if it can't be found this logs a warning and exits 0 so
32
+ * it never fails a build.
33
+ *
34
+ * Note: for an EAS *Hermes* production build the bundle + maps are
35
+ * platform-specific and must be composed first (Metro map + Hermes
36
+ * map); see docs → Recipes → "Source map upload" → React Native. This
37
+ * helper uploads whatever is under `./dist` (the default
38
+ * `expo export --source-maps` output) — fine for managed JS-only
39
+ * exports.
33
40
  */
34
41
 
35
42
  import { spawnSync } from 'node:child_process'
@@ -39,7 +46,7 @@ const args = parseArgs(process.argv.slice(2))
39
46
 
40
47
  const token = args.token ?? process.env.SENTORI_ADMIN_TOKEN
41
48
  const release = args.release ?? process.env.EAS_BUILD_RELEASE
42
- const ingestUrl = args.ingest ?? process.env.SENTORI_INGEST_URL
49
+ const apiUrl = args['api-url'] ?? process.env.SENTORI_API_URL ?? process.env.SENTORI_INGEST_URL
43
50
 
44
51
  if (!token || !release) {
45
52
  console.error(
@@ -50,29 +57,30 @@ if (!token || !release) {
50
57
  }
51
58
 
52
59
  const cli = resolveCli()
53
- if (!cli) {
60
+ if (!cli.length) {
54
61
  console.warn(
55
- '[sentori-expo:eas-post-build] sentori-cli not found on PATH or in node_modules. ' +
56
- 'Skipping upload install @goliapkg/sentori-cli to enable. ' +
57
- 'Phase 22 sub-A will land the proper upload subcommand.',
62
+ '[sentori-expo:eas-post-build] @goliapkg/sentori-cli not found on PATH or in ' +
63
+ 'node_modules, and npx is unavailable. Skipping source-map upload ' +
64
+ 'install @goliapkg/sentori-cli (or make npx available) to enable.',
58
65
  )
59
66
  process.exit(0)
60
67
  }
61
68
 
62
69
  const cmd = [
70
+ ...cli.slice(1),
63
71
  'upload',
64
72
  'sourcemap',
65
73
  '--token',
66
74
  token,
67
75
  '--release',
68
76
  release,
69
- ...(ingestUrl ? ['--ingest', ingestUrl] : []),
77
+ ...(apiUrl ? ['--api-url', apiUrl] : []),
70
78
  // Default Expo build output for the JS bundle + sourcemap.
71
79
  './dist',
72
80
  ]
73
81
 
74
- console.log(`[sentori-expo:eas-post-build] running: ${cli} ${cmd.join(' ')}`)
75
- const r = spawnSync(cli, cmd, { stdio: 'inherit' })
82
+ console.log(`[sentori-expo:eas-post-build] running: ${cli[0]} ${cmd.join(' ')}`)
83
+ const r = spawnSync(cli[0], cmd, { stdio: 'inherit' })
76
84
  process.exit(r.status ?? 0)
77
85
 
78
86
  function parseArgs(argv) {
@@ -87,17 +95,24 @@ function parseArgs(argv) {
87
95
  return out
88
96
  }
89
97
 
98
+ /** Returns `[command, ...prefixArgs]` to invoke the CLI, or `[]` if it
99
+ * can't be found anywhere. Prefers a locked node_modules copy over a
100
+ * global one; falls back to `npx`. */
90
101
  function resolveCli() {
91
- // Prefer node_modules/.bin so the locked @goliapkg/sentori-cli wins
92
- // over a globally-installed older copy.
93
- for (const p of [
94
- './node_modules/.bin/sentori-cli',
95
- './node_modules/@goliapkg/sentori-cli/bin/sentori-cli.js',
96
- ]) {
97
- if (existsSync(p)) return p
102
+ // node_modules/.bin/sentori-cli — npm creates this from the package's
103
+ // `bin` field; the locked version wins over a global install.
104
+ if (existsSync('./node_modules/.bin/sentori-cli')) {
105
+ return ['./node_modules/.bin/sentori-cli']
98
106
  }
99
- // PATH lookup as last resort.
107
+ // The package's bin entry directly (in case .bin wasn't linked).
108
+ const direct = './node_modules/@goliapkg/sentori-cli/lib/index.js'
109
+ if (existsSync(direct)) return ['node', direct]
110
+ // On PATH (global install).
100
111
  const which = spawnSync('which', ['sentori-cli'])
101
112
  const found = which.stdout?.toString().trim()
102
- return found || null
113
+ if (found) return [found]
114
+ // Last resort: npx (will fetch the package if not cached).
115
+ const npx = spawnSync('which', ['npx'])
116
+ if (npx.stdout?.toString().trim()) return ['npx', '--yes', '@goliapkg/sentori-cli@latest']
117
+ return []
103
118
  }
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, test } from 'bun:test'
2
2
 
3
- import { deriveRelease } from '../index.js'
3
+ import { deriveRelease } from '../release.js'
4
4
 
5
5
  describe('deriveRelease', () => {
6
6
  test('builds slug@version+build from expo-application fields', () => {
package/src/index.ts CHANGED
@@ -5,7 +5,8 @@
5
5
 
6
6
  import { init as initSentoriRN } from '@goliapkg/sentori-react-native'
7
7
 
8
- import type { ExpoApplicationLike, InitOptions } from './types.js'
8
+ import { deriveRelease } from './release.js'
9
+ import type { InitOptions } from './types.js'
9
10
 
10
11
  /**
11
12
  * Drop-in init for Expo apps. Reads bundleId / version / build from
@@ -47,21 +48,13 @@ export function initSentoriExpo(options: InitOptions): void {
47
48
  }
48
49
 
49
50
  /**
50
- * Build a `slug@version+build` release string from expo-application.
51
- * Returns `undefined` when the module isn't available so the caller
52
- * can fall back to a manually-supplied release.
53
- *
54
- * Exported for callers who want to use the same string outside of
55
- * init (e.g. as a tag, log prefix, or metric label).
51
+ * Re-export of `deriveRelease` (defined in `./release.ts`) for
52
+ * callers who want to use the same `slug@version+build` string outside
53
+ * of init (e.g. as a tag, log prefix, or metric label). Lives in its
54
+ * own module so it can be unit-tested without the SDK chain pulling
55
+ * in `react-native`'s Flow-typed exports.
56
56
  */
57
- export function deriveRelease(app: ExpoApplicationLike | undefined): string | undefined {
58
- if (!app) return undefined
59
- const id =
60
- app.applicationId ?? app.nativeApplicationVersion ?? 'app'
61
- const version = app.nativeApplicationVersion ?? '0.0.0'
62
- const build = app.nativeBuildVersion ?? '0'
63
- return `${id}@${version}+${build}`
64
- }
57
+ export { deriveRelease } from './release.js'
65
58
 
66
59
  function isDev(): boolean {
67
60
  // RN's __DEV__ is true under Metro dev server; bare false in
package/src/release.ts ADDED
@@ -0,0 +1,20 @@
1
+ // Phase 21 sub-D — pure release-derivation helper, intentionally
2
+ // isolated from `./index.ts` so unit tests can exercise it without
3
+ // pulling in `@goliapkg/sentori-react-native` (and its transitive
4
+ // static import of `react-native`, which Bun's test runner can't
5
+ // parse — RN ships Flow-typed re-exports). Index.ts re-exports it.
6
+
7
+ import type { ExpoApplicationLike } from './types.js'
8
+
9
+ /**
10
+ * Build a `slug@version+build` release string from expo-application.
11
+ * Returns `undefined` when the module isn't available so the caller
12
+ * can fall back to a manually-supplied release.
13
+ */
14
+ export function deriveRelease(app: ExpoApplicationLike | undefined): string | undefined {
15
+ if (!app) return undefined
16
+ const id = app.applicationId ?? app.nativeApplicationVersion ?? 'app'
17
+ const version = app.nativeApplicationVersion ?? '0.0.0'
18
+ const build = app.nativeBuildVersion ?? '0'
19
+ return `${id}@${version}+${build}`
20
+ }