pxt-core 7.3.6 → 7.3.10

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/cli.js CHANGED
@@ -403,6 +403,8 @@ function ciAsync() {
403
403
  pxt.log(`pull request: ${pullRequest}`);
404
404
  pxt.log(`upload api strings: ${uploadApiStrings}`);
405
405
  pxt.log(`upload docs: ${uploadDocs}`);
406
+ lintJSONInDirectory(path.resolve("."));
407
+ lintJSONInDirectory(path.resolve("docs"));
406
408
  function npmPublishAsync() {
407
409
  if (!npmPublish)
408
410
  return Promise.resolve();
@@ -459,6 +461,21 @@ function ciAsync() {
459
461
  });
460
462
  }
461
463
  }
464
+ function lintJSONInDirectory(dir) {
465
+ for (const file of fs.readdirSync(dir)) {
466
+ const fullPath = path.join(dir, file);
467
+ if (file.endsWith(".json")) {
468
+ const contents = fs.readFileSync(fullPath, "utf8");
469
+ try {
470
+ JSON.parse(contents);
471
+ }
472
+ catch (e) {
473
+ console.log("Could not parse " + fullPath);
474
+ process.exit(1);
475
+ }
476
+ }
477
+ }
478
+ }
462
479
  function bumpPxtCoreDepAsync() {
463
480
  let pkg = readJson("package.json");
464
481
  if (pkg["name"] == "pxt-core")
@@ -1751,7 +1768,9 @@ function buildSemanticUIAsync(parsed) {
1751
1768
  // Append icons.css to semantic.css (custom pxt icons)
1752
1769
  const iconsFile = (pkg["name"] == "pxt-core") ? 'built/web/icons.css' : 'node_modules/pxt-core/built/web/icons.css';
1753
1770
  const iconsCss = fs.readFileSync(iconsFile, "utf-8");
1754
- semCss = semCss + "\n" + iconsCss;
1771
+ const reactCommonFile = (pkg["name"] == "pxt-core") ? 'built/web/react-common.css' : 'node_modules/pxt-core/built/web/react-common.css';
1772
+ const reactCommonCss = fs.readFileSync(reactCommonFile, "utf-8");
1773
+ semCss = semCss + "\n" + iconsCss + "\n" + reactCommonCss;
1755
1774
  nodeutil.writeFileSync('built/web/semantic.css', semCss);
1756
1775
  }).then(() => {
1757
1776
  // generate blockly css
@@ -1819,6 +1838,7 @@ function buildSkillMapAsync(parsed) {
1819
1838
  nodeutil.cp("node_modules/pxt-core/built/pxtlib.js", `${skillmapRoot}/public/blb`);
1820
1839
  nodeutil.cp("built/web/semantic.css", `${skillmapRoot}/public/blb`);
1821
1840
  nodeutil.cp("node_modules/pxt-core/built/web/icons.css", `${skillmapRoot}/public/blb`);
1841
+ nodeutil.cp("node_modules/pxt-core/built/web/react-common.css", `${skillmapRoot}/public/blb`);
1822
1842
  // copy 'assets' over from docs/static
1823
1843
  nodeutil.cpR("docs/static/skillmap/assets", `${skillmapRoot}/public/assets`);
1824
1844
  if (docsPath) {
package/built/pxt.js CHANGED
@@ -98356,6 +98356,17 @@ var pxt;
98356
98356
  }
98357
98357
  }
98358
98358
  auth.generateUserProfilePicDataUrl = generateUserProfilePicDataUrl;
98359
+ /**
98360
+ * Checks only the ID and sourceURL
98361
+ */
98362
+ function badgeEquals(badgeA, badgeB) {
98363
+ return badgeA.id === badgeB.id && badgeA.sourceURL === badgeB.sourceURL;
98364
+ }
98365
+ auth.badgeEquals = badgeEquals;
98366
+ function hasBadge(preferences, badge) {
98367
+ return preferences.badges.some(toCheck => badgeEquals(toCheck, badge));
98368
+ }
98369
+ auth.hasBadge = hasBadge;
98359
98370
  })(auth = pxt.auth || (pxt.auth = {}));
