This commit is contained in:
Brian Terlson 2022-03-11 10:52:58 -08:00 коммит произвёл GitHub
Родитель 9013c3f2d4
Коммит 4bdf8938ca
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
39 изменённых файлов: 1361 добавлений и 44 удалений

Просмотреть файл

@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cadl-lang/compiler",
"comment": "Support browser builds",
"type": "patch"
}
],
"packageName": "@cadl-lang/compiler"
}

Просмотреть файл

@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cadl-lang/openapi3",
"comment": "Support browser builds",
"type": "patch"
}
],
"packageName": "@cadl-lang/openapi3"
}

Просмотреть файл

@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cadl-lang/prettier-plugin-cadl",
"comment": "",
"type": "none"
}
],
"packageName": "@cadl-lang/prettier-plugin-cadl"
}

Просмотреть файл

@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cadl-lang/rest",
"comment": "Support browser builds",
"type": "patch"
}
],
"packageName": "@cadl-lang/rest"
}

368
common/config/rush/pnpm-lock.yaml сгенерированный
Просмотреть файл

@ -3,6 +3,7 @@ dependencies:
'@rollup/plugin-json': 4.1.0_rollup@2.41.5
'@rollup/plugin-node-resolve': 11.2.1_rollup@2.41.5
'@rollup/plugin-replace': 2.4.2_rollup@2.41.5
'@rush-temp/cadl-playground': file:projects/cadl-playground.tgz
'@rush-temp/cadl-vs': file:projects/cadl-vs.tgz
'@rush-temp/cadl-vscode': file:projects/cadl-vscode.tgz
'@rush-temp/compiler': file:projects/compiler.tgz
@ -16,8 +17,10 @@ dependencies:
'@rush-temp/tmlanguage-generator': file:projects/tmlanguage-generator.tgz
'@rush-temp/versioning': file:projects/versioning.tgz
'@rushstack/eslint-patch': 1.1.0
'@types/debounce': 1.2.1
'@types/glob': 7.1.4
'@types/js-yaml': 4.0.5
'@types/lz-string': 1.3.34
'@types/mkdirp': 1.0.2
'@types/mocha': 9.1.0
'@types/mustache': 4.1.2
@ -33,6 +36,7 @@ dependencies:
autorest: 3.3.2
c8: 7.11.0
change-case: 4.1.2
debounce: 1.2.1
ecmarkup: 9.8.1
eslint: 8.9.0
eslint-config-prettier: 8.4.0_eslint@8.9.0
@ -40,8 +44,10 @@ dependencies:
glob: 7.1.7
grammarkdown: 3.1.2
js-yaml: 4.1.0
lzutf8: 0.6.1
mkdirp: 1.0.4
mocha: 9.2.1
monaco-editor: 0.32.1
mustache: 4.2.0
node-fetch: 3.2.0
node-watch: 0.7.3
@ -54,6 +60,7 @@ dependencies:
rollup: 2.41.5
source-map-support: 0.5.21
typescript: 4.5.5
vite: 2.8.6
vsce: 2.6.7
vscode-languageclient: 7.0.0
vscode-languageserver: 7.0.0
@ -306,6 +313,10 @@ packages:
dev: false
resolution:
integrity: sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==
/@types/debounce/1.2.1:
dev: false
resolution:
integrity: sha512-epMsEE85fi4lfmJUH/89/iV/LI+F5CvNIvmgs5g5jYFPfhO2S/ae8WSsLOKWdwtoaZw9Q2IhJ4tQ5tFCcS/4HA==
/@types/estree/0.0.39:
dev: false
resolution:
@ -333,6 +344,10 @@ packages:
dev: false
resolution:
integrity: sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
/@types/lz-string/1.3.34:
dev: false
resolution:
integrity: sha512-j6G1e8DULJx3ONf6NdR5JiR2ZY3K3PaaqiEuKYkLQO0Czfi1AzrtjfnfCROyWGeDd5IVMKCwsgSmMip9OWijow==
/@types/minimatch/3.0.5:
dev: false
resolution:
@ -1116,6 +1131,10 @@ packages:
dev: false
resolution:
integrity: sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==
/debounce/1.2.1:
dev: false
resolution:
integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==
/debug/4.3.3:
dependencies:
ms: 2.1.2
@ -1316,6 +1335,255 @@ packages:
dev: false
resolution:
integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
/esbuild-android-64/0.14.25:
cpu:
- x64
dev: false
engines:
node: '>=12'
optional: true
os:
- android
resolution:
integrity: sha512-L5vCUk7TzFbBnoESNoXjU3x9+/+7TDIE/1mTfy/erAfvZAqC+S3sp/Qa9wkypFMcFvN9FzvESkTlpeQDolREtQ==
/esbuild-android-arm64/0.14.25:
cpu:
- arm64
dev: false
engines:
node: '>=12'
optional: true
os:
- android
resolution:
integrity: sha512-4jv5xPjM/qNm27T5j3ZEck0PvjgQtoMHnz4FzwF5zNP56PvY2CT0WStcAIl6jNlsuDdN63rk2HRBIsO6xFbcFw==
/esbuild-darwin-64/0.14.25:
cpu:
- x64
dev: false
engines:
node: '>=12'
optional: true
os:
- darwin
resolution:
integrity: sha512-TGp8tuudIxOyWd1+8aYPxQmC1ZQyvij/AfNBa35RubixD0zJ1vkKHVAzo0Zao1zcG6pNqiSyzfPto8vmg0s7oA==
/esbuild-darwin-arm64/0.14.25:
cpu:
- arm64
dev: false
engines:
node: '>=12'
optional: true
os:
- darwin
resolution:
integrity: sha512-oTcDgdm0MDVEmw2DWu8BV68pYuImpFgvWREPErBZmNA4MYKGuBRaCiJqq6jZmBR1x+3y1DWCjez+5uLtuAm6mw==
/esbuild-freebsd-64/0.14.25:
cpu:
- x64
dev: false
engines:
node: '>=12'
optional: true
os:
- freebsd
resolution:
integrity: sha512-ueAqbnMZ8arnuLH8tHwTCQYeptnHOUV7vA6px6j4zjjQwDx7TdP7kACPf3TLZLdJQ3CAD1XCvQ2sPhX+8tacvQ==
/esbuild-freebsd-arm64/0.14.25:
cpu:
- arm64
dev: false
engines:
node: '>=12'
optional: true
os:
- freebsd
resolution:
integrity: sha512-+ZVWud2HKh+Ob6k/qiJWjBtUg4KmJGGmbvEXXW1SNKS7hW7HU+Zq2ZCcE1akFxOPkVB+EhOty/sSek30tkCYug==
/esbuild-linux-32/0.14.25:
cpu:
- ia32
dev: false
engines:
node: '>=12'
optional: true
os:
- linux
resolution:
integrity: sha512-3OP/lwV3kCzEz45tobH9nj+uE4ubhGsfx+tn0L26WAGtUbmmcRpqy7XRG/qK7h1mClZ+eguIANcQntYMdYklfw==
/esbuild-linux-64/0.14.25:
cpu:
- x64
dev: false
engines:
node: '>=12'
optional: true
os:
- linux
resolution:
integrity: sha512-+aKHdHZmX9qwVlQmu5xYXh7GsBFf4TWrePgeJTalhXHOG7NNuUwoHmketGiZEoNsWyyqwH9rE5BC+iwcLY30Ug==
/esbuild-linux-arm/0.14.25:
cpu:
- arm
dev: false
engines:
node: '>=12'
optional: true
os:
- linux
resolution:
integrity: sha512-aTLcE2VBoLydL943REcAcgnDi3bHtmULSXWLbjtBdtykRatJVSxKMjK9YlBXUZC4/YcNQfH7AxwVeQr9fNxPhw==
/esbuild-linux-arm64/0.14.25:
cpu:
- arm64
dev: false
engines:
node: '>=12'
optional: true
os:
- linux
resolution:
integrity: sha512-UxfenPx/wSZx55gScCImPtXekvZQLI2GW3qe5dtlmU7luiqhp5GWPzGeQEbD3yN3xg/pHc671m5bma5Ns7lBHw==
/esbuild-linux-mips64le/0.14.25:
cpu:
- mips64el
dev: false
engines:
node: '>=12'
optional: true
os:
- linux
resolution:
integrity: sha512-wLWYyqVfYx9Ur6eU5RT92yJVsaBGi5RdkoWqRHOqcJ38Kn60QMlcghsKeWfe9jcYut8LangYZ98xO1LxIoSXrQ==
/esbuild-linux-ppc64le/0.14.25:
cpu:
- ppc64
dev: false
engines:
node: '>=12'
optional: true
os:
- linux
resolution:
integrity: sha512-0dR6Csl6Zas3g4p9ULckEl8Mo8IInJh33VCJ3eaV1hj9+MHGdmDOakYMN8MZP9/5nl+NU/0ygpd14cWgy8uqRw==
/esbuild-linux-riscv64/0.14.25:
cpu:
- riscv64
dev: false
engines:
node: '>=12'
optional: true
os:
- linux
resolution:
integrity: sha512-J4d20HDmTrgvhR0bdkDhvvJGaikH3LzXQnNaseo8rcw9Yqby9A90gKUmWpfwqLVNRILvNnAmKLfBjCKU9ajg8w==
/esbuild-linux-s390x/0.14.25:
cpu:
- s390x
dev: false
engines:
node: '>=12'
optional: true
os:
- linux
resolution:
integrity: sha512-YI2d5V6nTE73ZnhEKQD7MtsPs1EtUZJ3obS21oxQxGbbRw1G+PtJKjNyur+3t6nzHP9oTg6GHQ3S3hOLLmbDIQ==
/esbuild-netbsd-64/0.14.25:
cpu:
- x64
dev: false
engines:
node: '>=12'
optional: true
os:
- netbsd
resolution:
integrity: sha512-TKIVgNWLUOkr+Exrye70XTEE1lJjdQXdM4tAXRzfHE9iBA7LXWcNtVIuSnphTqpanPzTDFarF0yqq4kpbC6miA==
/esbuild-openbsd-64/0.14.25:
cpu:
- x64
dev: false
engines:
node: '>=12'
optional: true
os:
- openbsd
resolution:
integrity: sha512-QgFJ37A15D7NIXBTYEqz29+uw3nNBOIyog+3kFidANn6kjw0GHZ0lEYQn+cwjyzu94WobR+fes7cTl/ZYlHb1A==
/esbuild-sunos-64/0.14.25:
cpu:
- x64
dev: false
engines:
node: '>=12'
optional: true
os:
- sunos
resolution:
integrity: sha512-rmWfjUItYIVlqr5EnTH1+GCxXiBOC42WBZ3w++qh7n2cS9Xo0lO5pGSG2N+huOU2fX5L+6YUuJ78/vOYvefeFw==
/esbuild-windows-32/0.14.25:
cpu:
- ia32
dev: false
engines:
node: '>=12'
optional: true
os:
- win32
resolution:
integrity: sha512-HGAxVUofl3iUIz9W10Y9XKtD0bNsK9fBXv1D55N/ljNvkrAYcGB8YCm0v7DjlwtyS6ws3dkdQyXadbxkbzaKOA==
/esbuild-windows-64/0.14.25:
cpu:
- x64
dev: false
engines:
node: '>=12'
optional: true
os:
- win32
resolution:
integrity: sha512-TirEohRkfWU9hXLgoDxzhMQD1g8I2mOqvdQF2RS9E/wbkORTAqJHyh7wqGRCQAwNzdNXdg3JAyhQ9/177AadWA==
/esbuild-windows-arm64/0.14.25:
cpu:
- arm64
dev: false
engines:
node: '>=12'
optional: true
os:
- win32
resolution:
integrity: sha512-4ype9ERiI45rSh+R8qUoBtaj6kJvUOI7oVLhKqPEpcF4Pa5PpT3hm/mXAyotJHREkHpM87PAJcA442mLnbtlNA==
/esbuild/0.14.25:
dev: false
engines:
node: '>=12'
hasBin: true
optionalDependencies:
esbuild-android-64: 0.14.25
esbuild-android-arm64: 0.14.25
esbuild-darwin-64: 0.14.25
esbuild-darwin-arm64: 0.14.25
esbuild-freebsd-64: 0.14.25
esbuild-freebsd-arm64: 0.14.25
esbuild-linux-32: 0.14.25
esbuild-linux-64: 0.14.25
esbuild-linux-arm: 0.14.25
esbuild-linux-arm64: 0.14.25
esbuild-linux-mips64le: 0.14.25
esbuild-linux-ppc64le: 0.14.25
esbuild-linux-riscv64: 0.14.25
esbuild-linux-s390x: 0.14.25
esbuild-netbsd-64: 0.14.25
esbuild-openbsd-64: 0.14.25
esbuild-sunos-64: 0.14.25
esbuild-windows-32: 0.14.25
esbuild-windows-64: 0.14.25
esbuild-windows-arm64: 0.14.25
requiresBuild: true
resolution:
integrity: sha512-4JHEIOMNFvK09ziiL+iVmldIhLbn49V4NAVo888tcGFKedEZY/Y8YapfStJ6zSE23tzYPKxqKwQBnQoIO0BI/Q==
/escalade/3.1.1:
dev: false
engines:
@ -2346,6 +2614,12 @@ packages:
node: '>=10'
resolution:
integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
/lzutf8/0.6.1:
dependencies:
readable-stream: 3.6.0
dev: false
resolution:
integrity: sha512-XsaftVRx/OFJC85vuqWsz4ihvD+DOOL1gU0UbgAR/MMLNvZWWOMncEnAAQf9XOMOHBeVcRxmujvWUo37LYJyMg==
/magic-string/0.25.7:
dependencies:
sourcemap-codec: 1.4.8
@ -2480,6 +2754,10 @@ packages:
hasBin: true
resolution:
integrity: sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ==
/monaco-editor/0.32.1:
dev: false
resolution:
integrity: sha512-LUt2wsUvQmEi2tfTOK+tjAPvt7eQ+K5C4rZPr6SeuyzjAuAHrIvlUloTcOiGjZW3fn3a/jFQCONrEJbNOaCqbA==
/ms/2.1.2:
dev: false
resolution:
@ -2504,6 +2782,13 @@ packages:
hasBin: true
resolution:
integrity: sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
/nanoid/3.3.1:
dev: false
engines:
node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1
hasBin: true
resolution:
integrity: sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==
/napi-build-utils/1.0.2:
dev: false
resolution:
@ -2745,6 +3030,10 @@ packages:
dev: false
resolution:
integrity: sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
/picocolors/1.0.0:
dev: false
resolution:
integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
/picomatch/2.3.1:
dev: false
engines:
@ -2764,6 +3053,16 @@ packages:
dev: false
resolution:
integrity: sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==
/postcss/8.4.8:
dependencies:
nanoid: 3.3.1
picocolors: 1.0.0
source-map-js: 1.0.2
dev: false
engines:
node: ^10 || ^12 || >=14
resolution:
integrity: sha512-2tXEqGxrjvAO6U+CJzDL2Fk2kPHTv1jQsYkSoMeOis2SsYaXRO2COxTdQp99cYvif9JTXaAk9lYGc3VhJt7JPQ==
/prebuild-install/7.0.1:
dependencies:
detect-libc: 2.0.1
@ -3050,6 +3349,15 @@ packages:
fsevents: 2.3.2
resolution:
integrity: sha512-uG+WNNxhOYyeuO7oRt98GA2CNVRgQ67zca75UQVMPzMrLG9FUKzTCgvYVWhtB18TNbV7Uqxo97h+wErAnpFNJw==
/rollup/2.70.0:
dev: false
engines:
node: '>=10.0.0'
hasBin: true
optionalDependencies:
fsevents: 2.3.2
resolution:
integrity: sha512-iEzYw+syFxQ0X9RefVwhr8BA2TNJsTaX8L8dhyeyMECDbmiba+8UQzcu+xZdji0+JQ+s7kouQnw+9Oz5M19XKA==
/run-parallel/1.2.0:
dependencies:
queue-microtask: 1.2.3
@ -3174,6 +3482,12 @@ packages:
dev: false
resolution:
integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==
/source-map-js/1.0.2:
dev: false
engines:
node: '>=0.10.0'
resolution:
integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
/source-map-support/0.5.21:
dependencies:
buffer-from: 1.1.2
@ -3549,6 +3863,31 @@ packages:
'0': node >=0.6.0
resolution:
integrity: sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
/vite/2.8.6:
dependencies:
esbuild: 0.14.25
postcss: 8.4.8
resolve: 1.22.0
rollup: 2.70.0
dev: false
engines:
node: '>=12.2.0'
hasBin: true
optionalDependencies:
fsevents: 2.3.2
peerDependencies:
less: '*'
sass: '*'
stylus: '*'
peerDependenciesMeta:
less:
optional: true
sass:
optional: true
stylus:
optional: true
resolution:
integrity: sha512-e4H0QpludOVKkmOsRyqQ7LTcMUDF3mcgyNU4lmi0B5JUbe0ZxeBBl8VoZ8Y6Rfn9eFKYtdXNPcYK97ZwH+K2ug==
/vsce/2.6.7:
dependencies:
azure-devops-node-api: 11.1.1
@ -3842,6 +4181,28 @@ packages:
node: '>=10'
resolution:
integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
file:projects/cadl-playground.tgz:
dependencies:
'@types/debounce': 1.2.1
'@types/lz-string': 1.3.34
'@types/mocha': 9.1.0
'@types/node': 14.0.27
c8: 7.11.0
debounce: 1.2.1
eslint: 8.9.0
lzutf8: 0.6.1
mocha: 9.2.1
monaco-editor: 0.32.1
rimraf: 3.0.2
typescript: 4.5.5
vite: 2.8.6
vscode-languageserver-textdocument: 1.0.4
dev: false
name: '@rush-temp/cadl-playground'
resolution:
integrity: sha512-h0FSYO38B5DmOMy9PaBeZqet7UK5N5+GxR3t3mybU8tbJ+R/o8SY1Xvsw2q9hzehNlFj8vZiYIyrHSou8QTMow==
tarball: file:projects/cadl-playground.tgz
version: 0.0.0
file:projects/cadl-vs.tgz:
dev: false
name: '@rush-temp/cadl-vs'
@ -4049,6 +4410,7 @@ specifiers:
'@rollup/plugin-json': ~4.1.0
'@rollup/plugin-node-resolve': ~11.2.0
'@rollup/plugin-replace': ~2.4.2
'@rush-temp/cadl-playground': file:./projects/cadl-playground.tgz
'@rush-temp/cadl-vs': file:./projects/cadl-vs.tgz
'@rush-temp/cadl-vscode': file:./projects/cadl-vscode.tgz
'@rush-temp/compiler': file:./projects/compiler.tgz
@ -4062,8 +4424,10 @@ specifiers:
'@rush-temp/tmlanguage-generator': file:./projects/tmlanguage-generator.tgz
'@rush-temp/versioning': file:./projects/versioning.tgz
'@rushstack/eslint-patch': '1.1.0 '
'@types/debounce': ~1.2.1
'@types/glob': ~7.1.3
'@types/js-yaml': ~4.0.1
'@types/lz-string': ~1.3.34
'@types/mkdirp': ~1.0.1
'@types/mocha': ~9.1.0
'@types/mustache': ~4.1.2
@ -4079,6 +4443,7 @@ specifiers:
autorest: ~3.3.2
c8: ~7.11.0
change-case: ~4.1.2
debounce: ~1.2.1
ecmarkup: ~9.8.1
eslint: ^8.7.0
eslint-config-prettier: ^8.3.0
@ -4086,8 +4451,10 @@ specifiers:
glob: ~7.1.6
grammarkdown: ~3.1.2
js-yaml: ~4.1.0
lzutf8: ~0.6.1
mkdirp: ~1.0.4
mocha: ~9.2.0
monaco-editor: ~0.32.1
mustache: ~4.2.0
node-fetch: ~3.2.0
node-watch: ~0.7.1
@ -4100,6 +4467,7 @@ specifiers:
rollup: ~2.41.4
source-map-support: ~0.5.19
typescript: ~4.5.5
vite: ^2.8.0
vsce: ~2.6.7
vscode-languageclient: ~7.0.0
vscode-languageserver: ~7.0.0

