Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
name: CI
on:
pull_request:
branches:
- v2

# Ensure scripts are run with pipefail. See:
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference
defaults:
run:
shell: bash

jobs:
tests:
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- windows-latest
- macos-latest

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with:
node-version: "18.x"
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0

- run: pnpm install

# Grab localizations
- run: pnpm docs-sync pull microsoft/TypeScript-Website-localizations#main 1

# Build the packages
- run: pnpm bootstrap
- run: pnpm build

# Verify it compiles
- run: pnpm build-site

- uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
if: github.event_name == 'pull_request' && matrix.os == 'ubuntu-latest'
with:
name: site
path: packages/typescriptlang-org/public

# Run all the package's tests
- run: pnpm test

# danger for PR builds
- if: github.event_name == 'pull_request' && github.event.pull_request.base.repo.id == github.event.pull_request.head.repo.id && matrix.os == 'ubuntu-latest'
run: "pnpm danger ci"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- run: |
git add .
if ! git diff --staged --exit-code --quiet; then
echo "This PR is missing some generated changes. Please update locally or merge the patch artifact."
echo ""
git diff --staged
git diff --staged > missing.patch
exit 1
fi
name: Check for uncommitted changes
id: check-diff
if: github.event_name == 'pull_request'

- name: Upload diff artifact
if: ${{ failure() && steps.check-diff.conclusion == 'failure' }}
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
name: missing.patch
path: missing.patch

changesets:
name: changesets
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with:
node-version: 'lts/*'
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0

- run: pnpm install

- name: Check for missing changesets
run: |
PR_CHANGESETS=$(ls .changeset | (grep -v -E 'README\.md|config\.json' || true) | wc -l)
MAIN_CHANGESETS=$(git ls-tree -r origin/v2 .changeset | (grep -v -E 'README\.md|config\.json' || true) | wc -l)

# If the PR has no changesets, but main has changesets, assume this is PR is a versioning PR and exit
if [[ $PR_CHANGESETS -eq 0 && $MAIN_CHANGESETS -gt 0 ]]; then
echo "This PR is a versioning PR, exiting"
exit 0
fi

# git switch -c changesets-temp
# git checkout origin/v2 -- <ignored files>
pnpm changeset status --since=origin/v2

required:
runs-on: ubuntu-latest
if: ${{ always() }}
needs:
- tests
- changesets

steps:
- name: Check required jobs
env:
NEEDS: ${{ toJson(needs) }}
run: |
! echo $NEEDS | jq -e 'to_entries[] | { job: .key, result: .value.result } | select(.result != "success")'
71 changes: 71 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: 'Code Scanning - Action'

on:
push:
branches:
- v2
pull_request:
branches:
- v2
schedule:
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
# │ │ │ │ │
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
- cron: '30 1 * * 0'

permissions:
contents: read

# Ensure scripts are run with pipefail. See:
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference
defaults:
run:
shell: bash

jobs:
CodeQL-Build:
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
runs-on: ubuntu-latest
if: github.repository == 'microsoft/TypeScript-Website'

permissions:
# required for all workflows
security-events: write

steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
with:
config-file: ./.github/codeql/codeql-configuration.yml
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java

# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below).
- name: Autobuild
uses: github/codeql-action/autobuild@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10

# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

# ✏️ If the Autobuild fails above, remove it and uncomment the following
# three lines and modify them (or add more) to build your code if your
# project uses a compiled language

#- run: |
# make bootstrap
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
70 changes: 70 additions & 0 deletions .github/workflows/deploy-prod-static.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Deploy to GitHub Pages

on:
push:
branches:
- v2
workflow_dispatch:
schedule:
# https://crontab.guru/#0_12_*_*_1
- cron: "0 12 * * 1"

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# Fetch the full history, to build attribution.json
fetch-depth: 0
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with:
node-version: "18.x"

- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0

# Builds the modules, and boostraps the other modules
- name: Build website
run: |
pnpm install
pnpm docs-sync pull microsoft/TypeScript-Website-localizations#main 1
pnpm bootstrap
pnpm run --filter=typescriptlang-org setup-playground-cache-bust
pnpm build

- name: Makes the site
run: |
pnpm build-site
cp -r packages/typescriptlang-org/public site

- name: Setup Pages
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5

- name: Upload artifact
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
with:
path: './site'

deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
41 changes: 41 additions & 0 deletions .github/workflows/publish-packages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Publish packages

on:
push:
branches: [v2]
workflow_dispatch:

permissions:
contents: write
pull-requests: write

concurrency: ${{ github.workflow }}-${{ github.ref }}

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
filter: blob:none
token: ${{ secrets.TS_BOT_TOKEN }}
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with:
node-version: "18.x"
registry-url: "https://registry.npmjs.org/"
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0

- name: Prepare website v2
run: |
pnpm install
pnpm bootstrap
pnpm build

