-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
improve(laboratory): validate editor content with TypeScript #6476
base: main
Are you sure you want to change the base?
Conversation
Draft because there are no tests yet. |
📚 Storybook DeploymentThe latest changes are available as preview in: https://c2692f09.hive-storybook.pages.dev |
🐋 This PR was built and pushed to the following Docker images: Targets: Platforms: Image Tag: Docker Bake metadata{
"app": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/api/health",
"build-arg:IMAGE_DESCRIPTION": "The app of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/app",
"build-arg:PORT": "3000",
"build-arg:RELEASE": "08b3640040230552a4bb431c4b3ec75cfb725211",
"build-arg:SERVICE_DIR_NAME": "@hive/app",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:dockerfile": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:shared": "8xs5k936gdes1o03mjam1jht0"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-713199cf-705d-4778-8686-5fb6c1837733/builder-713199cf-705d-4778-8686-5fb6c18377330/xs3jlkohtq5biahn22w7k8tmc",
"containerimage.config.digest": "sha256:6d7855016c0e9af61f3f95ebf26b3072b7510136645b846820869adae800df84",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:070089a6344ff45a8de5fe520e9ca732d5e02ac73d8f8cce5ecc14de31e73655",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:070089a6344ff45a8de5fe520e9ca732d5e02ac73d8f8cce5ecc14de31e73655",
"image.name": "ghcr.io/graphql-hive/app:08b3640040230552a4bb431c4b3ec75cfb725211-arm64,ghcr.io/graphql-hive/app:console_1003-arm64"
},
"buildx.build.warnings": [
{
"vertex": "sha256:8fca626ca6d6e5fcf05de91423f50525022451ddd8faa6441f9cb28df47c533e",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRSRUxFQVNFJyAobGluZSAxMyk=",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 13
},
"end": {
"line": 13
}
}
]
},
{
"vertex": "sha256:8fca626ca6d6e5fcf05de91423f50525022451ddd8faa6441f9cb28df47c533e",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRQT1JUJyAobGluZSAyMik=",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 22
},
"end": {
"line": 22
}
}
]
},
{
"vertex": "sha256:a278d71b031ff67e2765de8c5a91ace36a140b5e97d4614a9cc23c74a96ba4f4",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRSRUxFQVNFJyAobGluZSAxMik=",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "migrations.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQgcHJvZHVjdGlvbgpFTlYgTk9ERV9FTlYgcHJvZHVjdGlvbgpFTlYgUkVMRUFTRSAkUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 12
},
"end": {
"line": 12
}
}
]
},
{
"vertex": "sha256:a278d71b031ff67e2765de8c5a91ace36a140b5e97d4614a9cc23c74a96ba4f4",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRJTUFHRV9USVRMRScgKGxpbmUgMTUp",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "migrations.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQgcHJvZHVjdGlvbgpFTlYgTk9ERV9FTlYgcHJvZHVjdGlvbgpFTlYgUkVMRUFTRSAkUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 15
},
"end": {
"line": 15
}
}
]
},
{
"vertex": "sha256:a278d71b031ff67e2765de8c5a91ace36a140b5e97d4614a9cc23c74a96ba4f4",
"level": 1,
"short": "TGVnYWN5S2V5VmFsdWVGb3JtYXQ6ICJFTlYga2V5PXZhbHVlIiBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mIGxlZ2FjeSAiRU5WIGtleSB2YWx1ZSIgZm9ybWF0IChsaW5lIDEyKQ==",
"detail": [
"TGVnYWN5IGtleS92YWx1ZSBmb3JtYXQgd2l0aCB3aGl0ZXNwYWNlIHNlcGFyYXRvciBzaG91bGQgbm90IGJlIHVzZWQ="
],
"url": "https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/",
"sourceInfo": {
"filename": "migrations.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQgcHJvZHVjdGlvbgpFTlYgTk9ERV9FTlYgcHJvZHVjdGlvbgpFTlYgUkVMRUFTRSAkUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 12
},
"end": {
"line": 12
}
}
]
},
{
"vertex": "sha256:a278d71b031ff67e2765de8c5a91ace36a140b5e97d4614a9cc23c74a96ba4f4",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRJTUFHRV9ERVNDUklQVElPTicgKGxpbmUgMTcp",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "migrations.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQgcHJvZHVjdGlvbgpFTlYgTk9ERV9FTlYgcHJvZHVjdGlvbgpFTlYgUkVMRUFTRSAkUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 17
},
"end": {
"line": 17
}
}
]
},
{
"vertex": "sha256:a278d71b031ff67e2765de8c5a91ace36a140b5e97d4614a9cc23c74a96ba4f4",
"level": 1,
"short": "TGVnYWN5S2V5VmFsdWVGb3JtYXQ6ICJFTlYga2V5PXZhbHVlIiBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mIGxlZ2FjeSAiRU5WIGtleSB2YWx1ZSIgZm9ybWF0IChsaW5lIDExKQ==",
"detail": [
"TGVnYWN5IGtleS92YWx1ZSBmb3JtYXQgd2l0aCB3aGl0ZXNwYWNlIHNlcGFyYXRvciBzaG91bGQgbm90IGJlIHVzZWQ="
],
"url": "https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/",
"sourceInfo": {
"filename": "migrations.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQgcHJvZHVjdGlvbgpFTlYgTk9ERV9FTlYgcHJvZHVjdGlvbgpFTlYgUkVMRUFTRSAkUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 11
},
"end": {
"line": 11
}
}
]
},
{
"vertex": "sha256:8fca626ca6d6e5fcf05de91423f50525022451ddd8faa6441f9cb28df47c533e",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRJTUFHRV9ERVNDUklQVElPTicgKGxpbmUgMTQp",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 14
},
"end": {
"line": 14
}
}
]
},
{
"vertex": "sha256:8fca626ca6d6e5fcf05de91423f50525022451ddd8faa6441f9cb28df47c533e",
"level": 1,
"short": "TGVnYWN5S2V5VmFsdWVGb3JtYXQ6ICJFTlYga2V5PXZhbHVlIiBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mIGxlZ2FjeSAiRU5WIGtleSB2YWx1ZSIgZm9ybWF0IChsaW5lIDIwKQ==",
"detail": [
"TGVnYWN5IGtleS92YWx1ZSBmb3JtYXQgd2l0aCB3aGl0ZXNwYWNlIHNlcGFyYXRvciBzaG91bGQgbm90IGJlIHVzZWQ="
],
"url": "https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 20
},
"end": {
"line": 20
}
}
]
},
{
"vertex": "sha256:8fca626ca6d6e5fcf05de91423f50525022451ddd8faa6441f9cb28df47c533e",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRSRUxFQVNFJyAobGluZSAyMSk=",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 21
},
"end": {
"line": 21
}
}
]
},
{
"vertex": "sha256:8fca626ca6d6e5fcf05de91423f50525022451ddd8faa6441f9cb28df47c533e",
"level": 1,
"short": "TGVnYWN5S2V5VmFsdWVGb3JtYXQ6ICJFTlYga2V5PXZhbHVlIiBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mIGxlZ2FjeSAiRU5WIGtleSB2YWx1ZSIgZm9ybWF0IChsaW5lIDIyKQ==",
"detail": [
"TGVnYWN5IGtleS92YWx1ZSBmb3JtYXQgd2l0aCB3aGl0ZXNwYWNlIHNlcGFyYXRvciBzaG91bGQgbm90IGJlIHVzZWQ="
],
"url": "https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 22
},
"end": {
"line": 22
}
}
]
},
{
"vertex": "sha256:a278d71b031ff67e2765de8c5a91ace36a140b5e97d4614a9cc23c74a96ba4f4",
"level": 1,
"short": "TGVnYWN5S2V5VmFsdWVGb3JtYXQ6ICJFTlYga2V5PXZhbHVlIiBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mIGxlZ2FjeSAiRU5WIGtleSB2YWx1ZSIgZm9ybWF0IChsaW5lIDEwKQ==",
"detail": [
"TGVnYWN5IGtleS92YWx1ZSBmb3JtYXQgd2l0aCB3aGl0ZXNwYWNlIHNlcGFyYXRvciBzaG91bGQgbm90IGJlIHVzZWQ="
],
"url": "https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/",
"sourceInfo": {
"filename": "migrations.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQgcHJvZHVjdGlvbgpFTlYgTk9ERV9FTlYgcHJvZHVjdGlvbgpFTlYgUkVMRUFTRSAkUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 10
},
"end": {
"line": 10
}
}
]
},
{
"vertex": "sha256:8fca626ca6d6e5fcf05de91423f50525022451ddd8faa6441f9cb28df47c533e",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRJTUFHRV9USVRMRScgKGxpbmUgMTIp",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 12
},
"end": {
"line": 12
}
}
]
},
{
"vertex": "sha256:8fca626ca6d6e5fcf05de91423f50525022451ddd8faa6441f9cb28df47c533e",
"level": 1,
"short": "TGVnYWN5S2V5VmFsdWVGb3JtYXQ6ICJFTlYga2V5PXZhbHVlIiBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mIGxlZ2FjeSAiRU5WIGtleSB2YWx1ZSIgZm9ybWF0IChsaW5lIDIxKQ==",
"detail": [
"TGVnYWN5IGtleS92YWx1ZSBmb3JtYXQgd2l0aCB3aGl0ZXNwYWNlIHNlcGFyYXRvciBzaG91bGQgbm90IGJlIHVzZWQ="
],
"url": "https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 21
},
"end": {
"line": 21
}
}
]
}
],
"composition-federation-2": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "Federation 2 Composition Service for GraphQL Hive.",
"build-arg:IMAGE_TITLE": "graphql-hive/composition-federation-2",
"build-arg:PORT": "3069",
"build-arg:RELEASE": "08b3640040230552a4bb431c4b3ec75cfb725211",
"build-arg:SERVICE_DIR_NAME": "@hive/external-composition",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:dockerfile": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:shared": "8xs5k936gdes1o03mjam1jht0"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-713199cf-705d-4778-8686-5fb6c1837733/builder-713199cf-705d-4778-8686-5fb6c18377330/q5nztbdr4n5g7evunjs8sae2h",
"containerimage.config.digest": "sha256:79f35efc1e8684859728707c80b879154dbd476400658ac98aead9718ce28f12",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:373a64b5655de57b8404a3d6f6f1eed8b4e09b77cb1dd28d70ba22bdde22bf99",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:373a64b5655de57b8404a3d6f6f1eed8b4e09b77cb1dd28d70ba22bdde22bf99",
"image.name": "ghcr.io/graphql-hive/composition-federation-2:08b3640040230552a4bb431c4b3ec75cfb725211-arm64,ghcr.io/graphql-hive/composition-federation-2:console_1003-arm64"
},
"emails": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The emails service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/emails",
"build-arg:PORT": "3006",
"build-arg:RELEASE": "08b3640040230552a4bb431c4b3ec75cfb725211",
"build-arg:SERVICE_DIR_NAME": "@hive/emails",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:dockerfile": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:shared": "8xs5k936gdes1o03mjam1jht0"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-713199cf-705d-4778-8686-5fb6c1837733/builder-713199cf-705d-4778-8686-5fb6c18377330/umhswr9rwqktullswal2j6zao",
"containerimage.config.digest": "sha256:4c4a1f0db7069b1db8e7cc964ce786a67b437e39a73a12d8ff61a14f2ec96fa9",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:a86942bc32628000c9f34542aa6edc8df71adcb06c896a2252be6fda2824af9e",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:a86942bc32628000c9f34542aa6edc8df71adcb06c896a2252be6fda2824af9e",
"image.name": "ghcr.io/graphql-hive/emails:08b3640040230552a4bb431c4b3ec75cfb725211-arm64,ghcr.io/graphql-hive/emails:console_1003-arm64"
},
"policy": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The policy service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/policy",
"build-arg:PORT": "3012",
"build-arg:RELEASE": "08b3640040230552a4bb431c4b3ec75cfb725211",
"build-arg:SERVICE_DIR_NAME": "@hive/policy",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:dockerfile": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:shared": "8xs5k936gdes1o03mjam1jht0"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-713199cf-705d-4778-8686-5fb6c1837733/builder-713199cf-705d-4778-8686-5fb6c18377330/y69hsq5vxilve1klii14iqowe",
"containerimage.config.digest": "sha256:bc20d0b6d0d3db57e58424087efe22d468eac9baf8f9d8f0fb7bff8388da2b73",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:4ddba75bf2229539114fa7af05be80541e5315c0cd7c2a9f420150cefe9d67c6",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:4ddba75bf2229539114fa7af05be80541e5315c0cd7c2a9f420150cefe9d67c6",
"image.name": "ghcr.io/graphql-hive/policy:08b3640040230552a4bb431c4b3ec75cfb725211-arm64,ghcr.io/graphql-hive/policy:console_1003-arm64"
},
"rate-limit": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The rate limit service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/rate-limit",
"build-arg:PORT": "3009",
"build-arg:RELEASE": "08b3640040230552a4bb431c4b3ec75cfb725211",
"build-arg:SERVICE_DIR_NAME": "@hive/rate-limit",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:dockerfile": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:shared": "8xs5k936gdes1o03mjam1jht0"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-713199cf-705d-4778-8686-5fb6c1837733/builder-713199cf-705d-4778-8686-5fb6c18377330/kskzc7qy3l7xh4ov7ts34er8c",
"containerimage.config.digest": "sha256:201b3b100bb800f56adafd065bb59dc07878d30aa4d89f8f23a049cec64fbf06",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:6ff92939d027222dd10763b53ca58eaccbde8d3cfd0c78411857666ebfceb721",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:6ff92939d027222dd10763b53ca58eaccbde8d3cfd0c78411857666ebfceb721",
"image.name": "ghcr.io/graphql-hive/rate-limit:08b3640040230552a4bb431c4b3ec75cfb725211-arm64,ghcr.io/graphql-hive/rate-limit:console_1003-arm64"
},
"schema": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The schema service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/schema",
"build-arg:PORT": "3002",
"build-arg:RELEASE": "08b3640040230552a4bb431c4b3ec75cfb725211",
"build-arg:SERVICE_DIR_NAME": "@hive/schema",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:dockerfile": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:shared": "8xs5k936gdes1o03mjam1jht0"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-713199cf-705d-4778-8686-5fb6c1837733/builder-713199cf-705d-4778-8686-5fb6c18377330/jop58uzcnqrxf0jyz969fk96d",
"containerimage.config.digest": "sha256:543ff55b888915c988e16aafab1f4669a73c9a191afc1aab9cc9319e8eb0feae",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:ae5961c9f37102f16dd229636e04003d5ea82db39a9f4b2141b96b56ee7238e8",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:ae5961c9f37102f16dd229636e04003d5ea82db39a9f4b2141b96b56ee7238e8",
"image.name": "ghcr.io/graphql-hive/schema:08b3640040230552a4bb431c4b3ec75cfb725211-arm64,ghcr.io/graphql-hive/schema:console_1003-arm64"
},
"server": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The server service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/server",
"build-arg:PORT": "3001",
"build-arg:RELEASE": "08b3640040230552a4bb431c4b3ec75cfb725211",
"build-arg:SERVICE_DIR_NAME": "@hive/server",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:dockerfile": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:shared": "8xs5k936gdes1o03mjam1jht0"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-713199cf-705d-4778-8686-5fb6c1837733/builder-713199cf-705d-4778-8686-5fb6c18377330/d529jq5nf9owu7lzx52hryxme",
"containerimage.config.digest": "sha256:8e8f656915a68129b3e2d710da0e2f1932efc3610f4004cfb159a07fd40597d9",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:abda444d2671de4a070f686ce8161841dff0896591c4fc928bb10f1f579833e8",
"size": 2076,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:abda444d2671de4a070f686ce8161841dff0896591c4fc928bb10f1f579833e8",
"image.name": "ghcr.io/graphql-hive/server:08b3640040230552a4bb431c4b3ec75cfb725211-arm64,ghcr.io/graphql-hive/server:console_1003-arm64"
},
"storage": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "migrations.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:IMAGE_DESCRIPTION": "The migrations service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/storage",
"build-arg:RELEASE": "08b3640040230552a4bb431c4b3ec75cfb725211",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:dockerfile": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:shared": "8xs5k936gdes1o03mjam1jht0"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-713199cf-705d-4778-8686-5fb6c1837733/builder-713199cf-705d-4778-8686-5fb6c18377330/bttklhsx5fztbwrjlkfl56tmf",
"containerimage.config.digest": "sha256:3fad981df079c0850c20689fde0445bca306fc74dfc0a63b7fd31a5a8fa9f4c5",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:b8add7d22d706d43dbc0ce589407d8ddcc76d649f07b19decf57b28c25517717",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:b8add7d22d706d43dbc0ce589407d8ddcc76d649f07b19decf57b28c25517717",
"image.name": "ghcr.io/graphql-hive/storage:08b3640040230552a4bb431c4b3ec75cfb725211-arm64,ghcr.io/graphql-hive/storage:console_1003-arm64"
},
"stripe-billing": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The stripe billing service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/stripe-billing",
"build-arg:PORT": "3010",
"build-arg:RELEASE": "08b3640040230552a4bb431c4b3ec75cfb725211",
"build-arg:SERVICE_DIR_NAME": "@hive/stripe-billing",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:dockerfile": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:shared": "8xs5k936gdes1o03mjam1jht0"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-713199cf-705d-4778-8686-5fb6c1837733/builder-713199cf-705d-4778-8686-5fb6c18377330/pmm099nbox87n3wf3vhwuvvvz",
"containerimage.config.digest": "sha256:43753930639b10cc3448bc322515745e3947604e532cf134f461256dc34fe651",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:7c082187940382140a0323e3666e084d463aa8bef0ac75a153ba6a48c9637ed4",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:7c082187940382140a0323e3666e084d463aa8bef0ac75a153ba6a48c9637ed4",
"image.name": "ghcr.io/graphql-hive/stripe-billing:08b3640040230552a4bb431c4b3ec75cfb725211-arm64,ghcr.io/graphql-hive/stripe-billing:console_1003-arm64"
},
"tokens": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The tokens service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/tokens",
"build-arg:PORT": "3003",
"build-arg:RELEASE": "08b3640040230552a4bb431c4b3ec75cfb725211",
"build-arg:SERVICE_DIR_NAME": "@hive/tokens",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:dockerfile": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:shared": "8xs5k936gdes1o03mjam1jht0"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-713199cf-705d-4778-8686-5fb6c1837733/builder-713199cf-705d-4778-8686-5fb6c18377330/onw1lawopdxz0iiugzaer6mgm",
"containerimage.config.digest": "sha256:10ba0cd038f163c59755541fa78a5ec71e124e3e72dc446598d59ddb189c9702",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:f9100792c3dd0cc24d30d94184b43b71acd23754ab40d46df974cfea7dae7f85",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:f9100792c3dd0cc24d30d94184b43b71acd23754ab40d46df974cfea7dae7f85",
"image.name": "ghcr.io/graphql-hive/tokens:08b3640040230552a4bb431c4b3ec75cfb725211-arm64,ghcr.io/graphql-hive/tokens:console_1003-arm64"
},
"usage": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The usage ingestor service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/usage",
"build-arg:PORT": "3006",
"build-arg:RELEASE": "08b3640040230552a4bb431c4b3ec75cfb725211",
"build-arg:SERVICE_DIR_NAME": "@hive/usage",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:dockerfile": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:shared": "8xs5k936gdes1o03mjam1jht0"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-713199cf-705d-4778-8686-5fb6c1837733/builder-713199cf-705d-4778-8686-5fb6c18377330/r6fgidatg5sm8rv04m9okov40",
"containerimage.config.digest": "sha256:f83ccbda35df182ac373b003a9fcb248f4d4a42a39a99d37820dbe0ed5e3d2a5",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:46758237a9b8a3f203ada827495247a1f199d53c0857f468f6fde84b1833c435",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:46758237a9b8a3f203ada827495247a1f199d53c0857f468f6fde84b1833c435",
"image.name": "ghcr.io/graphql-hive/usage:08b3640040230552a4bb431c4b3ec75cfb725211-arm64,ghcr.io/graphql-hive/usage:console_1003-arm64"
},
"usage-estimator": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The usage estimator service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/usage-estimator",
"build-arg:PORT": "3008",
"build-arg:RELEASE": "08b3640040230552a4bb431c4b3ec75cfb725211",
"build-arg:SERVICE_DIR_NAME": "@hive/usage-estimator",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:dockerfile": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:shared": "8xs5k936gdes1o03mjam1jht0"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-713199cf-705d-4778-8686-5fb6c1837733/builder-713199cf-705d-4778-8686-5fb6c18377330/xjai3f2n8mmwhn2qof3kyvknu",
"containerimage.config.digest": "sha256:50a685393dbcdac1d4021402d83d6267aeece1f6a04e9c8887ed54ebf6126cff",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:03449ee26f38e10c2fd1c9ffb75afbbc5d73924437e556f7047f13abd5699bf0",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:03449ee26f38e10c2fd1c9ffb75afbbc5d73924437e556f7047f13abd5699bf0",
"image.name": "ghcr.io/graphql-hive/usage-estimator:08b3640040230552a4bb431c4b3ec75cfb725211-arm64,ghcr.io/graphql-hive/usage-estimator:console_1003-arm64"
},
"usage-ingestor": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The usage ingestor service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/usage-ingestor",
"build-arg:PORT": "3007",
"build-arg:RELEASE": "08b3640040230552a4bb431c4b3ec75cfb725211",
"build-arg:SERVICE_DIR_NAME": "@hive/usage-ingestor",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:dockerfile": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:shared": "8xs5k936gdes1o03mjam1jht0"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-713199cf-705d-4778-8686-5fb6c1837733/builder-713199cf-705d-4778-8686-5fb6c18377330/o78f0flr5x27fsvlvo4gw64k8",
"containerimage.config.digest": "sha256:2fc31d1025d525b94349168916e025fdce4101b9a388931853d19ba058394555",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:05bf61ce297eb08b1d3e4669c096b281708b104c7132e962ab3bdb4d65f4d881",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:05bf61ce297eb08b1d3e4669c096b281708b104c7132e962ab3bdb4d65f4d881",
"image.name": "ghcr.io/graphql-hive/usage-ingestor:08b3640040230552a4bb431c4b3ec75cfb725211-arm64,ghcr.io/graphql-hive/usage-ingestor:console_1003-arm64"
},
"webhooks": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The webhooks ingestor service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/webhooks",
"build-arg:PORT": "3005",
"build-arg:RELEASE": "08b3640040230552a4bb431c4b3ec75cfb725211",
"build-arg:SERVICE_DIR_NAME": "@hive/webhooks",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:dockerfile": "8xs5k936gdes1o03mjam1jht0",
"local-sessionid:shared": "8xs5k936gdes1o03mjam1jht0"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-713199cf-705d-4778-8686-5fb6c1837733/builder-713199cf-705d-4778-8686-5fb6c18377330/ycvdokvds2zkxtr4w9r9p6z1z",
"containerimage.config.digest": "sha256:c1af4e3d95d91c2228c9613f4d92277750ce2088708056aea75657ff69ff51b2",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:d46b7799e6de356b19b86024165b492fee6c7165519f00317dfb403073b26a96",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:d46b7799e6de356b19b86024165b492fee6c7165519f00317dfb403073b26a96",
"image.name": "ghcr.io/graphql-hive/webhooks:08b3640040230552a4bb431c4b3ec75cfb725211-arm64,ghcr.io/graphql-hive/webhooks:console_1003-arm64"
}
} |
cypress/e2e/laboratory/_cy.ts
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried creating a laboratory domain of its sub sections and co-located the Cypress helpers.
I can undo this change if its out of scope or worse than the previous setup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved this to its own module since its just its own lib.
cypress/support/monaco.ts
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created a monaco lib to keep this generic utility away from specific monaco instances.
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe changes involve a refactor of Cypress tests, replacing the Changes
Possibly related PRs
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (11)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (8)
package.json (1)
80-80
: Consider pinning the cypress-real-events version.Using
^1.14.0
could lead to unexpected updates. Consider pinning to an exact version for better reproducibility.- "cypress-real-events": "^1.14.0", + "cypress-real-events": "1.14.0",cypress/support/monaco.ts (2)
7-7
: Consider type safety improvements for Monaco editor access.The
(win as any).monaco
cast bypasses type checking. Consider using a more type-safe approach.- const editor = (win as any).monaco.editor + interface MonacoWindow extends Window { + monaco: { + editor: { + getEditors(): Array<{ + getContainerDomNode(): HTMLElement; + setValue(value: string): void; + }>; + }; + }; + } + const editor = (win as MonacoWindow).monaco.editor
14-16
: Enhance error message with more context.The error message could be more helpful by including the
editorCyName
in the message.- throw new Error('Monaco editor not found on the window or frames[0]'); + throw new Error(`Monaco editor not found for data-cy="${editorCyName}"`);cypress/e2e/laboratory/_cy.ts (3)
8-11
: Improve type safety for CodeMirror access.The CodeMirror instance is accessed using
any
type. Consider using proper types.+ interface CodeMirrorEditor { + CodeMirror: { + setValue(value: string): void; + getValue(): string; + }; + } - const editor = ($editor[0] as any).CodeMirror; + const editor = ($editor[0] as CodeMirrorEditor).CodeMirror;
52-60
: Consider non-recursive implementation for closeTabsUntilOneLeft.The recursive implementation could be replaced with a simpler while loop to avoid potential stack overflow.
export function closeTabsUntilOneLeft() { - cy.get('li.graphiql-tab').then($tabs => { - if ($tabs.length > 1) { - closeActiveTab(); - // Recurse until there's only one tab left - return closeTabsUntilOneLeft(); - } - }); + cy.get('li.graphiql-tab').then($tabs => { + const closeTabs = () => { + if ($tabs.length > 1) { + closeActiveTab(); + cy.get('li.graphiql-tab').then($newTabs => { + $tabs = $newTabs; + closeTabs(); + }); + } + }; + closeTabs(); + });
63-79
: Consider using an enum for selector constants.The selectors object could be defined as an enum or const enum for better type safety and maintainability.
- export const selectors = { + export const enum Selectors { + ButtonGraphiQLPreflight = '[aria-label*="Preflight Script"]', + ButtonModalCy = 'preflight-modal-button', + // ... rest of the selectors + }packages/web/app/src/lib/preflight/graphiql-plugin.tsx (1)
649-669
: LGTM! Comprehensive TypeScript validation enabled.The configuration enables thorough TypeScript validation with strict mode and modern JavaScript features. Consider documenting these settings in a configuration file or README to help other developers understand the validation rules.
Add a comment block explaining the TypeScript validation settings:
+ // Enable comprehensive TypeScript validation with strict mode + // - Semantic and syntax validation for better error detection + // - Modern JavaScript features (ESNext) with DOM types + // - Strict checks for improved code quality monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({cypress/support/dedent.ts (1)
25-44
: Consider optimizing the indentation detection logic.While the implementation is correct, there are a few potential improvements:
- The TypeScript type narrowing comment could be more descriptive
- The indentation detection could be more robust by handling mixed indentation
Consider this alternative implementation:
- const m = mindent; // appease TypeScript + const m = mindent; // TypeScript needs this assignment to narrow the type from 'number | null' to 'number' result = lines.map(l => (l[0] === ' ' || l[0] === '\t' ? l.slice(m) : l)).join('\n');Additionally, consider adding a warning when mixed indentation (spaces and tabs) is detected:
const lines = result.split('\n'); let mindent: null | number = null; + let hasSpaces = false; + let hasTabs = false; for (const l of lines) { const m = l.match(/^(\s+)\S+/); if (m) { + if (m[1].includes(' ')) hasSpaces = true; + if (m[1].includes('\t')) hasTabs = true; const indent = m[1].length; if (!mindent) { // this is the first indented line mindent = indent; } else { mindent = Math.min(mindent, indent); } } } + + if (hasSpaces && hasTabs) { + console.warn('Mixed indentation detected: both spaces and tabs are used'); + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (12)
cypress.config.ts
(1 hunks)cypress/e2e/laboratory/_cy.ts
(1 hunks)cypress/e2e/laboratory/collections.cy.ts
(9 hunks)cypress/e2e/laboratory/preflight.cy.ts
(16 hunks)cypress/e2e/laboratory/tabs.cy.ts
(2 hunks)cypress/support/dedent.ts
(1 hunks)cypress/support/e2e.ts
(1 hunks)cypress/support/monaco.ts
(1 hunks)cypress/support/testkit.ts
(0 hunks)package.json
(2 hunks)packages/web/app/src/lib/preflight/graphiql-plugin.tsx
(2 hunks)tsconfig.json
(1 hunks)
💤 Files with no reviewable changes (1)
- cypress/support/testkit.ts
✅ Files skipped from review due to trivial changes (1)
- cypress/support/e2e.ts
⏰ Context from checks skipped due to timeout of 90000ms (10)
- GitHub Check: test / unit
- GitHub Check: typescript / typecheck
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: storybook-preview / deployment
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: alpha / cli-artifacts
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: SonarCloud
🔇 Additional comments (11)
cypress.config.ts (1)
11-17
: Consider moving environment variable configuration to a separate file.The local service configuration block could be moved to a dedicated configuration file to improve maintainability and separation of concerns.
Also, the commented-out
CYPRESS_BASE_URL
line suggests a potential issue with environment variable configuration.Please verify if the
CYPRESS_BASE_URL
needs to be set here or if it's correctly handled through the CLI command inpackage.json
.tsconfig.json (1)
6-6
: LGTM! Types configuration is correct.The addition of "cypress-real-events" types is necessary for TypeScript support.
package.json (2)
49-49
: LGTM! New script enhances local testing capabilities.The script correctly sets up the environment for local end-to-end testing.
47-49
: Verify test coverage for TypeScript validation.The PR is marked as draft due to missing tests. Consider adding end-to-end tests that verify the TypeScript validation functionality in the laboratory editor.
Would you like help generating test cases for the TypeScript validation feature?
cypress/e2e/laboratory/tabs.cy.ts (1)
1-35
: LGTM!The changes correctly implement the new cyLaboratory namespace while maintaining the existing test logic.
cypress/e2e/laboratory/collections.cy.ts (1)
1-250
: LGTM!The changes correctly implement the new cyLaboratory namespace while maintaining the existing test logic and coverage.
cypress/e2e/laboratory/preflight.cy.ts (1)
54-66
: 🛠️ Refactor suggestionImprove test reliability and fix type issues.
The test case has the following issues:
- The hardcoded delay (
cy.wait(1000)
) could make the test flaky.- The
@ts-expect-error
annotation suggests a type issue withrealPress
.Apply this diff to improve test reliability:
- cy.wait(1000); // :( + // Wait for TypeScript validation to complete + cy.contains(tsErrorMessage, { timeout: 5000 });Let's verify if there's a better way to handle keyboard events in Cypress:
✅ Verification successful
🌐 Web query:
What is the recommended way to handle keyboard events in Cypress? Are there any alternatives to cypress-real-events?
💡 Result:
The recommended approach for handling keyboard events in Cypress involves a combination of built-in commands and specialized plugins depending on testing requirements: ## Core Cypress Methods For most use cases: 1. **`.type()` command** handles simulated keyboard input with automatic event sequencing: - Fires `keydown`, `keypress`, `input`, and `keyup` events[1] - Supports special sequences like `{enter}` and modifier keys (`{ctrl}`, `{alt}`)[9] ```javascript cy.get('input').type('Hello{enter}') // Types text and presses Enter ``` 2. **`.trigger()`** manually dispatches events but has limitations: - Only creates generic `Event` objects without native `keyCode`/`code` properties[4] - Requires manual event configuration ## Real Event Simulation (cypress-real-events) When testing requires authentic browser interactions: - **Chromium-only solution** using Chrome DevTools Protocol[8] - Key features: ```javascript cy.get('input').realType('Text') // Native keystrokes cy.realPress('Tab') // Actual tab navigation cy.realPress(['Meta', 'A']) // Key combinations ``` - Advantages: - Generates trusted (`isTrusted: true`) events[8] - Handles focus management like real users[10] - Supports hover states and system dialogs | Feature | Built-in Commands | cypress-real-events | |-----------------------|-------------------|---------------------| | Trusted Events | ❌ | ✅ | | Cross-browser Support | ✅ | ❌ (Chromium only) | | Physical Key Presses | ❌ | ✅ | ## Alternatives & Workarounds 1. **Focus management**: ```javascript cy.get('input').focus().type('text') // Ensure element focus ``` 2. **Custom event dispatching** (for specific key properties): ```javascript cy.get('input').trigger('keydown', { key: 'a', code: 'KeyA', keyCode: 65 }) ``` 3. **Community plugins**: - `cypress-plugin-tab` for tab navigation[10] - `cypress-keycloak-commands` for specialized auth flows For most projects, combining native Cypress commands with selective use of cypress-real-events provides optimal coverage while maintaining cross-browser compatibility where needed[1][8]. Reserve low-level event triggering for edge cases requiring specific keyboard property validation[4]. Citations: - 1: https://docs.cypress.io/api/commands/type - 2: https://dev.to/samelawrence/my-favorite-cytype-tips-and-tricks-3166 - 3: https://betterstack.com/community/comparisons/cypress-alternative/ - 4: https://github.com/cypress-io/cypress/issues/29040 - 5: https://glebbahmutov.com/blog/how-to-pick-cypress-plugins/ - 6: https://www.lambdatest.com/blog/handling-touch-and-mouse-events-in-cypress/ - 7: https://www.browserstack.com/guide/handle-click-events-in-cypress - 8: https://github.com/dmtrKovalenko/cypress-real-events - 9: https://www.lambdatest.com/learning-hub/cypress-tips-and-tricks - 10: https://platform.text.com/resource-center/updates/cypress-axe-automated-testing
Update test to wait on validations and resolve TypeScript issues
- Replace the hardcoded delay (
cy.wait(1000)
) with an explicit wait for the expected error message (e.g. usingcy.contains(tsErrorMessage, { timeout: 5000 })
).- Investigate the TypeScript error on
realPress
: ensure you’re installing and importing the correct type definitions (or update them as needed) so that the plugin’s API is recognized without needing@ts-expect-error
.packages/web/app/src/lib/preflight/graphiql-plugin.tsx (1)
107-112
: LGTM! Enhanced editor features enabled.The Monaco editor configuration enables essential features for a better coding experience:
- Quick suggestions and auto-completion
- Code folding based on indentation
cypress/support/dedent.ts (3)
6-23
: LGTM! Robust string interpolation implementation.The implementation correctly handles raw template strings, escape sequences, and interpolation values.
46-52
: LGTM! Clean final string processing.The implementation correctly handles whitespace trimming and preserves escaped newlines in the right order.
1-4
: Consider resolving moduleResolution issues instead of copying code.While the implementation is properly attributed, copying code due to moduleResolution issues might lead to maintenance overhead and missed updates from the original package.
Let's verify if the moduleResolution issues can be resolved:
✅ Verification successful
🏁 Script executed:
#!/bin/bash # Check if dedent package is already listed in package.json if ! grep -q '"dedent":' package.json; then # Try installing dedent package to verify if it works npm install --save-dev dedent # Check TypeScript compilation npx tsc --noEmit fiLength of output: 1641
Module Resolution Conflict Prevents Switching from Local Implementation
The attempt to install the dedent package failed with a dependency resolution error related to ESLint and eslint-plugin-cypress. This confirms that the moduleResolution issues preventing the use of the package still exist. Therefore, until you update your dependency tree (e.g., upgrading ESLint to meet peer requirements) or adjust the conflicting packages, using the local implementation in
cypress/support/dedent.ts
remains the most viable workaround.
- The dedent package installation fails due to a peer dependency conflict (ESLint v8 vs. eslint-plugin-cypress expecting ESLint ≥9).
- Upgrading these dependencies might resolve the issue, but it could have wider implications.
- Retaining the local dedent implementation is acceptable for now given the current dependency constraints.
it('code is validated with TypeScript', () => { | ||
const tsErrorMessage = "Type 'string' is not assignable to type 'number'."; | ||
const script = 'let a = 1; a = ""'; | ||
cyp.setEditorContent(script); | ||
cy.wait(1000); // :( | ||
cy.dataCy(s.modal.editorCy) | ||
.find('textarea') | ||
.focus() | ||
// Followed instructions but does not work https://github.com/dmtrKovalenko/cypress-real-events?tab=readme-ov-file#installation | ||
// @ts-expect-error | ||
.realPress(['Alt', 'F8']); | ||
cy.contains(tsErrorMessage); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the noisy diff caused by refactoring, highlighting that here is the new test for this feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
cypress/e2e/laboratory/preflight.cy.ts (1)
267-292
:🧩 Analysis chain
Add security tests for header injection.
The current test suite verifies header substitution but doesn't validate against header injection attacks. Consider adding tests to ensure that malicious header values are properly sanitized.
Consider adding these test cases:
it('header placeholders are substituted with environment variables', () => { // ... existing test code ... }); + +it('prevents header injection attacks', () => { + cy.dataCy('toggle-preflight').click(); + cy.get('[data-name="headers"]').click(); + // Test with potentially malicious header values + cy.get('.graphiql-editor-tool .graphiql-editor:last-child textarea').type( + '{ "__test": "{{foo}}\r\nMalicious-Header: value" }', + { + force: true, + parseSpecialCharSequences: false, + } + ); + cy.dataCy('env-editor-mini').within(() => { + cy.get('textarea').type('{"foo":"injected"}', { + force: true, + parseSpecialCharSequences: false, + }); + }); + + // Verify that header injection is prevented + cy.intercept({ + method: 'POST', + headers: { + __test: 'injected\r\nMalicious-Header: value', + }, + }).as('post'); + cy.get('.graphiql-execute-button').click(); + cy.wait('@post'); +});
🏁 Script executed:
#!/bin/bash # Search for header sanitization in the codebase rg -A 5 'headers\.append|headers\.set' --type tsLength of output: 4757
Attention: Missing Security Validation for Header Injection
The current test in cypress/e2e/laboratory/preflight.cy.ts only verifies header substitution against environment variables and does not check for header injection scenarios. Our codebase (as seen with calls to headers.append and headers.set) lacks explicit sanitization checks against header injection attacks. Consider adding dedicated tests (for example, using malicious characters to attempt header injection) to ensure that the application properly escapes or sanitizes header values.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
cypress/e2e/laboratory/preflight.cy.ts
(16 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (10)
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: typescript / typecheck
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: storybook-preview / deployment
- GitHub Check: test / unit
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: alpha / cli-artifacts
- GitHub Check: SonarCloud
🔇 Additional comments (1)
cypress/e2e/laboratory/preflight.cy.ts (1)
1-7
: LGTM! Clean import refactoring.The imports have been refactored to use the new
cyLaboratory
namespace, and the code introduces clear aliases (s
andcyp
) for better readability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
package.json (2)
49-49
: New Script Addition: "test:e2e:local".
This script provides a clear and concise way to run Cypress tests against your local environment by explicitly setting CYPRESS_BASE_URL and RUN_AGAINST_LOCAL_SERVICES. It adheres to the PR's objective of improving local testing capabilities. Consider adding a brief note or updating your documentation (e.g., in a README) to inform developers about when and how to use this script.
80-80
: New Dev Dependency: "cypress-real-events".
Introducing "cypress-real-events" at version 1.14.0 is a good move for simulating realistic user interactions in your E2E tests—especially relevant given the enhancements to the laboratory editor validation. Ensure that its usage is clearly demonstrated in your test files and that any setup requirements (if not already documented) are communicated to your team.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (1)
package.json
(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (12)
- GitHub Check: storybook-preview / deployment
- GitHub Check: test / unit
- GitHub Check: typescript / typecheck
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: db-types / diff
- GitHub Check: test / db-migrations
- GitHub Check: alpha / cli-artifacts
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: SonarCloud
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
cypress/e2e/laboratory/preflight.cy.ts
(16 hunks)cypress/tsconfig.json
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (10)
- GitHub Check: alpha / cli-artifacts
- GitHub Check: typescript / typecheck
- GitHub Check: test / unit
- GitHub Check: storybook-preview / deployment
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: SonarCloud
🔇 Additional comments (3)
cypress/tsconfig.json (1)
5-5
: LGTM! Configuration updated correctly.The addition of "cypress-real-events" to the types array properly enables TypeScript support for the cypress-real-events library.
cypress/e2e/laboratory/preflight.cy.ts (2)
24-24
: LGTM! Well-organized test structure.The tests are logically grouped into clear describe blocks that separate different aspects of functionality:
- Preflight Tab
- Preflight Modal
- Execution
This organization makes the test suite easy to understand and maintain.
Also applies to: 45-45, 187-187
54-61
:⚠️ Potential issueReplace hardcoded wait with proper assertions.
The test has several potential issues:
- Using a hardcoded
cy.wait(1000)
is an anti-pattern in Cypress and could make the test flaky- The keyboard shortcut
Alt+F8
might not work consistently across different platformsApply this diff to make the test more robust:
it('code is validated with TypeScript', () => { const tsErrorMessage = "Type 'string' is not assignable to type 'number'."; const script = 'let a = 1; a = ""'; cyp.setEditorContent(script); - cy.wait(1000); // :( + // Wait for TypeScript validation to complete + cy.get(s.modal.editorCy).should('exist'); + cy.get('.monaco-editor').should('exist') + cy.get('.monaco-editor .error-widget').should('exist'); cy.dataCy(s.modal.editorCy) .find('textarea') .focus() .realPress(['Alt', 'F8']); - cy.contains(tsErrorMessage); + // Wait for error message to appear and verify it + cy.contains(tsErrorMessage).should('be.visible');Additionally, consider adding a comment explaining the keyboard shortcut's purpose and documenting any platform-specific considerations.
Likely invalid or redundant comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
cypress/e2e/laboratory/_cy.ts (2)
8-11
: Improve type safety when accessing CodeMirror instance.The current implementation uses type assertion to
any
which bypasses TypeScript's type checking. Consider adding proper type definitions for CodeMirror.+// Add at the top of the file +interface CodeMirrorEditor { + CodeMirror: { + setValue: (value: string) => void; + getValue: () => string; + }; +} export function updateEditorValue(value: string) { cy.get('.graphiql-query-editor .cm-s-graphiql').then($editor => { - const editor = ($editor[0] as any).CodeMirror; + const editor = ($editor[0] as CodeMirrorEditor).CodeMirror; editor.setValue(value); }); }Also applies to: 18-21
52-60
: Optimize tab closing logic to prevent potential stack overflow.The recursive implementation could cause stack overflow with many tabs. Consider using a loop instead.
export function closeTabsUntilOneLeft() { - cy.get('li.graphiql-tab').then($tabs => { - if ($tabs.length > 1) { - closeActiveTab(); - // Recurse until there's only one tab left - return closeTabsUntilOneLeft(); - } + cy.get('li.graphiql-tab').then(function closeTabs($tabs) { + if ($tabs.length <= 1) return; + closeActiveTab(); + cy.get('li.graphiql-tab').then(closeTabs); }); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (5)
cypress/e2e/laboratory/_cy.ts
(1 hunks)cypress/e2e/laboratory/preflight.cy.ts
(18 hunks)cypress/support/monaco.ts
(1 hunks)cypress/tsconfig.json
(1 hunks)package.json
(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- cypress/tsconfig.json
- cypress/support/monaco.ts
- package.json
⏰ Context from checks skipped due to timeout of 90000ms (10)
- GitHub Check: storybook-preview / deployment
- GitHub Check: alpha / cli-artifacts
- GitHub Check: test / unit
- GitHub Check: typescript / typecheck
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: SonarCloud
🔇 Additional comments (5)
cypress/e2e/laboratory/_cy.ts (2)
62-80
: LGTM! Well-organized selectors.The selectors are well-structured and follow a consistent naming convention.
84-93
: LGTM! Clean implementation of editor content management.The functions are well-organized and follow DRY principles.
cypress/e2e/laboratory/preflight.cy.ts (3)
53-60
: Replace hardcoded wait with proper assertions.The previous review comment about replacing the hardcoded wait with proper assertions is still valid.
23-44
: LGTM! Well-organized test structure.The tests are logically grouped with clear descriptions and consistent patterns.
173-183
: LGTM! Robust error handling tests.The error cases are well-covered with specific assertions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
cypress/e2e/laboratory/preflight.cy.ts (1)
53-61
: Document the TypeScript validation workaround.The test includes a hardcoded wait and keyboard shortcut that might be platform-dependent. While this is a known limitation (as per retrieved learnings), it should be documented more thoroughly.
const script = 'let a = 1; a = ""'; cyp.setEditorContent(script); - // Hack: Seemingly only way to reliably interact with the monaco text area from Cypress. + // HACK: Monaco editor's TypeScript validation is challenging to test in Cypress: + // 1. The hardcoded wait is necessary as there's no reliable way to detect when validation completes + // 2. The Alt+F8 shortcut might not work on all platforms (e.g., macOS) + // See: graphql-hive/console#6476 for more context cy.wait(1000); cy.dataCy(s.modal.editorCy).find('textarea').focus().realPress(['Alt', 'F8']); cy.contains(tsErrorMessage);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (1)
cypress/e2e/laboratory/preflight.cy.ts
(18 hunks)
🧰 Additional context used
📓 Learnings (1)
cypress/e2e/laboratory/preflight.cy.ts (1)
Learnt from: jasonkuhrt
PR: graphql-hive/console#6476
File: cypress/e2e/laboratory/preflight.cy.ts:0-0
Timestamp: 2025-02-06T19:32:05.091Z
Learning: TypeScript validation in Cypress tests for Monaco editor may require workarounds like hardcoded waits, as proper assertions may not work reliably.
⏰ Context from checks skipped due to timeout of 90000ms (10)
- GitHub Check: test / unit
- GitHub Check: typescript / typecheck
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: storybook-preview / deployment
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: alpha / cli-artifacts
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: SonarCloud
🔇 Additional comments (3)
cypress/e2e/laboratory/preflight.cy.ts (3)
1-6
: LGTM! Clean refactor of imports and selector references.The code has been improved by:
- Importing utilities from dedicated modules
- Using a consistent selector reference through
cyLaboratory.preflight.selectors
50-51
: LGTM! Consistent use of editor content setting methods.The code has been standardized to use
cyp.setEditorContent
andcyp.setEnvironmentEditorContent
throughout the test file, improving maintainability.Also applies to: 64-65, 76-77, 98-99, 154-155, 165-166, 175-176, 181-182, 195-196, 219-220, 247-251, 301-302, 328-334, 360-361, 379-387, 423-431
23-24
: LGTM! Improved test organization.The test suites have been renamed for better clarity:
- "Laboratory > Preflight Script" → "Preflight Tab"
- "Preflight Script Modal" → "Preflight Modal"
Also applies to: 44-45
@@ -0,0 +1,52 @@ | |||
export function dedent(strings: TemplateStringsArray, ...values: unknown[]): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the benefit of having dedent.ts
that exports dedent
function?
Why not just have libs.ts
or shared.ts
or similar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now when we change it's name to dedentString
we rename a file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and change ~5 imports and can loose git history if file rename is done incorrectly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find large modules that accumulate dozens of imports and thousands of lines that span various concerns difficult to cognitively navigate. Since the contents of these files change significantly more often than their file names, the readability gains have outweighed the diff loss for me.
If we could only write code in one file, I would try writing large comment section headers that divide areas of concern. Inline namespaces would be good too, but being only TS, not real ESM, there's always that tradeoff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me, a file with 500LOC and 20 functions is fine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to have a style guide, because it's not like we use X, but not Y, everywhere, always and that's the rule. We had 200 eslint rules, because somebody wanted to enforce patterns, and it did not work, was blocking progress, because the amount of time we spent on fighting the missing object destruction, was too annoying.
In general, we just start simple, see when it breaks, we do not try to predict future (imo it's always a failure, no matter how long you are on this world) and improve over time.
We had so many refactors, especially on the frontend that having to rename files was just super hard to track and most of the time the git history for a file, was gone. Maybe it did not happen to you, but it did to me, a few times in past 2 years.
You say that the content of the file changes more frequently that the file names. That's your assumption and based on my experience from this codebase, it's not true, not for frontend and not for tests.
Regarding the style. When I enter a new codebase, I look how people write it. You did see a chunk of the codebase already, and you can tell what the style is (I assume, because you worked on the CLI and probably looked at other pieces).
You see how Laboratory is written, yes it's not the best thing in the world, but not because it has 1 file instead of 5, or 3 components instead of 7, but rather the logic is hard to follow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mind refactors when they are necessary (like when you can't achieve something and it's blocking a new feature). Even when they are nice-to-have and we already delivered something to customers, but when we discuss it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all your insights on this project. You describe thresholds that I see crossed and you don't. For example the graphiql module's range of concerns is a some kind of blocking like factor for me. most things aren't actually blocking, we're talking about what it takes for a human to develop sustainably. What I see ahead is an approach leaning on code ownership rather than principals, which for me personally is a more confusing way to work. I like spontaneity and creativity but I have no agency to exercise that here so from a group perspective, if the cohesion is not high, then principals and rules thereof are the most transparent form of collaboration I think.
In regards to asking for permission to refactor things, I've taken note of that I understand the point. One downside for me is that there's need and opportunity for improvement in this project and a lot of that doesn't cross a need-threshold that matches the energy I have to summon to negotiate permission, especially in an async multi-timezone setup where what I would do according to my experience would require permission, waiting until tomorrow for a response in many cases (time zones), probably being told no, etc. So instead I just slog through repeatedly which is not satisfying.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To discuss it first, I mean, show it to the group to see if people like or not, or they see it necessary, or not. You mentions guidelines and rules, but then you have issues discussing something or to get an approval, to me it's conflicting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mention a downside I see to permission processes which is a kind of group level social organizing rule in lieu of (in this case) craft principals or rules that would obviate the need for such permission process in some degree of cases. I see no contradiction, hopefully that's clear.
🚀 Snapshot Release (
|
Package | Version | Info |
---|---|---|
@graphql-hive/cli |
0.48.2-alpha-20250212202247-08b3640040230552a4bb431c4b3ec75cfb725211 |
npm ↗︎ unpkg ↗︎ |
hive |
5.2.0-alpha-20250212202247-08b3640040230552a4bb431c4b3ec75cfb725211 |
npm ↗︎ unpkg ↗︎ |
@graphql-hive/federation-link-utils |
0.0.1 |
npm ↗︎ unpkg ↗︎ |
@n1ru4l Please let me know if refactors to the Cypress tests should also be undone in this PR, or if undoing just the app refactor is enough. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (5)
cypress/support/monaco.ts (1)
23-25
: Document platform-specific keyboard shortcut behavior.The keyboard shortcut
Alt+F8
might not work consistently across different operating systems.Add a comment explaining platform-specific considerations:
export function goToNextProblem(editorCyName: string) { + // Note: Alt+F8 is the default Monaco keyboard shortcut for "Go to Next Problem". + // This might need adjustment for different operating systems (e.g., Option+F8 on macOS). cy.dataCy(editorCyName).find('textarea').focus().realPress(['Alt', 'F8']); }cypress/e2e/laboratory/__cypress__.ts (1)
52-60
: Consider adding a safety check for infinite recursion.The recursive
closeTabsUntilOneLeft
function could potentially cause a stack overflow if the tab count doesn't decrease.Add a safety check:
export function closeTabsUntilOneLeft() { + let attempts = 0; + const maxAttempts = 100; // Adjust based on expected maximum number of tabs + + function closeTabsRecursive() { cy.get('li.graphiql-tab').then($tabs => { if ($tabs.length > 1) { + if (attempts++ > maxAttempts) { + throw new Error('Failed to close tabs after maximum attempts'); + } closeActiveTab(); - return closeTabsUntilOneLeft(); + return closeTabsRecursive(); } }); + } + + closeTabsRecursive(); }packages/web/app/src/lib/preflight/graphiql-plugin.tsx (1)
649-660
: Consider documenting compiler options choices.The compiler options are well-chosen but would benefit from documentation explaining the rationale.
Add comments explaining key choices:
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({ allowNonTsExtensions: true, allowJs: true, checkJs: true, + // Using ES2020 for modern JavaScript features while maintaining broad compatibility target: monaco.languages.typescript.ScriptTarget.ES2020, + // Using webworker lib as the script runs in a sandboxed environment lib: ['webworker'], + // Enabling strict mode and related checks for better error detection strict: true, noUnusedLocals: true, noUnusedParameters: true, noImplicitReturns: true, noFallthroughCasesInSwitch: true, });.changeset/funny-poets-hang.md (2)
5-9
: Enhance readability with proper punctuation and more details.The content is informative but needs some grammatical improvements:
-Also, the `WebWorker` runtime types are applied giving you confidence about what globals are available to you in your script. +Also, the `WebWorker` runtime types are applied, giving you confidence about what globals are available to you in your script. -However at this time we do not prevent script saving because of static type errors. Therefore your workflow should only at worst be visually impacted. +However, at this time we do not prevent script saving because of static type errors. Therefore, your workflow should only, at worst, be visually impacted.Consider adding an example of what kind of script code might now trigger static errors.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~5-~5: A comma might be missing here.
Context: ...Also, theWebWorker
runtime types are applied giving you confidence about what global...(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[uncategorized] ~9-~9: A comma may be missing after the conjunctive/linking adverb ‘However’.
Context: ...iously not statically errored will now. However at this time we do not prevent script s...(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
[uncategorized] ~9-~9: A comma may be missing after the conjunctive/linking adverb ‘Therefore’.
Context: ...t saving because of static type errors. Therefore your workflow should only at worst be v...(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
23-32
: Enhance code example relevance and clarity.Consider making the example more relevant to the WebWorker context and clarifying the difference between the two TypeScript directives:
-let a = 1; -let b = ''; +// Example with WebWorker-specific globals +let response = ''; +let headers = new Headers(); // @ts-ignore -a = b; +response = headers; // Silently ignores the type error // @ts-expect-error -a = b; +response = headers; // Will error if types become compatibleThis example better demonstrates the usage in the context of WebWorker globals while maintaining the explanation of TypeScript directives.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~32-~32: Possible missing comma found.
Context: ...ore, then the comment itself becomes an error whereas@ts-ignore
sits there quietly...(AI_HYDRA_LEO_MISSING_COMMA)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (8)
.changeset/funny-poets-hang.md
(1 hunks)cypress/e2e/laboratory/__cypress__.ts
(1 hunks)cypress/e2e/laboratory/collections.cy.ts
(9 hunks)cypress/e2e/laboratory/preflight.cy.ts
(17 hunks)cypress/e2e/laboratory/tabs.cy.ts
(2 hunks)cypress/support/monaco.ts
(1 hunks)package.json
(3 hunks)packages/web/app/src/lib/preflight/graphiql-plugin.tsx
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- cypress/e2e/laboratory/tabs.cy.ts
- package.json
- cypress/e2e/laboratory/collections.cy.ts
🧰 Additional context used
📓 Path-based instructions (1)
`.changeset/**`: A special folder with the files created/man...
.changeset/**
: A special folder with the files created/managed by Changesets tool.
In PRs that already includes this file, please make sure that the content of the markdown file includes:
- Full description of the change
- A link to the relevant GitHub issues (if any)
- Example with before/after
- If the change is of type
major
, please ensure that the content have content about migration with before/after.
.changeset/funny-poets-hang.md
🧠 Learnings (1)
cypress/e2e/laboratory/preflight.cy.ts (1)
Learnt from: jasonkuhrt
PR: graphql-hive/console#6476
File: cypress/e2e/laboratory/preflight.cy.ts:0-0
Timestamp: 2025-02-06T19:32:05.091Z
Learning: TypeScript validation in Cypress tests for Monaco editor may require workarounds like hardcoded waits, as proper assertions may not work reliably.
🪛 LanguageTool
.changeset/funny-poets-hang.md
[uncategorized] ~5-~5: A comma might be missing here.
Context: ...Also, the WebWorker
runtime types are applied giving you confidence about what global...
(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[uncategorized] ~9-~9: A comma may be missing after the conjunctive/linking adverb ‘However’.
Context: ...iously not statically errored will now. However at this time we do not prevent script s...
(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
[uncategorized] ~9-~9: A comma may be missing after the conjunctive/linking adverb ‘Therefore’.
Context: ...t saving because of static type errors. Therefore your workflow should only at worst be v...
(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
[uncategorized] ~32-~32: Possible missing comma found.
Context: ...ore, then the comment itself becomes an error whereas @ts-ignore
sits there quietly...
(AI_HYDRA_LEO_MISSING_COMMA)
⏰ Context from checks skipped due to timeout of 90000ms (11)
- GitHub Check: alpha / npm / snapshot
- GitHub Check: storybook-preview / deployment
- GitHub Check: typescript / typecheck
- GitHub Check: alpha / cli-artifacts
- GitHub Check: test / unit
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: SonarCloud
🔇 Additional comments (6)
cypress/support/monaco.ts (2)
5-21
: LGTM! Well-structured helper function for setting Monaco editor content.The function properly handles the Monaco editor instance lookup and includes appropriate error handling.
27-32
: Consider alternatives to hardcoded wait.The hardcoded wait of 1000ms is an anti-pattern in Cypress and could make tests flaky.
While the comment indicates this is a known limitation, let's verify if there are better alternatives:
✅ Verification successful
🌐 Web query:
What are the best practices for handling Monaco editor validation timing in Cypress tests?
💡 Result:
When handling validation timing in Monaco Editor during Cypress tests, implement these best practices to ensure reliable test execution:
1. Target Editor Elements Effectively
Use role-based selectors combined with Monaco's DOM structure:
cy.get('[role="code"]').first().click().type('{selectall}New content')This mimics real user interaction better than direct API calls[3][6].
2. Leverage Cypress Retry Mechanism
Add explicit assertions with custom timeouts:
cy.get('.suggest-widget', { timeout: 15000 }) .should('be.visible') .contains('Expected Validation Message')Cypress automatically retries until DOM elements meet specified conditions or timeout[2][6].
3. Avoid Static Waits
Replace arbitrary delays with dynamic validation:
// Anti-pattern cy.wait(5000) // Recommended cy.get('.monaco-editor') .should('contain', 'Expected Validation Text') .and('have.class', 'valid-state')4. Use Direct API Access Sparingly
For complex validation scenarios, access Monaco's API through Cypress:
cy.window().then((win) => { const model = win.monaco.editor.getModels()[0] expect(model.getValue()).to.include('expected content') })Reserve this for validation checks rather than interactions[3][9].
5. Handle Keyboard Interactions
Simulate real user input patterns:
cy.get('[role="code"]') .click() .type('{ctrl}a') // Select all .type('New content{enter}')6. Configure Timeout Settings
Adjust timeouts for Monaco-specific operations:
Cypress.config('defaultCommandTimeout', 10000)Validation Timing Strategies
Approach Use Case Example DOM Assertions Visual validation states cy.get('.error-marker').should('exist')
API Validation Content accuracy checks win.monaco.editor.getModel().getValue()
Network Stubbing Validate backend integration cy.intercept('POST', '/validate').as('validation')
Key Considerations:
- Use
data-testid
attributes for stable element targeting[6]- Clear editor state between tests using
beforeEach
hooks[4]- Combine visual assertions with content validation checks[2]
- Monitor network requests for validation callbacks[6]
These techniques address Monaco's dynamic rendering behavior while maintaining test reliability and execution speed[3][9]. For complex validation scenarios, consider combining DOM assertions with direct model checks through Monaco's API[3][9].
Citations:
- 1: https://www.youtube.com/watch?v=Uiab_UvJLVA
- 2: https://jignect.tech/maximizing-test-efficiency-with-cypress-best-practices-for-fast-reliable-results/
- 3: https://giacomocerquone.com/notes/monaco-playwright/
- 4: https://docs.cypress.io/app/core-concepts/best-practices
- 5: https://discuss.codemirror.net/t/cypress-and-codemirror-react/7525
- 6: https://www.lambdatest.com/blog/cypress-best-practices/
- 7: https://www.lambdatest.com/automation-testing-advisor/javascript/cypress-openProject.close
- 8: https://github.com/vuejs/awesome-vue?search=1
- 9: Monaco Issues with Cypress cypress-io/cypress#25685
- 10: https://gce-lter.marsci.uga.edu/public/app/biblio_results.asp?Library=GCE&SubjectMode=contains&URLs=yes&Order=year&SortOrder=DESC&Abstracts=yes&Format=&PageTitle=
Action: Replace Hardcoded Waits with Dynamic Assertions
The use of a static
cy.wait(waitMs)
is an anti-pattern in Cypress and can indeed lead to flaky tests. As confirmed by best practices for handling Monaco Editor timing in Cypress, it’s preferable to replace arbitrary delays with dynamic assertions. For example:
- Use DOM Assertions: Instead of a fixed wait, wait for a clear condition or DOM element to appear (e.g., using
cy.get('.monaco-editor').should('contain', 'expected content')
).- Leverage Cypress Retry: With explicit, expectation-based waits, Cypress can automatically retry until the condition is met.
- Utilize Editor API if Needed: In more complex scenarios, accessing Monaco’s API via
cy.window()
can provide additional state validation.These changes will improve test reliability by synchronizing the test flow with the actual application state, eliminating unnecessary wait times.
cypress/e2e/laboratory/__cypress__.ts (1)
62-94
: LGTM! Well-organized preflight namespace.The preflight namespace is well-structured with clear separation of selectors and editor functions.
cypress/e2e/laboratory/preflight.cy.ts (1)
54-57
: Document known limitation with Monaco editor validation.The test uses
nextProblemContains
which internally uses a hardcoded wait. While this is not ideal, it's a known limitation when testing Monaco editor validation.Add a comment to document this:
it('script is validated with TypeScript', () => { + // Note: Monaco editor validation timing is unpredictable in tests. + // Using nextProblemContains with a wait is a known workaround. cyPreflight.setScriptEditorContent('let a = 1; a = ""'); cyMonaco.nextProblemContains(selectors.modal.editorCy, "Type 'string' is not assignable to type 'number'."); // prettier-ignore });packages/web/app/src/lib/preflight/graphiql-plugin.tsx (1)
643-648
: LGTM! Comprehensive diagnostic options for JavaScript validation.The configuration enables all necessary validation features for a robust development experience.
.changeset/funny-poets-hang.md (1)
1-3
: LGTM! Version bump is appropriate.The 'minor' version bump correctly reflects the addition of TypeScript validation while maintaining backwards compatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
cypress/e2e/laboratory/preflight.cy.ts (1)
64-71
: 🛠️ Refactor suggestionReplace hardcoded wait with proper assertions.
The test uses a hardcoded
wait(1000)
, which is an anti-pattern in Cypress and could make the test flaky.Consider using Cypress's built-in retry-ability and assertions:
- cy.wait(1000); + // Wait for Monaco editor to be ready + cy.get(selectors.modal.scriptEditor).should('exist'); + cy.get('.monaco-editor').should('exist');
🧹 Nitpick comments (2)
cypress/e2e/laboratory/__cypress__.ts (1)
52-60
: Consider using a loop instead of recursion.The recursive implementation could be replaced with a loop for better readability and to avoid potential stack overflow with a large number of tabs.
- export function closeTabsUntilOneLeft() { - cy.get('li.graphiql-tab').then($tabs => { - if ($tabs.length > 1) { - closeActiveTab(); - // Recurse until there's only one tab left - return closeTabsUntilOneLeft(); - } - }); - } + export function closeTabsUntilOneLeft() { + cy.get('li.graphiql-tab').then($tabs => { + while ($tabs.length > 1) { + closeActiveTab(); + $tabs = Cypress.$('li.graphiql-tab'); + } + }); + }.changeset/funny-poets-hang.md (1)
5-5
: Fix missing commas in sentences.Add commas after conjunctive adverbs and in compound sentences:
-Also, the `WebWorker` runtime types are applied giving you confidence about what globals are available to you in your script. +Also, the `WebWorker` runtime types are applied, giving you confidence about what globals are available to you in your script. -However at this time we do not prevent script saving because of static type errors. Therefore your workflow should only at worst be visually impacted. +However, at this time we do not prevent script saving because of static type errors. Therefore, your workflow should only at worst be visually impacted.Also applies to: 9-9
🧰 Tools
🪛 LanguageTool
[uncategorized] ~5-~5: A comma might be missing here.
Context: ...Also, theWebWorker
runtime types are applied giving you confidence about what global...(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
.changeset/funny-poets-hang.md
(1 hunks)cypress/e2e/laboratory/__cypress__.ts
(1 hunks)cypress/e2e/laboratory/preflight.cy.ts
(17 hunks)cypress/support/monaco.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- cypress/support/monaco.ts
🧰 Additional context used
📓 Path-based instructions (1)
`.changeset/**`: A special folder with the files created/man...
.changeset/**
: A special folder with the files created/managed by Changesets tool.
In PRs that already includes this file, please make sure that the content of the markdown file includes:
- Full description of the change
- A link to the relevant GitHub issues (if any)
- Example with before/after
- If the change is of type
major
, please ensure that the content have content about migration with before/after.
.changeset/funny-poets-hang.md
🧠 Learnings (1)
cypress/e2e/laboratory/preflight.cy.ts (1)
Learnt from: jasonkuhrt
PR: graphql-hive/console#6476
File: cypress/e2e/laboratory/preflight.cy.ts:0-0
Timestamp: 2025-02-06T19:32:05.091Z
Learning: TypeScript validation in Cypress tests for Monaco editor may require workarounds like hardcoded waits, as proper assertions may not work reliably.
🪛 LanguageTool
.changeset/funny-poets-hang.md
[uncategorized] ~5-~5: A comma might be missing here.
Context: ...Also, the WebWorker
runtime types are applied giving you confidence about what global...
(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[uncategorized] ~9-~9: A comma may be missing after the conjunctive/linking adverb ‘However’.
Context: ...iously not statically errored will now. However at this time we do not prevent script s...
(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
[uncategorized] ~9-~9: A comma may be missing after the conjunctive/linking adverb ‘Therefore’.
Context: ...t saving because of static type errors. Therefore your workflow should only at worst be v...
(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
⏰ Context from checks skipped due to timeout of 90000ms (11)
- GitHub Check: alpha / npm / snapshot
- GitHub Check: test / unit
- GitHub Check: typescript / typecheck
- GitHub Check: storybook-preview / deployment
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: alpha / cli-artifacts
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: SonarCloud
🔇 Additional comments (2)
cypress/e2e/laboratory/__cypress__.ts (1)
8-11
: Add error handling for CodeMirror instance.The code uses type assertion without checking if the CodeMirror instance exists.
cypress/e2e/laboratory/preflight.cy.ts (1)
54-57
: LGTM! TypeScript validation test is well-implemented.The test effectively verifies that TypeScript type checking is working by asserting on the expected error message.
This may be related suren-atoyan/monaco-react#517 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🔭 Outside diff range comments (1)
cypress/e2e/laboratory/preflight.cy.ts (1)
71-476
: 💡 Verification agent🧩 Analysis chain
Ensure proper test isolation.
The tests share state through localStorage and environment variables. Consider:
- Clearing all shared state in
beforeEach
hooks- Using unique identifiers for each test to prevent interference
- Adding
afterEach
hooks to clean up any remaining state
🏁 Script executed:
#!/bin/bash # Check for potential state leaks between tests rg -A 5 'localStorage|environment' cypress/e2e/laboratory/Length of output: 5203
Test Isolation Needs Improvement
The tests exhibit shared state usage—evidenced by a call to
window.localStorage.setItem('hive:laboratory:environment', '{}');and multiple invocations to
lab.environment.set
. This indicates that state can persist across tests, potentially leading to interference. Consider the following improvements:
- BeforeEach Hooks: Reset shared state (e.g., clear localStorage and reset environment variables) at the start of each test.
- AfterEach Hooks: Clean up any state modifications to ensure tests remain independent.
- Unique Identifiers: Use unique identifiers or values for environment settings where applicable to avoid conflicts.
🧹 Nitpick comments (5)
cypress/e2e/laboratory/preflight.cy.ts (1)
54-70
: Consider adding more test cases for TypeScript validation.While the current tests cover basic scenarios, consider adding tests for:
- Complex type inference scenarios
- Multiple type errors in the same script
- Edge cases like
any
type usage- Global type definitions from the preflight context
packages/web/app/src/lib/preflight/graphiql-plugin.tsx (4)
641-677
: Document the module detection workaround.The module detection workaround uses a magic number (
3
) formoduleDetection
. This should be documented more clearly or use a proper enum value.Apply this diff to improve clarity:
- // This is a workaround. - // 3 = 'force' - // - // Problem: https://github.com/graphql-hive/console/pull/6476#issuecomment-2654056957 - // Solution: https://github.com/microsoft/monaco-editor/issues/2976#issuecomment-2334468503 - // Reference: https://www.typescriptlang.org/tsconfig/#moduleDetection - moduleDetection: 3, + // Force module detection to prevent errors with top-level 'this' and 'await' + // See: https://github.com/microsoft/monaco-editor/issues/2976#issuecomment-2334468503 + moduleDetection: monaco.languages.typescript.ModuleDetectionKind.Force,
649-667
: Consider making compiler options configurable.The TypeScript compiler options are hardcoded. Consider:
- Making them configurable through props
- Using environment variables for different environments
- Adding comments explaining the choice of options
604-833
: Optimize component performance.Consider these performance improvements:
- Memoize callback functions with
useCallback
- Use
useMemo
for complex computations- Split the component into smaller, more focused components
Example optimization:
+ const memoizedHandleMonacoEditorBeforeMount = useMemo( + () => (monaco: Monaco) => { + // Existing setup code + }, + [] + ); - beforeMount={handleMonacoEditorBeforeMount} + beforeMount={memoizedHandleMonacoEditorBeforeMount}
169-407
: Enhance error handling robustness.The error handling could be improved by:
- Adding timeouts for long-running operations
- Implementing retry logic for transient failures
- Adding more detailed error messages
Example implementation:
const EXECUTION_TIMEOUT = 30000; // 30 seconds async function execute(script: string, isPreview = false): Promise<PreflightResultData> { const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Execution timeout')), EXECUTION_TIMEOUT); }); try { const result = await Promise.race([executeScript(script, isPreview), timeoutPromise]); return result; } catch (error) { if (error instanceof Error) { setLogs(prev => [ ...prev, { level: 'error', message: `Execution failed: ${error.message}`, }, ]); } throw error; } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (3)
cypress/e2e/laboratory/preflight.cy.ts
(17 hunks)cypress/support/monaco.ts
(1 hunks)packages/web/app/src/lib/preflight/graphiql-plugin.tsx
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- cypress/support/monaco.ts
🧰 Additional context used
🧠 Learnings (1)
cypress/e2e/laboratory/preflight.cy.ts (1)
Learnt from: jasonkuhrt
PR: graphql-hive/console#6476
File: cypress/e2e/laboratory/preflight.cy.ts:0-0
Timestamp: 2025-02-06T19:32:05.091Z
Learning: TypeScript validation in Cypress tests for Monaco editor may require workarounds like hardcoded waits, as proper assertions may not work reliably.
⏰ Context from checks skipped due to timeout of 90000ms (11)
- GitHub Check: alpha / npm / snapshot
- GitHub Check: test / unit
- GitHub Check: storybook-preview / deployment
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: alpha / cli-artifacts
- GitHub Check: typescript / typecheck
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: SonarCloud
🔇 Additional comments (1)
cypress/e2e/laboratory/preflight.cy.ts (1)
1-22
: Well-structured imports and setup!The code demonstrates good organization with clear separation of concerns. The use of the
cyLaboratory
namespace improves modularity and maintainability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
cypress/e2e/laboratory/preflight.cy.ts (2)
33-34
: Consider using a more robust wait strategy.Instead of waiting for text to disappear, consider waiting for a specific state or element attribute.
- // Wait loading disappears - cy.dataCy('preflight-editor-mini').should('not.contain', 'Loading'); + // Wait for editor to be ready + cy.dataCy('preflight-editor-mini').should('have.attr', 'data-ready', 'true');
407-410
: Document the force click workaround.Add a more detailed comment explaining why the force click is necessary and any potential risks.
- // it's because the button is not fully visible on the screen + // Force click is required because the button might be partially obscured by other elements. + // This is a known limitation of the current UI layout and has been verified as safe. force: true,
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
cypress/e2e/laboratory/preflight.cy.ts
(17 hunks)cypress/support/e2e.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- cypress/support/e2e.ts
🧰 Additional context used
🧠 Learnings (1)
cypress/e2e/laboratory/preflight.cy.ts (1)
Learnt from: jasonkuhrt
PR: graphql-hive/console#6476
File: cypress/e2e/laboratory/preflight.cy.ts:0-0
Timestamp: 2025-02-06T19:32:05.091Z
Learning: TypeScript validation in Cypress tests for Monaco editor may require workarounds like hardcoded waits, as proper assertions may not work reliably.
⏰ Context from checks skipped due to timeout of 90000ms (11)
- GitHub Check: alpha / npm / snapshot
- GitHub Check: test / unit
- GitHub Check: storybook-preview / deployment
- GitHub Check: typescript / typecheck
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: alpha / cli-artifacts
- GitHub Check: SonarCloud
🔇 Additional comments (5)
cypress/e2e/laboratory/preflight.cy.ts (5)
1-8
: LGTM! Clean import organization and setup.The imports are well-organized, and the new utility constants improve code maintainability by centralizing selectors and preflight-related functionality.
54-62
: Well-structured TypeScript validation tests.The new tests effectively validate both TypeScript type checking and syntax restrictions, aligning with the PR's objective to improve editor content validation.
Note: The use of
cyMonaco.nextProblemContains
is a good approach to handle Monaco editor's asynchronous validation.
64-70
: Good regression test for validation state.The test ensures that previous validation states are cleared when reopening the editor, preventing stale error messages from persisting.
51-51
: Consistent use of the new editor content setting methods.The refactor successfully standardizes the use of
cyPreflight.setScriptEditorContent
andcyPreflight.setEnvironmentEditorContent
across all test cases, improving maintainability.Also applies to: 73-73, 85-85, 89-89, 112-112, 140-140, 163-163, 174-174, 184-184, 190-190, 204-204, 230-230, 260-260, 314-314, 341-341, 373-373, 374-374, 392-392, 436-436
24-24
: Clear and descriptive test organization.The test suite is well-organized with clear describe blocks that accurately represent the functionality being tested:
- "Preflight Tab" for tab-specific functionality
- "Preflight Modal" for modal-specific features
Also applies to: 45-45
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
cypress/e2e/laboratory/preflight.cy.ts (1)
196-476
: Consider adding error case tests for header manipulation.While the execution tests are comprehensive, consider adding tests for:
- Invalid header values
- Malformed environment variables
- Network failures during header substitution
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
cypress/e2e/laboratory/preflight.cy.ts
(17 hunks)
🧰 Additional context used
🧠 Learnings (1)
cypress/e2e/laboratory/preflight.cy.ts (1)
Learnt from: jasonkuhrt
PR: graphql-hive/console#6476
File: cypress/e2e/laboratory/preflight.cy.ts:0-0
Timestamp: 2025-02-06T19:32:05.091Z
Learning: TypeScript validation in Cypress tests for Monaco editor may require workarounds like hardcoded waits, as proper assertions may not work reliably.
⏰ Context from checks skipped due to timeout of 90000ms (10)
- GitHub Check: alpha / npm / snapshot
- GitHub Check: typescript / typecheck
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: storybook-preview / deployment
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: alpha / cli-artifacts
- GitHub Check: SonarCloud
🔇 Additional comments (4)
cypress/e2e/laboratory/preflight.cy.ts (4)
1-7
: LGTM! Well-structured imports and namespace organization.The refactoring improves modularity by separating concerns into dedicated modules (
dedent
,cyMonaco
,cyLaboratory
).
24-43
: LGTM! Comprehensive test coverage for the Preflight Tab.Tests effectively cover regression cases and validate read-only behavior of the mini editor.
54-70
: LGTM! Comprehensive TypeScript validation tests.The tests effectively verify:
- Type checking functionality
- Prevention of TypeScript syntax
- Proper clearing of validation state
51-51
: LGTM! Consistent use of cyPreflight methods.The refactoring consistently uses
cyPreflight.setScriptEditorContent
andcyPreflight.setEnvironmentEditorContent
across all tests, improving maintainability.Also applies to: 73-73, 85-85, 89-89, 112-112, 140-140, 163-163, 174-174, 184-184, 190-190, 204-204, 230-230, 260-260, 314-314, 341-341, 373-373, 392-392, 436-436
Background
This brings TypeScript validation to the laboratory editor so that users have a better experience writing code, because the compiler will catch more of their mistakes for them.
Description
Monaco React has built in support for this so not much doing was needed.
Checklist