Просмотреть файл

@ -1,4 +1,3 @@
import { inspect } from "util";
import { createSymbol, createSymbolTable } from "./binder.js";
import { compilerAssert, ProjectionError } from "./diagnostics.js";
import {
@ -309,17 +308,6 @@ export function createChecker(program: Program): Checker {
},
declarations: [],
});
// a utility function to dump a type
cadlNamespaceBinding!.exports!.set("inspect", {
flags: SymbolFlags.Function,
name: "inspect",
value(p: Program, arg: Type): Type {
program.logger.log({ level: "debug", message: inspect(arg) });
return voidType;
},
declarations: [],
});
}
function mergeSourceFile(file: CadlScriptNode | JsSourceFileNode) {

Просмотреть файл

@ -13,8 +13,8 @@ import { compile, Program } from "../core/program.js";
import { initCadlProject } from "../init/index.js";
import { compilerAssert, logDiagnostics } from "./diagnostics.js";
import { findUnformattedCadlFiles, formatCadlFiles } from "./formatter.js";
import { NodeHost } from "./host.js";
import { installCadlDependencies } from "./install.js";
import { NodeHost } from "./node-host.js";
import { getAnyExtensionFromPath, getBaseFileName, joinPaths, resolvePath } from "./path-utils.js";
import { Diagnostic } from "./types.js";
import { cadlVersion } from "./util.js";

Просмотреть файл

@ -1,4 +1,3 @@
import { AssertionError } from "assert";
import { CharCode } from "./charcode.js";
import { formatLog } from "./logger.js";
import { Program } from "./program.js";
@ -282,7 +281,7 @@ export function compilerAssert(
}
}
throw new AssertionError({ message });
throw new Error(message);
}
function scanLineStarts(text: string): number[] {

Просмотреть файл

@ -1,12 +1,16 @@
export * from "../lib/decorators.js";
export * as decorators from "../lib/decorators.js";
export * from "../lib/service.js";
export * as service from "../lib/service.js";
export * from "../server/serverlib.js";
export * from "./decorator-utils.js";
export * from "./diagnostics.js";
export * from "./host.js";
export * from "./library.js";
export * from "./node-host.js";
export * from "./parser.js";
export * from "./path-utils.js";
export * from "./program.js";
export * from "./scanner.js";
export * from "./semantic-walker.js";
export * from "./types.js";
import * as formatter from "../formatter/index.js";

Просмотреть файл

@ -0,0 +1,5 @@
export const NodeHost = undefined;
// browsers shouldn't use this const and should instead
// create some const at bundle time.
export const cadlVersion = "browser";

Просмотреть файл

@ -1,3 +1,4 @@
import { readFileSync } from "fs";
import { readdir, readFile, realpath, rmdir, stat, writeFile } from "fs/promises";
import mkdirp from "mkdirp";
import fetch from "node-fetch";
@ -5,7 +6,7 @@ import { fileURLToPath, pathToFileURL } from "url";
import { createSourceFile } from "./diagnostics.js";
import { createConsoleSink } from "./logger.js";
import { joinPaths, resolvePath } from "./path-utils.js";
import { CompilerHost, RemoveDirOptions } from "./types.js";
import { CompilerHost, RemoveDirOptions } from "./types";
/**
* Implementation of the @see CompilerHost using the real file system.
@ -15,7 +16,6 @@ export const NodeHost: CompilerHost = {
readUrl: async (url: string) => {
const response = await fetch(url);
const text = await response.text();
return createSourceFile(text, url);
},
readFile: async (path: string) => createSourceFile(await readFile(path, "utf-8"), path),
@ -36,4 +36,16 @@ export const NodeHost: CompilerHost = {
},
logSink: createConsoleSink(),
mkdirp: (path: string) => mkdirp(path),
fileURLToPath,
pathToFileURL(path: string) {
return pathToFileURL(path).href;
},
};
export const cadlVersion = getVersion();
function getVersion(): string {
const packageJsonPath = fileURLToPath(new URL("../../package.json", import.meta.url).href);
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
return packageJson.version;
}

Просмотреть файл

@ -1,4 +1,3 @@
import { fileURLToPath } from "url";
import { createBinder } from "./binder.js";
import { Checker, createChecker } from "./checker.js";
import { createSourceFile, getSourceLocation } from "./diagnostics.js";
@ -620,7 +619,7 @@ export async function createProgram(
}
const expected = await host.realpath(
resolvePath(fileURLToPath(import.meta.url), "../index.js")
resolvePath(host.fileURLToPath(import.meta.url), "../index.js")
);
if (actual !== expected) {

Просмотреть файл

@ -1130,6 +1130,12 @@ export interface CompilerHost {
// get the real path of a possibly symlinked path
realpath(path: string): Promise<string>;
// convert a file URL to a path in a file system
fileURLToPath(url: string): string;
// convert a file system path to a URL
pathToFileURL(path: string): string;
logSink: LogSink;
}

Просмотреть файл

@ -1,17 +1,9 @@
import fs from "fs";
import { fileURLToPath, URL } from "url";
import { createSourceFile, DiagnosticHandler } from "./diagnostics.js";
import { createDiagnostic } from "./messages.js";
import { getDirectoryPath, isPathAbsolute, isUrl, joinPaths, resolvePath } from "./path-utils.js";
import { CompilerHost, Diagnostic, DiagnosticTarget, NoTarget, SourceFile } from "./types.js";
export const cadlVersion = getVersion();
function getVersion(): string {
const packageJsonPath = fileURLToPath(new URL("../../package.json", import.meta.url));
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
return packageJson.version;
}
export { cadlVersion, NodeHost } from "./node-host.js";
export function deepFreeze<T>(value: T): T {
if (Array.isArray(value)) {

Просмотреть файл

@ -23,6 +23,9 @@
".": "./dist/core/index.js",
"./testing": "./dist/testing/index.js"
},
"browser": {
"./dist/core/node-host.js": "./dist/core/node-host.browser.js"
},
"types": "dist/core/index.d.ts",
"engines": {
"node": ">=14.0.0"

Просмотреть файл

@ -7,7 +7,7 @@ import {
PublishDiagnosticsParams,
TextDocuments,
} from "vscode-languageserver/node.js";
import { NodeHost } from "../core/host.js";
import { NodeHost } from "../core/node-host.js";
import { cadlVersion } from "../core/util.js";
import { createServer, Server, ServerHost } from "./serverlib.js";

Просмотреть файл

@ -1,4 +1,3 @@
import { fileURLToPath, pathToFileURL } from "url";
import { TextDocument } from "vscode-languageserver-textdocument";
import {
CompletionItemKind,
@ -191,7 +190,7 @@ export function createServer(host: ServerHost): Server {
workspaceFolders =
params.workspaceFolders?.map((w) => ({
...w,
path: ensureTrailingDirectorySeparator(resolvePath(fileURLToPath(w.uri))),
path: ensureTrailingDirectorySeparator(resolvePath(compilerHost.fileURLToPath(w.uri))),
})) ?? [];
capabilities.workspace = {
workspaceFolders: {
@ -204,14 +203,16 @@ export function createServer(host: ServerHost): Server {
{
name: "<root>",
uri: params.rootUri,
path: ensureTrailingDirectorySeparator(resolvePath(fileURLToPath(params.rootUri))),
path: ensureTrailingDirectorySeparator(
resolvePath(compilerHost.fileURLToPath(params.rootUri))
),
},
];
} else if (params.rootPath) {
workspaceFolders = [
{
name: "<root>",
uri: pathToFileURL(params.rootPath).href,
uri: compilerHost.pathToFileURL(params.rootPath),
path: ensureTrailingDirectorySeparator(resolvePath(params.rootPath)),
},
];
@ -233,7 +234,7 @@ export function createServer(host: ServerHost): Server {
map.delete(folder.uri);
}
for (const folder of e.added) {
map.set(folder.uri, { ...folder, path: fileURLToPath(folder.uri) });
map.set(folder.uri, { ...folder, path: compilerHost.fileURLToPath(folder.uri) });
}
workspaceFolders = Array.from(map.values());
log("Workspace Folders", workspaceFolders);
@ -243,7 +244,7 @@ export function createServer(host: ServerHost): Server {
// remove stale file system cache entries on file change notification
for (const each of params.changes) {
if (each.uri.startsWith("file:")) {
const path = fileURLToPath(each.uri);
const path = compilerHost.fileURLToPath(each.uri);
fileSystemCache.delete(path);
}
}
@ -377,6 +378,7 @@ export function createServer(host: ServerHost): Server {
document.offsetAt(params.position),
(node) => node.kind === SyntaxKind.TypeReference
);
if (!referringNode) {
return undefined;
}
@ -636,7 +638,7 @@ export function createServer(host: ServerHost): Server {
if (isUntitled(document.uri)) {
return document.uri;
}
const path = resolvePath(fileURLToPath(document.uri));
const path = resolvePath(compilerHost.fileURLToPath(document.uri));
pathToURLMap.set(path, document.uri);
return path;
}
@ -645,7 +647,7 @@ export function createServer(host: ServerHost): Server {
if (isUntitled(path)) {
return path;
}
return pathToURLMap.get(path) ?? pathToFileURL(path).href;
return pathToURLMap.get(path) ?? compilerHost.pathToFileURL(path);
}
function isUntitled(pathOrUrl: string) {

Просмотреть файл

@ -4,7 +4,7 @@ import { fileURLToPath } from "url";
import { CadlConfigJsonSchema } from "../../config/config-schema.js";
import { CadlRawConfig, loadCadlConfigForPath } from "../../config/index.js";
import { createSourceFile } from "../../core/diagnostics.js";
import { NodeHost } from "../../core/host.js";
import { NodeHost } from "../../core/node-host.js";
import { SchemaValidator } from "../../core/schema-validator.js";
const __dirname = dirname(fileURLToPath(import.meta.url));

Просмотреть файл

@ -1,5 +1,5 @@
import { fileURLToPath, URL } from "url";
import { NodeHost } from "../../core/host.js";
import { NodeHost } from "../../core/node-host.js";
import { createProgram } from "../../core/program.js";
import { createTestHost, expectDiagnosticEmpty, expectDiagnostics } from "../../testing/index.js";

Просмотреть файл

@ -3,7 +3,7 @@ import { readFile } from "fs/promises";
import glob from "glob";
import { fileURLToPath, pathToFileURL } from "url";
import { createSourceFile, logDiagnostics, logVerboseTestOutput } from "../core/diagnostics.js";
import { NodeHost } from "../core/host.js";
import { NodeHost } from "../core/node-host.js";
import { CompilerOptions } from "../core/options.js";
import { getAnyExtensionFromPath, resolvePath } from "../core/path-utils.js";
import { createProgram, Program } from "../core/program.js";
@ -123,6 +123,10 @@ function createTestCompilerHost(
logSink: NodeHost.logSink,
mkdirp: async (path: string) => path,
fileURLToPath,
pathToFileURL(path: string) {
return pathToFileURL(path).href;
},
};
}
@ -282,7 +286,7 @@ async function createTestHostInternal(): Promise<TestHost> {
}
}
async function findFilesFromPattern(directory: string, pattern: string): Promise<string[]> {
export async function findFilesFromPattern(directory: string, pattern: string): Promise<string[]> {
return new Promise((resolve, reject) => {
glob(
pattern,

Просмотреть файл

@ -18,6 +18,20 @@
],
"type": "module",
"main": "dist/src/openapi.js",
"exports": {
".": "./dist/src/openapi.js",
"./testing": "./dist/src/testing/index.js"
},
"typesVersions": {
"*": {
"*": [
"./dist/src/openapi.d.ts"
],
"testing": [
"./dist/src/testing/index.d.ts"
]
}
},
"cadlMain": "dist/src/openapi.js",
"engines": {
"node": ">=14.0.0"

Просмотреть файл

@ -0,0 +1,5 @@
require("@cadl-lang/eslint-config-cadl/patch/modern-module-resolution");
module.exports = {
extends: "@cadl-lang/eslint-config-cadl",
};

Просмотреть файл

@ -0,0 +1,3 @@
# Cadl Playground
A web app to play with Cadl in the browser.

Просмотреть файл

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Cadl Playground</title>
</head>
<body>
<div id="grid">
<div id="commandBar">
<label>
<button id="share">Share</button>
</label>
<label>
Load a sample:
<select id="samples">
<option value="" disabled selected>Select sample...</option>
</select>
</label>
<label>
<button id="newIssue">Open Issue</button>
</label>
</div>
<div id="outputTabs">
</div>
<div id="editorContainer">
<div id="editor"></div>
</div>
<div id="outputContainer">
<div id="output">
</div>
</div>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,62 @@
{
"name": "cadl-playground",
"version": "1.0.0",
"author": "Microsoft Corporation",
"description": "An app to play with CADL in the browser",
"homepage": "https://github.com/microsoft/cadl",
"readme": "https://github.com/microsoft/cadl/blob/main/README.md",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/Azure/adl.git"
},
"bugs": {
"url": "https://github.com/Azure/adl/issues"
},
"keywords": [
"cadl"
],
"type": "module",
"main": "dist/src/lib.js",
"engines": {
"node": ">=14.0.0"
},
"scripts": {
"clean": "rimraf ./dist ./dist-dev ./temp ./cadlContents.json",
"build": "tsc -p . && node dist-dev/scripts/preload.js && vite build",
"watch": "vite",
"test": "echo 'no tests'",
"test-official": "echo 'no tests'",
"lint": "eslint . --ext .ts --max-warnings=0",
"lint:fix": "eslint . --fix --ext .ts"
},
"files": [
"lib/*.cadl",
"dist/**",
"!dist/test/**"
],
"dependencies": {
"@cadl-lang/versioning": "~0.3.2",
"@cadl-lang/compiler": "~0.29.0",
"@cadl-lang/rest": "~0.12.0",
"@cadl-lang/openapi3": "~0.9.0",
"@cadl-lang/openapi": "~0.7.0",
"monaco-editor": "~0.32.1",
"vite": "^2.8.0",
"vscode-languageserver-textdocument": "~1.0.1",
"lzutf8": "~0.6.1",
"debounce": "~1.2.1"
},
"devDependencies": {
"@types/mocha": "~9.1.0",
"@types/node": "~14.0.27",
"@cadl-lang/eslint-config-cadl": "~0.2.0",
"eslint": "^8.7.0",
"mocha": "~9.2.0",
"c8": "~7.11.0",
"rimraf": "~3.0.2",
"typescript": "~4.5.5",
"@types/lz-string": "~1.3.34",
"@types/debounce": "~1.2.1"
}
}

Просмотреть файл

@ -0,0 +1,47 @@
import { getAnyExtensionFromPath, resolvePath } from "@cadl-lang/compiler";
import {
CadlTestLibrary,
findFilesFromPattern,
resolveVirtualPath,
StandardTestLibrary,
} from "@cadl-lang/compiler/testing";
import { OpenAPITestLibrary } from "@cadl-lang/openapi/testing";
import { OpenAPI3TestLibrary } from "@cadl-lang/openapi3/testing";
import { RestTestLibrary } from "@cadl-lang/rest/testing";
import { VersioningTestLibrary } from "@cadl-lang/versioning/testing";
import { readFile, writeFile } from "fs/promises";
const staticContents: Record<string, string> = {};
async function addCadlLibrary(testLibrary: CadlTestLibrary) {
for (const { realDir, pattern, virtualPath } of testLibrary.files) {
const lookupDir = resolvePath(testLibrary.packageRoot, realDir);
const entries = await findFilesFromPattern(lookupDir, pattern);
for (const entry of entries) {
const fileRealPath = resolvePath(lookupDir, entry);
const fileVirtualPath = resolveVirtualPath(virtualPath, entry).replace("Z:", "");
switch (getAnyExtensionFromPath(fileRealPath)) {
case ".cadl":
case ".json":
const contents = await readFile(fileRealPath, "utf-8");
staticContents[fileVirtualPath] = contents;
break;
case ".js":
case ".mjs":
// TODO:
break;
}
}
}
}
async function load() {
await addCadlLibrary(StandardTestLibrary);
await addCadlLibrary(RestTestLibrary);
await addCadlLibrary(VersioningTestLibrary);
await addCadlLibrary(OpenAPITestLibrary);
await addCadlLibrary(OpenAPI3TestLibrary);
await writeFile("./dist-dev/cadlContents.json", JSON.stringify(staticContents));
}
load();

Просмотреть файл

@ -0,0 +1,156 @@
import {
CompilerHost,
createSourceFile,
decorators,
resolvePath,
service,
} from "@cadl-lang/compiler";
import * as openapi from "@cadl-lang/openapi";
import * as openapi3 from "@cadl-lang/openapi3";
import { http, resource, rest, route } from "@cadl-lang/rest";
import * as versioning from "@cadl-lang/versioning";
import cadlContentsString from "../dist-dev/cadlContents.json?raw";
const cadlContents: Record<string, string> = JSON.parse(cadlContentsString);
export interface BrowserHost extends CompilerHost {
unlink(path: string): Promise<void>;
}
export function resolveVirtualPath(path: string, ...paths: string[]) {
return resolvePath("/test", path, ...paths);
}
export async function createBrowserHost(): Promise<BrowserHost> {
const virtualFs = new Map<string, string>();
const jsImports = new Map<string, Promise<any>>();
addJsImport("/test/.cadl/dist/lib/decorators.js", decorators);
addJsImport("/test/.cadl/dist/lib/service.js", service);
addJsImport("/test/node_modules/@cadl-lang/rest/dist/src/rest.js", rest);
addJsImport("/test/node_modules/@cadl-lang/rest/dist/src/route.js", route);
addJsImport("/test/node_modules/@cadl-lang/rest/dist/src/http.js", http);
addJsImport("/test/node_modules/@cadl-lang/rest/dist/src/resource.js", resource);
addJsImport("/test/node_modules/@cadl-lang/openapi/dist/src/index.js", openapi);
addJsImport("/test/node_modules/@cadl-lang/openapi3/dist/src/openapi.js", openapi3);
addJsImport("/test/node_modules/@cadl-lang/versioning/dist/src/versioning.js", versioning);
for (const [key, value] of Object.entries(cadlContents)) {
virtualFs.set(key, value);
}
function addJsImport(path: string, value: any) {
virtualFs.set(path, "");
jsImports.set(path, value);
}
return {
async readUrl(url: string) {
const contents = virtualFs.get(url);
if (contents === undefined) {
const e = new Error(`File ${url} not found.`);
(e as any).code = "ENOENT";
throw e;
}
return createSourceFile(contents, url);
},
async readFile(path: string) {
path = resolveVirtualPath(path);
const contents = virtualFs.get(path);
if (contents === undefined) {
const e = new Error(`File ${path} not found.`);
(e as any).code = "ENOENT";
throw e;
}
return createSourceFile(contents, path);
},
async writeFile(path: string, content: string) {
path = resolveVirtualPath(path);
virtualFs.set(path, content);
},
async readDir(path: string) {
path = resolveVirtualPath(path);
return [...virtualFs.keys()]
.filter((x) => x.startsWith(`${path}/`))
.map((x) => x.replace(`${path}/`, ""));
},
async removeDir(path: string) {
path = resolveVirtualPath(path);
for (const key of virtualFs.keys()) {
if (key.startsWith(`${path}/`)) {
virtualFs.delete(key);
}
}
},
getLibDirs() {
return [resolveVirtualPath(".cadl/lib")];
},
getExecutionRoot() {
return resolveVirtualPath(".cadl");
},
async getJsImport(path) {
path = resolveVirtualPath(path);
const module = await jsImports.get(path);
if (module === undefined) {
const e = new Error(`Module ${path} not found`);
(e as any).code = "MODULE_NOT_FOUND";
throw e;
}
return module;
},
async stat(path: string) {
path = resolveVirtualPath(path);
if (virtualFs.has(path)) {
return {
isDirectory() {
return false;
},
isFile() {
return true;
},
};
}
for (const fsPath of virtualFs.keys()) {
if (fsPath.startsWith(path) && fsPath !== path) {
return {
isDirectory() {
return true;
},
isFile() {
return false;
},
};
}
}
const e = new Error(`File ${path} not found.`);
(e as any).code = "ENOENT";
throw e;
},
// symlinks not supported in test-host
async realpath(path) {
return path;
},
async unlink(path) {
path = resolveVirtualPath(path);
virtualFs.delete(path);
},
logSink: console,
mkdirp: async (path: string) => path,
fileURLToPath(path) {
return path.replace("inmemory:/", "");
},
pathToFileURL(path) {
return "inmemory:/" + resolveVirtualPath(path);
},
};
}

Просмотреть файл

@ -0,0 +1,19 @@
import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker";
import { createBrowserHost } from "./browserHost";
import { attachServices } from "./services";
import "./style.css";
import { createUI } from "./ui";
(self as any).MonacoEnvironment = {
getWorker(_: any, label: string) {
if (label === "json") {
return new jsonWorker();
}
return new editorWorker();
},
};
const host = await createBrowserHost();
attachServices(host);
createUI(host);

Просмотреть файл

@ -0,0 +1,77 @@
export const samples: Record<string, string> = {
Http: `import "@cadl-lang/rest";
@serviceTitle("Widget Service")
namespace DemoService;
using Cadl.Http;
model Widget {
@key id: string;
weight: int32;
color: "red" | "blue";
}
@error model Error {
code: int32;
message: string;
}
interface WidgetService {
@get list(): Widget[] | Error;
@route("widgets/{id}") @get read(@path id: string): Widget | Error;
@post create(@body body: Widget): Widget | Error;
@route("customGet") @get customGet(): Widget | Error;
}`,
"Rest framework": `import "@cadl-lang/rest";
@serviceTitle("Widget Service")
namespace DemoService;
using Cadl.Http;
using Cadl.Rest;
model Widget {
@key id: string;
weight: int32;
color: "red" | "blue";
}
@error model Error {
code: int32;
message: string;
}
interface WidgetService mixes Resource.ResourceOperations<Widget, Error> {
@get @route("customGet") customGet(): Widget;
}`,
"Versioned Rest Framework": `import "@cadl-lang/rest";
import "@cadl-lang/versioning";
@serviceTitle("Widget Service")
@versioned(VERSIONS)
namespace DemoService;
alias VERSIONS = "v1" | "v2";
using Cadl.Http;
using Cadl.Rest;
model Widget {
@key id: string;
weight: int32;
color: "red" | "blue";
@added("v2") name: string;
}
@error model Error {
code: int32;
message: string;
}
interface WidgetService mixes Resource.ResourceOperations<Widget, Error> {
@added("v2")
@get
@route("customGet")
customGet(): Widget;
}`,
};

Просмотреть файл

@ -0,0 +1,188 @@
import {
createScanner,
createServer,
createSourceFile,
ServerHost,
Token,
} from "@cadl-lang/compiler";
import * as monaco from "monaco-editor";
import { TextDocument } from "vscode-languageserver-textdocument";
import { BrowserHost } from "./browserHost";
import "./style.css";
export function attachServices(host: BrowserHost) {
monaco.languages.register({ id: "cadl" });
const serverHost: ServerHost = {
compilerHost: host,
getDocumentByURL(url: string) {
const model = monaco.editor.getModel(monaco.Uri.parse(url));
if (model) {
return TextDocument.create(url, "cadl", 1, model.getValue());
}
return undefined;
},
sendDiagnostics() {},
// eslint-disable-next-line no-console
log: console.log,
};
const serverLib = createServer(serverHost);
function textDocumentForModel(model: monaco.editor.IModel) {
return TextDocument.create(model.uri.toString(), "cadl", 1, model.getValue());
}
monaco.languages.registerDefinitionProvider("cadl", {
async provideDefinition(model, position) {
const result = await serverLib.gotoDefinition({
position: {
line: position.lineNumber - 1,
character: position.column - 1,
},
textDocument: textDocumentForModel(model),
});
if (!result) return;
const loc: monaco.languages.Location = {
uri: monaco.Uri.parse(result.uri),
range: {
startColumn: result.range.start.character + 1,
startLineNumber: result.range.start.line + 1,
endColumn: result.range.end.character + 1,
endLineNumber: result.range.end.line + 1,
},
};
return loc;
},
});
const lsConfig = serverLib.initialize({
capabilities: {},
processId: 1,
workspaceFolders: [],
rootUri: "inmemory://",
});
serverLib.initialized(lsConfig);
monaco.languages.registerCompletionItemProvider("cadl", {
triggerCharacters: lsConfig.capabilities.completionProvider!.triggerCharacters,
async provideCompletionItems(model, position) {
const result = await serverLib.complete({
position: {
line: position.lineNumber - 1,
character: position.column - 1,
},
textDocument: textDocumentForModel(model),
});
const word = model.getWordUntilPosition(position);
const range = {
startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber,
startColumn: word.startColumn,
endColumn: word.endColumn,
};
const suggestions: monaco.languages.CompletionItem[] = [];
for (const item of result.items) {
suggestions.push({
label: item.label,
kind: item.kind as any,
documentation: item.documentation,
insertText: item.insertText!,
range,
commitCharacters:
item.commitCharacters ?? lsConfig.capabilities.completionProvider!.allCommitCharacters,
});
}
return { suggestions };
},
});
const tokenTypes = [
"comment",
"string",
"number",
"keyword",
"namespace",
"variable",
"type",
"function",
"operator",
"source",
];
function mapToken(tok: Token) {
switch (tok) {
case Token.SingleLineComment:
case Token.MultiLineComment:
return 0;
case Token.StringLiteral:
return 1;
case Token.NumericLiteral:
return 2;
case Token.TrueKeyword:
case Token.FalseKeyword:
case Token.IfKeyword:
case Token.IsKeyword:
case Token.AliasKeyword:
case Token.OpKeyword:
case Token.ElseKeyword:
case Token.EnumKeyword:
case Token.VoidKeyword:
case Token.ModelKeyword:
case Token.NeverKeyword:
case Token.UnionKeyword:
case Token.UsingKeyword:
case Token.ImportKeyword:
case Token.ReturnKeyword:
case Token.ExtendsKeyword:
case Token.InterfaceKeyword:
case Token.NamespaceKeyword:
case Token.ProjectionKeyword:
return 3;
default:
return 9;
}
}
monaco.languages.registerDocumentSemanticTokensProvider("cadl", {
getLegend() {
return {
tokenTypes,
tokenModifiers: [],
};
},
provideDocumentSemanticTokens(model) {
const content = model.getValue();
const file = createSourceFile(content, "");
const scanner = createScanner(file, () => {});
const tokens = [];
let prevLine = 0;
let prevChar = 0;
let tok = scanner.scan();
while (tok !== Token.EndOfFile) {
const pos = file.getLineAndCharacterOfPosition(scanner.tokenPosition);
tokens.push(
pos.line - prevLine,
prevLine === pos.line ? pos.character - prevChar : pos.character,
scanner.position - scanner.tokenPosition,
mapToken(tok),
0
);
prevLine = pos.line;
prevChar = pos.character;
tok = scanner.scan();
}
return {
data: new Uint32Array(tokens),
};
},
releaseDocumentSemanticTokens() {},
});
}

Просмотреть файл

@ -0,0 +1,75 @@
body {
margin: 0;
padding: 0;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
overflow: hidden;
}
* {
box-sizing: content-box;
}
#grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 30px 1fr;
width: 100vw;
height: 100vh;
overflow: hidden;
}
#commandBar {
grid-column: 1;
grid-row: 1;
align-items: center;
display: flex;
}
#commandBar > * {
padding: 2px 2px;
}
#outputTabs {
grid-column: 2;
grid-row: 1;
display: flex;
overflow: hidden;
}
#outputTabs a {
padding: 0 5px;
border: 1px solid #ccc;
border-top: none;
border-bottom: none;
margin: 2px;
color: #000;
text-decoration: none;
cursor: pointer;
}
#outputTabs a.active {
font-weight: bold;
background-color: #eee;
}
#editorContainer {
grid-column: 1;
grid-row: 2;
overflow: hidden;
}
#editor {
width: 100%;
height: 100%;
overflow: hidden;
}
#outputContainer {
grid-column: 2;
grid-row: 2;
overflow: hidden;
}
#output {
width: 100%;
height: 100%;
overflow: hidden;
}

Просмотреть файл

@ -0,0 +1,167 @@
import { compile, getSourceLocation } from "@cadl-lang/compiler";
import debounce from "debounce";
import lzutf8 from "lzutf8";
import * as monaco from "monaco-editor";
import { BrowserHost } from "./browserHost";
import { samples } from "./samples";
import "./style.css";
export function createUI(host: BrowserHost) {
const tabContainer = document.getElementById("outputTabs")!;
const mainModel = monaco.editor.createModel(
"",
"cadl",
monaco.Uri.parse("inmemory://test/main.cadl")
);
mainModel.onDidChangeContent(
debounce(() => {
doCompile();
}, 200)
);
const editor = monaco.editor.create(document.getElementById("editor")!, {
model: mainModel,
language: "cadl",
"semanticHighlighting.enabled": true,
automaticLayout: true,
tabSize: 2,
minimap: {
enabled: false,
},
});
const output = monaco.editor.create(document.getElementById("output")!, {
readOnly: true,
language: "json",
automaticLayout: true,
minimap: {
enabled: false,
},
});
window.addEventListener("resize", () => {
editor.layout();
});
if (window.location.search.length > 0) {
const parsed = new URLSearchParams(window.location.search);
const compressed = parsed.get("c");
if (compressed) {
const content = lzutf8.decompress(compressed, { inputEncoding: "Base64" });
mainModel.setValue(content);
}
}
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
saveCode();
});
document.getElementById("share")?.addEventListener("click", saveCode);
document.getElementById("newIssue")?.addEventListener("click", newIssue);
initSamples();
doCompile();
return;
function saveCode() {
const contents = mainModel.getValue();
const compressed = lzutf8.compress(contents, { outputEncoding: "Base64" });
history.pushState(null, "", window.location.pathname + "?c=" + encodeURIComponent(compressed));
navigator.clipboard.writeText(window.location.toString());
}
function initSamples() {
const sampleSelect = document.getElementById("samples")! as HTMLSelectElement;
for (const sample of Object.keys(samples)) {
const option = document.createElement("option");
option.innerText = sample;
sampleSelect.appendChild(option);
}
sampleSelect.addEventListener("change", () => {
const value = sampleSelect.value;
const code = samples[value];
mainModel.setValue(code);
});
}
async function emptyOutputDir() {
// empty output directory
const dirs = await host.readDir("./cadl-output");
for (const file of dirs) {
const path = "./cadl-output/" + file;
const uri = monaco.Uri.parse(host.pathToFileURL(path));
const model = monaco.editor.getModel(uri);
if (model) {
model.dispose();
}
await host.unlink(path);
}
}
async function doCompile() {
host.writeFile("main.cadl", mainModel.getValue());
await emptyOutputDir();
const program = await compile("main.cadl", host, {
outputPath: "cadl-output",
swaggerOutputFile: "cadl-output/openapi.json",
emitters: ["@cadl-lang/openapi3"],
});
const markers: monaco.editor.IMarkerData[] = [];
for (const diag of program.diagnostics) {
const loc = getSourceLocation(diag.target);
if (!loc) continue;
const start = loc.file.getLineAndCharacterOfPosition(loc.pos);
const end = loc.file.getLineAndCharacterOfPosition(loc.end);
markers.push({
startLineNumber: start.line + 1,
startColumn: start.character + 1,
endLineNumber: end.line + 1,
endColumn: end.character + 1,
message: diag.message,
severity: monaco.MarkerSeverity.Error,
});
}
monaco.editor.setModelMarkers(mainModel, "owner", markers);
tabContainer.innerHTML = "";
const dirs = await host.readDir("./cadl-output");
let first = true;
for (const file of dirs) {
const link = document.createElement("a");
link.addEventListener("click", async () => {
await loadOutputFile(link, "./cadl-output/" + file);
});
link.innerText = file;
tabContainer.appendChild(link);
if (first) {
loadOutputFile(link, "./cadl-output/" + file);
first = false;
}
}
}
async function loadOutputFile(link: HTMLAnchorElement, path: string) {
for (const link of tabContainer.querySelectorAll("a") as any) {
(link as HTMLLinkElement).classList.remove("active");
}
link.classList.add("active");
const contents = await host.readFile(path);
const uri = monaco.Uri.parse(host.pathToFileURL(path));
const model = monaco.editor.getModel(uri) ?? monaco.editor.createModel("", "json", uri);
model.setValue(contents.text);
output.setModel(model);
}
function newIssue() {
saveCode();
const bodyPayload = encodeURIComponent(`\n\n\n[Playground Link](${document.location.href})`);
const url = `https://github.com/microsoft/cadl/issues/new?body=${bodyPayload}`;
window.open(url, "_blank");
}
}

1
packages/playground/src/vite-env.d.ts поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
/// <reference types="vite/client" />

Просмотреть файл

@ -0,0 +1,17 @@
{
"extends": "../tsconfig.json",
"references": [
{ "path": "../compiler/tsconfig.json" },
{ "path": "../rest/tsconfig.json" },
{ "path": "../openapi/tsconfig.json" },
{ "path": "../openapi3/tsconfig.json" }
],
"compilerOptions": {
"outDir": "dist-dev",
"rootDir": ".",
"tsBuildInfoFile": "temp/tsconfig.tsbuildinfo",
"types": ["node", "mocha"],
"skipLibCheck": true
},
"include": ["scripts/**/*.ts", "src/**/*.ts", "test/**/*.ts"]
}