98360
98371
  })(pxt || (pxt = {}));
98361
98372
  // Needs to be in its own file to avoid a circular dependency: util.ts -> main.ts -> util.ts
@@ -124143,6 +124154,53 @@ ${info.id}_IfaceVT:
124143
124154
  else
124144
124155
  return `0xffffffff, 0xffffffff ; -> ${vt}`;
124145
124156
  }
124157
+ function encodeSourceMap(srcmap) {
124158
+ // magic: 0x4d435253 0x2d4e1588 0x719986aa ('SRCM' ... )
124159
+ const res = [0x53, 0x52, 0x43, 0x4d, 0x88, 0x15, 0x4e, 0x2d, 0xaa, 0x86, 0x99, 0x71, 0x00, 0x00, 0x00, 0x00];
124160
+ for (const fn of Object.keys(srcmap)) {
124161
+ for (const c of pxtc.U.stringToUint8Array(fn))
124162
+ res.push(c);
124163
+ res.push(0);
124164
+ const arr = srcmap[fn];
124165
+ let prevLn = 0;
124166
+ let prevOff = 0;
124167
+ for (let i = 0; i < arr.length; i += 3) {
124168
+ encodeNumber(arr[i] - prevLn);
124169
+ encodeNumber((arr[i + 1] - prevOff) >> 1);
124170
+ encodeNumber(arr[i + 2] >> 1);
124171
+ prevLn = arr[i];
124172
+ prevOff = arr[i + 1];
124173
+ }
124174
+ res.push(0xff); // end-marker
124175
+ }
124176
+ res.push(0);
124177
+ if (res.length & 1)
124178
+ res.push(0);
124179
+ const res2 = [];
124180
+ for (let i = 0; i < res.length; i += 2)
124181
+ res2.push(res[i] | (res[i + 1] << 8));
124182
+ return res2;
124183
+ function encodeNumber(k) {
124184
+ if (0 <= k && k < 0xf0)
124185
+ res.push(k);
124186
+ else {
124187
+ let mark = 0xf0;
124188
+ if (k < 0) {
124189
+ k = -k;
124190
+ mark |= 0x08;
124191
+ }
124192
+ const idx = res.length;
124193
+ res.push(null); // placeholder
124194
+ let len = 0;
124195
+ while (k != 0) {
124196
+ res.push(k & 0xff);
124197
+ k >>>= 8;
124198
+ len++;
124199
+ }
124200
+ res[idx] = mark | len;
124201
+ }
124202
+ }
124203
+ }
124146
124204
  /* eslint-disable no-trailing-spaces */
