pxt-core 13.2.15 → 13.2.17
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/built/backendutils.js +53 -16
- package/built/cli.js +14 -9
- package/built/nodeutil.js +3 -7
- package/built/pxt.js +67 -25
- package/built/pxtlib.js +53 -16
- package/built/target.js +1 -1
- package/built/targetlight.js +1 -1
- package/built/tests/cli-test/cli/commandparser.d.ts +49 -0
- package/built/tests/cli-test/cli/nodeutil.d.ts +95 -0
- package/built/tests/cli-test/tests/cli-test/bump.d.ts +1 -0
- package/built/tests/cli-test/tests/cli-test/clirunner.d.ts +1 -0
- package/built/web/main.js +1 -1
- package/built/web/pxtapp.js +2 -2
- package/built/web/pxtembed.js +1 -1
- package/built/web/pxtlib.js +1 -1
- package/built/web/pxtworker.js +1 -1
- package/built/web/rtlsemantic.css +1 -1
- package/built/web/semantic.css +1 -1
- package/package.json +1 -1
- package/theme/highcontrast.less +4 -0
package/built/backendutils.js
CHANGED
|
@@ -572,6 +572,8 @@ const lf = ts.pxtc.Util.lf;
|
|
|
572
572
|
let parts = k.split(".");
|
|
573
573
|
for (let i = 0; i < parts.length; ++i) {
|
|
574
574
|
let part = parts[i];
|
|
575
|
+
if (part === "__proto__" || part === "constructor" || part === "prototype")
|
|
576
|
+
Util.userError("Invalid configuration key: " + k);
|
|
575
577
|
if (i == parts.length - 1)
|
|
576
578
|
ptr[part] = v[k];
|
|
577
579
|
else {
|
|
@@ -1416,12 +1418,20 @@ ${opts.repo.name.replace(/^pxt-/, '')}=github:${opts.repo.fullName}#${opts.repo.
|
|
|
1416
1418
|
strong: 1,
|
|
1417
1419
|
em: 1,
|
|
1418
1420
|
};
|
|
1421
|
+
/** Keeps metadata and token-only HTML out of the translation catalog. */
|
|
1422
|
+
function isNonTranslatable(text) {
|
|
1423
|
+
if (text.startsWith("IE=edge,") || text.startsWith("width=device-width"))
|
|
1424
|
+
return true;
|
|
1425
|
+
// Remove URLs, template placeholders, and spacing entities to look for prose.
|
|
1426
|
+
const prose = text.replace(/(?:https?:\/\/|\/)[\w@\/.]+|@[-\w]+@|\{[^{}]+\}| /g, "");
|
|
1427
|
+
return !/[a-zA-Z]/.test(prose);
|
|
1428
|
+
}
|
|
1419
1429
|
function translate(html, locale) {
|
|
1420
1430
|
const missing = {};
|
|
1421
1431
|
function translateOne(toTranslate) {
|
|
1422
1432
|
let spm = /^(\s*)([^]*?)(\s*)$/.exec(toTranslate);
|
|
1423
1433
|
let text = spm[2].replace(/\s+/g, " ");
|
|
1424
|
-
if (
|
|
1434
|
+
if (isNonTranslatable(text))
|
|
1425
1435
|
return null;
|
|
1426
1436
|
let v = U.lookup(locale, text);
|
|
1427
1437
|
if (v)
|
|
@@ -3056,10 +3066,11 @@ var pxt;
|
|
|
3056
3066
|
if (!inEnum)
|
|
3057
3067
|
return;
|
|
3058
3068
|
// parse the enum case, with lots of optional stuff (?)
|
|
3059
|
-
|
|
3069
|
+
const enumLine = lnNC.trim().replace(/,$/, "").trim();
|
|
3070
|
+
let mm = /^(\w+)(?:\s*=(.*))?$/.exec(enumLine);
|
|
3060
3071
|
if (mm) {
|
|
3061
3072
|
let nm = mm[1];
|
|
3062
|
-
let v = mm[
|
|
3073
|
+
let v = mm[2] && mm[2].trim();
|
|
3063
3074
|
let opt = "";
|
|
3064
3075
|
if (v) {
|
|
3065
3076
|
// user-supplied value
|
|
@@ -3097,23 +3108,26 @@ var pxt;
|
|
|
3097
3108
|
}
|
|
3098
3109
|
function parseArg(parsedAttrs, s) {
|
|
3099
3110
|
s = s.trim();
|
|
3100
|
-
|
|
3111
|
+
const equals = s.lastIndexOf("=");
|
|
3112
|
+
const m = equals < 0 ? null : /^\s*(-?\w+)$/.exec(s.slice(equals + 1));
|
|
3101
3113
|
let defl = "";
|
|
3102
3114
|
let qm = "";
|
|
3103
3115
|
if (m) {
|
|
3104
|
-
defl = m[
|
|
3116
|
+
defl = m[1];
|
|
3105
3117
|
qm = "?";
|
|
3106
|
-
s =
|
|
3118
|
+
s = s.slice(0, equals).trim();
|
|
3107
3119
|
}
|
|
3108
|
-
|
|
3109
|
-
|
|
3120
|
+
let nameStart = s.length;
|
|
3121
|
+
while (nameStart > 0 && /\w/.test(s.charAt(nameStart - 1)))
|
|
3122
|
+
--nameStart;
|
|
3123
|
+
if (nameStart == s.length || /[\r\n\u2028\u2029]/.test(s.slice(0, nameStart))) {
|
|
3110
3124
|
err("invalid argument: " + s);
|
|
3111
3125
|
return {
|
|
3112
3126
|
name: "???",
|
|
3113
3127
|
type: "int"
|
|
3114
3128
|
};
|
|
3115
3129
|
}
|
|
3116
|
-
let argName =
|
|
3130
|
+
let argName = s.slice(nameStart);
|
|
3117
3131
|
if (parsedAttrs.paramDefl[argName]) {
|
|
3118
3132
|
defl = parsedAttrs.paramDefl[argName];
|
|
3119
3133
|
qm = "?";
|
|
@@ -3128,7 +3142,7 @@ var pxt;
|
|
|
3128
3142
|
}
|
|
3129
3143
|
return {
|
|
3130
3144
|
name: argName + qm,
|
|
3131
|
-
type:
|
|
3145
|
+
type: s.slice(0, nameStart)
|
|
3132
3146
|
};
|
|
3133
3147
|
}
|
|
3134
3148
|
function parseCpp(src, isHeader) {
|
|
@@ -3138,9 +3152,28 @@ var pxt;
|
|
|
3138
3152
|
inDocComment = false;
|
|
3139
3153
|
let indexedInstanceAttrs;
|
|
3140
3154
|
let indexedInstanceIdx = -1;
|
|
3141
|
-
//
|
|
3142
|
-
|
|
3143
|
-
|
|
3155
|
+
// Match directives one line at a time so unterminated blocks cannot rescan the source.
|
|
3156
|
+
const lines = src.split(/\r?\n/);
|
|
3157
|
+
let ifStart = -1;
|
|
3158
|
+
let ifArg = "";
|
|
3159
|
+
lines.forEach((ln, i) => {
|
|
3160
|
+
const directive = /^#\s*(?:if\s+(\w+)|(elif|else|endif))$/.exec(ln.trim());
|
|
3161
|
+
if (!directive)
|
|
3162
|
+
return;
|
|
3163
|
+
if (ifStart < 0) {
|
|
3164
|
+
if (directive[1]) {
|
|
3165
|
+
ifStart = i;
|
|
3166
|
+
ifArg = directive[1];
|
|
3167
|
+
}
|
|
3168
|
+
}
|
|
3169
|
+
else if (directive[2]) {
|
|
3170
|
+
if (hash_if_options.indexOf(ifArg) >= 0 && !cpp_options[ifArg]) {
|
|
3171
|
+
for (let j = ifStart + 1; j < i; ++j)
|
|
3172
|
+
lines[j] = "";
|
|
3173
|
+
}
|
|
3174
|
+
ifStart = -1;
|
|
3175
|
+
}
|
|
3176
|
+
});
|
|
3144
3177
|
// special handling of C++ namespace that ends with Methods (e.g. FooMethods)
|
|
3145
3178
|
// such a namespace will be converted into a TypeScript interface
|
|
3146
3179
|
// this enables simple objects with methods to be defined. See, for example:
|
|
@@ -3218,10 +3251,14 @@ var pxt;
|
|
|
3218
3251
|
return "T";
|
|
3219
3252
|
case "String":
|
|
3220
3253
|
return "S";
|
|
3221
|
-
default:
|
|
3254
|
+
default: {
|
|
3222
3255
|
if (U.lookup(knownEnums, tp))
|
|
3223
3256
|
return "I";
|
|
3224
|
-
|
|
3257
|
+
let typeEnd = tp.length;
|
|
3258
|
+
while (typeEnd > 0 && /[\*_]/.test(tp.charAt(typeEnd - 1)))
|
|
3259
|
+
--typeEnd;
|
|
3260
|
+
return "_" + tp.slice(0, typeEnd);
|
|
3261
|
+
}
|
|
3225
3262
|
}
|
|
3226
3263
|
}
|
|
3227
3264
|
function generateVMWrapper(fi, argTypes) {
|
|
@@ -3303,7 +3340,7 @@ var pxt;
|
|
|
3303
3340
|
enumVal = 0;
|
|
3304
3341
|
enumsDTS.setNs("");
|
|
3305
3342
|
shimsDTS.setNs("");
|
|
3306
|
-
|
|
3343
|
+
lines.forEach(ln => {
|
|
3307
3344
|
++lineNo;
|
|
3308
3345
|
// remove comments (NC = no comments)
|
|
3309
3346
|
let lnNC = stripComments(ln);
|
package/built/cli.js
CHANGED
|
@@ -618,10 +618,14 @@ async function bumpAsync(parsed) {
|
|
|
618
618
|
}
|
|
619
619
|
catch (e) {
|
|
620
620
|
console.warn(chalk.yellow("Unable to determine branch protection status."), e.message);
|
|
621
|
+
pr = true;
|
|
621
622
|
}
|
|
622
623
|
if (nopr) {
|
|
623
624
|
pr = false;
|
|
624
625
|
}
|
|
626
|
+
if (pr && (!currBranchName || !token || !user || !owner || !repo)) {
|
|
627
|
+
U.userError("Unable to prepare a bump pull request. Check GitHub credentials and the origin URL, or explicitly use --nopr for a direct push.");
|
|
628
|
+
}
|
|
625
629
|
if (fs.existsSync(pxt.CONFIG_NAME)) {
|
|
626
630
|
if (upload) {
|
|
627
631
|
U.userError("upload only supported on targets");
|
|
@@ -634,7 +638,7 @@ async function bumpAsync(parsed) {
|
|
|
634
638
|
.then(() => nodeutil.runGitAsync("pull"))
|
|
635
639
|
.then(() => nodeutil.createBranchAsync(newBranchName))
|
|
636
640
|
.then(() => justBumpPkgAsync(bumpType, false)) // don't tag when creating a PR
|
|
637
|
-
.then((version) => nodeutil.gitPushAsync().then(() => version))
|
|
641
|
+
.then((version) => nodeutil.gitPushAsync(false).then(() => version))
|
|
638
642
|
.then((version) => nodeutil.createPullRequestAsync({
|
|
639
643
|
title: `[pxt-cli] bump version to ${version}`,
|
|
640
644
|
body: "__Do not edit the PR title.__\n" +
|
|
@@ -654,8 +658,7 @@ async function bumpAsync(parsed) {
|
|
|
654
658
|
return Promise.resolve()
|
|
655
659
|
.then(() => nodeutil.runGitAsync("pull"))
|
|
656
660
|
.then(() => justBumpPkgAsync(bumpType))
|
|
657
|
-
.then(() => nodeutil.runGitAsync("push", "--follow-tags"))
|
|
658
|
-
.then(() => nodeutil.runGitAsync("push"));
|
|
661
|
+
.then(() => nodeutil.runGitAsync("push", "--atomic", "--follow-tags"));
|
|
659
662
|
}
|
|
660
663
|
}
|
|
661
664
|
else if (fs.existsSync("pxtarget.json"))
|
|
@@ -668,7 +671,7 @@ async function bumpAsync(parsed) {
|
|
|
668
671
|
.then(() => nodeutil.createBranchAsync(newBranchName))
|
|
669
672
|
.then(() => bumpPxt ? bumpPxtCoreDepAsync() : Promise.resolve())
|
|
670
673
|
.then(() => nodeutil.npmVersionBumpAsync(bumpType, false)) // don't tag when creating a PR
|
|
671
|
-
.then((version) => nodeutil.gitPushAsync().then(() => version))
|
|
674
|
+
.then((version) => nodeutil.gitPushAsync(false).then(() => version))
|
|
672
675
|
.then((version) => nodeutil.createPullRequestAsync({
|
|
673
676
|
title: `[pxt-cli] bump version to ${version}`,
|
|
674
677
|
body: "__Do not edit the PR title.__\n" +
|
|
@@ -687,10 +690,9 @@ async function bumpAsync(parsed) {
|
|
|
687
690
|
console.log("Bumping via direct push.");
|
|
688
691
|
return Promise.resolve()
|
|
689
692
|
.then(() => nodeutil.runGitAsync("pull"))
|
|
690
|
-
.then(() => bumpPxt ? bumpPxtCoreDepAsync().then(() => nodeutil.runGitAsync("push")) : Promise.resolve())
|
|
693
|
+
.then(() => bumpPxt ? bumpPxtCoreDepAsync().then(() => nodeutil.runGitAsync("push", "--atomic", "--no-follow-tags")) : Promise.resolve())
|
|
691
694
|
.then(() => nodeutil.runNpmAsync("version", bumpType))
|
|
692
|
-
.then(() => nodeutil.runGitAsync("push", "--follow-tags"))
|
|
693
|
-
.then(() => nodeutil.runGitAsync("push"))
|
|
695
|
+
.then(() => nodeutil.runGitAsync("push", "--atomic", "--follow-tags"))
|
|
694
696
|
.then(() => upload ? uploadTaggedTargetAsync() : Promise.resolve());
|
|
695
697
|
}
|
|
696
698
|
else {
|
|
@@ -4701,7 +4703,7 @@ async function staticpkgAsync(parsed) {
|
|
|
4701
4703
|
pxt.log(`packaging editor to ${builtPackaged}`);
|
|
4702
4704
|
await rimrafAsync(builtPackaged, {});
|
|
4703
4705
|
if (bump) {
|
|
4704
|
-
await bumpAsync();
|
|
4706
|
+
await bumpAsync(parsed);
|
|
4705
4707
|
}
|
|
4706
4708
|
if (locs) {
|
|
4707
4709
|
await internalGenDocsAsync(false, true);
|
|
@@ -6552,7 +6554,7 @@ ${pxt.crowdin.KEY_VARIABLE} - crowdin key
|
|
|
6552
6554
|
update: { description: "(package only) Updates pxt-core reference to the latest release" },
|
|
6553
6555
|
upload: { description: "(package only) Upload after bumping" },
|
|
6554
6556
|
pr: { description: "Bump via pull request rather than direct push" },
|
|
6555
|
-
nopr: { description: "
|
|
6557
|
+
nopr: { description: "Force a direct bump (overrides --pr and protection detection)" },
|
|
6556
6558
|
version: {
|
|
6557
6559
|
description: "Which part of the version to bump, or a complete version number to assign. Defaults to 'patch'",
|
|
6558
6560
|
argument: "version",
|
|
@@ -6670,6 +6672,9 @@ ${pxt.crowdin.KEY_VARIABLE} - crowdin key
|
|
|
6670
6672
|
bump: {
|
|
6671
6673
|
description: "bump version number prior to package"
|
|
6672
6674
|
},
|
|
6675
|
+
nopr: {
|
|
6676
|
+
description: "With --bump, force a direct bump rather than a pull request"
|
|
6677
|
+
},
|
|
6673
6678
|
cloudbuild: {
|
|
6674
6679
|
description: "(deprecated) forces build to happen in the cloud",
|
|
6675
6680
|
aliases: ["cloud", "cloud-build", "cb"]
|
package/built/nodeutil.js
CHANGED
|
@@ -219,7 +219,7 @@ async function getGitHubOwnerAndRepoAsync() {
|
|
|
219
219
|
if (!remoteUrl) {
|
|
220
220
|
Util.userError("No remote origin URL found");
|
|
221
221
|
}
|
|
222
|
-
const match = remoteUrl.match(/github\.com[:\/](.+?)\/(.+?)(\.git)?$/);
|
|
222
|
+
const match = remoteUrl.replace(/\/+$/, "").match(/github\.com[:\/](.+?)\/(.+?)(\.git)?$/);
|
|
223
223
|
if (!match) {
|
|
224
224
|
Util.userError("Invalid remote origin URL: " + remoteUrl);
|
|
225
225
|
}
|
|
@@ -236,7 +236,7 @@ async function createBranchAsync(branchName) {
|
|
|
236
236
|
});
|
|
237
237
|
await spawnAsync({
|
|
238
238
|
cmd: "git",
|
|
239
|
-
args: ["push", "--set-upstream", "origin", branchName],
|
|
239
|
+
args: ["push", "--no-follow-tags", "--set-upstream", "origin", branchName],
|
|
240
240
|
silent: true,
|
|
241
241
|
});
|
|
242
242
|
}
|
|
@@ -299,13 +299,9 @@ function quoteIfNeeded(arg) {
|
|
|
299
299
|
return arg;
|
|
300
300
|
}
|
|
301
301
|
function gitPushAsync(followTags = true) {
|
|
302
|
-
const args = ["push"];
|
|
303
|
-
if (followTags)
|
|
304
|
-
args.push("--follow-tags");
|
|
305
|
-
args.push("origin", "HEAD");
|
|
306
302
|
return spawnAsync({
|
|
307
303
|
cmd: "git",
|
|
308
|
-
args,
|
|
304
|
+
args: ["push", "--atomic", followTags ? "--follow-tags" : "--no-follow-tags", "origin", "HEAD"],
|
|
309
305
|
cwd: ".",
|
|
310
306
|
silent: true,
|
|
311
307
|
});
|
package/built/pxt.js
CHANGED
|
@@ -99231,6 +99231,8 @@ const lf = ts.pxtc.Util.lf;
|
|
|
99231
99231
|
let parts = k.split(".");
|
|
99232
99232
|
for (let i = 0; i < parts.length; ++i) {
|
|
99233
99233
|
let part = parts[i];
|
|
99234
|
+
if (part === "__proto__" || part === "constructor" || part === "prototype")
|
|
99235
|
+
Util.userError("Invalid configuration key: " + k);
|
|
99234
99236
|
if (i == parts.length - 1)
|
|
99235
99237
|
ptr[part] = v[k];
|
|
99236
99238
|
else {
|
|
@@ -105525,10 +105527,11 @@ var pxt;
|
|
|
105525
105527
|
if (!inEnum)
|
|
105526
105528
|
return;
|
|
105527
105529
|
// parse the enum case, with lots of optional stuff (?)
|
|
105528
|
-
|
|
105530
|
+
const enumLine = lnNC.trim().replace(/,$/, "").trim();
|
|
105531
|
+
let mm = /^(\w+)(?:\s*=(.*))?$/.exec(enumLine);
|
|
105529
105532
|
if (mm) {
|
|
105530
105533
|
let nm = mm[1];
|
|
105531
|
-
let v = mm[
|
|
105534
|
+
let v = mm[2] && mm[2].trim();
|
|
105532
105535
|
let opt = "";
|
|
105533
105536
|
if (v) {
|
|
105534
105537
|
// user-supplied value
|
|
@@ -105566,23 +105569,26 @@ var pxt;
|
|
|
105566
105569
|
}
|
|
105567
105570
|
function parseArg(parsedAttrs, s) {
|
|
105568
105571
|
s = s.trim();
|
|
105569
|
-
|
|
105572
|
+
const equals = s.lastIndexOf("=");
|
|
105573
|
+
const m = equals < 0 ? null : /^\s*(-?\w+)$/.exec(s.slice(equals + 1));
|
|
105570
105574
|
let defl = "";
|
|
105571
105575
|
let qm = "";
|
|
105572
105576
|
if (m) {
|
|
105573
|
-
defl = m[
|
|
105577
|
+
defl = m[1];
|
|
105574
105578
|
qm = "?";
|
|
105575
|
-
s =
|
|
105579
|
+
s = s.slice(0, equals).trim();
|
|
105576
105580
|
}
|
|
105577
|
-
|
|
105578
|
-
|
|
105581
|
+
let nameStart = s.length;
|
|
105582
|
+
while (nameStart > 0 && /\w/.test(s.charAt(nameStart - 1)))
|
|
105583
|
+
--nameStart;
|
|
105584
|
+
if (nameStart == s.length || /[\r\n\u2028\u2029]/.test(s.slice(0, nameStart))) {
|
|
105579
105585
|
err("invalid argument: " + s);
|
|
105580
105586
|
return {
|
|
105581
105587
|
name: "???",
|
|
105582
105588
|
type: "int"
|
|
105583
105589
|
};
|
|
105584
105590
|
}
|
|
105585
|
-
let argName =
|
|
105591
|
+
let argName = s.slice(nameStart);
|
|
105586
105592
|
if (parsedAttrs.paramDefl[argName]) {
|
|
105587
105593
|
defl = parsedAttrs.paramDefl[argName];
|
|
105588
105594
|
qm = "?";
|
|
@@ -105597,7 +105603,7 @@ var pxt;
|
|
|
105597
105603
|
}
|
|
105598
105604
|
return {
|
|
105599
105605
|
name: argName + qm,
|
|
105600
|
-
type:
|
|
105606
|
+
type: s.slice(0, nameStart)
|
|
105601
105607
|
};
|
|
105602
105608
|
}
|
|
105603
105609
|
function parseCpp(src, isHeader) {
|
|
@@ -105607,9 +105613,28 @@ var pxt;
|
|
|
105607
105613
|
inDocComment = false;
|
|
105608
105614
|
let indexedInstanceAttrs;
|
|
105609
105615
|
let indexedInstanceIdx = -1;
|
|
105610
|
-
//
|
|
105611
|
-
|
|
105612
|
-
|
|
105616
|
+
// Match directives one line at a time so unterminated blocks cannot rescan the source.
|
|
105617
|
+
const lines = src.split(/\r?\n/);
|
|
105618
|
+
let ifStart = -1;
|
|
105619
|
+
let ifArg = "";
|
|
105620
|
+
lines.forEach((ln, i) => {
|
|
105621
|
+
const directive = /^#\s*(?:if\s+(\w+)|(elif|else|endif))$/.exec(ln.trim());
|
|
105622
|
+
if (!directive)
|
|
105623
|
+
return;
|
|
105624
|
+
if (ifStart < 0) {
|
|
105625
|
+
if (directive[1]) {
|
|
105626
|
+
ifStart = i;
|
|
105627
|
+
ifArg = directive[1];
|
|
105628
|
+
}
|
|
105629
|
+
}
|
|
105630
|
+
else if (directive[2]) {
|
|
105631
|
+
if (hash_if_options.indexOf(ifArg) >= 0 && !cpp_options[ifArg]) {
|
|
105632
|
+
for (let j = ifStart + 1; j < i; ++j)
|
|
105633
|
+
lines[j] = "";
|
|
105634
|
+
}
|
|
105635
|
+
ifStart = -1;
|
|
105636
|
+
}
|
|
105637
|
+
});
|
|
105613
105638
|
// special handling of C++ namespace that ends with Methods (e.g. FooMethods)
|
|
105614
105639
|
// such a namespace will be converted into a TypeScript interface
|
|
105615
105640
|
// this enables simple objects with methods to be defined. See, for example:
|
|
@@ -105687,10 +105712,14 @@ var pxt;
|
|
|
105687
105712
|
return "T";
|
|
105688
105713
|
case "String":
|
|
105689
105714
|
return "S";
|
|
105690
|
-
default:
|
|
105715
|
+
default: {
|
|
105691
105716
|
if (U.lookup(knownEnums, tp))
|
|
105692
105717
|
return "I";
|
|
105693
|
-
|
|
105718
|
+
let typeEnd = tp.length;
|
|
105719
|
+
while (typeEnd > 0 && /[\*_]/.test(tp.charAt(typeEnd - 1)))
|
|
105720
|
+
--typeEnd;
|
|
105721
|
+
return "_" + tp.slice(0, typeEnd);
|
|
105722
|
+
}
|
|
105694
105723
|
}
|
|
105695
105724
|
}
|
|
105696
105725
|
function generateVMWrapper(fi, argTypes) {
|
|
@@ -105772,7 +105801,7 @@ var pxt;
|
|
|
105772
105801
|
enumVal = 0;
|
|
105773
105802
|
enumsDTS.setNs("");
|
|
105774
105803
|
shimsDTS.setNs("");
|
|
105775
|
-
|
|
105804
|
+
lines.forEach(ln => {
|
|
105776
105805
|
++lineNo;
|
|
105777
105806
|
// remove comments (NC = no comments)
|
|
105778
105807
|
let lnNC = stripComments(ln);
|
|
@@ -124958,12 +124987,20 @@ ${opts.repo.name.replace(/^pxt-/, '')}=github:${opts.repo.fullName}#${opts.repo.
|
|
|
124958
124987
|
strong: 1,
|
|
124959
124988
|
em: 1,
|
|
124960
124989
|
};
|
|
124990
|
+
/** Keeps metadata and token-only HTML out of the translation catalog. */
|
|
124991
|
+
function isNonTranslatable(text) {
|
|
124992
|
+
if (text.startsWith("IE=edge,") || text.startsWith("width=device-width"))
|
|
124993
|
+
return true;
|
|
124994
|
+
// Remove URLs, template placeholders, and spacing entities to look for prose.
|
|
124995
|
+
const prose = text.replace(/(?:https?:\/\/|\/)[\w@\/.]+|@[-\w]+@|\{[^{}]+\}| /g, "");
|
|
124996
|
+
return !/[a-zA-Z]/.test(prose);
|
|
124997
|
+
}
|
|
124961
124998
|
function translate(html, locale) {
|
|
124962
124999
|
const missing = {};
|
|
124963
125000
|
function translateOne(toTranslate) {
|
|
124964
125001
|
let spm = /^(\s*)([^]*?)(\s*)$/.exec(toTranslate);
|
|
124965
125002
|
let text = spm[2].replace(/\s+/g, " ");
|
|
124966
|
-
if (
|
|
125003
|
+
if (isNonTranslatable(text))
|
|
124967
125004
|
return null;
|
|
124968
125005
|
let v = U.lookup(locale, text);
|
|
124969
125006
|
if (v)
|
|
@@ -165904,10 +165941,14 @@ async function bumpAsync(parsed) {
|
|
|
165904
165941
|
}
|
|
165905
165942
|
catch (e) {
|
|
165906
165943
|
console.warn(chalk.yellow("Unable to determine branch protection status."), e.message);
|
|
165944
|
+
pr = true;
|
|
165907
165945
|
}
|
|
165908
165946
|
if (nopr) {
|
|
165909
165947
|
pr = false;
|
|
165910
165948
|
}
|
|
165949
|
+
if (pr && (!currBranchName || !token || !user || !owner || !repo)) {
|
|
165950
|
+
U.userError("Unable to prepare a bump pull request. Check GitHub credentials and the origin URL, or explicitly use --nopr for a direct push.");
|
|
165951
|
+
}
|
|
165911
165952
|
if (fs.existsSync(pxt.CONFIG_NAME)) {
|
|
165912
165953
|
if (upload) {
|
|
165913
165954
|
U.userError("upload only supported on targets");
|
|
@@ -165920,7 +165961,7 @@ async function bumpAsync(parsed) {
|
|
|
165920
165961
|
.then(() => nodeutil.runGitAsync("pull"))
|
|
165921
165962
|
.then(() => nodeutil.createBranchAsync(newBranchName))
|
|
165922
165963
|
.then(() => justBumpPkgAsync(bumpType, false)) // don't tag when creating a PR
|
|
165923
|
-
.then((version) => nodeutil.gitPushAsync().then(() => version))
|
|
165964
|
+
.then((version) => nodeutil.gitPushAsync(false).then(() => version))
|
|
165924
165965
|
.then((version) => nodeutil.createPullRequestAsync({
|
|
165925
165966
|
title: `[pxt-cli] bump version to ${version}`,
|
|
165926
165967
|
body: "__Do not edit the PR title.__\n" +
|
|
@@ -165940,8 +165981,7 @@ async function bumpAsync(parsed) {
|
|
|
165940
165981
|
return Promise.resolve()
|
|
165941
165982
|
.then(() => nodeutil.runGitAsync("pull"))
|
|
165942
165983
|
.then(() => justBumpPkgAsync(bumpType))
|
|
165943
|
-
.then(() => nodeutil.runGitAsync("push", "--follow-tags"))
|
|
165944
|
-
.then(() => nodeutil.runGitAsync("push"));
|
|
165984
|
+
.then(() => nodeutil.runGitAsync("push", "--atomic", "--follow-tags"));
|
|
165945
165985
|
}
|
|
165946
165986
|
}
|
|
165947
165987
|
else if (fs.existsSync("pxtarget.json"))
|
|
@@ -165954,7 +165994,7 @@ async function bumpAsync(parsed) {
|
|
|
165954
165994
|
.then(() => nodeutil.createBranchAsync(newBranchName))
|
|
165955
165995
|
.then(() => bumpPxt ? bumpPxtCoreDepAsync() : Promise.resolve())
|
|
165956
165996
|
.then(() => nodeutil.npmVersionBumpAsync(bumpType, false)) // don't tag when creating a PR
|
|
165957
|
-
.then((version) => nodeutil.gitPushAsync().then(() => version))
|
|
165997
|
+
.then((version) => nodeutil.gitPushAsync(false).then(() => version))
|
|
165958
165998
|
.then((version) => nodeutil.createPullRequestAsync({
|
|
165959
165999
|
title: `[pxt-cli] bump version to ${version}`,
|
|
165960
166000
|
body: "__Do not edit the PR title.__\n" +
|
|
@@ -165973,10 +166013,9 @@ async function bumpAsync(parsed) {
|
|
|
165973
166013
|
console.log("Bumping via direct push.");
|
|
165974
166014
|
return Promise.resolve()
|
|
165975
166015
|
.then(() => nodeutil.runGitAsync("pull"))
|
|
165976
|
-
.then(() => bumpPxt ? bumpPxtCoreDepAsync().then(() => nodeutil.runGitAsync("push")) : Promise.resolve())
|
|
166016
|
+
.then(() => bumpPxt ? bumpPxtCoreDepAsync().then(() => nodeutil.runGitAsync("push", "--atomic", "--no-follow-tags")) : Promise.resolve())
|
|
165977
166017
|
.then(() => nodeutil.runNpmAsync("version", bumpType))
|
|
165978
|
-
.then(() => nodeutil.runGitAsync("push", "--follow-tags"))
|
|
165979
|
-
.then(() => nodeutil.runGitAsync("push"))
|
|
166018
|
+
.then(() => nodeutil.runGitAsync("push", "--atomic", "--follow-tags"))
|
|
165980
166019
|
.then(() => upload ? uploadTaggedTargetAsync() : Promise.resolve());
|
|
165981
166020
|
}
|
|
165982
166021
|
else {
|
|
@@ -169987,7 +170026,7 @@ async function staticpkgAsync(parsed) {
|
|
|
169987
170026
|
pxt.log(`packaging editor to ${builtPackaged}`);
|
|
169988
170027
|
await rimrafAsync(builtPackaged, {});
|
|
169989
170028
|
if (bump) {
|
|
169990
|
-
await bumpAsync();
|
|
170029
|
+
await bumpAsync(parsed);
|
|
169991
170030
|
}
|
|
169992
170031
|
if (locs) {
|
|
169993
170032
|
await internalGenDocsAsync(false, true);
|
|
@@ -171838,7 +171877,7 @@ ${pxt.crowdin.KEY_VARIABLE} - crowdin key
|
|
|
171838
171877
|
update: { description: "(package only) Updates pxt-core reference to the latest release" },
|
|
171839
171878
|
upload: { description: "(package only) Upload after bumping" },
|
|
171840
171879
|
pr: { description: "Bump via pull request rather than direct push" },
|
|
171841
|
-
nopr: { description: "
|
|
171880
|
+
nopr: { description: "Force a direct bump (overrides --pr and protection detection)" },
|
|
171842
171881
|
version: {
|
|
171843
171882
|
description: "Which part of the version to bump, or a complete version number to assign. Defaults to 'patch'",
|
|
171844
171883
|
argument: "version",
|
|
@@ -171956,6 +171995,9 @@ ${pxt.crowdin.KEY_VARIABLE} - crowdin key
|
|
|
171956
171995
|
bump: {
|
|
171957
171996
|
description: "bump version number prior to package"
|
|
171958
171997
|
},
|
|
171998
|
+
nopr: {
|
|
171999
|
+
description: "With --bump, force a direct bump rather than a pull request"
|
|
172000
|
+
},
|
|
171959
172001
|
cloudbuild: {
|
|
171960
172002
|
description: "(deprecated) forces build to happen in the cloud",
|
|
171961
172003
|
aliases: ["cloud", "cloud-build", "cb"]
|
package/built/pxtlib.js
CHANGED
|
@@ -1510,6 +1510,8 @@ const lf = ts.pxtc.Util.lf;
|
|
|
1510
1510
|
let parts = k.split(".");
|
|
1511
1511
|
for (let i = 0; i < parts.length; ++i) {
|
|
1512
1512
|
let part = parts[i];
|
|
1513
|
+
if (part === "__proto__" || part === "constructor" || part === "prototype")
|
|
1514
|
+
Util.userError("Invalid configuration key: " + k);
|
|
1513
1515
|
if (i == parts.length - 1)
|
|
1514
1516
|
ptr[part] = v[k];
|
|
1515
1517
|
else {
|
|
@@ -7804,10 +7806,11 @@ var pxt;
|
|
|
7804
7806
|
if (!inEnum)
|
|
7805
7807
|
return;
|
|
7806
7808
|
// parse the enum case, with lots of optional stuff (?)
|
|
7807
|
-
|
|
7809
|
+
const enumLine = lnNC.trim().replace(/,$/, "").trim();
|
|
7810
|
+
let mm = /^(\w+)(?:\s*=(.*))?$/.exec(enumLine);
|
|
7808
7811
|
if (mm) {
|
|
7809
7812
|
let nm = mm[1];
|
|
7810
|
-
let v = mm[
|
|
7813
|
+
let v = mm[2] && mm[2].trim();
|
|
7811
7814
|
let opt = "";
|
|
7812
7815
|
if (v) {
|
|
7813
7816
|
// user-supplied value
|
|
@@ -7845,23 +7848,26 @@ var pxt;
|
|
|
7845
7848
|
}
|
|
7846
7849
|
function parseArg(parsedAttrs, s) {
|
|
7847
7850
|
s = s.trim();
|
|
7848
|
-
|
|
7851
|
+
const equals = s.lastIndexOf("=");
|
|
7852
|
+
const m = equals < 0 ? null : /^\s*(-?\w+)$/.exec(s.slice(equals + 1));
|
|
7849
7853
|
let defl = "";
|
|
7850
7854
|
let qm = "";
|
|
7851
7855
|
if (m) {
|
|
7852
|
-
defl = m[
|
|
7856
|
+
defl = m[1];
|
|
7853
7857
|
qm = "?";
|
|
7854
|
-
s =
|
|
7858
|
+
s = s.slice(0, equals).trim();
|
|
7855
7859
|
}
|
|
7856
|
-
|
|
7857
|
-
|
|
7860
|
+
let nameStart = s.length;
|
|
7861
|
+
while (nameStart > 0 && /\w/.test(s.charAt(nameStart - 1)))
|
|
7862
|
+
--nameStart;
|
|
7863
|
+
if (nameStart == s.length || /[\r\n\u2028\u2029]/.test(s.slice(0, nameStart))) {
|
|
7858
7864
|
err("invalid argument: " + s);
|
|
7859
7865
|
return {
|
|
7860
7866
|
name: "???",
|
|
7861
7867
|
type: "int"
|
|
7862
7868
|
};
|
|
7863
7869
|
}
|
|
7864
|
-
let argName =
|
|
7870
|
+
let argName = s.slice(nameStart);
|
|
7865
7871
|
if (parsedAttrs.paramDefl[argName]) {
|
|
7866
7872
|
defl = parsedAttrs.paramDefl[argName];
|
|
7867
7873
|
qm = "?";
|
|
@@ -7876,7 +7882,7 @@ var pxt;
|
|
|
7876
7882
|
}
|
|
7877
7883
|
return {
|
|
7878
7884
|
name: argName + qm,
|
|
7879
|
-
type:
|
|
7885
|
+
type: s.slice(0, nameStart)
|
|
7880
7886
|
};
|
|
7881
7887
|
}
|
|
7882
7888
|
function parseCpp(src, isHeader) {
|
|
@@ -7886,9 +7892,28 @@ var pxt;
|
|
|
7886
7892
|
inDocComment = false;
|
|
7887
7893
|
let indexedInstanceAttrs;
|
|
7888
7894
|
let indexedInstanceIdx = -1;
|
|
7889
|
-
//
|
|
7890
|
-
|
|
7891
|
-
|
|
7895
|
+
// Match directives one line at a time so unterminated blocks cannot rescan the source.
|
|
7896
|
+
const lines = src.split(/\r?\n/);
|
|
7897
|
+
let ifStart = -1;
|
|
7898
|
+
let ifArg = "";
|
|
7899
|
+
lines.forEach((ln, i) => {
|
|
7900
|
+
const directive = /^#\s*(?:if\s+(\w+)|(elif|else|endif))$/.exec(ln.trim());
|
|
7901
|
+
if (!directive)
|
|
7902
|
+
return;
|
|
7903
|
+
if (ifStart < 0) {
|
|
7904
|
+
if (directive[1]) {
|
|
7905
|
+
ifStart = i;
|
|
7906
|
+
ifArg = directive[1];
|
|
7907
|
+
}
|
|
7908
|
+
}
|
|
7909
|
+
else if (directive[2]) {
|
|
7910
|
+
if (hash_if_options.indexOf(ifArg) >= 0 && !cpp_options[ifArg]) {
|
|
7911
|
+
for (let j = ifStart + 1; j < i; ++j)
|
|
7912
|
+
lines[j] = "";
|
|
7913
|
+
}
|
|
7914
|
+
ifStart = -1;
|
|
7915
|
+
}
|
|
7916
|
+
});
|
|
7892
7917
|
// special handling of C++ namespace that ends with Methods (e.g. FooMethods)
|
|
7893
7918
|
// such a namespace will be converted into a TypeScript interface
|
|
7894
7919
|
// this enables simple objects with methods to be defined. See, for example:
|
|
@@ -7966,10 +7991,14 @@ var pxt;
|
|
|
7966
7991
|
return "T";
|
|
7967
7992
|
case "String":
|
|
7968
7993
|
return "S";
|
|
7969
|
-
default:
|
|
7994
|
+
default: {
|
|
7970
7995
|
if (U.lookup(knownEnums, tp))
|
|
7971
7996
|
return "I";
|
|
7972
|
-
|
|
7997
|
+
let typeEnd = tp.length;
|
|
7998
|
+
while (typeEnd > 0 && /[\*_]/.test(tp.charAt(typeEnd - 1)))
|
|
7999
|
+
--typeEnd;
|
|
8000
|
+
return "_" + tp.slice(0, typeEnd);
|
|
8001
|
+
}
|
|
7973
8002
|
}
|
|
7974
8003
|
}
|
|
7975
8004
|
function generateVMWrapper(fi, argTypes) {
|
|
@@ -8051,7 +8080,7 @@ var pxt;
|
|
|
8051
8080
|
enumVal = 0;
|
|
8052
8081
|
enumsDTS.setNs("");
|
|
8053
8082
|
shimsDTS.setNs("");
|
|
8054
|
-
|
|
8083
|
+
lines.forEach(ln => {
|
|
8055
8084
|
++lineNo;
|
|
8056
8085
|
// remove comments (NC = no comments)
|
|
8057
8086
|
let lnNC = stripComments(ln);
|
|
@@ -27237,12 +27266,20 @@ ${opts.repo.name.replace(/^pxt-/, '')}=github:${opts.repo.fullName}#${opts.repo.
|
|
|
27237
27266
|
strong: 1,
|
|
27238
27267
|
em: 1,
|
|
27239
27268
|
};
|
|
27269
|
+
/** Keeps metadata and token-only HTML out of the translation catalog. */
|
|
27270
|
+
function isNonTranslatable(text) {
|
|
27271
|
+
if (text.startsWith("IE=edge,") || text.startsWith("width=device-width"))
|
|
27272
|
+
return true;
|
|
27273
|
+
// Remove URLs, template placeholders, and spacing entities to look for prose.
|
|
27274
|
+
const prose = text.replace(/(?:https?:\/\/|\/)[\w@\/.]+|@[-\w]+@|\{[^{}]+\}| /g, "");
|
|
27275
|
+
return !/[a-zA-Z]/.test(prose);
|
|
27276
|
+
}
|
|
27240
27277
|
function translate(html, locale) {
|
|
27241
27278
|
const missing = {};
|
|
27242
27279
|
function translateOne(toTranslate) {
|
|
27243
27280
|
let spm = /^(\s*)([^]*?)(\s*)$/.exec(toTranslate);
|
|
27244
27281
|
let text = spm[2].replace(/\s+/g, " ");
|
|
27245
|
-
if (
|
|
27282
|
+
if (isNonTranslatable(text))
|
|
27246
27283
|
return null;
|
|
27247
27284
|
let v = U.lookup(locale, text);
|
|
27248
27285
|
if (v)
|