waha-shared 1.0.509 → 1.0.511
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 +12 -12
- package/dist/data/bibleAudios/bibleAudios.json +12 -0
- package/dist/data/bibleStatuses/bibleStatuses.json +852 -0
- package/dist/data/bibleTexts/bibleTexts.json +11 -0
- package/dist/data/countriesAndLanguages/countriesAndLanguages.json +25 -20
- package/dist/data/countriesAndLanguages/countriesAndLanguages.schema.json +1 -1
- package/dist/data/countriesAndLanguages/countriesAndLanguages.zod.js +1 -1
- package/dist/data/languages/index.d.ts +1 -1
- package/dist/data/languages/languages.json +18 -11
- package/dist/data/languages/languages.schema.json +3 -1
- package/dist/data/languages/languages.zod.d.ts +1 -1
- package/dist/data/languages/languages.zod.js +6 -1
- package/dist/data/mediaDurations/mediaDurations.json +1090 -0
- package/dist/data/notification/index.d.ts +2 -2
- package/dist/data/notification/notification.schema.json +9 -3
- package/dist/data/notification/notification.zod.d.ts +3 -3
- package/dist/data/notification/notification.zod.js +4 -6
- package/dist/data/phoneLanguages/phoneLanguages.json +32 -0
- package/dist/data/releaseNotes/releaseNotes.json +9 -2
- package/dist/data/translationsApp/translationsApp.json +878 -8
- package/dist/data/translationsFtb/translationsFtb.json +136 -0
- package/dist/data/translationsIntroduction/translationsIntroduction.json +31 -31
- package/dist/data/translationsQuestion/translationsQuestion.json +64 -0
- package/dist/data/translationsSet/translationsSet.json +1661 -83
- package/dist/data/translationsSpokenQuestion/translationsSpokenQuestion.json +64 -0
- package/dist/functions/activeCampaign.d.ts +6 -0
- package/dist/functions/activeCampaign.js +10 -1
- package/dist/functions/bibleBooks.d.ts +6 -1
- package/dist/functions/bibleBooks.js +6 -1
- package/dist/functions/bibles.d.ts +22 -8
- package/dist/functions/bibles.js +54 -120
- package/dist/functions/crowdin.d.ts +53 -4
- package/dist/functions/crowdin.js +55 -43
- package/dist/functions/donations.d.ts +40 -0
- package/dist/functions/donations.js +135 -0
- package/dist/functions/ffmpeg.d.ts +21 -0
- package/dist/functions/ffmpeg.js +37 -9
- package/dist/functions/languages.d.ts +2 -2
- package/dist/functions/languages.js +26 -44
- package/dist/functions/scripturePassages.d.ts +9 -5
- package/dist/functions/scripturePassages.js +6 -10
- package/dist/functions/sets.d.ts +15 -7
- package/dist/functions/sets.js +34 -28
- package/dist/functions/upload.d.ts +16 -6
- package/dist/functions/upload.js +15 -6
- package/dist/functions/utils.d.ts +0 -2
- package/dist/functions/utils.js +1 -9
- package/dist/types/logs.d.ts +2 -2
- package/dist/types/notifications.d.ts +3 -3
- package/dist/types/sets.d.ts +14 -0
- package/dist/types/users.d.ts +1 -1
- package/package.json +4 -4
package/dist/functions/sets.js
CHANGED
|
@@ -75,6 +75,23 @@ function getSetTranslations({ setInfo, lessonId, languageId, t, }) {
|
|
|
75
75
|
: undefined;
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Fills in a section's own audio duration and its FTB clip's, so nothing
|
|
80
|
+
* downstream has to look them up. A story section's own duration only exists
|
|
81
|
+
* for custom passage recordings.
|
|
82
|
+
*/
|
|
83
|
+
function resolveDurations(section) {
|
|
84
|
+
const [bibleId, passageId] = section.id.split(';');
|
|
85
|
+
return {
|
|
86
|
+
...section,
|
|
87
|
+
duration: section.chapter === sets_2.Chapter.STORY
|
|
88
|
+
? bibleStatuses_1.bibleStatuses[bibleId]?.customPassages?.[passageId]
|
|
89
|
+
: (0, media_1.getCachedDuration)(section.path),
|
|
90
|
+
ftbDuration: section.ftbPath
|
|
91
|
+
? (0, media_1.getCachedDuration)(section.ftbPath)
|
|
92
|
+
: undefined,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
78
95
|
/** Assembles all of the audio sections for a lesson. */
|
|
79
96
|
function assembleLessonSections({ languageInfo, setInfo, lesson, t, useSpokenQuestions, }) {
|
|
80
97
|
const fellowshipQuestions = languageInfo.questionSets.find((questionSet) => questionSet.questionSetId === lesson.f)?.questions ?? [];
|
|
@@ -214,18 +231,14 @@ function assembleLessonSections({ languageInfo, setInfo, lesson, t, useSpokenQue
|
|
|
214
231
|
].join('.')),
|
|
215
232
|
});
|
|
216
233
|
});
|
|
234
|
+
const resolved = sections.map(resolveDurations);
|
|
235
|
+
const chapterDuration = (chapter) => resolved
|
|
236
|
+
.filter((s) => s.chapter === chapter)
|
|
237
|
+
.reduce((sum, section) => sum + (section.pauseBefore ?? 0) + (section.duration ?? 0), 0);
|
|
217
238
|
return {
|
|
218
|
-
sections,
|
|
219
|
-
fellowshipDuration:
|
|
220
|
-
|
|
221
|
-
.reduce((sum, section) => sum +
|
|
222
|
-
(section.pauseBefore ?? 0) +
|
|
223
|
-
((0, media_1.getCachedDuration)(section.path) ?? 0), 0),
|
|
224
|
-
applicationDuration: sections
|
|
225
|
-
.filter((s) => s.chapter === sets_2.Chapter.APPLICATION)
|
|
226
|
-
.reduce((sum, section) => sum +
|
|
227
|
-
(section.pauseBefore ?? 0) +
|
|
228
|
-
((0, media_1.getCachedDuration)(section.path) ?? 0), 0),
|
|
239
|
+
sections: resolved,
|
|
240
|
+
fellowshipDuration: chapterDuration(sets_2.Chapter.FELLOWSHIP),
|
|
241
|
+
applicationDuration: chapterDuration(sets_2.Chapter.APPLICATION),
|
|
229
242
|
};
|
|
230
243
|
}
|
|
231
244
|
function getTrainingVideoPaths({ languageInfo, lessonId, }) {
|
|
@@ -296,10 +309,12 @@ function getLessonInfo({ lessonId, languageInfo, setInfo, t, useSpokenQuestions,
|
|
|
296
309
|
...languageInfo,
|
|
297
310
|
};
|
|
298
311
|
if (specialIds_1.specialIds.evaluationQuestionLessonIds.includes(lesson.lessonId)) {
|
|
312
|
+
const eqPath = (0, utils_1.join)(languageInfo.contentLanguages.intros, 'introductions', `${languageInfo.contentLanguages.intros}.eq.mp3`);
|
|
299
313
|
return {
|
|
300
314
|
type: 'eq',
|
|
301
315
|
...baseInfo,
|
|
302
|
-
eqPath
|
|
316
|
+
eqPath,
|
|
317
|
+
mediaDuration: (0, media_1.getCachedDuration)(eqPath),
|
|
303
318
|
};
|
|
304
319
|
}
|
|
305
320
|
if (setInfo.setId === specialIds_1.specialIds.dmCourseSetId || languageId === 'ase') {
|
|
@@ -333,6 +348,7 @@ function getLessonInfo({ lessonId, languageInfo, setInfo, t, useSpokenQuestions,
|
|
|
333
348
|
lessonSectionHeader: thisSetTranslations?.sectionHeaders?.[lessonId],
|
|
334
349
|
lessonSectionBody: thisSetTranslations?.sectionBodies?.[lessonId],
|
|
335
350
|
videoPath,
|
|
351
|
+
mediaDuration: (0, media_1.getCachedDuration)(videoPath),
|
|
336
352
|
fullPath: lesson.s.length > 0 && languageId !== 'ase'
|
|
337
353
|
? videoFullAudioPath
|
|
338
354
|
: undefined,
|
|
@@ -352,6 +368,7 @@ function getLessonInfo({ lessonId, languageInfo, setInfo, t, useSpokenQuestions,
|
|
|
352
368
|
passagesString,
|
|
353
369
|
fullPath,
|
|
354
370
|
storyPath,
|
|
371
|
+
mediaDuration: (0, media_1.getCachedDuration)(fullPath),
|
|
355
372
|
dbsCastPath: (0, utils_1.join)(languageId, `full_lessons${languageInfo.assetVersions?.cast ?? ''}`, setInfo.setId, [languageId, lessonId, '1080', 'mp4'].join('.')),
|
|
356
373
|
};
|
|
357
374
|
}
|
|
@@ -362,24 +379,13 @@ function shouldShowLesson(lessonInfo) {
|
|
|
362
379
|
console.log('Missing lesson info or lessonTitle lesson:', lessonInfo?.lessonId);
|
|
363
380
|
return false;
|
|
364
381
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}
|
|
370
|
-
else if (lessonInfo.type === 'dbs' &&
|
|
371
|
-
(0, media_1.getCachedDuration)(lessonInfo.fullPath) === undefined) {
|
|
372
|
-
console.log('Missing remote dbs file for lesson:', lessonInfo.lessonId);
|
|
373
|
-
return false;
|
|
374
|
-
}
|
|
375
|
-
else if (lessonInfo.type === 'video' &&
|
|
376
|
-
lessonInfo.videoPath &&
|
|
377
|
-
(0, media_1.getCachedDuration)(lessonInfo.videoPath) === undefined) {
|
|
378
|
-
console.log('Missing remote video for lesson:', lessonInfo.lessonId);
|
|
382
|
+
// Video-only lessons without a video file have nothing to check.
|
|
383
|
+
const hasMedia = lessonInfo.type !== 'video' || Boolean(lessonInfo.videoPath);
|
|
384
|
+
if (hasMedia && lessonInfo.mediaDuration === undefined) {
|
|
385
|
+
console.log(`Missing remote ${lessonInfo.type} file for lesson:`, lessonInfo.lessonId);
|
|
379
386
|
return false;
|
|
380
387
|
}
|
|
381
|
-
|
|
382
|
-
return true;
|
|
388
|
+
return true;
|
|
383
389
|
}
|
|
384
390
|
/**
|
|
385
391
|
* Validates that the computed lesson duration (from section lengths) matches
|
|
@@ -17,6 +17,21 @@ export interface UploadBucket {
|
|
|
17
17
|
}): Promise<unknown>;
|
|
18
18
|
}
|
|
19
19
|
export type UploadResult = 'uploaded' | 'skipped';
|
|
20
|
+
/** The content type to upload a file with, from its extension. */
|
|
21
|
+
export declare function contentTypeFor(path: string): string;
|
|
22
|
+
export interface UploadFileParams {
|
|
23
|
+
bucket: UploadBucket;
|
|
24
|
+
localPath: string;
|
|
25
|
+
remotePath: string;
|
|
26
|
+
overwrite?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The metadata recording a file's duration, or undefined when the probe didn't
|
|
30
|
+
* return a usable one.
|
|
31
|
+
*/
|
|
32
|
+
export declare function durationMetadata(duration: number): {
|
|
33
|
+
duration: string;
|
|
34
|
+
} | undefined;
|
|
20
35
|
/**
|
|
21
36
|
* Upload a local file to a Cloud Storage bucket. The content type is inferred
|
|
22
37
|
* from the file extension via {@link CONTENT_TYPE_BY_EXTENSION}. Returns
|
|
@@ -26,9 +41,4 @@ export type UploadResult = 'uploaded' | 'skipped';
|
|
|
26
41
|
* Sets a `duration` metadata field (in seconds) from ffprobe when probing
|
|
27
42
|
* succeeds; metadata failures are swallowed since they're non-fatal.
|
|
28
43
|
*/
|
|
29
|
-
export declare function uploadFile({ bucket, localPath, overwrite, remotePath, }:
|
|
30
|
-
bucket: UploadBucket;
|
|
31
|
-
localPath: string;
|
|
32
|
-
remotePath: string;
|
|
33
|
-
overwrite?: boolean;
|
|
34
|
-
}): Promise<UploadResult>;
|
|
44
|
+
export declare function uploadFile({ bucket, localPath, overwrite, remotePath, }: UploadFileParams): Promise<UploadResult>;
|
package/dist/functions/upload.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.contentTypeFor = contentTypeFor;
|
|
4
|
+
exports.durationMetadata = durationMetadata;
|
|
3
5
|
exports.uploadFile = uploadFile;
|
|
4
6
|
const path_1 = require("path");
|
|
5
7
|
const ffmpeg_1 = require("./ffmpeg");
|
|
@@ -7,6 +9,7 @@ const CONTENT_TYPE_BY_EXTENSION = {
|
|
|
7
9
|
'.mp3': 'audio/mpeg',
|
|
8
10
|
'.mp4': 'video/mp4',
|
|
9
11
|
};
|
|
12
|
+
/** The content type to upload a file with, from its extension. */
|
|
10
13
|
function contentTypeFor(path) {
|
|
11
14
|
const ext = (0, path_1.extname)(path).toLowerCase();
|
|
12
15
|
const contentType = CONTENT_TYPE_BY_EXTENSION[ext];
|
|
@@ -15,6 +18,15 @@ function contentTypeFor(path) {
|
|
|
15
18
|
`Add it to CONTENT_TYPE_BY_EXTENSION in shared/functions/upload.ts.`);
|
|
16
19
|
return contentType;
|
|
17
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* The metadata recording a file's duration, or undefined when the probe didn't
|
|
23
|
+
* return a usable one.
|
|
24
|
+
*/
|
|
25
|
+
function durationMetadata(duration) {
|
|
26
|
+
if (isNaN(duration) || duration <= 0)
|
|
27
|
+
return;
|
|
28
|
+
return { duration: duration.toString() };
|
|
29
|
+
}
|
|
18
30
|
/**
|
|
19
31
|
* Upload a local file to a Cloud Storage bucket. The content type is inferred
|
|
20
32
|
* from the file extension via {@link CONTENT_TYPE_BY_EXTENSION}. Returns
|
|
@@ -35,12 +47,9 @@ async function uploadFile({ bucket, localPath, overwrite, remotePath, }) {
|
|
|
35
47
|
public: true,
|
|
36
48
|
});
|
|
37
49
|
try {
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
await bucket.file(remotePath).setMetadata({
|
|
41
|
-
metadata: { duration: duration.toString() },
|
|
42
|
-
});
|
|
43
|
-
}
|
|
50
|
+
const metadata = durationMetadata(await (0, ffmpeg_1.getDurationFromFile)(localPath));
|
|
51
|
+
if (metadata)
|
|
52
|
+
await bucket.file(remotePath).setMetadata({ metadata });
|
|
44
53
|
}
|
|
45
54
|
catch {
|
|
46
55
|
// Non-fatal — proceed even if setting duration metadata fails.
|
|
@@ -2,8 +2,6 @@ export declare const join: (...parts: string[]) => string;
|
|
|
2
2
|
export declare const basename: (p: string) => string;
|
|
3
3
|
export declare const first: (p: string) => string;
|
|
4
4
|
export declare const dirname: (p: string) => string;
|
|
5
|
-
export declare const extname: (p: string) => string;
|
|
6
|
-
export declare const basenamenoext: (p: string) => string;
|
|
7
5
|
/** Safely read `code`/`message` off an unknown thrown value. */
|
|
8
6
|
export declare function getErrorInfo(e: unknown): {
|
|
9
7
|
code?: string;
|
package/dist/functions/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.dirname = exports.first = exports.basename = exports.join = void 0;
|
|
4
4
|
exports.getErrorInfo = getErrorInfo;
|
|
5
5
|
const join = (...parts) => parts.join('/').replace(/\/+/g, '/');
|
|
6
6
|
exports.join = join;
|
|
@@ -10,14 +10,6 @@ const first = (p) => p.split('/')[0];
|
|
|
10
10
|
exports.first = first;
|
|
11
11
|
const dirname = (p) => p.substring(0, p.lastIndexOf('/'));
|
|
12
12
|
exports.dirname = dirname;
|
|
13
|
-
const extname = (p) => p.slice(p.lastIndexOf('.'));
|
|
14
|
-
exports.extname = extname;
|
|
15
|
-
const basenamenoext = (p) => {
|
|
16
|
-
const base = (0, exports.basename)(p);
|
|
17
|
-
const dotIndex = base.lastIndexOf('.');
|
|
18
|
-
return dotIndex !== -1 ? base.slice(0, dotIndex) : base;
|
|
19
|
-
};
|
|
20
|
-
exports.basenamenoext = basenamenoext;
|
|
21
13
|
/** Safely read `code`/`message` off an unknown thrown value. */
|
|
22
14
|
function getErrorInfo(e) {
|
|
23
15
|
const code = typeof e === 'object' &&
|
package/dist/types/logs.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import z from 'zod';
|
|
|
2
2
|
export declare const WahaShareContent: z.ZodEnum<{
|
|
3
3
|
lesson: "lesson";
|
|
4
4
|
note: "note";
|
|
5
|
-
setLink: "setLink";
|
|
6
5
|
lessonLink: "lessonLink";
|
|
6
|
+
setLink: "setLink";
|
|
7
7
|
app: "app";
|
|
8
8
|
passcode: "passcode";
|
|
9
9
|
lessonAudio: "lessonAudio";
|
|
@@ -30,8 +30,8 @@ export declare const ShareLogEvent: z.ZodObject<{
|
|
|
30
30
|
content: z.ZodEnum<{
|
|
31
31
|
lesson: "lesson";
|
|
32
32
|
note: "note";
|
|
33
|
-
setLink: "setLink";
|
|
34
33
|
lessonLink: "lessonLink";
|
|
34
|
+
setLink: "setLink";
|
|
35
35
|
app: "app";
|
|
36
36
|
passcode: "passcode";
|
|
37
37
|
lessonAudio: "lessonAudio";
|
|
@@ -19,13 +19,13 @@ export declare const PushNotificationRecord: z.ZodObject<{
|
|
|
19
19
|
actionUrl: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
20
20
|
countriesToNotSendTo: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
21
21
|
countriesToSendTo: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
22
|
-
faithJourney: z.
|
|
22
|
+
faithJourney: z.ZodEnum<{
|
|
23
23
|
all: "all";
|
|
24
24
|
seekers: "seekers";
|
|
25
25
|
believers: "believers";
|
|
26
|
-
}
|
|
26
|
+
}>;
|
|
27
27
|
imageUrl: z.ZodOptional<z.ZodString>;
|
|
28
|
-
meetLanguages: z.
|
|
28
|
+
meetLanguages: z.ZodUnion<readonly [z.ZodLiteral<"all">, z.ZodArray<z.ZodString>]>;
|
|
29
29
|
minCompletions: z.ZodOptional<z.ZodNumber>;
|
|
30
30
|
pushBody: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
31
31
|
pushTitle: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
package/dist/types/sets.d.ts
CHANGED
|
@@ -22,6 +22,12 @@ export interface BaseInfo extends LanguageInfo {
|
|
|
22
22
|
fellowshipDuration: number;
|
|
23
23
|
/** Full duration in seconds of all of the lesson's application questions. */
|
|
24
24
|
applicationDuration: number;
|
|
25
|
+
/**
|
|
26
|
+
* Duration in seconds of the lesson's main media file (`fullPath` for DBS,
|
|
27
|
+
* `videoPath` for video, `eqPath` for EQ). Undefined when the file isn't in
|
|
28
|
+
* `mediaDurations`, i.e. it hasn't been uploaded.
|
|
29
|
+
*/
|
|
30
|
+
mediaDuration: number | undefined;
|
|
25
31
|
}
|
|
26
32
|
export interface Section {
|
|
27
33
|
id: string;
|
|
@@ -38,6 +44,14 @@ export interface Section {
|
|
|
38
44
|
*/
|
|
39
45
|
ftbPath?: string;
|
|
40
46
|
path: string;
|
|
47
|
+
/**
|
|
48
|
+
* Duration in seconds of this section's own audio, resolved when the lesson
|
|
49
|
+
* is assembled. Story sections only have one when they're a custom passage
|
|
50
|
+
* recording; otherwise their length comes from verse timings.
|
|
51
|
+
*/
|
|
52
|
+
duration?: number;
|
|
53
|
+
/** Duration in seconds of the `ftbPath` clip, when there is one. */
|
|
54
|
+
ftbDuration?: number;
|
|
41
55
|
}
|
|
42
56
|
export interface EnrichedSection extends Section {
|
|
43
57
|
startTime: number;
|
package/dist/types/users.d.ts
CHANGED
|
@@ -245,8 +245,8 @@ export declare const LegacyWahaUser: z.ZodObject<{
|
|
|
245
245
|
content: z.ZodEnum<{
|
|
246
246
|
lesson: "lesson";
|
|
247
247
|
note: "note";
|
|
248
|
-
setLink: "setLink";
|
|
249
248
|
lessonLink: "lessonLink";
|
|
249
|
+
setLink: "setLink";
|
|
250
250
|
app: "app";
|
|
251
251
|
passcode: "passcode";
|
|
252
252
|
lessonAudio: "lessonAudio";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "waha-shared",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.511",
|
|
4
4
|
"author": "Waha",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@types/signale": "^1.4.7",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"description": "Shared assets for Waha's various apps",
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@crowdin/crowdin-api-client": "^1.59.
|
|
16
|
+
"@crowdin/crowdin-api-client": "^1.59.1",
|
|
17
17
|
"@types/react": "^19.3.0",
|
|
18
18
|
"copyfiles": "^2.4.1",
|
|
19
19
|
"react": "^19.3.0",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"scripts": {
|
|
30
30
|
"build": "npx tsc && npx copyfiles \"data/**/*.json\" dist",
|
|
31
|
-
"update": "
|
|
32
|
-
"updateManual": "(npm whoami || npm login) &&
|
|
31
|
+
"update": "npm run build && REGISTRY_VERSION=$(npm view waha-shared version) && npm version $REGISTRY_VERSION --no-git-tag-version --allow-same-version && npm version patch --no-git-tag-version && git add . && (git commit -m 'chore: build waha-shared' || true) && bash -c 'npm publish --access public --registry https://registry.npmjs.org --//registry.npmjs.org/:_authToken=$(grep NPM_TOKEN= ../.env | cut -d \"=\" -f2-)'",
|
|
32
|
+
"updateManual": "(npm whoami || npm login) && npm run build && REGISTRY_VERSION=$(npm view waha-shared version) && npm version $REGISTRY_VERSION --no-git-tag-version --allow-same-version && npm version patch --no-git-tag-version && git add dist package.json && (git commit -m 'chore: build waha-shared' || true) && npm publish"
|
|
33
33
|
}
|
|
34
34
|
}
|