Просмотреть файл

@ -0,0 +1,18 @@
import { defineConfig } from "vite";
// https://vitejs.dev/config/
export default defineConfig({
build: {
target: "esnext",
chunkSizeWarningLimit: 4000,
},
assetsInclude: [/\.cadl$/],
optimizeDeps: {
exclude: ["node-fetch"],
},
server: {
fs: {
strict: false,
},
},
});

Просмотреть файл

@ -14,7 +14,7 @@ export default {
},
inlineDynamicImports: true,
context: "this",
external: ["fs/promises", "prettier"],
external: ["fs/promises", "prettier", "ajv", "js-yaml"],
plugins: [
resolve({ preferBuiltins: true }),
commonjs(),

Просмотреть файл

@ -1,4 +1,7 @@
export * as http from "./http.js";
export * from "./resource.js";
export * as resource from "./resource.js";
export * from "./rest.js";
export * as rest from "./rest.js";
export * from "./route.js";
export * as route from "./route.js";

Просмотреть файл

@ -125,6 +125,12 @@
"projectFolder": "packages/versioning",
"reviewCategory": "production",
"shouldPublish": true
},
{
"packageName": "cadl-playground",
"projectFolder": "packages/playground",
"reviewCategory": "production",
"shouldPublish": false
}
]
}

Просмотреть файл

@ -7,7 +7,8 @@
{ "path": "packages/openapi3/tsconfig.json" },
{ "path": "packages/cadl-vscode/tsconfig.json" },
{ "path": "packages/tmlanguage-generator/tsconfig.json" },
{ "path": "packages/openapi3/tsconfig.json" }
{ "path": "packages/openapi3/tsconfig.json" },
{ "path": "packages/playground/tsconfig.json" }
],
"files": []
}