- uses: changesets/action@c8bada60c408975afd1a20b3db81d6eee6789308 # v1.4.9
with:
publish: pnpm ci:publish
env:
GITHUB_TOKEN: ${{ secrets.TS_BOT_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
31 changes: 31 additions & 0 deletions .github/workflows/weekly-stats.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Publish Weekly Stats

on:
schedule:
# https://crontab.guru/#0_12_*_*_1
- cron: "0 12 * * 1"
workflow_dispatch:

permissions:
contents: read
comments: write

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with:
node-version: "18.x"

- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0

- run: pnpm install

# Update the site stats
- run: node packages/typescriptlang-org/scripts/updateAppInsightsGitHubIssue.js
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APP_INSIGHTS_API_KEY: ${{ secrets.APP_INSIGHTS_API_KEY }}
APP_INSIGHTS_ID: ${{ secrets.APP_INSIGHTS_ID }}
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@ Choosing compilation settings as a library author is a fundamentally different p
"verbatimModuleSyntax": true,
"declaration": true,
"sourceMap": true,
"declarationMap": true
"declarationMap": true,
"rootDir": "src",
"outDir": "dist"
}
}
```
Expand Down Expand Up @@ -185,6 +187,7 @@ Let’s examine why we picked each of these settings:
- **`verbatimModuleSyntax: true`**. This setting protects against a few module-related pitfalls that can cause problems for library consumers. First, it prevents writing any import statements that could be interpreted ambiguously based on the user’s value of `esModuleInterop` or `allowSyntheticDefaultImports`. Previously, it was often suggested that libraries compile without `esModuleInterop`, since its use in libraries could force users to adopt it too. However, it’s also possible to write imports that only work _without_ `esModuleInterop`, so neither value for the setting guarantees portability for libraries. `verbatimModuleSyntax` does provide such a guarantee.[^1] Second, it prevents the use of `export default` in modules that will be emitted as CommonJS, which can require bundler users and Node.js ESM users to consume the module differently. See the appendix on [ESM/CJS Interop](/docs/handbook/modules/appendices/esm-cjs-interop.html#library-code-needs-special-considerations) for more details.
- **`declaration: true`** emits type declaration files alongside the output JavaScript. This is needed for consumers of the library to have any type information.
- **`sourceMap: true`** and **`declarationMap: true`** emit source maps for the output JavaScript and type declaration files, respectively. These are only useful if the library also ships its source (`.ts`) files. By shipping source maps and source files, consumers of the library will be able to debug the library code somewhat more easily. By shipping declaration maps and source files, consumers will be able to see the original TypeScript sources when they run Go To Definition on imports from the libraries. Both of these represent a tradeoff between developer experience and library size, so it’s up to you whether to include them.
- **`rootDir: "src"`** and **`outDir: "dist"`**. Using a separate output directory is always a good idea, but it’s _necessary_ for libraries that publish their input files. Otherwise, [extension substitution](/docs/handbook/modules/reference.html#file-extension-substitution) will cause the library’s consumers to load the library’s `.ts` files instead of `.d.ts` files, causing type errors and performance problems.

### Considerations for bundling libraries

Expand All @@ -205,4 +208,4 @@ If you’re using a bundler to emit your library, then all your (non-externalize

A single TypeScript compilation (whether emitting or just type checking) assumes that each input file will only produce one output file. Even if `tsc` isn’t emitting anything, the type checking it performs on imported names rely on knowledge about how the output file will behave at runtime, based on the module- and emit-related options set in the tsconfig.json. While third-party emitters are generally safe to use in combination with `tsc` type checking as long as `tsc` can be configured to understand what the other emitter will emit, any solution that emits two different sets of outputs with different module formats while only type checking once leaves (at least) one of the outputs unchecked. Because external dependencies may expose different APIs to CommonJS and ESM consumers, there’s no configuration you can use to guarantee in a single compilation that both outputs will be type-safe. In practice, most dependencies follow best practices and dual-emit outputs work. Running tests and [static analysis](https://npmjs.com/package/@arethetypeswrong/cli) against all output bundles before publishing significantly reduces the chance of a serious problem going unnoticed.

[^1]: `verbatimModuleSyntax` can only work when the JS emitter emits the same module kind as `tsc` would given the tsconfig.json, source file extension, and package.json `"type"`. The option works by enforcing that the `import`/`require` written is identical to the `import`/`require` emitted. Any configuration that produces both an ESM and a CJS output from the same source file is fundamentally incompatible with `verbatimModuleSyntax`, since its whole purpose is to prevent you from writing `import` anywhere that a `require` would be emitted. `verbatimModuleSyntax` can also be defeated by configuring a third-party emitter to emit a different module kind than `tsc` would—for example, by setting `"module": "esnext"` in tsconfig.json while configuring Babel to emit CommonJS.
[^1]: `verbatimModuleSyntax` can only work when the JS emitter emits the same module kind as `tsc` would given the tsconfig.json, source file extension, and package.json `"type"`. The option works by enforcing that the `import`/`require` written is identical to the `import`/`require` emitted. Any configuration that produces both an ESM and a CJS output from the same source file is fundamentally incompatible with `verbatimModuleSyntax`, since its whole purpose is to prevent you from writing `import` anywhere that a `require` would be emitted. `verbatimModuleSyntax` can also be defeated by configuring a third-party emitter to emit a different module kind than `tsc` would—for example, by setting `"module": "esnext"` in tsconfig.json while configuring Babel to emit CommonJS.
2 changes: 1 addition & 1 deletion packages/playground/src/ds/createDesignSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export const createDesignSystem = (sandbox: Sandbox) => {
createCodePre.setAttribute("tabindex", "0")
const codeElement = document.createElement("code")

codeElement.innerHTML = code
codeElement.textContent = code

createCodePre.appendChild(codeElement)
container.appendChild(createCodePre)
Expand Down
4 changes: 2 additions & 2 deletions packages/tsconfig-reference/scripts/tsconfigRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,8 @@ function formatAllowedValues(type: CommandLineOption["type"]) {

export const releaseToConfigsMap: { [key: string]: AnOption[] } = {
"5.7": ["rewriteRelativeImportExtensions"],
"5.6": ["strictBuiltinIteratorReturn", "noUncheckedSideEffectImports"],
"5.5": ["isolatedDeclarations", "noCheck"],
"5.6": ["strictBuiltinIteratorReturn", "noUncheckedSideEffectImports", "noCheck"],
"5.5": ["isolatedDeclarations"],
"5.0": [
"allowArbitraryExtensions",
"allowImportingTsExtensions",
Expand Down