diff --git a/.github/workflows/pxt-buildpush.yml b/.github/workflows/pxt-buildpush.yml index 34ce4c3721e2..011f2a95d08f 100644 --- a/.github/workflows/pxt-buildpush.yml +++ b/.github/workflows/pxt-buildpush.yml @@ -9,6 +9,11 @@ on: pull_request: branches: - '**' # Run workflow for pull requests targeting any branch + merge_group: + branches: + - '**' # Run workflow for merge queue checks targeting any branch + types: + - checks_requested permissions: contents: write @@ -38,9 +43,9 @@ jobs: uses: actions/setup-node@main with: node-version: 20.x - + - name: Update npm - run: npm install -g npm@latest + run: npm install -g npm@11 - name: npm install run: | @@ -75,7 +80,7 @@ jobs: node-version: 20.x - name: Update npm - run: npm install -g npm@latest + run: npm install -g npm@11 - name: npm install run: | diff --git a/.vscode/settings.json b/.vscode/settings.json index c0421ef1bbf0..d62b6f37b868 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -27,5 +27,6 @@ "*.variables": "less", "*.jres": "json" }, - "git.ignoreLimitWarning": true + "git.ignoreLimitWarning": true, + "js/ts.tsdk.path": "node_modules/typescript/lib" } \ No newline at end of file diff --git a/ThirdPartyNotice b/ThirdPartyNotice index 8d0e5ab22166..d1857cafdb4b 100644 --- a/ThirdPartyNotice +++ b/ThirdPartyNotice @@ -882,6 +882,7 @@ General Public License. 864. @fortawesome/fontawesome-free 5.15.4 (https://www.npmjs.com/package/@fortawesome/fontawesome-free/v/5.15.4) 865. @blockly/plugin-workspace-search 4.0.10 (https://www.npmjs.com/package/@blockly/plugin-workspace-search/v/4.0.10) 866. @blockly/keyboard-navigation 1.0.0-beta.0 (https://www.npmjs.com/package/@blockly/keyboard-navigation/v/1.0.0-beta.0) +867. Qix-/color-convert 5c106a633b5cd2de554d9c287ad31f9eeca7a271 (https://github.com/Qix-/color-convert) @@ -28361,14 +28362,14 @@ The copyright in this software is being made available under the BSD License, in **Copyright (c) 2015, Dash Industry Forum. **All rights reserved.** - + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Dash Industry Forum nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. **THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.** - + ========================================= END OF dashjs 4.4.0 NOTICES AND INFORMATION @@ -28955,3 +28956,30 @@ END OF @blockly/plugin-workspace-search 4.0.10 NOTICES AND INFORMATION limitations under the License. ========================================= END OF @blockly/keyboard-navigation 1.0.0-beta.0 NOTICES AND INFORMATION + + +%% Qix-/color-convert 5c106a633b5cd2de554d9c287ad31f9eeca7a271 NOTICES AND INFORMATION BEGIN HERE +========================================= +Copyright (c) 2011-2016 Heather Arthur . +Copyright (c) 2016-2021 Josh Junon . + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF Qix-/color-convert 5c106a633b5cd2de554d9c287ad31f9eeca7a271 NOTICES AND INFORMATION \ No newline at end of file diff --git a/cli/cli.ts b/cli/cli.ts index c16596e9fcb0..c3d71ea714fa 100644 --- a/cli/cli.ts +++ b/cli/cli.ts @@ -276,8 +276,8 @@ class FileGithubDb implements pxt.github.IGithubDb { return this.loadAsync(repopath, tag, "pxt", (r, t) => this.db.loadConfigAsync(r, t)); } - loadPackageAsync(repopath: string, tag: string): Promise { - return this.loadAsync(repopath, tag, "pkg", (r, t) => this.db.loadPackageAsync(r, t)); + loadPackageAsync(repopath: string, tag: string, fallbackPackageFiles?: pxt.Map): Promise { + return this.loadAsync(repopath, tag, "pkg", (r, t) => this.db.loadPackageAsync(r, t, fallbackPackageFiles)); } loadTutorialMarkdown(repopath: string, tag?: string): Promise { @@ -5839,7 +5839,9 @@ export async function buildCoreDeclarationFiles(parsed: commandParser.ParsedComm nodeutil.mkdirP(builtFolder); process.chdir(cwd); - const host = shareId ? new Host() : new SnippetHost("decl-build", { "main.ts" : "" }, { "blocksprj": "*" }); + const blocksprjConfig = readBlocksprjConfig(); + + const host = shareId ? new Host() : new SnippetHost("decl-build", { "main.ts" : "" }, { ...blocksprjConfig.dependencies }); const mainPkg = new pxt.MainPackage(host); if (shareId) { @@ -6223,6 +6225,16 @@ function checkDocsAsync(parsed?: commandParser.ParsedCommand): Promise { ) } +function readBlocksprjConfig(): pxt.PackageConfig { + const configPath = path.join("libs", pxt.BLOCKS_PROJECT_NAME, "pxt.json"); + + if (!nodeutil.fileExistsSync(configPath)) { + return undefined; + } + const config = nodeutil.readJson(configPath) as pxt.PackageConfig; + return config; +} + function checkFileSize(files: string[]): number { if (!pxt.appTarget.cloud) return 0; @@ -6262,6 +6274,8 @@ function internalCheckDocsAsync(compileSnippets?: boolean, re?: string, fix?: bo const existingSnippets: pxt.Map = {}; let snippets: CodeSnippet[] = []; + const blocksprjConfig = readBlocksprjConfig(); + const maxFileSize = checkFileSize(nodeutil.allFiles("docs", { maxDepth: 10, allowMissing: true, includeDirs: true, ignoredFileMarker: ".ignorelargefiles" })); if (!pxt.appTarget.ignoreDocsErrors && maxFileSize > (pxt.appTarget.cloud.maxFileSize || (30000000))) @@ -6434,7 +6448,7 @@ function internalCheckDocsAsync(compileSnippets?: boolean, re?: string, fix?: bo } // look for snippets - getCodeSnippets(entrypath, md).forEach((snippet, snipIndex) => addSnippet(snippet, entrypath, snipIndex, entrypath)); + getCodeSnippets(entrypath, md, blocksprjConfig).forEach((snippet, snipIndex) => addSnippet(snippet, entrypath, snipIndex, entrypath)); } nodeutil.mkdirP("temp"); @@ -6479,8 +6493,7 @@ function internalCheckDocsAsync(compileSnippets?: boolean, re?: string, fix?: bo continue; } const tutorial = pxt.tutorial.parseTutorial(tutorialMd); - const pkgs: pxt.Map = { "blocksprj": "*" }; - pxt.Util.jsonMergeFrom(pkgs, pxt.gallery.parsePackagesFromMarkdown(tutorialMd) || {}); + const pkgs = pxt.tutorial.mergeTutorialDependencies(blocksprjConfig.dependencies, pxt.gallery.parsePackagesFromMarkdown(tutorialMd) || {}); let extraFiles: Map = null; @@ -6497,7 +6510,7 @@ function internalCheckDocsAsync(compileSnippets?: boolean, re?: string, fix?: bo || (tutorial.language == "python")) { tutorial.steps .filter(step => !!step.contentMd) - .forEach((step, stepIndex) => getCodeSnippets(`${card.name}-step${stepIndex}`, step.contentMd) + .forEach((step, stepIndex) => getCodeSnippets(`${card.name}-step${stepIndex}`, step.contentMd, blocksprjConfig) .forEach((snippet, snippetIndex) => { snippet.packages = pkgs; snippet.extraFiles = extraFiles; @@ -6539,8 +6552,7 @@ function internalCheckDocsAsync(compileSnippets?: boolean, re?: string, fix?: bo continue; } const prj = pxt.gallery.parseExampleMarkdown(card.name, exMd); - const pkgs: pxt.Map = { "blocksprj": "*" }; - pxt.U.jsonMergeFrom(pkgs, prj.dependencies); + const pkgs = pxt.tutorial.mergeTutorialDependencies(blocksprjConfig.dependencies, prj.dependencies); let extraFiles: Map = undefined; @@ -6616,6 +6628,8 @@ function internalCacheUsedBlocksAsync(): Promise> { const mdRegex = /\.md$/; const targetDirs = pxt.appTarget.cacheusedblocksdirs; const builtTututorialInfo: Map = {}; + const blocksprjConfig = readBlocksprjConfig(); + if (targetDirs) { targetDirs.forEach(dir => { pxt.log(`looking for tutorial markdown in ${dir}`); @@ -6633,8 +6647,9 @@ function internalCacheUsedBlocksAsync(): Promise> { pxt.log(`error resolving tutorial markdown at ${path}`); } const tutorial = pxt.tutorial.parseTutorial(md) as TutorialInfo; - const pkgs: pxt.Map = { "blocksprj": "*" }; - pxt.Util.jsonMergeFrom(pkgs, pxt.gallery.parsePackagesFromMarkdown(md) || {}); + const tutorialDeps = pxt.gallery.parsePackagesFromMarkdown(md) || {}; + const pkgs: pxt.Map = pxt.tutorial.mergeTutorialDependencies(blocksprjConfig.dependencies, tutorialDeps); + tutorial.pkgs = pkgs; tutorial.path = path; @@ -6752,7 +6767,7 @@ export interface CodeSnippet { src?: string; } -export function getCodeSnippets(fileName: string, md: string): CodeSnippet[] { +export function getCodeSnippets(fileName: string, md: string, baseConfig: pxt.PackageConfig): CodeSnippet[] { const supported: pxt.Map = { "blocks": "ts", "block": "ts", @@ -6778,21 +6793,20 @@ export function getCodeSnippets(fileName: string, md: string): CodeSnippet[] { }; } - - const pkgs: pxt.Map = { - "blocksprj": "*" - } - snippets.filter(snip => snip.type == "package") + const tutorialDeps = snippets.filter(snip => snip.type == "package") .map(snip => snip.code.split('\n')) - .forEach(lines => lines - .map(l => l.replace(/\s*$/, '')) - .filter(line => !!line) - .forEach(line => { + .reduce((acc, lines) => { + for (let line of lines) { + line = line.replace(/\s*$/, ''); + if (!line) continue; const i = line.indexOf('='); - if (i < 0) pkgs[line] = "*"; - else pkgs[line.substring(0, i)] = line.substring(i + 1); - }) - ); + if (i < 0) acc[line] = "*"; + else acc[line.substring(0, i).trim()] = line.substring(i + 1); + } + return acc; + }, {} as pxt.Map); + + const pkgs = pxt.tutorial.mergeTutorialDependencies(baseConfig.dependencies, tutorialDeps); const pkgName = fileName.replace(/\\/g, '-').replace(/.md$/i, ''); return codeSnippets.map((snip, i) => { diff --git a/common-docs/javascript/generics.md b/common-docs/javascript/generics.md index f812b55873f7..cdc2acd2bbd9 100644 --- a/common-docs/javascript/generics.md +++ b/common-docs/javascript/generics.md @@ -131,7 +131,7 @@ function identity(arg: T): T { return arg; } -let myIdentity: (arg: U) => U = identity; +let myIdentity: (arg: V) => V = identity; ``` We can also write the generic type as a call signature of an object literal type: diff --git a/common-docs/share.md b/common-docs/share.md index fa196157e410..7a4931f3d705 100644 --- a/common-docs/share.md +++ b/common-docs/share.md @@ -56,6 +56,16 @@ By default, all shared projects in MakeCode can be copied and edited. There is n ![Edit shared project button](/static/share/edit-shared-project.png) +## Asset Packs #asset-packs + +Certain editors (such as [MakeCode Arcade](https://arcade.makecode.com)) can include resource files inside of projects. The resources, or _assets_, might contain byte respresentations of images, animations, sounds, tilemaps, etc. An **Asset Pack** is a resource only project where just the assets are shared and no code is loaded from the shared project. + +If this feature is supported by your editor, you can set a project as an asset pack by going to the **Settings** (⚙️) menu and selecting 'Project Settings'. Enable the 'Import as asset pack' setting. Watch this video to see how it's done: + +https://youtu.be/CjLYl5KJiSk + +See the [Asset Packs](https://makecode.com/extensions/asset-packs) page to learn more. + ## Report Abuse All MakeCode shared projects pass through Microsoft standard scanning for security and safety compliance. In addition, the "Report Abuse" option is available on any shared project if you deem the contents of the project not appropriate (contains unsafe content or includes personally identifiable information). For these types of projects, the MakeCode Team will remove the project from our databases. diff --git a/common-docs/static/logo/Microsoft-logo_rgb_c-gray.png b/common-docs/static/logo/Microsoft-logo_rgb_c-gray.png new file mode 100644 index 000000000000..6b77415ea54c Binary files /dev/null and b/common-docs/static/logo/Microsoft-logo_rgb_c-gray.png differ diff --git a/common-docs/teachertool/catalog-shared.json b/common-docs/teachertool/catalog-shared.json index 6679295131c4..70f7d5dcfa20 100644 --- a/common-docs/teachertool/catalog-shared.json +++ b/common-docs/teachertool/catalog-shared.json @@ -123,7 +123,7 @@ "use": "variable_usage", "template": "Uses at least ${count} variable(s)", "docPath": "/teachertool", - "description": "The program creates and uses at least this many user-defined variables.", + "description": "At least this many user-defined variables are both set and read — auto-generated variables like loop indices do not count.", "maxCount": 1, "tags": ["Code Elements"], "params": [ diff --git a/docfiles/footer.html b/docfiles/footer.html index ab249b637ceb..a778901e1695 100644 --- a/docfiles/footer.html +++ b/docfiles/footer.html @@ -3,8 +3,8 @@