Skip to content

Commit d2ea5eb

Browse files
authored
Merge pull request #640 from Telegram-Mini-Apps/feature/retrieve-raw-lp
Feature/retrieve raw lp
2 parents 1895d11 + e356df3 commit d2ea5eb

File tree

9 files changed

+81
-65
lines changed

9 files changed

+81
-65
lines changed

.changeset/gorgeous-forks-clap.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@telegram-apps/sdk": patch
3+
---
4+
5+
Remove some errors exported from bridge.

.changeset/polite-spies-nail.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@telegram-apps/bridge": minor
3+
---
4+
5+
Implement `retrieveRawLaunchParams`.

packages/bridge/src/errors.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { errorClass, errorClassWithData } from 'error-kid';
1+
import { errorClass } from 'error-kid';
22
import type { Version } from '@telegram-apps/types';
33

44
export const [
@@ -30,11 +30,7 @@ const retrieveLaunchParamsError = [
3030
export const [
3131
LaunchParamsRetrieveError,
3232
isLaunchParamsRetrieveError,
33-
] = errorClassWithData<unknown[], [errors: unknown[]]>(
34-
'LaunchParamsRetrieveError',
35-
errors => errors,
36-
retrieveLaunchParamsError,
37-
);
33+
] = errorClass<unknown[]>('LaunchParamsRetrieveError', retrieveLaunchParamsError);
3834

3935
export const [
4036
InvalidLaunchParamsError,
@@ -43,11 +39,6 @@ export const [
4339
`Invalid value for launch params: ${value}`,
4440
]);
4541

46-
export const [
47-
InitDataRetrieveError,
48-
isInitDataRetrieveError,
49-
] = errorClass('InitDataRetrieveError', retrieveLaunchParamsError);
50-
5142
export const [UnknownEnvError, isUnknownEnvError] = errorClass('UnknownEnvError');
5243

5344
export const [

packages/bridge/src/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export {
1313
type RetrieveLPResultCamelCased,
1414
type RetrieveLPResult,
1515
} from '@/launch-params/retrieveLaunchParams.js';
16+
export { retrieveRawLaunchParams } from '@/launch-params/retrieveRawLaunchParams.js';
1617
export { retrieveRawInitData } from '@/launch-params/retrieveRawInitData.js';
1718

1819
export type * from '@/methods/types/index.js';
@@ -55,8 +56,6 @@ export {
5556
isMethodMethodParameterUnsupportedError,
5657
UnknownEnvError,
5758
isUnknownEnvError,
58-
InitDataRetrieveError,
59-
isInitDataRetrieveError,
6059
InvalidLaunchParamsError,
6160
isInvalidLaunchParamsError,
6261
} from '@/errors.js';

packages/bridge/src/launch-params/retrieveLaunchParams.ts

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ import { LaunchParamsSchema, parseLaunchParamsQuery } from '@telegram-apps/trans
22
import {
33
type DeepConvertSnakeKeysToCamelCase,
44
deepSnakeToCamelObjKeys,
5-
setStorageValue,
65
} from '@telegram-apps/toolkit';
76
import type { InferOutput } from 'valibot';
87

9-
import { LaunchParamsRetrieveError } from '@/errors.js';
10-
import { forEachLpSource } from '@/launch-params/forEachLpSource.js';
8+
import { retrieveRawLaunchParams } from '@/launch-params/retrieveRawLaunchParams.js';
119

1210
export type RetrieveLPResult = InferOutput<typeof LaunchParamsSchema>;
1311
export type RetrieveLPResultCamelCased =
@@ -37,21 +35,6 @@ export function retrieveLaunchParams(camelCase: true): RetrieveLPResultCamelCase
3735
export function retrieveLaunchParams(camelCase?: boolean):
3836
| RetrieveLPResult
3937
| RetrieveLPResultCamelCased {
40-
const errors: unknown[] = [];
41-
let launchParams: RetrieveLPResult | undefined;
42-
43-
forEachLpSource(v => {
44-
try {
45-
launchParams = parseLaunchParamsQuery(v);
46-
setStorageValue('launchParams', v);
47-
return false;
48-
} catch (e) {
49-
errors.push(e);
50-
return true;
51-
}
52-
});
53-
if (!launchParams) {
54-
throw new LaunchParamsRetrieveError(errors);
55-
}
38+
const launchParams = parseLaunchParamsQuery(retrieveRawLaunchParams());
5639
return camelCase ? deepSnakeToCamelObjKeys(launchParams) : launchParams;
5740
}
Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,9 @@
1-
import { isLaunchParamsQuery } from '@telegram-apps/transformers';
2-
3-
import { forEachLpSource } from '@/launch-params/forEachLpSource.js';
4-
import { InitDataRetrieveError } from '@/errors.js';
5-
import { retrieveLaunchParams } from '@/launch-params/retrieveLaunchParams.js';
1+
import { retrieveRawLaunchParams } from '@/launch-params/retrieveRawLaunchParams.js';
62

73
/**
84
* @returns Raw init data from any known source.
9-
* @throws {InitDataRetrieveError} Unable to retrieve init data from any known source.
5+
* @throws {LaunchParamsRetrieveError} Unable to retrieve launch params from any known source.
106
*/
117
export function retrieveRawInitData(): string | undefined {
12-
// Init data depends on the launch parameters. We also want them to be saved.
13-
try {
14-
retrieveLaunchParams();
15-
} catch {
16-
throw new InitDataRetrieveError();
17-
}
18-
19-
let initData: string | undefined;
20-
forEachLpSource(v => {
21-
if (isLaunchParamsQuery(v)) {
22-
initData = new URLSearchParams(v).get('tgWebAppData') || undefined;
23-
return false;
24-
}
25-
return true;
26-
});
27-
return initData;
8+
return new URLSearchParams(retrieveRawLaunchParams()).get('tgWebAppData') || undefined;
289
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { afterEach, describe, expect, it, vi } from 'vitest';
2+
3+
import { retrieveRawLaunchParams } from '@/launch-params/retrieveRawLaunchParams.js';
4+
5+
afterEach(() => {
6+
vi.restoreAllMocks();
7+
});
8+
9+
describe('window.location.href contains launch params', () => {
10+
it('should retrieve launch params from the window.location.href. Throw an error if data is invalid or missing', () => {
11+
vi
12+
.spyOn(window.location, 'href', 'get')
13+
.mockImplementationOnce(() => {
14+
return '/abc?tgWebAppStartParam=location_hash#tgWebAppPlatform=tdesktop&tgWebAppVersion=7.0&tgWebAppThemeParams=%7B%7D';
15+
});
16+
17+
expect(retrieveRawLaunchParams()).toBe('tgWebAppStartParam=location_hash&tgWebAppPlatform=tdesktop&tgWebAppVersion=7.0&tgWebAppThemeParams=%7B%7D');
18+
});
19+
});
20+
21+
describe('first navigation entry contains launch params', () => {
22+
it('should retrieve launch params from the window.performance. Throw an error if data is invalid or missing', () => {
23+
vi
24+
.spyOn(performance, 'getEntriesByType')
25+
.mockImplementationOnce(() => [{
26+
name: '/abc?tgWebAppStartParam=performance#tgWebAppPlatform=macos&tgWebAppVersion=7.3&tgWebAppThemeParams=%7B%7D',
27+
}] as any);
28+
29+
expect(retrieveRawLaunchParams()).toBe('tgWebAppStartParam=performance&tgWebAppPlatform=macos&tgWebAppVersion=7.3&tgWebAppThemeParams=%7B%7D');
30+
});
31+
});
32+
33+
describe('session storage contains launch params', () => {
34+
it('should return launch parameters from the session storage tapps/launchParams key. If data is missing or invalid, throw an error', () => {
35+
const spy = vi
36+
.spyOn(sessionStorage, 'getItem')
37+
.mockImplementationOnce(() => '');
38+
expect(() => retrieveRawLaunchParams()).toThrow();
39+
40+
spy.mockClear();
41+
spy.mockImplementationOnce(() => {
42+
return '"tgWebAppPlatform=android&tgWebAppThemeParams=%7B%22bg_color%22%3A%22%23ffffff%22%7D&tgWebAppVersion=7.5"';
43+
});
44+
expect(retrieveRawLaunchParams()).toBe('tgWebAppPlatform=android&tgWebAppThemeParams=%7B%22bg_color%22%3A%22%23ffffff%22%7D&tgWebAppVersion=7.5');
45+
});
46+
});

packages/bridge/src/launch-params/forEachLpSource.ts renamed to packages/bridge/src/launch-params/retrieveRawLaunchParams.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { getStorageValue } from '@telegram-apps/toolkit';
1+
import { isLaunchParamsQuery } from '@telegram-apps/transformers';
2+
import { getStorageValue, setStorageValue } from '@telegram-apps/toolkit';
3+
4+
import { LaunchParamsRetrieveError } from '@/errors.js';
5+
6+
const SESSION_STORAGE_KEY = 'launchParams';
27

38
/**
49
* @param urlString - URL to extract launch parameters from.
@@ -14,25 +19,27 @@ function fromURL(urlString: string): string {
1419
}
1520

1621
/**
17-
* Runs the specified function for each value, where the value is one stored in any known
18-
* launch parameters source.
19-
* @param fn - function to run. Should return false when the execution must be stopped.
22+
* @returns Launch parameters in a raw format from any known source.
23+
* @throws {LaunchParamsRetrieveError} Unable to retrieve launch parameters. They are probably
24+
* invalid.
2025
*/
21-
export function forEachLpSource(fn: (value: string) => boolean): void {
26+
export function retrieveRawLaunchParams(): string {
2227
for (const retrieve of [
2328
// Try to retrieve launch parameters from the current location. This method can return
2429
// nothing in case, location was changed, and then the page was reloaded.
2530
() => fromURL(window.location.href),
2631
// Then, try using the lower level API - window.performance.
2732
() => {
2833
const navigationEntry = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming | undefined;
29-
return navigationEntry ? fromURL(navigationEntry.name) : undefined;
34+
return navigationEntry && fromURL(navigationEntry.name);
3035
},
31-
() => getStorageValue<string>('launchParams') || '',
36+
() => getStorageValue<string>(SESSION_STORAGE_KEY),
3237
]) {
3338
const v = retrieve();
34-
if (v && !fn(v)) {
35-
return;
39+
if (v && isLaunchParamsQuery(v)) {
40+
setStorageValue(SESSION_STORAGE_KEY, v);
41+
return v;
3642
}
3743
}
44+
throw new LaunchParamsRetrieveError();
3845
}

packages/sdk/src/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export {
5555
on,
5656
off,
5757
retrieveLaunchParams,
58+
retrieveRawLaunchParams,
5859
retrieveRawInitData,
5960
type RetrieveLPResult,
6061
type RetrieveLPResultCamelCased,
@@ -114,8 +115,6 @@ export {
114115
isLaunchParamsRetrieveError,
115116
LaunchParamsRetrieveError,
116117
InvalidLaunchParamsError,
117-
InitDataRetrieveError,
118-
isInitDataRetrieveError,
119118
isInvalidLaunchParamsError,
120119
type BackgroundColor,
121120
type PopupParams,

0 commit comments

Comments
 (0)