waha-shared 1.0.486 → 1.0.487

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.
@@ -16,7 +16,6 @@ const languages_1 = require("../functions/languages");
16
16
  const sets_1 = require("../types/sets");
17
17
  const bibleBooks_1 = require("./bibleBooks");
18
18
  const bibles_1 = require("./bibles");
19
- const media_1 = require("./media");
20
19
  const utils_1 = require("./utils");
21
20
  var bibleBooks_2 = require("./bibleBooks");
22
21
  Object.defineProperty(exports, "parseVerseRange", { enumerable: true, get: function () { return bibleBooks_2.parseVerseRange; } });
@@ -215,7 +214,7 @@ function verseToSuperscript(num) {
215
214
  function getFtbDuration(section, lessonInfo) {
216
215
  if (!section.ftbPath)
217
216
  return 0;
218
- const ftbDuration = (0, media_1.getCachedDuration)(section.ftbPath);
217
+ const ftbDuration = (0, utils_1.getCachedDuration)(section.ftbPath);
219
218
  if (ftbDuration == null) {
220
219
  console.warn(`FTB duration not found for ${(0, utils_1.basename)(section.ftbPath)}`);
221
220
  }
@@ -245,7 +244,7 @@ function enrichSections(lessonInfo, scripture) {
245
244
  const ignoreTimings = isStory && priorStoryLengthUnknown ? true : undefined;
246
245
  const startTime = currentTime;
247
246
  if (!isStory) {
248
- length = (0, media_1.getCachedDuration)(section.path);
247
+ length = (0, utils_1.getCachedDuration)(section.path);
249
248
  }
250
249
  else {
251
250
  currentTime += getFtbDuration(section, lessonInfo);
@@ -276,7 +275,7 @@ function enrichSections(lessonInfo, scripture) {
276
275
  * slightly off.
277
276
  */
278
277
  const path = lessonInfo.type === 'dbs' ? lessonInfo.fullPath : lessonInfo.videoPath;
279
- const totalDuration = (0, media_1.getCachedDuration)(path);
278
+ const totalDuration = (0, utils_1.getCachedDuration)(path);
280
279
  if (totalDuration) {
281
280
  let timeFromEnd = totalDuration;
282
281
  const applicationSections = enriched.filter((s) => s.chapter === sets_1.Chapter.APPLICATION);
@@ -12,7 +12,6 @@ const youtubeVideos_1 = require("../data/youtubeVideos");
12
12
  const scripturePassages_1 = require("../functions/scripturePassages");
13
13
  const sets_2 = require("../types/sets");
14
14
  const bibles_1 = require("./bibles");
15
- const media_1 = require("./media");
16
15
  const utils_1 = require("./utils");
17
16
  function getSetInfo({ setId, languageId, setIds, t, }) {
18
17
  const idComponents = setId.split('.');
@@ -220,12 +219,12 @@ function assembleLessonSections({ languageInfo, setInfo, lesson, t, useSpokenQue
220
219
  .filter((s) => s.chapter === sets_2.Chapter.FELLOWSHIP)
221
220
  .reduce((sum, section) => sum +
222
221
  (section.pauseBefore ?? 0) +
223
- ((0, media_1.getCachedDuration)(section.path) ?? 0), 0),
222
+ ((0, utils_1.getCachedDuration)(section.path) ?? 0), 0),
224
223
  applicationDuration: sections
225
224
  .filter((s) => s.chapter === sets_2.Chapter.APPLICATION)
226
225
  .reduce((sum, section) => sum +
227
226
  (section.pauseBefore ?? 0) +
228
- ((0, media_1.getCachedDuration)(section.path) ?? 0), 0),
227
+ ((0, utils_1.getCachedDuration)(section.path) ?? 0), 0),
229
228
  };
230
229
  }
231
230
  function getTrainingVideoPaths({ languageInfo, lessonId, }) {
@@ -363,18 +362,18 @@ function shouldShowLesson(lessonInfo) {
363
362
  return false;
364
363
  }
365
364
  else if (lessonInfo.type === 'eq' &&
366
- (0, media_1.getCachedDuration)(lessonInfo.eqPath) === undefined) {
365
+ (0, utils_1.getCachedDuration)(lessonInfo.eqPath) === undefined) {
367
366
  console.log('Missing remote eq file for lesson:', lessonInfo.lessonId);
368
367
  return false;
369
368
  }
370
369
  else if (lessonInfo.type === 'dbs' &&
371
- (0, media_1.getCachedDuration)(lessonInfo.fullPath) === undefined) {
370
+ (0, utils_1.getCachedDuration)(lessonInfo.fullPath) === undefined) {
372
371
  console.log('Missing remote dbs file for lesson:', lessonInfo.lessonId);
373
372
  return false;
374
373
  }
375
374
  else if (lessonInfo.type === 'video' &&
376
375
  lessonInfo.videoPath &&
377
- (0, media_1.getCachedDuration)(lessonInfo.videoPath) === undefined) {
376
+ (0, utils_1.getCachedDuration)(lessonInfo.videoPath) === undefined) {
378
377
  console.log('Missing remote video for lesson:', lessonInfo.lessonId);
379
378
  return false;
380
379
  }
@@ -4,8 +4,4 @@ export declare const first: (p: string) => string;
4
4
  export declare const dirname: (p: string) => string;
5
5
  export declare const extname: (p: string) => string;
6
6
  export declare const basenamenoext: (p: string) => string;
7
- /** Safely read `code`/`message` off an unknown thrown value. */
8
- export declare function getErrorInfo(e: unknown): {
9
- code?: string;
10
- message?: string;
11
- };
7
+ export declare const getCachedDuration: (path: string) => number | undefined;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.basenamenoext = exports.extname = exports.dirname = exports.first = exports.basename = exports.join = void 0;
4
- exports.getErrorInfo = getErrorInfo;
3
+ exports.getCachedDuration = exports.basenamenoext = exports.extname = exports.dirname = exports.first = exports.basename = exports.join = void 0;
4
+ const mediaDurations_1 = require("../data/mediaDurations");
5
5
  const join = (...parts) => parts.join('/').replace(/\/+/g, '/');
6
6
  exports.join = join;
7
7
  const basename = (p) => p.split('/').pop();
@@ -18,14 +18,5 @@ const basenamenoext = (p) => {
18
18
  return dotIndex !== -1 ? base.slice(0, dotIndex) : base;
19
19
  };
20
20
  exports.basenamenoext = basenamenoext;
21
- /** Safely read `code`/`message` off an unknown thrown value. */
22
- function getErrorInfo(e) {
23
- const code = typeof e === 'object' &&
24
- e !== null &&
25
- 'code' in e &&
26
- typeof e.code === 'string'
27
- ? e.code
28
- : undefined;
29
- const message = e instanceof Error ? e.message : undefined;
30
- return { code, message };
31
- }
21
+ const getCachedDuration = (path) => mediaDurations_1.mediaDurations[(0, exports.first)(path)]?.[(0, exports.basename)(path)];
22
+ exports.getCachedDuration = getCachedDuration;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waha-shared",
3
- "version": "1.0.486",
3
+ "version": "1.0.487",
4
4
  "author": "Waha",
5
5
  "dependencies": {
6
6
  "@types/signale": "^1.4.7",
@@ -13,8 +13,12 @@
13
13
  },
14
14
  "description": "Shared assets for Waha's various apps",
15
15
  "devDependencies": {
16
+ "@crowdin/crowdin-api-client": "^1.57.0",
17
+ "@types/react": "^19.3.0",
16
18
  "copyfiles": "^2.4.1",
17
- "typescript": "~5.9.2"
19
+ "react": "^19.3.0",
20
+ "typescript": "~5.9.2",
21
+ "zod": "^4.6.5"
18
22
  },
19
23
  "files": [
20
24
  "dist",
@@ -1,17 +0,0 @@
1
- import { AppTranslations } from '../types/languages';
2
- /**
3
- * Maps a Firebase Auth error to a user-readable message to display in the UI.
4
- */
5
- export declare function mapFirebaseAuthError(app: AppTranslations, e: unknown): string;
6
- /**
7
- * Whether an auth error is a routine one we don't want reported to Sentry.
8
- */
9
- export declare function isExpectedAuthError(e: unknown): boolean;
10
- /**
11
- * Whether a thrown SSO error is just the user dismissing the provider's UI,
12
- * rather than a real failure worth reporting. Each app passes the identifiers
13
- * its own providers use: the native flows put Apple-on-Android's identifier on
14
- * the error message and Apple-on-iOS's and Google's on `code`, while the web
15
- * SDK reports a dismissed popup as a `code`.
16
- */
17
- export declare function ignoreError(ignoreIds: Set<string>, e: unknown): boolean;
@@ -1,64 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mapFirebaseAuthError = mapFirebaseAuthError;
4
- exports.isExpectedAuthError = isExpectedAuthError;
5
- exports.ignoreError = ignoreError;
6
- const utils_1 = require("./utils");
7
- /*
8
- * The Firebase Auth error codes every Waha app shows a tailored message for.
9
- * Anything not listed here falls back to the generic message, so adding a code
10
- * in one place adds it everywhere.
11
- *
12
- * Two auth messages deliberately live outside this map because they aren't
13
- * driven by a Firebase error code: `popups_auth_errors_provider_error` (an SSO
14
- * provider failing before Firebase is ever reached, and it interpolates the
15
- * provider name) and `popups_auth_errors_link_wrong_device` (a magic link
16
- * opened where its email was never entered, which throws nothing at all).
17
- */
18
- const authErrorMessages = (app) => new Map([
19
- ['auth/too-many-requests', app.popups_auth_errors_too_many_requests],
20
- ['auth/user-disabled', app.popups_auth_errors_user_disabled],
21
- ['auth/network-request-failed', app.connect_to_continue],
22
- // Passwordless email-link (magic link) return leg. `invalid-action-code`
23
- // and `expired-action-code` share a message — to the user, an expired link
24
- // and an already-used one are the same story.
25
- ['auth/invalid-action-code', app.popups_auth_errors_link_expired],
26
- ['auth/expired-action-code', app.popups_auth_errors_link_expired],
27
- ]);
28
- /**
29
- * Maps a Firebase Auth error to a user-readable message to display in the UI.
30
- */
31
- function mapFirebaseAuthError(app, e) {
32
- const { code } = (0, utils_1.getErrorInfo)(e);
33
- // A Map rather than an object literal: looked up on an object, an error
34
- // carrying a code like `constructor` resolves up the prototype chain and
35
- // hands back a function where this signature promises a string.
36
- const message = code === undefined ? undefined : authErrorMessages(app).get(code);
37
- return message || app.popups_auth_errors_generic;
38
- }
39
- /** Auth failures to not log to Sentry. */
40
- const EXPECTED_AUTH_ERROR_CODES = new Set([
41
- // A magic link that was already used, or has aged out.
42
- 'auth/invalid-action-code',
43
- 'auth/expired-action-code',
44
- 'auth/network-request-failed',
45
- ]);
46
- /**
47
- * Whether an auth error is a routine one we don't want reported to Sentry.
48
- */
49
- function isExpectedAuthError(e) {
50
- const { code } = (0, utils_1.getErrorInfo)(e);
51
- return code !== undefined && EXPECTED_AUTH_ERROR_CODES.has(code);
52
- }
53
- /**
54
- * Whether a thrown SSO error is just the user dismissing the provider's UI,
55
- * rather than a real failure worth reporting. Each app passes the identifiers
56
- * its own providers use: the native flows put Apple-on-Android's identifier on
57
- * the error message and Apple-on-iOS's and Google's on `code`, while the web
58
- * SDK reports a dismissed popup as a `code`.
59
- */
60
- function ignoreError(ignoreIds, e) {
61
- const { code, message } = (0, utils_1.getErrorInfo)(e);
62
- return ((code !== undefined && ignoreIds.has(code)) ||
63
- (message !== undefined && ignoreIds.has(message)));
64
- }
@@ -1,2 +0,0 @@
1
- /** The pre-computed duration of a media file, in seconds. */
2
- export declare const getCachedDuration: (path: string) => number | undefined;
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getCachedDuration = void 0;
4
- const mediaDurations_1 = require("../data/mediaDurations");
5
- const utils_1 = require("./utils");
6
- /** The pre-computed duration of a media file, in seconds. */
7
- const getCachedDuration = (path) => mediaDurations_1.mediaDurations[(0, utils_1.first)(path)]?.[(0, utils_1.basename)(path)];
8
- exports.getCachedDuration = getCachedDuration;