@oxyhq/bloom 0.69.0 → 0.69.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/bloom",
3
- "version": "0.69.0",
3
+ "version": "0.69.1",
4
4
  "description": "Bloom UI — Oxy ecosystem component library for React Native + Expo + Web",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -1490,6 +1490,7 @@
1490
1490
  "@react-native-community/netinfo": "^12.0.1"
1491
1491
  },
1492
1492
  "peerDependencies": {
1493
+ "@react-native-community/netinfo": ">=11.1.0",
1493
1494
  "expo": "*",
1494
1495
  "expo-blur": "*",
1495
1496
  "expo-font": "*",
@@ -1498,18 +1499,21 @@
1498
1499
  "expo-image": "*",
1499
1500
  "expo-router": ">=3.0.0",
1500
1501
  "expo-symbols": ">=0.4.5",
1502
+ "nativewind": ">=5.0.0",
1501
1503
  "react": ">=18.0.0",
1502
1504
  "react-dom": ">=18.0.0",
1503
1505
  "react-native": ">=0.73.0",
1504
1506
  "react-native-gesture-handler": ">=2.16.1",
1507
+ "react-native-keyboard-controller": ">=1.11.4",
1505
1508
  "react-native-reanimated": ">=3.13.0",
1506
1509
  "react-native-safe-area-context": ">=5.0.0",
1507
1510
  "react-native-screens": ">=3.16.0",
1508
- "react-native-svg": ">=13.0.0",
1509
- "nativewind": ">=5.0.0",
1510
- "@react-native-community/netinfo": ">=11.1.0"
1511
+ "react-native-svg": ">=13.0.0"
1511
1512
  },
1512
1513
  "peerDependenciesMeta": {
1514
+ "@react-native-community/netinfo": {
1515
+ "optional": true
1516
+ },
1513
1517
  "expo": {
1514
1518
  "optional": true
1515
1519
  },
@@ -1522,13 +1526,13 @@
1522
1526
  "expo-router": {
1523
1527
  "optional": true
1524
1528
  },
1525
- "react-dom": {
1529
+ "nativewind": {
1526
1530
  "optional": true
1527
1531
  },
1528
- "nativewind": {
1532
+ "react-dom": {
1529
1533
  "optional": true
1530
1534
  },
1531
- "@react-native-community/netinfo": {
1535
+ "react-native-keyboard-controller": {
1532
1536
  "optional": true
1533
1537
  }
1534
1538
  },
@@ -50,6 +50,7 @@ import ts from 'typescript';
50
50
 
51
51
  const SRC = join(__dirname, '..');
52
52
  const PKG = JSON.parse(readFileSync(join(SRC, '..', 'package.json'), 'utf8')) as {
53
+ dependencies?: Record<string, string>;
53
54
  peerDependencies: Record<string, string>;
54
55
  peerDependenciesMeta: Record<string, { optional?: boolean }>;
55
56
  };
@@ -94,6 +95,7 @@ const DYNAMIC_BOUNDARIES: { peer: string; file: string }[] = [
94
95
  { peer: 'expo-haptics', file: 'hooks/haptics-module.ts' },
95
96
  { peer: 'nativewind', file: 'theme/color-scope/style-builder.ts' },
96
97
  { peer: 'expo-router', file: 'theme/adaptive-colors.ts' },
98
+ { peer: 'react-native-keyboard-controller', file: 'bottom-sheet/index.tsx' },
97
99
  ];
98
100
 
99
101
  /**
@@ -341,6 +343,39 @@ describe('optional peers are loaded through Metro’s optional-dependency form',
341
343
  expect(notOptional).toEqual([]);
342
344
  });
343
345
 
346
+ it('declares every package it loads through a require boundary', () => {
347
+ // The inverse direction, and the one that matters: every other assertion in
348
+ // this file starts from `peerDependenciesMeta` and asks whether the code
349
+ // matches it, so by construction none of them can see a package the manifest
350
+ // never mentions. `react-native-keyboard-controller` sat in `bottom-sheet`
351
+ // for exactly that reason — loaded, degraded correctly, and invisible to a
352
+ // consumer, who had no range to install against and no way to learn the
353
+ // integration existed.
354
+ const declared = new Set([
355
+ ...Object.keys(PKG.peerDependencies),
356
+ ...Object.keys(PKG.dependencies ?? {}),
357
+ ]);
358
+
359
+ const undeclared = new Set<string>();
360
+ for (const file of files) {
361
+ for (const { specifier, line } of requireCalls(parse(file))) {
362
+ if (specifier === null || specifier.startsWith('.')) continue;
363
+ const pkg = specifier.startsWith('@')
364
+ ? specifier.split('/').slice(0, 2).join('/')
365
+ : (specifier.split('/')[0] as string);
366
+ if (declared.has(pkg)) continue;
367
+ if (VARIABLE_REQUIRE_ALLOWED.some((entry) => file.endsWith(entry.file))) continue;
368
+ undeclared.add(
369
+ `${file.slice(SRC.length + 1)}:${line} requires '${pkg}', which appears in neither ` +
370
+ 'dependencies nor peerDependencies — a consumer cannot know the integration exists ' +
371
+ 'or which versions satisfy it',
372
+ );
373
+ }
374
+ }
375
+
376
+ expect([...undeclared].sort()).toEqual([]);
377
+ });
378
+
344
379
  it('loads each optional peer from exactly the documented boundary file', () => {
345
380
  // Both directions in one assertion: a boundary that moved (or was deleted)
346
381
  // leaves a stale table entry; a second load site for the same peer, or a new