From 6ac43917293a3901e7a9f71716bf2e40457adca6 Mon Sep 17 00:00:00 2001 From: David Pine Date: Wed, 18 Mar 2026 13:47:35 -0500 Subject: [PATCH] Add polyglot exports for dapr Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../ValidationAppHost/.aspire/settings.json | 7 + .../ValidationAppHost/apphost.run.json | 11 + .../ValidationAppHost/apphost.ts | 105 ++ .../ValidationAppHost/components/binding.yaml | 10 + .../ValidationAppHost/components/pubsub.yaml | 7 + .../components/statestore.yaml | 7 + .../ValidationAppHost/package-lock.json | 962 ++++++++++++++++++ .../ValidationAppHost/package.json | 19 + .../ValidationAppHost/tsconfig.json | 15 + ...ommunityToolkit.Aspire.Hosting.Dapr.csproj | 1 + .../DaprComponentOptions.cs | 3 + .../DaprMetadataResourceBuilderExtensions.cs | 36 +- .../DaprOptions.cs | 6 +- .../DaprPolyglotOptions.cs | 100 ++ .../IDaprComponentResource.cs | 2 + ...DistributedApplicationBuilderExtensions.cs | 25 + ...edApplicationComponentBuilderExtensions.cs | 20 + 17 files changed, 1324 insertions(+), 12 deletions(-) create mode 100644 playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/.aspire/settings.json create mode 100644 playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/apphost.run.json create mode 100644 playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/apphost.ts create mode 100644 playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/components/binding.yaml create mode 100644 playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/components/pubsub.yaml create mode 100644 playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/components/statestore.yaml create mode 100644 playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/package-lock.json create mode 100644 playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/package.json create mode 100644 playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/tsconfig.json create mode 100644 src/CommunityToolkit.Aspire.Hosting.Dapr/DaprPolyglotOptions.cs diff --git a/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/.aspire/settings.json b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/.aspire/settings.json new file mode 100644 index 000000000..235c0e1d6 --- /dev/null +++ b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/.aspire/settings.json @@ -0,0 +1,7 @@ +{ + "appHostPath": "../apphost.ts", + "language": "typescript/nodejs", + "packages": { + "CommunityToolkit.Aspire.Hosting.Dapr": "" + } +} diff --git a/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/apphost.run.json b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/apphost.run.json new file mode 100644 index 000000000..7ab9dec4c --- /dev/null +++ b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/apphost.run.json @@ -0,0 +1,11 @@ +{ + "profiles": { + "https": { + "applicationUrl": "https://localhost:29750;http://localhost:28931", + "environmentVariables": { + "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:10975", + "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:13319" + } + } + } +} diff --git a/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/apphost.ts b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/apphost.ts new file mode 100644 index 000000000..9a656779a --- /dev/null +++ b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/apphost.ts @@ -0,0 +1,105 @@ +import { createBuilder, type DaprComponentOptions, type ReferenceExpression } from './.modules/aspire.js'; + +const builder = await createBuilder(); + +await builder.addDapr({ + configure: async (dapr) => { + await dapr.daprPath.set('dapr'); + await dapr.enableTelemetry.set(false); + + const configuredDaprPath = await dapr.daprPath.get(); + const telemetryEnabled = await dapr.enableTelemetry.get(); + + void [configuredDaprPath, telemetryEnabled]; + } +}); + +const componentSecret = await builder.addParameter('component-secret', { secret: true }); + +const cacheBackend = builder + .addContainer('cache-backend', 'redis') + .withEndpoint({ name: 'tcp', targetPort: 6379 }); + +const cacheEndpoint = await cacheBackend.getEndpoint('tcp'); + +let cacheConnectionExpression!: ReferenceExpression; +await builder.addConnectionStringBuilder('cache-connection', async (connectionString) => { + await connectionString.appendLiteral('redis://'); + await connectionString.appendValueProvider(cacheEndpoint); + cacheConnectionExpression = await connectionString.build(); +}); + +const customComponent = builder.addDaprComponent('custom-binding', 'bindings.http', { + componentOptions: { localPath: './components/binding.yaml' } +}); + +const pubsub = builder + .addDaprPubSub('pubsub', { + componentOptions: { localPath: './components/pubsub.yaml' } + }) + .withMetadata('consumerId', 'checkout') + .withMetadataEndpoint('redisHost', cacheEndpoint) + .withMetadataReferenceExpression('redisAddress', cacheConnectionExpression) + .withMetadataParameter('redisPassword', componentSecret); + +const stateStore = builder + .addDaprStateStore('statestore', { + componentOptions: { localPath: './components/statestore.yaml' } + }) + .withMetadata('actorStateStore', 'true'); + +const frontend = builder + .addContainer('frontend', 'nginx') + .withEndpoint({ name: 'http', scheme: 'http', targetPort: 80 }) + .withDaprSidecar({ + sidecarOptions: { + appId: 'frontend', + appPort: 80, + appProtocol: 'http', + daprHttpPort: 3500, + enableApiLogging: true, + resourcesPaths: ['./components'] + } + }); + +const api = builder + .addContainer('api', 'nginx') + .withEndpoint({ name: 'http', scheme: 'http', targetPort: 80 }) + .configureDaprSidecar(async (sidecar) => { + await sidecar.withOptions({ + appId: 'api', + appPort: 80, + appProtocol: 'http', + daprGrpcPort: 50001, + enableApiLogging: true, + logLevel: 'debug', + resourcesPaths: ['./components'] + }); + await sidecar.withReference(await customComponent); + await sidecar.withReference(await pubsub); + await sidecar.withReference(await stateStore); + }); + +const customComponentResource = await customComponent; +const pubsubResource = await pubsub; +const stateStoreResource = await stateStore; + +const customComponentType = await customComponentResource.type.get(); +const customComponentSettings: DaprComponentOptions = await customComponentResource.options.get(); +const pubsubType = await pubsubResource.type.get(); +const pubsubSettings: DaprComponentOptions = await pubsubResource.options.get(); +const stateStoreType = await stateStoreResource.type.get(); +const stateStoreSettings: DaprComponentOptions = await stateStoreResource.options.get(); + +await Promise.all([frontend, api]); + +void [ + customComponentType, + customComponentSettings.localPath, + pubsubType, + pubsubSettings.localPath, + stateStoreType, + stateStoreSettings.localPath +]; + +await builder.build().run(); diff --git a/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/components/binding.yaml b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/components/binding.yaml new file mode 100644 index 000000000..28aa4be31 --- /dev/null +++ b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/components/binding.yaml @@ -0,0 +1,10 @@ +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: custom-binding +spec: + type: bindings.http + version: v1 + metadata: + - name: url + value: http://localhost:8080 diff --git a/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/components/pubsub.yaml b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/components/pubsub.yaml new file mode 100644 index 000000000..9ed6b19d9 --- /dev/null +++ b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/components/pubsub.yaml @@ -0,0 +1,7 @@ +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: pubsub +spec: + type: pubsub.in-memory + version: v1 diff --git a/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/components/statestore.yaml b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/components/statestore.yaml new file mode 100644 index 000000000..419cdcbf1 --- /dev/null +++ b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/components/statestore.yaml @@ -0,0 +1,7 @@ +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: statestore +spec: + type: state.in-memory + version: v1 diff --git a/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/package-lock.json b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/package-lock.json new file mode 100644 index 000000000..67af33374 --- /dev/null +++ b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/package-lock.json @@ -0,0 +1,962 @@ +{ + "name": "validationapphost", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "validationapphost", + "version": "1.0.0", + "dependencies": { + "vscode-jsonrpc": "^8.2.0" + }, + "devDependencies": { + "@types/node": "^20.0.0", + "nodemon": "^3.1.11", + "tsx": "^4.19.0", + "typescript": "^5.3.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", + "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz", + "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", + "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz", + "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", + "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", + "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", + "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", + "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", + "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", + "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", + "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", + "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", + "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", + "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", + "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", + "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", + "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", + "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", + "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", + "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", + "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", + "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", + "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", + "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", + "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", + "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@types/node": { + "version": "20.19.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.37.tgz", + "integrity": "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/esbuild": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz", + "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.4", + "@esbuild/android-arm": "0.27.4", + "@esbuild/android-arm64": "0.27.4", + "@esbuild/android-x64": "0.27.4", + "@esbuild/darwin-arm64": "0.27.4", + "@esbuild/darwin-x64": "0.27.4", + "@esbuild/freebsd-arm64": "0.27.4", + "@esbuild/freebsd-x64": "0.27.4", + "@esbuild/linux-arm": "0.27.4", + "@esbuild/linux-arm64": "0.27.4", + "@esbuild/linux-ia32": "0.27.4", + "@esbuild/linux-loong64": "0.27.4", + "@esbuild/linux-mips64el": "0.27.4", + "@esbuild/linux-ppc64": "0.27.4", + "@esbuild/linux-riscv64": "0.27.4", + "@esbuild/linux-s390x": "0.27.4", + "@esbuild/linux-x64": "0.27.4", + "@esbuild/netbsd-arm64": "0.27.4", + "@esbuild/netbsd-x64": "0.27.4", + "@esbuild/openbsd-arm64": "0.27.4", + "@esbuild/openbsd-x64": "0.27.4", + "@esbuild/openharmony-arm64": "0.27.4", + "@esbuild/sunos-x64": "0.27.4", + "@esbuild/win32-arm64": "0.27.4", + "@esbuild/win32-ia32": "0.27.4", + "@esbuild/win32-x64": "0.27.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.6", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz", + "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nodemon": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.14.tgz", + "integrity": "sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^10.2.1", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true, + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "dev": true, + "license": "ISC", + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true, + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.1.tgz", + "integrity": "sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + } + } +} diff --git a/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/package.json b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/package.json new file mode 100644 index 000000000..54f1c98e3 --- /dev/null +++ b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/package.json @@ -0,0 +1,19 @@ +{ + "name": "validationapphost", + "version": "1.0.0", + "type": "module", + "scripts": { + "start": "aspire run", + "build": "tsc", + "dev": "tsc --watch" + }, + "dependencies": { + "vscode-jsonrpc": "^8.2.0" + }, + "devDependencies": { + "@types/node": "^20.0.0", + "nodemon": "^3.1.11", + "tsx": "^4.19.0", + "typescript": "^5.3.0" + } +} diff --git a/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/tsconfig.json b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/tsconfig.json new file mode 100644 index 000000000..e8c2d93b8 --- /dev/null +++ b/playground/polyglot/TypeScript/CommunityToolkit.Aspire.Hosting.Dapr/ValidationAppHost/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "outDir": "./dist", + "rootDir": "." + }, + "include": ["apphost.ts", ".modules/**/*.ts", ".modules/**/*.d.ts"], + "exclude": ["node_modules"] +} diff --git a/src/CommunityToolkit.Aspire.Hosting.Dapr/CommunityToolkit.Aspire.Hosting.Dapr.csproj b/src/CommunityToolkit.Aspire.Hosting.Dapr/CommunityToolkit.Aspire.Hosting.Dapr.csproj index 2db57b2e8..5d10733ab 100644 --- a/src/CommunityToolkit.Aspire.Hosting.Dapr/CommunityToolkit.Aspire.Hosting.Dapr.csproj +++ b/src/CommunityToolkit.Aspire.Hosting.Dapr/CommunityToolkit.Aspire.Hosting.Dapr.csproj @@ -4,6 +4,7 @@ aspire integration hosting dapr Dapr support for Aspire. true + $(NoWarn);ASPIREATS001 diff --git a/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprComponentOptions.cs b/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprComponentOptions.cs index 27d3de2d4..82c8f32f9 100644 --- a/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprComponentOptions.cs +++ b/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprComponentOptions.cs @@ -1,11 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Aspire.Hosting; + namespace CommunityToolkit.Aspire.Hosting.Dapr; /// /// Options for configuring a Dapr component. /// +[AspireDto] public sealed record DaprComponentOptions { /// diff --git a/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprMetadataResourceBuilderExtensions.cs b/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprMetadataResourceBuilderExtensions.cs index cc70fdfb9..1bae97017 100644 --- a/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprMetadataResourceBuilderExtensions.cs +++ b/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprMetadataResourceBuilderExtensions.cs @@ -9,12 +9,13 @@ namespace Aspire.Hosting; public static class DaprMetadataResourceBuilderExtensions { /// - /// Adds static value metadata to the Dapr component + /// Adds static metadata to the Dapr component. /// - /// - /// - /// - /// + /// The resource builder for the Dapr component being configured. + /// The name of the metadata property to add to the Dapr component configuration. + /// The static metadata value to assign. + /// The resource builder instance. + [AspireExport("withMetadata", Description = "Adds static metadata to a Dapr component")] public static IResourceBuilder WithMetadata(this IResourceBuilder builder, string name, string value) => builder.WithAnnotation(new DaprComponentConfigurationAnnotation((schema, ct) => { @@ -55,6 +56,8 @@ public static IResourceBuilder WithMetadata(this IResour /// .WithMetadata("redisHost", redis.GetEndpoint("tcp")); /// /// + /// This overload is not available in polyglot app hosts. Use the generated withMetadataEndpoint, withMetadataReferenceExpression, or withMetadataParameter overloads instead. + [AspireExportIgnore(Reason = "IValueProvider is too broad for stable polyglot code generation. Use the endpoint, reference expression, or parameter overloads instead.")] public static IResourceBuilder WithMetadata(this IResourceBuilder builder, string name, IValueProvider valueProvider) { // Create a unique environment variable name for this value provider @@ -87,14 +90,27 @@ public static IResourceBuilder WithMetadata(this IResour })); } + [AspireExport("withMetadataEndpoint", MethodName = "withMetadataEndpoint", Description = "Adds endpoint-backed metadata to a Dapr component")] + internal static IResourceBuilder WithMetadata(this IResourceBuilder builder, string name, EndpointReference endpointReference) + { + return builder.WithMetadata(name, (IValueProvider)endpointReference); + } + + [AspireExport("withMetadataReferenceExpression", MethodName = "withMetadataReferenceExpression", Description = "Adds reference-expression-backed metadata to a Dapr component")] + internal static IResourceBuilder WithMetadata(this IResourceBuilder builder, string name, ReferenceExpression referenceExpression) + { + return builder.WithMetadata(name, (IValueProvider)referenceExpression); + } + /// - /// Adds a parameter resource as metadata to the Dapr component + /// Adds a parameter resource as metadata to the Dapr component. /// - /// - /// - /// - /// + /// The resource builder for the Dapr component being configured. + /// The name of the metadata property to add to the Dapr component configuration. + /// The parameter resource whose value should back the metadata entry. + /// The resource builder instance. + [AspireExport("withMetadataParameter", MethodName = "withMetadataParameter", Description = "Adds parameter-backed metadata to a Dapr component")] public static IResourceBuilder WithMetadata(this IResourceBuilder builder, string name, ParameterResource parameterResource) { if (parameterResource.Secret) diff --git a/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprOptions.cs b/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprOptions.cs index 6de21a8e7..59a340484 100644 --- a/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprOptions.cs +++ b/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprOptions.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Aspire.Hosting; using Aspire.Hosting.ApplicationModel; namespace CommunityToolkit.Aspire.Hosting.Dapr; @@ -8,6 +9,7 @@ namespace CommunityToolkit.Aspire.Hosting.Dapr; /// /// Options for configuring Dapr. /// +[AspireExport(ExposeProperties = true)] public sealed record DaprOptions { /// @@ -26,7 +28,7 @@ public sealed record DaprOptions /// /// Gets or sets the action to be executed during the publishing process. /// - /// This property allows customization of the publishing behavior by assigning a delegate that - /// defines the desired operation. + /// This property is not available in polyglot app hosts. + [AspireExportIgnore(Reason = "Action callbacks are not ATS-compatible.")] public Action? PublishingConfigurationAction { get; set; } } diff --git a/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprPolyglotOptions.cs b/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprPolyglotOptions.cs new file mode 100644 index 000000000..a759a1c50 --- /dev/null +++ b/src/CommunityToolkit.Aspire.Hosting.Dapr/DaprPolyglotOptions.cs @@ -0,0 +1,100 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Immutable; +using System.Linq; +using Aspire.Hosting; + +namespace CommunityToolkit.Aspire.Hosting.Dapr; + +[AspireDto] +internal sealed record DaprComponentExportOptions +{ + public string? LocalPath { get; init; } + + public DaprComponentOptions ToDaprComponentOptions() + { + return new DaprComponentOptions + { + LocalPath = LocalPath + }; + } +} + +[AspireDto] +internal sealed record DaprSidecarExportOptions +{ + public string? AppChannelAddress { get; init; } + public string? AppHealthCheckPath { get; init; } + public int? AppHealthProbeInterval { get; init; } + public int? AppHealthProbeTimeout { get; init; } + public int? AppHealthThreshold { get; init; } + public string? AppId { get; init; } + public int? AppMaxConcurrency { get; init; } + public int? AppPort { get; init; } + public string? AppProtocol { get; init; } + public string? AppEndpoint { get; init; } + public string[]? Command { get; init; } + public string? Config { get; init; } + public int? DaprGrpcPort { get; init; } + public int? DaprHttpMaxRequestSize { get; init; } + public string? DaprMaxBodySize { get; init; } + public int? DaprHttpPort { get; init; } + public int? DaprHttpReadBufferSize { get; init; } + public string? DaprReadBufferSize { get; init; } + public int? DaprInternalGrpcPort { get; init; } + public string? DaprListenAddresses { get; init; } + public bool? EnableApiLogging { get; init; } + public bool? EnableAppHealthCheck { get; init; } + public bool? EnableProfiling { get; init; } + public string? LogLevel { get; init; } + public int? MetricsPort { get; init; } + public string? PlacementHostAddress { get; init; } + public int? ProfilePort { get; init; } + public string[]? ResourcesPaths { get; init; } + public string? RunFile { get; init; } + public string? RuntimePath { get; init; } + public string? SchedulerHostAddress { get; init; } + public string? UnixDomainSocket { get; init; } + + public DaprSidecarOptions ToDaprSidecarOptions() + { +#pragma warning disable CS0618 + return new DaprSidecarOptions + { + AppChannelAddress = AppChannelAddress, + AppHealthCheckPath = AppHealthCheckPath, + AppHealthProbeInterval = AppHealthProbeInterval, + AppHealthProbeTimeout = AppHealthProbeTimeout, + AppHealthThreshold = AppHealthThreshold, + AppId = AppId, + AppMaxConcurrency = AppMaxConcurrency, + AppPort = AppPort, + AppProtocol = AppProtocol, + AppEndpoint = AppEndpoint, + Command = Command?.ToImmutableList() ?? ImmutableList.Empty, + Config = Config, + DaprGrpcPort = DaprGrpcPort, + DaprHttpMaxRequestSize = DaprHttpMaxRequestSize, + DaprMaxBodySize = DaprMaxBodySize, + DaprHttpPort = DaprHttpPort, + DaprHttpReadBufferSize = DaprHttpReadBufferSize, + DaprReadBufferSize = DaprReadBufferSize, + DaprInternalGrpcPort = DaprInternalGrpcPort, + DaprListenAddresses = DaprListenAddresses, + EnableApiLogging = EnableApiLogging, + EnableAppHealthCheck = EnableAppHealthCheck, + EnableProfiling = EnableProfiling, + LogLevel = LogLevel, + MetricsPort = MetricsPort, + PlacementHostAddress = PlacementHostAddress, + ProfilePort = ProfilePort, + ResourcesPaths = ResourcesPaths?.ToImmutableHashSet(StringComparer.Ordinal) ?? ImmutableHashSet.Empty, + RunFile = RunFile, + RuntimePath = RuntimePath, + SchedulerHostAddress = SchedulerHostAddress, + UnixDomainSocket = UnixDomainSocket + }; +#pragma warning restore CS0618 + } +} diff --git a/src/CommunityToolkit.Aspire.Hosting.Dapr/IDaprComponentResource.cs b/src/CommunityToolkit.Aspire.Hosting.Dapr/IDaprComponentResource.cs index c66cddc7d..449b4ed23 100644 --- a/src/CommunityToolkit.Aspire.Hosting.Dapr/IDaprComponentResource.cs +++ b/src/CommunityToolkit.Aspire.Hosting.Dapr/IDaprComponentResource.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Aspire.Hosting; using Aspire.Hosting.ApplicationModel; namespace CommunityToolkit.Aspire.Hosting.Dapr; @@ -8,6 +9,7 @@ namespace CommunityToolkit.Aspire.Hosting.Dapr; /// /// Represents a Dapr component resource. /// +[AspireExport(ExposeProperties = true)] public interface IDaprComponentResource : IResource, IResourceWithWaitSupport { /// diff --git a/src/CommunityToolkit.Aspire.Hosting.Dapr/IDistributedApplicationBuilderExtensions.cs b/src/CommunityToolkit.Aspire.Hosting.Dapr/IDistributedApplicationBuilderExtensions.cs index e2dceb04c..f7cf4bc03 100644 --- a/src/CommunityToolkit.Aspire.Hosting.Dapr/IDistributedApplicationBuilderExtensions.cs +++ b/src/CommunityToolkit.Aspire.Hosting.Dapr/IDistributedApplicationBuilderExtensions.cs @@ -23,6 +23,7 @@ public static partial class IDistributedApplicationBuilderExtensions /// The distributed application builder instance. /// Callback to configure dapr options. /// The distributed application builder instance. + [AspireExport("addDapr", Description = "Adds Dapr support to the distributed application builder")] public static IDistributedApplicationBuilder AddDapr(this IDistributedApplicationBuilder builder, Action? configure = null) { if (configure is not null) @@ -43,6 +44,8 @@ public static IDistributedApplicationBuilder AddDapr(this IDistributedApplicatio /// The type of the component. This can be a generic "state" or "pubsub" string, to have Aspire choose an appropriate type when running or deploying. /// Options for configuring the component, if any. /// A reference to the . + /// This overload is not available in polyglot app hosts. Use the generated addDaprComponent overload that accepts a Dapr component options object instead. + [AspireExportIgnore(Reason = "Use the exported DTO-based overload instead to avoid ambiguous polyglot wrapper generation.")] public static IResourceBuilder AddDaprComponent(this IDistributedApplicationBuilder builder, [ResourceName] string name, string type, DaprComponentOptions? options = null) { var resource = new DaprComponentResource(name, type) { Options = options }; @@ -63,6 +66,12 @@ public static IResourceBuilder AddDaprComponent(this IDi return resourceBuilder; } + [AspireExport("addDaprComponent", MethodName = "addDaprComponent", Description = "Adds a Dapr component resource to the distributed application model")] + internal static IResourceBuilder AddDaprComponentExport(this IDistributedApplicationBuilder builder, [ResourceName] string name, string type, DaprComponentExportOptions? componentOptions = null) + { + return builder.AddDaprComponent(name, type, componentOptions?.ToDaprComponentOptions()); + } + private static void SetupComponentLifecycle(IResourceBuilder componentBuilder) { // Hook into the component initialization for state management @@ -108,11 +117,19 @@ await evt.Notifications.PublishUpdateAsync(component, s => s with /// The name of the component. /// Options for configuring the component, if any. /// A reference to the . + /// This overload is not available in polyglot app hosts. Use the generated addDaprPubSub overload that accepts a Dapr component options object instead. + [AspireExportIgnore(Reason = "Use the exported DTO-based overload instead to avoid ambiguous polyglot wrapper generation.")] public static IResourceBuilder AddDaprPubSub(this IDistributedApplicationBuilder builder, [ResourceName] string name, DaprComponentOptions? options = null) { return builder.AddDaprComponent(name, DaprConstants.BuildingBlocks.PubSub, options); } + [AspireExport("addDaprPubSub", MethodName = "addDaprPubSub", Description = "Adds a generic Dapr pub-sub component resource")] + internal static IResourceBuilder AddDaprPubSubExport(this IDistributedApplicationBuilder builder, [ResourceName] string name, DaprComponentExportOptions? componentOptions = null) + { + return builder.AddDaprPubSub(name, componentOptions?.ToDaprComponentOptions()); + } + /// /// Adds a Dapr state store component to the application model. Aspire will configure an appropriate type when running or deploying. /// @@ -120,11 +137,19 @@ public static IResourceBuilder AddDaprPubSub(this IDistr /// The name of the component. /// Options for configuring the component, if any. /// A reference to the . + /// This overload is not available in polyglot app hosts. Use the generated addDaprStateStore overload that accepts a Dapr component options object instead. + [AspireExportIgnore(Reason = "Use the exported DTO-based overload instead to avoid ambiguous polyglot wrapper generation.")] public static IResourceBuilder AddDaprStateStore(this IDistributedApplicationBuilder builder, [ResourceName] string name, DaprComponentOptions? options = null) { return builder.AddDaprComponent(name, DaprConstants.BuildingBlocks.StateStore, options); } + [AspireExport("addDaprStateStore", MethodName = "addDaprStateStore", Description = "Adds a generic Dapr state store component resource")] + internal static IResourceBuilder AddDaprStateStoreExport(this IDistributedApplicationBuilder builder, [ResourceName] string name, DaprComponentExportOptions? componentOptions = null) + { + return builder.AddDaprStateStore(name, componentOptions?.ToDaprComponentOptions()); + } + private static void WriteDaprComponentResourceToManifest(ManifestPublishingContext context, DaprComponentResource resource) { context.Writer.WriteString("type", "dapr.component.v0"); diff --git a/src/CommunityToolkit.Aspire.Hosting.Dapr/IDistributedApplicationComponentBuilderExtensions.cs b/src/CommunityToolkit.Aspire.Hosting.Dapr/IDistributedApplicationComponentBuilderExtensions.cs index a2964d3bb..423775c63 100644 --- a/src/CommunityToolkit.Aspire.Hosting.Dapr/IDistributedApplicationComponentBuilderExtensions.cs +++ b/src/CommunityToolkit.Aspire.Hosting.Dapr/IDistributedApplicationComponentBuilderExtensions.cs @@ -18,6 +18,8 @@ public static class IDistributedApplicationResourceBuilderExtensions /// The resource builder instance. /// The ID for the application, used for service discovery. /// The resource builder instance. + /// This overload is not available in polyglot app hosts. Use the generated withDaprSidecar overload that accepts a Dapr sidecar configuration object instead. + [AspireExportIgnore(Reason = "Use the options-based overload instead to avoid ambiguous polyglot overloads.")] public static IResourceBuilder WithDaprSidecar(this IResourceBuilder builder, string appId) where T : IResource { return builder.WithDaprSidecar(new DaprSidecarOptions { AppId = appId }); @@ -30,6 +32,8 @@ public static IResourceBuilder WithDaprSidecar(this IResourceBuilder bu /// The resource builder instance. /// Options for configuring the Dapr sidecar, if any. /// The resource builder instance. + /// This overload is not available in polyglot app hosts. Use the generated withDaprSidecar overload that accepts a Dapr sidecar configuration object instead. + [AspireExportIgnore(Reason = "Use the exported DTO-based overload instead to avoid ambiguous polyglot wrapper generation.")] public static IResourceBuilder WithDaprSidecar(this IResourceBuilder builder, DaprSidecarOptions? options = null) where T : IResource { return builder.WithDaprSidecar( @@ -42,6 +46,12 @@ public static IResourceBuilder WithDaprSidecar(this IResourceBuilder bu }); } + [AspireExport("withDaprSidecar", MethodName = "withDaprSidecar", Description = "Adds a Dapr sidecar to the resource and optionally configures it")] + internal static IResourceBuilder WithDaprSidecarExport(this IResourceBuilder builder, DaprSidecarExportOptions? sidecarOptions = null) where T : IResource + { + return builder.WithDaprSidecar(sidecarOptions?.ToDaprSidecarOptions()); + } + /// /// Ensures that a Dapr sidecar is started for the resource. /// @@ -49,6 +59,7 @@ public static IResourceBuilder WithDaprSidecar(this IResourceBuilder bu /// The resource builder instance. /// A callback that can be use to configure the Dapr sidecar. /// The resource builder instance. + [AspireExport("configureDaprSidecar", MethodName = "configureDaprSidecar", Description = "Adds a Dapr sidecar to the resource and exposes it for callback configuration")] public static IResourceBuilder WithDaprSidecar(this IResourceBuilder builder, Action> configureSidecar) where T : IResource { // Add Dapr is idempotent, so we can call it multiple times. @@ -76,11 +87,19 @@ public static IResourceBuilder WithDaprSidecar(this IResourceBuilder bu /// The Dapr sidecar resource builder instance. /// Options for configuring the Dapr sidecar. /// The Dapr sidecar resource builder instance. + /// This overload is not available in polyglot app hosts. Use the generated withOptions overload that accepts a Dapr sidecar configuration object instead. + [AspireExportIgnore(Reason = "Use the exported DTO-based overload instead to avoid ambiguous polyglot wrapper generation.")] public static IResourceBuilder WithOptions(this IResourceBuilder builder, DaprSidecarOptions options) { return builder.WithAnnotation(new DaprSidecarOptionsAnnotation(options)); } + [AspireExport("withOptions", MethodName = "withOptions", Description = "Configures options for a Dapr sidecar resource")] + internal static IResourceBuilder WithOptionsExport(this IResourceBuilder builder, DaprSidecarExportOptions sidecarOptions) + { + return builder.WithOptions(sidecarOptions.ToDaprSidecarOptions()); + } + /// /// Associates a Dapr component with the Dapr sidecar started for the resource. /// @@ -97,6 +116,7 @@ public static IResourceBuilder WithReference(this IR /// /// The resource builder instance. /// The Dapr component to use with the sidecar. + [AspireExport("withReference", Description = "Associates a Dapr component with a Dapr sidecar resource")] public static IResourceBuilder WithReference(this IResourceBuilder builder, IResourceBuilder component) { return builder.WithAnnotation(new DaprComponentReferenceAnnotation(component.Resource));