@symbiote-native/sharing 0.0.1 → 0.1.0

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.
@@ -1,4 +1,4 @@
1
1
  // @symbiote-native/sharing/angular: the Angular entry over the framework-agnostic core. Same
2
2
  // reasoning as the React/Vue entries — no per-instance state or event stream to wrap in a
3
3
  // service, so this is a plain re-export.
4
- export * from '../core';
4
+ export * from '../core/index.js';
@@ -1 +1 @@
1
- export { isAvailableAsync, shareAsync } from './sharing';
1
+ export { isAvailableAsync, shareAsync } from './sharing.js';
@@ -1,5 +1,5 @@
1
1
  import { UnavailabilityError } from 'expo-modules-core';
2
- import { expoSharing } from './native-module';
2
+ import { expoSharing } from './native-module.js';
3
3
  const NATIVE_MODULE_NAME = 'expo-sharing';
4
4
  /**
5
5
  * Whether the share sheet can be opened on this device. Resolves `true` on Android and iOS.
@@ -3,4 +3,4 @@
3
3
  // hook could own or clean up — so this is a plain re-export, the same shape
4
4
  // packages/secure-store's React entry has for the same reason. The one part of expo-sharing that
5
5
  // WOULD need a hook (incoming share) is out of scope here; see the README.
6
- export * from '../core';
6
+ export * from '../core/index.js';
@@ -1,4 +1,4 @@
1
1
  // @symbiote-native/sharing/vue: the Vue entry over the framework-agnostic core. Same reasoning
2
2
  // as the React entry — no per-instance state or event stream to wire onto Vue's reactivity, so
3
3
  // this is a plain re-export.
4
- export * from '../core';
4
+ export * from '../core/index.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/sharing",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "description": "expo-sharing wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, and Angular adapters. Opens the platform share sheet for a local file.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -40,7 +40,10 @@
40
40
  "src",
41
41
  "build",
42
42
  "build-ngc",
43
- "native-link.json"
43
+ "native-link.json",
44
+ "!src/**/*.test.*",
45
+ "!src/**/*.spec.*",
46
+ "!src/**/*.detox.*"
44
47
  ],
45
48
  "publishConfig": {
46
49
  "access": "public"
@@ -56,7 +59,7 @@
56
59
  "react": ">=19.0.0",
57
60
  "react-native": ">=0.86",
58
61
  "vue": ">=3.5.0",
59
- "@symbiote-native/angular": "0.6.1",
62
+ "@symbiote-native/angular": "0.6.2",
60
63
  "@symbiote-native/react": "0.2.8",
61
64
  "@symbiote-native/vue": "0.3.8"
62
65
  },
@@ -92,11 +95,11 @@
92
95
  "@vue/runtime-core": "^3.5.13",
93
96
  "react": "19.2.3",
94
97
  "typescript": "~6.0.0",
95
- "@symbiote-native/test-utils": "0.1.6",
96
- "@symbiote-native/react": "0.2.8",
98
+ "@symbiote-native/angular": "0.6.2",
97
99
  "@symbiote-native/engine": "0.1.7",
98
- "@symbiote-native/vue": "0.3.8",
99
- "@symbiote-native/angular": "0.6.1"
100
+ "@symbiote-native/react": "0.2.8",
101
+ "@symbiote-native/test-utils": "0.1.6",
102
+ "@symbiote-native/vue": "0.3.8"
100
103
  },