124147
124205
  function vmEmit(bin, opts) {
124148
124206
  let vmsource = `; VM start
@@ -124266,9 +124324,10 @@ _start_${name}:
124266
124324
  vmsource += "\n; The end.\n";
124267
124325
  bin.writeFile(pxtc.BINARY_ASM, vmsource);
124268
124326
  let res = pxtc.assemble(opts.target, bin, vmsource);
124269
- if (res.src)
124270
- bin.writeFile(pxtc.BINARY_ASM, res.src);
124271
124327
  const srcmap = res.thumbFile.getSourceMap();
124328
+ const encodedSrcMap = encodeSourceMap(srcmap);
124329
+ if (res.src)
124330
+ bin.writeFile(pxtc.BINARY_ASM, `; srcmap size: ${encodedSrcMap.length << 1} bytes\n` + res.src);
124272
124331
  {
124273
124332
  let binstring = "";
124274
124333
  for (let v of res.buf)
@@ -124294,12 +124353,16 @@ _start_${name}:
124294
124353
  }
124295
124354
  if (res.buf) {
124296
124355
  let binstring = "";
124297
- for (let v of res.buf)
124356
+ const buf = res.buf;
124357
+ while (buf.length & 0xf)
124358
+ buf.push(0);
124359
+ pxtc.U.pushRange(buf, encodedSrcMap);
124360
+ for (let v of buf)
124298
124361
  binstring += String.fromCharCode(v & 0xff, v >> 8);
124299
124362
  binstring = ts.pxtc.encodeBase64(binstring);
124300
124363
  if (embedVTs()) {
124301
124364
  bin.writeFile(pxtc.BINARY_PXT64, binstring);
124302
- const patched = pxtc.hexfile.patchHex(bin, res.buf, false, !!pxtc.target.useUF2)[0];
124365
+ const patched = pxtc.hexfile.patchHex(bin, buf, false, !!pxtc.target.useUF2)[0];
124303
124366
  bin.writeFile(pxt.outputName(pxtc.target), ts.pxtc.encodeBase64(patched));
124304
124367
  }
124305
124368
  else {
@@ -138996,6 +139059,7 @@ var ts;
138996
139059
  }
138997
139060
  service.snippetAddsDefinitions = snippetAddsDefinitions;
138998
139061
  function getSnippet(context, fn, decl, python, recursionDepth = 0) {
139062
+ var _a;
138999
139063
  // TODO: a lot of this is duplicate logic with blocklyloader.ts:buildBlockFromDef; we should
139000
139064
  // unify these approaches
139001
139065
  let { apis, takenNames, blocksInfo, screenSize, checker } = context;
@@ -139028,10 +139092,15 @@ var ts;
139028
139092
  if (attrs.shim === "TD_ID" && recursionDepth && decl.parameters.length) {
139029
139093
  return getParameterDefault(decl.parameters[0]);
139030
139094
  }
139095
+ const element = fn;
139096
+ const params = pxt.blocks.compileInfo(element);
139031
139097
  const blocksById = blocksInfo.blocksById;
139032
139098
  // TODO: move out of getSnippet for general reuse
139099
+ const blockParameters = ((_a = attrs._def) === null || _a === void 0 ? void 0 : _a.parameters.filter(param => !!params.definitionNameToParam[param.name]).map(param => params.definitionNameToParam[param.name].actualName)) || [];
139033
139100
  const includedParameters = decl.parameters ? decl.parameters
139034
- .filter(param => !param.initializer && !param.questionToken) : [];
139101
+ // Only keep required parameters and parameters included in the blockdef
139102
+ .filter(param => (!param.initializer && !param.questionToken)
139103
+ || (blockParameters.indexOf(param.name.getText()) >= 0)) : [];
139035
139104
  const args = includedParameters
139036
139105
  .map(getParameterDefault)
139037
139106
  .map(p =>
@@ -139041,7 +139110,6 @@ var ts;
139041
139110
  default: p,
139042
139111
  isLiteral: true
139043
139112
  }));
139044
- const element = fn;
139045
139113
  if (element.attributes.block) {
139046
139114
  if (element.attributes.defaultInstance) {
139047
139115
  snippetPrefix = element.attributes.defaultInstance;
@@ -139089,7 +139157,6 @@ var ts;
139089
139157
  isInstance = true;
139090
139158
  }
139091
139159
  else if (element.kind == 1 /* Method */ || element.kind == 2 /* Property */) {
139092
- const params = pxt.blocks.compileInfo(element);
139093
139160
  if (params.thisParameter) {
139094
139161
  let varName = undefined;
139095
139162
  if (params.thisParameter.definitionName) {
@@ -156220,6 +156287,8 @@ function ciAsync() {
156220
156287
  pxt.log(`pull request: ${pullRequest}`);
156221
156288
  pxt.log(`upload api strings: ${uploadApiStrings}`);
156222
156289
  pxt.log(`upload docs: ${uploadDocs}`);
156290
+ lintJSONInDirectory(path.resolve("."));
156291
+ lintJSONInDirectory(path.resolve("docs"));
156223
156292
  function npmPublishAsync() {
156224
156293
  if (!npmPublish)
156225
156294
  return Promise.resolve();
@@ -156276,6 +156345,21 @@ function ciAsync() {
156276
156345
  });
156277
156346
  }
156278
156347
  }
156348
+ function lintJSONInDirectory(dir) {
156349
+ for (const file of fs.readdirSync(dir)) {
156350
+ const fullPath = path.join(dir, file);
156351
+ if (file.endsWith(".json")) {
156352
+ const contents = fs.readFileSync(fullPath, "utf8");
156353
+ try {
156354
+ JSON.parse(contents);
156355
+ }
156356
+ catch (e) {
156357
+ console.log("Could not parse " + fullPath);
156358
+ process.exit(1);
156359
+ }
156360
+ }
156361
+ }
156362
+ }
156279
156363
  function bumpPxtCoreDepAsync() {
156280
156364
  let pkg = readJson("package.json");
156281
156365
  if (pkg["name"] == "pxt-core")
@@ -157568,7 +157652,9 @@ function buildSemanticUIAsync(parsed) {
157568
157652
  // Append icons.css to semantic.css (custom pxt icons)
157569
157653
  const iconsFile = (pkg["name"] == "pxt-core") ? 'built/web/icons.css' : 'node_modules/pxt-core/built/web/icons.css';
157570
157654
  const iconsCss = fs.readFileSync(iconsFile, "utf-8");
157571
- semCss = semCss + "\n" + iconsCss;
157655
+ const reactCommonFile = (pkg["name"] == "pxt-core") ? 'built/web/react-common.css' : 'node_modules/pxt-core/built/web/react-common.css';
157656
+ const reactCommonCss = fs.readFileSync(reactCommonFile, "utf-8");
157657
+ semCss = semCss + "\n" + iconsCss + "\n" + reactCommonCss;
157572
157658
  nodeutil.writeFileSync('built/web/semantic.css', semCss);
157573
157659
  }).then(() => {
157574
157660
  // generate blockly css
@@ -157636,6 +157722,7 @@ function buildSkillMapAsync(parsed) {
157636
157722
  nodeutil.cp("node_modules/pxt-core/built/pxtlib.js", `${skillmapRoot}/public/blb`);
157637
157723
  nodeutil.cp("built/web/semantic.css", `${skillmapRoot}/public/blb`);
157638
157724
  nodeutil.cp("node_modules/pxt-core/built/web/icons.css", `${skillmapRoot}/public/blb`);
157725
+ nodeutil.cp("node_modules/pxt-core/built/web/react-common.css", `${skillmapRoot}/public/blb`);
157639
157726
  // copy 'assets' over from docs/static
157640
157727
  nodeutil.cpR("docs/static/skillmap/assets", `${skillmapRoot}/public/assets`);
157641
157728
  if (docsPath) {
@@ -3350,6 +3350,53 @@ ${info.id}_IfaceVT:
3350
3350
  else
3351
3351
  return `0xffffffff, 0xffffffff ; -> ${vt}`;
3352
3352
  }
3353
+ function encodeSourceMap(srcmap) {
3354
+ // magic: 0x4d435253 0x2d4e1588 0x719986aa ('SRCM' ... )
3355
+ const res = [0x53, 0x52, 0x43, 0x4d, 0x88, 0x15, 0x4e, 0x2d, 0xaa, 0x86, 0x99, 0x71, 0x00, 0x00, 0x00, 0x00];
3356
+ for (const fn of Object.keys(srcmap)) {
3357
+ for (const c of pxtc.U.stringToUint8Array(fn))
3358
+ res.push(c);
3359
+ res.push(0);
3360
+ const arr = srcmap[fn];
3361
+ let prevLn = 0;
3362
+ let prevOff = 0;
3363
+ for (let i = 0; i < arr.length; i += 3) {
3364
+ encodeNumber(arr[i] - prevLn);
3365
+ encodeNumber((arr[i + 1] - prevOff) >> 1);
3366
+ encodeNumber(arr[i + 2] >> 1);
3367
+ prevLn = arr[i];
3368
+ prevOff = arr[i + 1];
3369
+ }
3370
+ res.push(0xff); // end-marker
3371
+ }
3372
+ res.push(0);
3373
+ if (res.length & 1)
3374
+ res.push(0);
3375
+ const res2 = [];
3376
+ for (let i = 0; i < res.length; i += 2)
3377
+ res2.push(res[i] | (res[i + 1] << 8));
3378
+ return res2;
3379
+ function encodeNumber(k) {
3380
+ if (0 <= k && k < 0xf0)
3381
+ res.push(k);
3382
+ else {
3383
+ let mark = 0xf0;
3384
+ if (k < 0) {
3385
+ k = -k;
3386
+ mark |= 0x08;
3387
+ }
3388
+ const idx = res.length;
3389
+ res.push(null); // placeholder
3390
+ let len = 0;
3391
+ while (k != 0) {
3392
+ res.push(k & 0xff);
3393
+ k >>>= 8;
3394
+ len++;
3395
+ }
3396
+ res[idx] = mark | len;
3397
+ }
3398
+ }
3399
+ }
3353
3400
  /* eslint-disable no-trailing-spaces */
3354
3401
  function vmEmit(bin, opts) {
3355
3402
  let vmsource = `; VM start
@@ -3473,9 +3520,10 @@ _start_${name}:
3473
3520
  vmsource += "\n; The end.\n";
3474
3521
  bin.writeFile(pxtc.BINARY_ASM, vmsource);
3475
3522
  let res = pxtc.assemble(opts.target, bin, vmsource);
3476
- if (res.src)
3477
- bin.writeFile(pxtc.BINARY_ASM, res.src);
3478
3523
  const srcmap = res.thumbFile.getSourceMap();
3524
+ const encodedSrcMap = encodeSourceMap(srcmap);
3525
+ if (res.src)
3526
+ bin.writeFile(pxtc.BINARY_ASM, `; srcmap size: ${encodedSrcMap.length << 1} bytes\n` + res.src);
3479
3527
  {
3480
3528
  let binstring = "";
3481
3529
  for (let v of res.buf)
@@ -3501,12 +3549,16 @@ _start_${name}:
3501
3549
  }
3502
3550
  if (res.buf) {
3503
3551
  let binstring = "";
3504
- for (let v of res.buf)
3552
+ const buf = res.buf;
3553
+ while (buf.length & 0xf)
3554
+ buf.push(0);
3555
+ pxtc.U.pushRange(buf, encodedSrcMap);
3556
+ for (let v of buf)
3505
3557
  binstring += String.fromCharCode(v & 0xff, v >> 8);
3506
3558
  binstring = ts.pxtc.encodeBase64(binstring);
3507
3559
  if (embedVTs()) {
3508
3560
  bin.writeFile(pxtc.BINARY_PXT64, binstring);
3509
- const patched = pxtc.hexfile.patchHex(bin, res.buf, false, !!pxtc.target.useUF2)[0];
3561
+ const patched = pxtc.hexfile.patchHex(bin, buf, false, !!pxtc.target.useUF2)[0];
3510
3562
  bin.writeFile(pxt.outputName(pxtc.target), ts.pxtc.encodeBase64(patched));
3511
3563
  }
3512
3564
  else {
@@ -18203,6 +18255,7 @@ var ts;
18203
18255
  }
18204
18256
  service.snippetAddsDefinitions = snippetAddsDefinitions;
18205
18257
  function getSnippet(context, fn, decl, python, recursionDepth = 0) {
18258
+ var _a;
18206
18259
  // TODO: a lot of this is duplicate logic with blocklyloader.ts:buildBlockFromDef; we should
18207
18260
  // unify these approaches
18208
18261
  let { apis, takenNames, blocksInfo, screenSize, checker } = context;
@@ -18235,10 +18288,15 @@ var ts;
18235
18288
  if (attrs.shim === "TD_ID" && recursionDepth && decl.parameters.length) {
18236
18289
  return getParameterDefault(decl.parameters[0]);
18237
18290
  }
18291
+ const element = fn;
18292
+ const params = pxt.blocks.compileInfo(element);
18238
18293
  const blocksById = blocksInfo.blocksById;
18239
18294
  // TODO: move out of getSnippet for general reuse
18295
+ const blockParameters = ((_a = attrs._def) === null || _a === void 0 ? void 0 : _a.parameters.filter(param => !!params.definitionNameToParam[param.name]).map(param => params.definitionNameToParam[param.name].actualName)) || [];
18240
18296
  const includedParameters = decl.parameters ? decl.parameters
18241
- .filter(param => !param.initializer && !param.questionToken) : [];
18297
+ // Only keep required parameters and parameters included in the blockdef
18298
+ .filter(param => (!param.initializer && !param.questionToken)
18299
+ || (blockParameters.indexOf(param.name.getText()) >= 0)) : [];
18242
18300
  const args = includedParameters
18243
18301
  .map(getParameterDefault)
18244
18302
  .map(p =>
@@ -18248,7 +18306,6 @@ var ts;
18248
18306
  default: p,
18249
18307
  isLiteral: true
18250
18308
  }));
18251
- const element = fn;
18252
18309
  if (element.attributes.block) {
18253
18310
  if (element.attributes.defaultInstance) {
18254
18311
  snippetPrefix = element.attributes.defaultInstance;
@@ -18296,7 +18353,6 @@ var ts;
18296
18353
  isInstance = true;
18297
18354
  }
18298
18355
  else if (element.kind == 1 /* Method */ || element.kind == 2 /* Property */) {
18299
- const params = pxt.blocks.compileInfo(element);
18300
18356
  if (params.thisParameter) {
18301
18357
  let varName = undefined;
18302
18358
  if (params.thisParameter.definitionName) {
package/built/pxtlib.d.ts CHANGED
@@ -54,6 +54,9 @@ declare namespace pxt.auth {
54
54
  mapProgress: any;
55
55
  completedTags: any;
56
56
  };
57
+ type UserBadgeState = {
58
+ badges: Badge[];
59
+ };
57
60
  /**
58
61
  * User preference state that should be synced with the cloud.
59
62
  */
@@ -62,6 +65,7 @@ declare namespace pxt.auth {
62
65
  highContrast?: boolean;
63
66
  reader?: string;
64
67
  skillmap?: UserSkillmapState;
68
+ badges?: UserBadgeState;
65
69
  };
66
70
  const DEFAULT_USER_PREFERENCES: () => UserPreferences;
67
71
  /**
@@ -165,6 +169,11 @@ declare namespace pxt.auth {
165
169
  function userName(user: pxt.auth.UserProfile): string;
166
170
  function userInitials(user: pxt.auth.UserProfile): string;
167
171
  function generateUserProfilePicDataUrl(profile: pxt.auth.UserProfile): void;
172
+ /**
173
+ * Checks only the ID and sourceURL
174
+ */
175
+ function badgeEquals(badgeA: pxt.auth.Badge, badgeB: pxt.auth.Badge): boolean;
176
+ function hasBadge(preferences: pxt.auth.UserBadgeState, badge: pxt.auth.Badge): boolean;
168
177
  }
169
178
  declare namespace pxt {
170
179
  interface TelemetryEventOptions {
package/built/pxtlib.js CHANGED
@@ -670,6 +670,17 @@ var pxt;
670
670
  }
671
671
  }
672
672
  auth.generateUserProfilePicDataUrl = generateUserProfilePicDataUrl;
673
+ /**
674
+ * Checks only the ID and sourceURL
675
+ */
676
+ function badgeEquals(badgeA, badgeB) {
677
+ return badgeA.id === badgeB.id && badgeA.sourceURL === badgeB.sourceURL;
678
+ }
679
+ auth.badgeEquals = badgeEquals;
680
+ function hasBadge(preferences, badge) {
681
+ return preferences.badges.some(toCheck => badgeEquals(toCheck, badge));
682
+ }
683
+ auth.hasBadge = hasBadge;
673
684
  })(auth = pxt.auth || (pxt.auth = {}));
674
685
  })(pxt || (pxt = {}));
675
686
  // Needs to be in its own file to avoid a circular dependency: util.ts -> main.ts -> util.ts