pabal-web-mcp 1.4.4 → 1.4.5
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/dist/bin/mcp-server.js +85 -4
- package/package.json +1 -1
package/dist/bin/mcp-server.js
CHANGED
|
@@ -530,6 +530,7 @@ var GOOGLE_PLAY_LIMITS = {
|
|
|
530
530
|
shortDescription: 80,
|
|
531
531
|
fullDescription: 4e3
|
|
532
532
|
};
|
|
533
|
+
var INVALID_CHAR_REGEX = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\u007F-\u009F\uFEFF\u200B-\u200F\u202A-\u202E\u2060\uFE00-\uFE0F]/g;
|
|
533
534
|
var toJsonSchema2 = zodToJsonSchema2;
|
|
534
535
|
var publicToAsoInputSchema = z2.object({
|
|
535
536
|
slug: z2.string().describe("Product slug"),
|
|
@@ -540,6 +541,76 @@ var jsonSchema2 = toJsonSchema2(publicToAsoInputSchema, {
|
|
|
540
541
|
$refStrategy: "none"
|
|
541
542
|
});
|
|
542
543
|
var inputSchema2 = jsonSchema2.definitions?.PublicToAsoInput || jsonSchema2;
|
|
544
|
+
function sanitizeText(value, fieldPath, warnings) {
|
|
545
|
+
if (typeof value !== "string") {
|
|
546
|
+
return value;
|
|
547
|
+
}
|
|
548
|
+
const cleaned = value.replace(INVALID_CHAR_REGEX, "");
|
|
549
|
+
if (cleaned !== value) {
|
|
550
|
+
warnings.push(`Removed invalid characters from ${fieldPath}`);
|
|
551
|
+
}
|
|
552
|
+
return cleaned;
|
|
553
|
+
}
|
|
554
|
+
function sanitizeAsoData(configData) {
|
|
555
|
+
const sanitizedData = JSON.parse(JSON.stringify(configData));
|
|
556
|
+
const warnings = [];
|
|
557
|
+
if (sanitizedData.appStore) {
|
|
558
|
+
const appStoreData = sanitizedData.appStore;
|
|
559
|
+
const locales = isAppStoreMultilingual(appStoreData) ? appStoreData.locales : { [appStoreData.locale || DEFAULT_LOCALE]: appStoreData };
|
|
560
|
+
for (const [locale, data] of Object.entries(locales)) {
|
|
561
|
+
data.name = sanitizeText(data.name, `App Store [${locale}].name`, warnings);
|
|
562
|
+
data.subtitle = sanitizeText(
|
|
563
|
+
data.subtitle,
|
|
564
|
+
`App Store [${locale}].subtitle`,
|
|
565
|
+
warnings
|
|
566
|
+
);
|
|
567
|
+
data.keywords = sanitizeText(
|
|
568
|
+
data.keywords,
|
|
569
|
+
`App Store [${locale}].keywords`,
|
|
570
|
+
warnings
|
|
571
|
+
);
|
|
572
|
+
data.promotionalText = sanitizeText(
|
|
573
|
+
data.promotionalText,
|
|
574
|
+
`App Store [${locale}].promotionalText`,
|
|
575
|
+
warnings
|
|
576
|
+
);
|
|
577
|
+
data.description = sanitizeText(
|
|
578
|
+
data.description,
|
|
579
|
+
`App Store [${locale}].description`,
|
|
580
|
+
warnings
|
|
581
|
+
);
|
|
582
|
+
data.whatsNew = sanitizeText(
|
|
583
|
+
data.whatsNew,
|
|
584
|
+
`App Store [${locale}].whatsNew`,
|
|
585
|
+
warnings
|
|
586
|
+
);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
if (sanitizedData.googlePlay) {
|
|
590
|
+
const googlePlayData = sanitizedData.googlePlay;
|
|
591
|
+
const locales = isGooglePlayMultilingual(googlePlayData) ? googlePlayData.locales : {
|
|
592
|
+
[googlePlayData.defaultLanguage || DEFAULT_LOCALE]: googlePlayData
|
|
593
|
+
};
|
|
594
|
+
for (const [locale, data] of Object.entries(locales)) {
|
|
595
|
+
data.title = sanitizeText(
|
|
596
|
+
data.title,
|
|
597
|
+
`Google Play [${locale}].title`,
|
|
598
|
+
warnings
|
|
599
|
+
);
|
|
600
|
+
data.shortDescription = sanitizeText(
|
|
601
|
+
data.shortDescription,
|
|
602
|
+
`Google Play [${locale}].shortDescription`,
|
|
603
|
+
warnings
|
|
604
|
+
);
|
|
605
|
+
data.fullDescription = sanitizeText(
|
|
606
|
+
data.fullDescription,
|
|
607
|
+
`Google Play [${locale}].fullDescription`,
|
|
608
|
+
warnings
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return { sanitizedData, warnings };
|
|
613
|
+
}
|
|
543
614
|
function validateFieldLimits(configData) {
|
|
544
615
|
const issues = [];
|
|
545
616
|
if (configData.appStore) {
|
|
@@ -738,7 +809,8 @@ Before running, review ${FIELD_LIMITS_DOC_PATH} for per-store limits. This prepa
|
|
|
738
809
|
async function handlePublicToAso(input) {
|
|
739
810
|
const { slug, dryRun } = input;
|
|
740
811
|
const configData = loadAsoFromConfig(slug);
|
|
741
|
-
|
|
812
|
+
const { sanitizedData, warnings: sanitizeWarnings } = sanitizeAsoData(configData);
|
|
813
|
+
if (!sanitizedData.googlePlay && !sanitizedData.appStore) {
|
|
742
814
|
const productsDir = getProductsDir();
|
|
743
815
|
const configPath = path4.join(productsDir, slug, "config.json");
|
|
744
816
|
const localesDir = path4.join(productsDir, slug, "locales");
|
|
@@ -819,8 +891,8 @@ Possible causes:
|
|
|
819
891
|
4. Locale files don't contain valid ASO data`
|
|
820
892
|
);
|
|
821
893
|
}
|
|
822
|
-
const storeData = prepareAsoDataForPush(slug,
|
|
823
|
-
const validationIssues = validateFieldLimits(
|
|
894
|
+
const storeData = prepareAsoDataForPush(slug, sanitizedData);
|
|
895
|
+
const validationIssues = validateFieldLimits(sanitizedData);
|
|
824
896
|
const validationMessage = validationIssues.length > 0 ? `\u26A0\uFE0F Field limit issues (see ${FIELD_LIMITS_DOC_PATH}):
|
|
825
897
|
- ${validationIssues.join(
|
|
826
898
|
"\n- "
|
|
@@ -839,7 +911,9 @@ ${JSON.stringify(
|
|
|
839
911
|
2
|
|
840
912
|
)}
|
|
841
913
|
|
|
842
|
-
${validationMessage}`
|
|
914
|
+
${validationMessage}${sanitizeWarnings.length ? `
|
|
915
|
+
Sanitized invalid characters:
|
|
916
|
+
- ${sanitizeWarnings.join("\n- ")}` : ""}`
|
|
843
917
|
}
|
|
844
918
|
]
|
|
845
919
|
};
|
|
@@ -880,6 +954,13 @@ ${validationMessage}`
|
|
|
880
954
|
Next step: Push to stores using pabal-mcp's aso-push tool`;
|
|
881
955
|
responseText += `
|
|
882
956
|
Reference: ${FIELD_LIMITS_DOC_PATH}`;
|
|
957
|
+
if (sanitizeWarnings.length > 0) {
|
|
958
|
+
responseText += `
|
|
959
|
+
Sanitized invalid characters:
|
|
960
|
+
- ${sanitizeWarnings.join(
|
|
961
|
+
"\n- "
|
|
962
|
+
)}`;
|
|
963
|
+
}
|
|
883
964
|
return {
|
|
884
965
|
content: [
|
|
885
966
|
{
|