101
104
  "scripts": {
102
105
  "typecheck": "tsc --build",
@@ -1,105 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from 'vitest';
2
-
3
- const FAKE_NATIVE_SHARING = {
4
- shareAsync: vi.fn(async () => undefined),
5
- };
6
-
7
- // The real ExpoSharing native module only exists on device — resolving it via
8
- // requireNativeModule() at import time would throw in this headless run, so the module-lookup
9
- // file is faked in place of expo-modules-core's runtime resolution, the same pattern
10
- // packages/secure-store/src/core/secure-store.test.ts uses.
11
- vi.mock('./native-module', () => ({
12
- expoSharing: FAKE_NATIVE_SHARING,
13
- }));
14
-
15
- // expo-modules-core's real entry transitively imports 'react-native', whose Flow-typed source
16
- // Vitest's Oxc transform can't parse — so only the members used as values are faked.
17
- vi.mock('expo-modules-core', () => ({
18
- UnavailabilityError: class UnavailabilityError extends Error {
19
- constructor(moduleName: string, propertyName: string) {
20
- super(`${propertyName} is not available on ${moduleName}`);
21
- }
22
- },
23
- }));
24
-
25
- const { isAvailableAsync, shareAsync } = await import('./sharing');
26
-
27
- const LOCAL_FILE_URL = 'file:///tmp/report.pdf';
28
-
29
- afterEach(() => {
30
- vi.clearAllMocks();
31
- });
32
-
33
- describe('isAvailableAsync', () => {
34
- it('reports availability from the presence of the native share method', async () => {
35
- await expect(isAvailableAsync()).resolves.toBe(true);
36
- });
37
-
38
- it('reports unavailable when the native module cannot share', async () => {
39
- const { shareAsync: native } = FAKE_NATIVE_SHARING;
40
- // @ts-expect-error -- simulating a platform where the native module has no such method
41
- FAKE_NATIVE_SHARING.shareAsync = undefined;
42
-
43
- await expect(isAvailableAsync()).resolves.toBe(false);
44
-
45
- FAKE_NATIVE_SHARING.shareAsync = native;
46
- });
47
-
48
- it('defers to the native check when the module implements one', async () => {
49
- const nativeCheck = vi.fn(async () => false);
50
- Object.assign(FAKE_NATIVE_SHARING, { isAvailableAsync: nativeCheck });
51
-
52
- await expect(isAvailableAsync()).resolves.toBe(false);
53
- expect(nativeCheck).toHaveBeenCalled();
54
-
55
- Reflect.deleteProperty(FAKE_NATIVE_SHARING, 'isAvailableAsync');
56
- });
57
- });
58
-
59
- describe('shareAsync', () => {
60
- it('passes the url and options straight through', async () => {
61
- await shareAsync(LOCAL_FILE_URL, { mimeType: 'application/pdf', dialogTitle: 'Send report' });
62
- expect(FAKE_NATIVE_SHARING.shareAsync).toHaveBeenCalledWith(LOCAL_FILE_URL, {
63
- mimeType: 'application/pdf',
64
- dialogTitle: 'Send report',
65
- });
66
- });
67
-
68
- it('defaults the options to an empty object', async () => {
69
- await shareAsync(LOCAL_FILE_URL);
70
- expect(FAKE_NATIVE_SHARING.shareAsync).toHaveBeenCalledWith(LOCAL_FILE_URL, {});
71
- });
72
-
73
- it('forwards the iPad anchor rectangle unflattened', async () => {
74
- const anchor = { x: 10, y: 20, width: 1, height: 1 };
75
- await shareAsync(LOCAL_FILE_URL, { anchor });
76
- expect(FAKE_NATIVE_SHARING.shareAsync).toHaveBeenCalledWith(LOCAL_FILE_URL, { anchor });
77
- });
78
-
79
- it('throws an UnavailabilityError-shaped error when the native method is absent', async () => {
80
- const { shareAsync: native } = FAKE_NATIVE_SHARING;
81
- // @ts-expect-error -- simulating a platform where the native module has no such method
82
- FAKE_NATIVE_SHARING.shareAsync = undefined;
83
-
84
- await expect(shareAsync(LOCAL_FILE_URL)).rejects.toThrow(
85
- 'shareAsync is not available on expo-sharing',
86
- );
87
-
88
- FAKE_NATIVE_SHARING.shareAsync = native;
89
- });
90
- });
91
-
92
- // Validation happens before the native call so a bad url fails with a readable message here
93
- // rather than as an argument-conversion failure on iOS or a generic share failure on Android.
94
- describe('url validation', () => {
95
- it('rejects an empty url', async () => {
96
- await expect(shareAsync('')).rejects.toThrow(/Invalid url provided to Sharing/);
97
- expect(FAKE_NATIVE_SHARING.shareAsync).not.toHaveBeenCalled();
98
- });
99
-
100
- it('rejects a non-string url before reaching the native module', async () => {
101
- // @ts-expect-error -- the guard exists precisely for callers without type checking
102
- await expect(shareAsync(undefined)).rejects.toThrow(/Invalid url provided to Sharing/);
103
- expect(FAKE_NATIVE_SHARING.shareAsync).not.toHaveBeenCalled();
104
- });
105
- });