@mradex77/google-play-scraper 0.1.1 → 0.2.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.
- package/README.md +109 -33
- package/dist/index.cjs +77 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +77 -14
- package/dist/index.js.map +1 -1
- package/package.json +24 -3
package/dist/index.d.cts
CHANGED
|
@@ -252,8 +252,8 @@ declare const searchOptionsSchema: z.ZodObject<{
|
|
|
252
252
|
term: z.ZodString;
|
|
253
253
|
num: z.ZodDefault<z.ZodNumber>;
|
|
254
254
|
price: z.ZodDefault<z.ZodEnum<{
|
|
255
|
-
all: "all";
|
|
256
255
|
free: "free";
|
|
256
|
+
all: "all";
|
|
257
257
|
paid: "paid";
|
|
258
258
|
}>>;
|
|
259
259
|
fullDetail: z.ZodDefault<z.ZodBoolean>;
|
package/dist/index.d.ts
CHANGED
|
@@ -252,8 +252,8 @@ declare const searchOptionsSchema: z.ZodObject<{
|
|
|
252
252
|
term: z.ZodString;
|
|
253
253
|
num: z.ZodDefault<z.ZodNumber>;
|
|
254
254
|
price: z.ZodDefault<z.ZodEnum<{
|
|
255
|
-
all: "all";
|
|
256
255
|
free: "free";
|
|
256
|
+
all: "all";
|
|
257
257
|
paid: "paid";
|
|
258
258
|
}>>;
|
|
259
259
|
fullDetail: z.ZodDefault<z.ZodBoolean>;
|
package/dist/index.js
CHANGED
|
@@ -495,6 +495,36 @@ const appSchema = z.object({
|
|
|
495
495
|
url: z.string()
|
|
496
496
|
});
|
|
497
497
|
//#endregion
|
|
498
|
+
//#region src/core/text.ts
|
|
499
|
+
const TAB = 9;
|
|
500
|
+
const LINE_FEED = 10;
|
|
501
|
+
const CARRIAGE_RETURN = 13;
|
|
502
|
+
const UNIT_SEPARATOR = 31;
|
|
503
|
+
const DELETE = 127;
|
|
504
|
+
const C1_END = 159;
|
|
505
|
+
const SURROGATE_START = 55296;
|
|
506
|
+
const SURROGATE_END = 57343;
|
|
507
|
+
function isPreservedWhitespace(code) {
|
|
508
|
+
return code === TAB || code === LINE_FEED || code === CARRIAGE_RETURN;
|
|
509
|
+
}
|
|
510
|
+
function isControlCharacter(code) {
|
|
511
|
+
if (isPreservedWhitespace(code)) return false;
|
|
512
|
+
return code <= UNIT_SEPARATOR || code >= DELETE && code <= C1_END;
|
|
513
|
+
}
|
|
514
|
+
function isLoneSurrogate(code) {
|
|
515
|
+
return code >= SURROGATE_START && code <= SURROGATE_END;
|
|
516
|
+
}
|
|
517
|
+
function sanitizeText(value) {
|
|
518
|
+
if (typeof value !== "string") return;
|
|
519
|
+
let result = "";
|
|
520
|
+
for (const character of value) {
|
|
521
|
+
const code = character.codePointAt(0) ?? 0;
|
|
522
|
+
if (isControlCharacter(code) || isLoneSurrogate(code)) continue;
|
|
523
|
+
result += character;
|
|
524
|
+
}
|
|
525
|
+
return result;
|
|
526
|
+
}
|
|
527
|
+
//#endregion
|
|
498
528
|
//#region src/features/app/transforms.ts
|
|
499
529
|
const COMMENT_ROOTS = ["ds:8", "ds:9"];
|
|
500
530
|
const MAX_COMMENTS = 5;
|
|
@@ -511,12 +541,11 @@ function descriptionHtmlLocalized(value) {
|
|
|
511
541
|
0,
|
|
512
542
|
1
|
|
513
543
|
]);
|
|
514
|
-
|
|
515
|
-
return typeof resolved === "string" ? resolved : void 0;
|
|
544
|
+
return sanitizeText(typeof translated === "string" && translated.length > 0 ? translated : original);
|
|
516
545
|
}
|
|
517
546
|
function descriptionText(html) {
|
|
518
547
|
if (typeof html !== "string") return;
|
|
519
|
-
return cheerio.load(`<div>${html.replace(/<br>/g, "\r\n")}</div>`)("div").text();
|
|
548
|
+
return sanitizeText(cheerio.load(`<div>${html.replace(/<br>/g, "\r\n")}</div>`)("div").text());
|
|
520
549
|
}
|
|
521
550
|
function priceText(value) {
|
|
522
551
|
return typeof value === "string" && value.length > 0 ? value : "Free";
|
|
@@ -1295,7 +1324,8 @@ const appSpecs = {
|
|
|
1295
1324
|
1,
|
|
1296
1325
|
1
|
|
1297
1326
|
]],
|
|
1298
|
-
schema: shape$6.recentChanges
|
|
1327
|
+
schema: shape$6.recentChanges,
|
|
1328
|
+
transform: sanitizeText
|
|
1299
1329
|
},
|
|
1300
1330
|
comments: {
|
|
1301
1331
|
paths: [[]],
|
|
@@ -1853,6 +1883,17 @@ function priceGoogleValue(value) {
|
|
|
1853
1883
|
default: return 0;
|
|
1854
1884
|
}
|
|
1855
1885
|
}
|
|
1886
|
+
function matchesPriceFilter(free, filter) {
|
|
1887
|
+
switch (filter) {
|
|
1888
|
+
case "free": return free;
|
|
1889
|
+
case "paid": return !free;
|
|
1890
|
+
default: return true;
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
function filterByPrice(items, filter) {
|
|
1894
|
+
if (filter === "all") return [...items];
|
|
1895
|
+
return items.filter((item) => matchesPriceFilter(item.free, filter));
|
|
1896
|
+
}
|
|
1856
1897
|
//#endregion
|
|
1857
1898
|
//#region src/features/search/search.ts
|
|
1858
1899
|
const searchOptionsSchema = baseOptionsSchema.extend({
|
|
@@ -1913,7 +1954,7 @@ function createSearch(getApp) {
|
|
|
1913
1954
|
});
|
|
1914
1955
|
const client = clientFromOptions(parsed);
|
|
1915
1956
|
const page = firstPage(parseScriptData(await client.request({ url: `${SEARCH_URL}?${params.toString()}` })));
|
|
1916
|
-
const sliced = (await fetchClusterApps({
|
|
1957
|
+
const sliced = filterByPrice(await fetchClusterApps({
|
|
1917
1958
|
client,
|
|
1918
1959
|
lang: parsed.lang,
|
|
1919
1960
|
country: parsed.country,
|
|
@@ -1924,7 +1965,7 @@ function createSearch(getApp) {
|
|
|
1924
1965
|
appsPath: CLUSTER_MAPPINGS$1.apps,
|
|
1925
1966
|
tokenPath: CLUSTER_MAPPINGS$1.token,
|
|
1926
1967
|
context: SEARCH_CONTEXT
|
|
1927
|
-
})).slice(0, parsed.num);
|
|
1968
|
+
}), parsed.price).slice(0, parsed.num);
|
|
1928
1969
|
if (parsed.fullDetail) return resolveFullDetail(sliced, parsed, getApp);
|
|
1929
1970
|
return z.array(searchResultSchema).parse(sliced);
|
|
1930
1971
|
};
|
|
@@ -2547,17 +2588,35 @@ const developerOptionsSchema = baseOptionsSchema.extend({
|
|
|
2547
2588
|
fullDetail: z.boolean().default(false)
|
|
2548
2589
|
});
|
|
2549
2590
|
const DEVELOPER_CONTEXT = "developer";
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2591
|
+
const NUMERIC_LAYOUT = {
|
|
2592
|
+
mappings: NUMERIC_INITIAL_MAPPINGS,
|
|
2593
|
+
itemSpecs: numericItemSpecs
|
|
2594
|
+
};
|
|
2595
|
+
const NAME_LAYOUT = {
|
|
2596
|
+
mappings: NAME_INITIAL_MAPPINGS,
|
|
2597
|
+
itemSpecs: nameItemSpecs
|
|
2598
|
+
};
|
|
2599
|
+
function extractLayout(blocks, layout) {
|
|
2600
|
+
const appsData = getPath(blocks, layout.mappings.apps);
|
|
2601
|
+
if (!Array.isArray(appsData) || appsData.length === 0) return;
|
|
2602
|
+
const apps = appsData.map((item) => extract(item, layout.itemSpecs, DEVELOPER_CONTEXT));
|
|
2603
|
+
const token = getPath(blocks, layout.mappings.token);
|
|
2556
2604
|
return {
|
|
2557
2605
|
apps,
|
|
2558
2606
|
token: typeof token === "string" ? token : void 0
|
|
2559
2607
|
};
|
|
2560
2608
|
}
|
|
2609
|
+
function extractInitial(blocks, numeric) {
|
|
2610
|
+
const ordered = numeric ? [NUMERIC_LAYOUT, NAME_LAYOUT] : [NAME_LAYOUT, NUMERIC_LAYOUT];
|
|
2611
|
+
for (const layout of ordered) {
|
|
2612
|
+
const extracted = extractLayout(blocks, layout);
|
|
2613
|
+
if (extracted !== void 0) return extracted;
|
|
2614
|
+
}
|
|
2615
|
+
return {
|
|
2616
|
+
apps: [],
|
|
2617
|
+
token: void 0
|
|
2618
|
+
};
|
|
2619
|
+
}
|
|
2561
2620
|
function createDeveloper(getApp) {
|
|
2562
2621
|
return async function developer(options) {
|
|
2563
2622
|
const parsed = parseOptions(developerOptionsSchema, options, DEVELOPER_CONTEXT);
|
|
@@ -2841,6 +2900,9 @@ function alwaysNull() {
|
|
|
2841
2900
|
function emptyToUndefined(value) {
|
|
2842
2901
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2843
2902
|
}
|
|
2903
|
+
function cleanReplyText(value) {
|
|
2904
|
+
return emptyToUndefined(sanitizeText(value));
|
|
2905
|
+
}
|
|
2844
2906
|
function buildCriteria(entry) {
|
|
2845
2907
|
if (!Array.isArray(entry)) return {
|
|
2846
2908
|
criteria: void 0,
|
|
@@ -2892,7 +2954,8 @@ const reviewItemSpecs = {
|
|
|
2892
2954
|
},
|
|
2893
2955
|
text: {
|
|
2894
2956
|
paths: [[4]],
|
|
2895
|
-
schema: shape.text
|
|
2957
|
+
schema: shape.text,
|
|
2958
|
+
transform: sanitizeText
|
|
2896
2959
|
},
|
|
2897
2960
|
replyDate: {
|
|
2898
2961
|
paths: [[7, 2]],
|
|
@@ -2902,7 +2965,7 @@ const reviewItemSpecs = {
|
|
|
2902
2965
|
replyText: {
|
|
2903
2966
|
paths: [[7, 1]],
|
|
2904
2967
|
schema: shape.replyText,
|
|
2905
|
-
transform:
|
|
2968
|
+
transform: cleanReplyText
|
|
2906
2969
|
},
|
|
2907
2970
|
version: {
|
|
2908
2971
|
paths: [[10]],
|