{
  "manifest_version": "1.0.0",
  "template": {
    "id": "36cff9a2-a0cd-4ffe-861d-8c8febc094cc",
    "slug": "railway-functions-graphql-blog",
    "name": "Functions GraphQL Blog",
    "description": "A full-stack blog project with a react app, a pothos api and mongo database",
    "url": "https://railway.com/deploy/railway-functions-graphql-blog",
    "upstream": {
      "image": "ghcr.io/railwayapp/function-bun:1.3.0"
    }
  },
  "services": [
    {
      "name": "MongoDB",
      "source": {
        "image": "mongo:8.0"
      },
      "needs_volume": true,
      "volume_mount_path": "/data/db",
      "tcp_ports": [
        27017
      ],
      "http": false
    },
    {
      "name": "graphql-api",
      "source": {
        "image": "ghcr.io/railwayapp/function-bun:1.3.0"
      },
      "needs_volume": false,
      "http": true
    },
    {
      "name": "frontend",
      "source": {
        "image": "ghcr.io/railwayapp/function-bun:1.3.0"
      },
      "needs_volume": false,
      "http": true
    }
  ],
  "required_inputs": [
    {
      "key": "MONGOHOST",
      "service": "MongoDB",
      "description": "Railway Private Domain Name.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "MONGOPORT",
      "service": "MongoDB",
      "description": "MongoDB Port.",
      "secret": false,
      "strategy": "default",
      "default": "27017"
    },
    {
      "key": "MONGOUSER",
      "service": "MongoDB",
      "description": "Mongodb user.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "MONGO_URL",
      "service": "MongoDB",
      "description": "Private URL to connect to MongoDB.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "MONGOPASSWORD",
      "service": "MongoDB",
      "description": "Root password.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "MONGO_PUBLIC_URL",
      "service": "MongoDB",
      "description": "Public URL to connect to MongoDB, used for Data panel.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "MONGO_INITDB_ROOT_PASSWORD",
      "service": "MongoDB",
      "description": "Root user password, set during initialization.",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "MONGO_INITDB_ROOT_USERNAME",
      "service": "MongoDB",
      "description": "User created during initialization, given the root role.",
      "secret": false,
      "strategy": "default",
      "default": "mongo"
    },
    {
      "key": "MONGO_URL",
      "service": "graphql-api",
      "description": "Your database's connection URL",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PORT",
      "service": "frontend",
      "description": "Provide a value for PORT.",
      "secret": false,
      "strategy": "default",
      "default": "3000"
    },
    {
      "key": "API_URL",
      "service": "frontend",
      "description": "A reference-based URL of your api",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    }
  ],
  "deploy": {
    "mcp": {
      "server": "railway",
      "tool": "deploy_template",
      "args": {
        "template_code": "railway-functions-graphql-blog"
      }
    },
    "cli": "railway deploy --template railway-functions-graphql-blog",
    "api": {
      "method": "POST",
      "path": "/graphql/v2",
      "body": {
        "query": "mutation templateDeploy($input: TemplateDeployV2Input!) { templateDeployV2(input: $input) { projectId workflowId } }",
        "variables": {
          "input": {
            "templateId": "36cff9a2-a0cd-4ffe-861d-8c8febc094cc",
            "serializedConfig": {
              "services": {
                "6d253bed-85b1-40f8-abfd-04c16503ea63": {
                  "icon": "https://devicons.railway.app/i/mongodb.svg",
                  "name": "MongoDB",
                  "build": {},
                  "deploy": {
                    "startCommand": "docker-entrypoint.sh mongod --ipv6 --bind_ip ::,0.0.0.0 --setParameter diagnosticDataCollectionEnabled=false",
                    "requiredMountPath": "/data/db"
                  },
                  "source": {
                    "image": "mongo:8.0"
                  },
                  "variables": {
                    "MONGOHOST": {
                      "isOptional": false,
                      "description": "Railway Private Domain Name.",
                      "defaultValue": "${{ RAILWAY_PRIVATE_DOMAIN }}"
                    },
                    "MONGOPORT": {
                      "isOptional": false,
                      "description": "MongoDB Port.",
                      "defaultValue": "27017"
                    },
                    "MONGOUSER": {
                      "isOptional": false,
                      "description": "Mongodb user.",
                      "defaultValue": "${{ MONGO_INITDB_ROOT_USERNAME }}"
                    },
                    "MONGO_URL": {
                      "isOptional": false,
                      "description": "Private URL to connect to MongoDB.",
                      "defaultValue": "mongodb://${{MONGO_INITDB_ROOT_USERNAME}}:${{MONGO_INITDB_ROOT_PASSWORD}}@${{RAILWAY_PRIVATE_DOMAIN}}:27017"
                    },
                    "MONGOPASSWORD": {
                      "isOptional": false,
                      "description": "Root password.",
                      "defaultValue": "${{ MONGO_INITDB_ROOT_PASSWORD }}"
                    },
                    "MONGO_PUBLIC_URL": {
                      "description": "Public URL to connect to MongoDB, used for Data panel.",
                      "defaultValue": "mongodb://${{MONGO_INITDB_ROOT_USERNAME}}:${{MONGO_INITDB_ROOT_PASSWORD}}@${{RAILWAY_TCP_PROXY_DOMAIN}}:${{RAILWAY_TCP_PROXY_PORT}}"
                    },
                    "MONGO_INITDB_ROOT_PASSWORD": {
                      "isOptional": false,
                      "description": "Root user password, set during initialization.",
                      "defaultValue": "{{MONGO_INITDB_ROOT_PASSWORD}}"
                    },
                    "MONGO_INITDB_ROOT_USERNAME": {
                      "isOptional": false,
                      "description": "User created during initialization, given the root role.",
                      "defaultValue": "mongo"
                    }
                  },
                  "networking": {
                    "tcpProxies": {
                      "27017": {}
                    },
                    "serviceDomains": {}
                  },
                  "volumeMounts": {
                    "2431ba6b-248f-4466-bf09-0f9d5f5d90c3": {
                      "mountPath": "/data/db"
                    }
                  }
                },
                "75fd14d2-47d9-45ce-abff-4c560a7017b8": {
                  "icon": "https://emoji.aranja.com/emojis/apple/1fab4.png",
                  "name": "graphql-api",
                  "deploy": {
                    "startCommand": "./run.sh aW1wb3J0IHsgY3JlYXRlWW9nYSB9IGZyb20gImdyYXBocWwteW9nYSI7CmltcG9ydCB7IGNyZWF0ZVNlcnZlciB9IGZyb20gIm5vZGU6aHR0cCI7CmltcG9ydCBTY2hlbWFCdWlsZGVyIGZyb20gIkBwb3Rob3MvY29yZSI7CmltcG9ydCB7IE1vbmdvQ2xpZW50LCBPYmplY3RJZCB9IGZyb20gIm1vbmdvZGIiOwppbXBvcnQgeyBuYW5vaWQgfSBmcm9tICJuYW5vaWQiOwoKdHlwZSBEYlVzZXIgPSB7CiAgX2lkOiBzdHJpbmcgfCBPYmplY3RJZDsKICBuYW1lOiBzdHJpbmc7CiAgZW1haWw6IHN0cmluZzsKfTsKCnR5cGUgRGJQb3N0ID0gewogIF9pZDogc3RyaW5nIHwgT2JqZWN0SWQ7CiAgdGl0bGU6IHN0cmluZzsKICBjb250ZW50OiBzdHJpbmc7CiAgYXV0aG9ySWQ6IHN0cmluZzsKfTsKCi8vIFNtYWxsIHV0aWwgdG8ga2VlcCBtb25nb2RiIGhhcHB5IGFzIHRoZXkgdXNlIGEgY3VzdG9tIHR5cGUgZm9yIHRoZSBfaWQgZmllbGQKZnVuY3Rpb24gZW5zdXJlT2JqZWN0SWQoaWQ6IHN0cmluZyB8IE9iamVjdElkKTogT2JqZWN0SWQgewogIHJldHVybiBpZCBhcyB1bmtub3duIGFzIE9iamVjdElkOwp9CgovLyBTZXR1cCBvdXIgTW9uZ29EQiBjbGllbnQKY29uc3QgbW9uZ29DbGllbnQgPSBuZXcgTW9uZ29DbGllbnQocHJvY2Vzcy5lbnYuTU9OR09fVVJMKTsKYXdhaXQgbW9uZ29DbGllbnQuY29ubmVjdCgpOwpjb25zdCBkYiA9IG1vbmdvQ2xpZW50LmRiKCJyYWlsd2F5Iik7CgovLyBTZXR1cCBjb2xsZWN0aW9ucwpjb25zdCB1c2Vyc0NvbGxlY3Rpb24gPSBkYi5jb2xsZWN0aW9uKCJ1c2VycyIpOwpjb25zdCBwb3N0c0NvbGxlY3Rpb24gPSBkYi5jb2xsZWN0aW9uKCJwb3N0cyIpOwoKLy8gU2VlZCBkYXRhCmNvbnN0IHVzZXJDb3VudCA9IGF3YWl0IHVzZXJzQ29sbGVjdGlvbi5jb3VudERvY3VtZW50cygpOwppZiAodXNlckNvdW50ID09PSAwKSB7CiAgYXdhaXQgdXNlcnNDb2xsZWN0aW9uLmluc2VydE1hbnkoWwogICAgewogICAgICBfaWQ6IGVuc3VyZU9iamVjdElkKCIxIiksCiAgICAgIG5hbWU6ICJCb2IiLAogICAgICBlbWFpbDogImJvYkBleGFtcGxlLmNvbSIsCiAgICB9LAogICAgewogICAgICBfaWQ6IGVuc3VyZU9iamVjdElkKCIyIiksCiAgICAgIG5hbWU6ICJBbGljZSIsCiAgICAgIGVtYWlsOiAiYWxpY2VAZXhhbXBsZS5jb20iLAogICAgfSwKICBdIHNhdGlzZmllcyBEYlVzZXJbXSk7Cn0KY29uc3QgcG9zdENvdW50ID0gYXdhaXQgcG9zdHNDb2xsZWN0aW9uLmNvdW50RG9jdW1lbnRzKCk7CmlmIChwb3N0Q291bnQgPT09IDApIHsKICBhd2FpdCBwb3N0c0NvbGxlY3Rpb24uaW5zZXJ0TWFueShbCiAgICB7CiAgICAgIF9pZDogZW5zdXJlT2JqZWN0SWQoIjEiKSwKICAgICAgdGl0bGU6ICJHZXR0aW5nIFN0YXJ0ZWQgd2l0aCBHcmFwaFFMIiwKICAgICAgY29udGVudDoKICAgICAgICAiR3JhcGhRTCBpcyBhIHF1ZXJ5IGxhbmd1YWdlIGZvciBBUElzLCBhbGxvd2luZyBlbmQtdG8tZW5kIHR5cGUgc2FmZXR5LiIsCiAgICAgIGF1dGhvcklkOiAiMSIsCiAgICB9LAogICAgewogICAgICBfaWQ6IGVuc3VyZU9iamVjdElkKCIyIiksCiAgICAgIHRpdGxlOiAiUG90aG9zIEdyYXBoUUwgR3VpZGUiLAogICAgICBjb250ZW50OgogICAgICAgICJQb3Rob3MgbWFrZXMgYnVpbGRpbmcgR3JhcGhRTCBzY2hlbWFzIGVhc3ksIGZhc3QgYW5kIGVuam95YWJsZS4iLAogICAgICBhdXRob3JJZDogIjIiLAogICAgfSwKICBdIHNhdGlzZmllcyBEYlBvc3RbXSk7Cn0KCmNvbnN0IGJ1aWxkZXIgPSBuZXcgU2NoZW1hQnVpbGRlcih7fSk7CgovLyBEZWZpbmUgVXNlciBHUUwKdHlwZSBVc2VyID0gRGJVc2VyICYgewogIGlzV3JpdGVyOiBib29sZWFuOwp9Owpjb25zdCBVc2VyUmVmID0gYnVpbGRlci5vYmplY3RSZWY8VXNlcj4oIlVzZXIiKTsKVXNlclJlZi5pbXBsZW1lbnQoewogIGRlc2NyaXB0aW9uOiAiQSB1c2VyIG9mIG91ciBibG9nLiIsCiAgZmllbGRzOiAodCkgPT4gKHsKICAgIF9pZDogdC5maWVsZCh7CiAgICAgIHR5cGU6ICJTdHJpbmciLAogICAgICByZXNvbHZlOiAodXNlcikgPT4gdXNlci5faWQudG9TdHJpbmcoKSwKICAgIH0pLAogICAgbmFtZTogdC5leHBvc2VTdHJpbmcoIm5hbWUiKSwKICAgIGVtYWlsOiB0LmV4cG9zZVN0cmluZygiZW1haWwiKSwKICAgIGlzV3JpdGVyOiB0LmZpZWxkKHsKICAgICAgdHlwZTogIkJvb2xlYW4iLAogICAgICByZXNvbHZlOiBhc3luYyAodXNlcikgPT4gewogICAgICAgIGNvbnN0IHBvc3RGcm9tVXNlciA9IGF3YWl0IHBvc3RzQ29sbGVjdGlvbi5maW5kT25lKHsKICAgICAgICAgIGF1dGhvcklkOiB1c2VyLl9pZC50b1N0cmluZygpLAogICAgICAgIH0pOwoKICAgICAgICByZXR1cm4gISFwb3N0RnJvbVVzZXI7CiAgICAgIH0sCiAgICB9KSwKICAgIHBvc3RzOiB0LmZpZWxkKHsKICAgICAgdHlwZTogW1Bvc3RSZWZdLAogICAgICByZXNvbHZlOiBhc3luYyAodXNlcikgPT4gewogICAgICAgIGNvbnN0IHBvc3RzID0gYXdhaXQgcG9zdHNDb2xsZWN0aW9uCiAgICAgICAgICAuZmluZCh7IGF1dGhvcklkOiB1c2VyLl9pZC50b1N0cmluZygpIH0pCiAgICAgICAgICAudG9BcnJheSgpOwogICAgICAgIHJldHVybiBwb3N0cyBhcyBQb3N0W107CiAgICAgIH0sCiAgICB9KSwKICB9KSwKfSk7CgovLyBEZWZpbmUgUG9zdCBHUUwKdHlwZSBQb3N0ID0gRGJQb3N0ICYgewogIGF1dGhvcjogVXNlcjsKfTsKY29uc3QgUG9zdFJlZiA9IGJ1aWxkZXIub2JqZWN0UmVmPFBvc3Q+KCJQb3N0Iik7ClBvc3RSZWYuaW1wbGVtZW50KHsKICBkZXNjcmlwdGlvbjogIkEgYmxvZyBwb3N0LiIsCiAgZmllbGRzOiAodCkgPT4gKHsKICAgIF9pZDogdC5maWVsZCh7CiAgICAgIHR5cGU6ICJTdHJpbmciLAogICAgICByZXNvbHZlOiAocG9zdCkgPT4gcG9zdC5faWQudG9TdHJpbmcoKSwKICAgIH0pLAogICAgdGl0bGU6IHQuZXhwb3NlU3RyaW5nKCJ0aXRsZSIpLAogICAgY29udGVudDogdC5leHBvc2VTdHJpbmcoImNvbnRlbnQiKSwKICAgIGF1dGhvcjogdC5maWVsZCh7CiAgICAgIHR5cGU6IFVzZXJSZWYsCiAgICAgIHJlc29sdmU6IGFzeW5jIChwb3N0KSA9PiB7CiAgICAgICAgY29uc3QgdXNlciA9IGF3YWl0IHVzZXJzQ29sbGVjdGlvbi5maW5kT25lKHsKICAgICAgICAgIF9pZDogZW5zdXJlT2JqZWN0SWQocG9zdC5hdXRob3JJZCksCiAgICAgICAgfSk7CiAgICAgICAgaWYgKCF1c2VyKSB0aHJvdyBuZXcgRXJyb3IoIkF1dGhvciBub3QgZm91bmQiKTsKICAgICAgICByZXR1cm4geyAuLi51c2VyLCBpc1dyaXRlcjogdHJ1ZSB9IGFzIFVzZXI7CiAgICAgIH0sCiAgICB9KSwKICB9KSwKfSk7CgovLyBJbnB1dCB0eXBlcwpjb25zdCBDcmVhdGVVc2VySW5wdXQgPSBidWlsZGVyLmlucHV0VHlwZSgiQ3JlYXRlVXNlcklucHV0IiwgewogIGZpZWxkczogKHQpID0+ICh7CiAgICBuYW1lOiB0LnN0cmluZyh7IHJlcXVpcmVkOiB0cnVlIH0pLAogICAgZW1haWw6IHQuc3RyaW5nKHsgcmVxdWlyZWQ6IHRydWUgfSksCiAgfSksCn0pOwoKY29uc3QgQ3JlYXRlUG9zdElucHV0ID0gYnVpbGRlci5pbnB1dFR5cGUoIkNyZWF0ZVBvc3RJbnB1dCIsIHsKICBmaWVsZHM6ICh0KSA9PiAoewogICAgdGl0bGU6IHQuc3RyaW5nKHsgcmVxdWlyZWQ6IHRydWUgfSksCiAgICBjb250ZW50OiB0LnN0cmluZyh7IHJlcXVpcmVkOiB0cnVlIH0pLAogICAgYXV0aG9ySWQ6IHQuc3RyaW5nKHsgcmVxdWlyZWQ6IHRydWUgfSksCiAgfSksCn0pOwoKLy8gUXVlcnkgdHlwZQpidWlsZGVyLnF1ZXJ5VHlwZSh7CiAgZmllbGRzOiAodCkgPT4gKHsKICAgIGhlbGxvOiB0LnN0cmluZyh7CiAgICAgIGFyZ3M6IHsKICAgICAgICBuYW1lOiB0LmFyZy5zdHJpbmcoKSwKICAgICAgfSwKICAgICAgcmVzb2x2ZTogKHBhcmVudCwgeyBuYW1lIH0pID0+IGBoZWxsbywgJHtuYW1lIHx8ICJXb3JsZCJ9YCwKICAgIH0pLAogICAgcG9zdHM6IHQuZmllbGQoewogICAgICB0eXBlOiBbUG9zdFJlZl0sCiAgICAgIHJlc29sdmU6IGFzeW5jICgpID0+IHsKICAgICAgICBjb25zdCBwb3N0cyA9IGF3YWl0IHBvc3RzQ29sbGVjdGlvbi5maW5kKHt9KS50b0FycmF5KCk7CiAgICAgICAgcmV0dXJuIHBvc3RzIGFzIFBvc3RbXTsKICAgICAgfSwKICAgIH0pLAogICAgcG9zdDogdC5maWVsZCh7CiAgICAgIHR5cGU6IFBvc3RSZWYsCiAgICAgIG51bGxhYmxlOiB0cnVlLAogICAgICBhcmdzOiB7CiAgICAgICAgaWQ6IHQuYXJnLnN0cmluZyh7IHJlcXVpcmVkOiB0cnVlIH0pLAogICAgICB9LAogICAgICByZXNvbHZlOiBhc3luYyAoXywgeyBpZCB9KSA9PiB7CiAgICAgICAgY29uc3QgcG9zdCA9IGF3YWl0IHBvc3RzQ29sbGVjdGlvbi5maW5kT25lKHsgX2lkOiBlbnN1cmVPYmplY3RJZChpZCkgfSk7CiAgICAgICAgcmV0dXJuIHBvc3QgYXMgUG9zdCB8IG51bGw7CiAgICAgIH0sCiAgICB9KSwKICAgIHVzZXI6IHQuZmllbGQoewogICAgICB0eXBlOiBVc2VyUmVmLAogICAgICBudWxsYWJsZTogdHJ1ZSwKICAgICAgYXJnczogewogICAgICAgIGlkOiB0LmFyZy5zdHJpbmcoeyByZXF1aXJlZDogdHJ1ZSB9KSwKICAgICAgfSwKICAgICAgcmVzb2x2ZTogYXN5bmMgKF8sIHsgaWQgfSkgPT4gewogICAgICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB1c2Vyc0NvbGxlY3Rpb24uZmluZE9uZSh7IF9pZDogZW5zdXJlT2JqZWN0SWQoaWQpIH0pOwogICAgICAgIGlmICghdXNlcikgcmV0dXJuIG51bGw7CiAgICAgICAgcmV0dXJuIHsgLi4udXNlciwgaXNXcml0ZXI6IHRydWUgfSBhcyBVc2VyOwogICAgICB9LAogICAgfSksCiAgICB1c2VyczogdC5maWVsZCh7CiAgICAgIHR5cGU6IFtVc2VyUmVmXSwKICAgICAgcmVzb2x2ZTogYXN5bmMgKCkgPT4gewogICAgICAgIGNvbnN0IHVzZXJzID0gYXdhaXQgdXNlcnNDb2xsZWN0aW9uLmZpbmQoe30pLnRvQXJyYXkoKTsKICAgICAgICByZXR1cm4gdXNlcnMubWFwKCh1c2VyKSA9PiAoeyAuLi51c2VyLCBpc1dyaXRlcjogdHJ1ZSB9KSkgYXMgVXNlcltdOwogICAgICB9LAogICAgfSksCiAgfSksCn0pOwoKLy8gTXV0YXRpb24gdHlwZQpidWlsZGVyLm11dGF0aW9uVHlwZSh7CiAgZmllbGRzOiAodCkgPT4gKHsKICAgIGNyZWF0ZVVzZXI6IHQuZmllbGQoewogICAgICB0eXBlOiBVc2VyUmVmLAogICAgICBhcmdzOiB7CiAgICAgICAgaW5wdXQ6IHQuYXJnKHsgdHlwZTogQ3JlYXRlVXNlcklucHV0LCByZXF1aXJlZDogdHJ1ZSB9KSwKICAgICAgfSwKICAgICAgcmVzb2x2ZTogYXN5bmMgKF8sIHsgaW5wdXQgfSkgPT4gewogICAgICAgIGNvbnN0IG5ld1VzZXIgPSB7CiAgICAgICAgICBfaWQ6IGVuc3VyZU9iamVjdElkKG5hbm9pZCgpKSwKICAgICAgICAgIG5hbWU6IGlucHV0Lm5hbWUsCiAgICAgICAgICBlbWFpbDogaW5wdXQuZW1haWwsCiAgICAgICAgfSBzYXRpc2ZpZXMgRGJVc2VyOwogICAgICAgIGF3YWl0IHVzZXJzQ29sbGVjdGlvbi5pbnNlcnRPbmUobmV3VXNlcik7CiAgICAgICAgcmV0dXJuIG5ld1VzZXIgYXMgVXNlcjsKICAgICAgfSwKICAgIH0pLAogICAgY3JlYXRlUG9zdDogdC5maWVsZCh7CiAgICAgIHR5cGU6IFBvc3RSZWYsCiAgICAgIGFyZ3M6IHsKICAgICAgICBpbnB1dDogdC5hcmcoeyB0eXBlOiBDcmVhdGVQb3N0SW5wdXQsIHJlcXVpcmVkOiB0cnVlIH0pLAogICAgICB9LAogICAgICByZXNvbHZlOiBhc3luYyAoXywgeyBpbnB1dCB9KSA9PiB7CiAgICAgICAgY29uc3QgbmV3UG9zdCA9IHsKICAgICAgICAgIF9pZDogZW5zdXJlT2JqZWN0SWQobmFub2lkKCkpLAogICAgICAgICAgdGl0bGU6IGlucHV0LnRpdGxlLAogICAgICAgICAgY29udGVudDogaW5wdXQuY29udGVudCwKICAgICAgICAgIGF1dGhvcklkOiBpbnB1dC5hdXRob3JJZCwKICAgICAgICB9IHNhdGlzZmllcyBEYlBvc3Q7CiAgICAgICAgYXdhaXQgcG9zdHNDb2xsZWN0aW9uLmluc2VydE9uZShuZXdQb3N0KTsKICAgICAgICByZXR1cm4gbmV3UG9zdCBhcyBQb3N0OwogICAgICB9LAogICAgfSksCiAgICBkZWxldGVQb3N0OiB0LmZpZWxkKHsKICAgICAgdHlwZTogIkJvb2xlYW4iLAogICAgICBhcmdzOiB7CiAgICAgICAgaWQ6IHQuYXJnLnN0cmluZyh7IHJlcXVpcmVkOiB0cnVlIH0pLAogICAgICB9LAogICAgICByZXNvbHZlOiBhc3luYyAoXywgeyBpZCB9KSA9PiB7CiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcG9zdHNDb2xsZWN0aW9uLmRlbGV0ZU9uZSh7CiAgICAgICAgICBfaWQ6IGVuc3VyZU9iamVjdElkKGlkKSwKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gcmVzdWx0LmRlbGV0ZWRDb3VudCA+IDA7CiAgICAgIH0sCiAgICB9KSwKICAgIGRlbGV0ZVVzZXI6IHQuZmllbGQoewogICAgICB0eXBlOiAiQm9vbGVhbiIsCiAgICAgIGFyZ3M6IHsKICAgICAgICBpZDogdC5hcmcuc3RyaW5nKHsgcmVxdWlyZWQ6IHRydWUgfSksCiAgICAgIH0sCiAgICAgIHJlc29sdmU6IGFzeW5jIChfLCB7IGlkIH0pID0+IHsKICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB1c2Vyc0NvbGxlY3Rpb24uZGVsZXRlT25lKHsKICAgICAgICAgIF9pZDogZW5zdXJlT2JqZWN0SWQoaWQpLAogICAgICAgIH0pOwogICAgICAgIHJldHVybiByZXN1bHQuZGVsZXRlZENvdW50ID4gMDsKICAgICAgfSwKICAgIH0pLAogIH0pLAp9KTsKCmNvbnN0IHlvZ2EgPSBjcmVhdGVZb2dhKHsKICBzY2hlbWE6IGJ1aWxkZXIudG9TY2hlbWEoKSwKfSk7Cgpjb25zdCBzZXJ2ZXIgPSBjcmVhdGVTZXJ2ZXIoeW9nYSk7Cgpjb25zdCBQT1JUID0gaW1wb3J0Lm1ldGEuZW52LlBPUlQgPz8gODA4MDsKc2VydmVyLmxpc3RlbihQT1JULCAoKSA9PiB7CiAgY29uc29sZS5sb2coYFZpc2l0IGh0dHBzOi8vJHtwcm9jZXNzLmVudi5SQUlMV0FZX1BVQkxJQ19ET01BSU59L2dyYXBocWxgKTsKfSk7Cg==",
                    "healthcheckPath": "/graphql"
                  },
                  "source": {
                    "image": "ghcr.io/railwayapp/function-bun:1.3.0"
                  },
                  "variables": {
                    "MONGO_URL": {
                      "isOptional": false,
                      "description": "Your database's connection URL",
                      "defaultValue": "${{MongoDB.MONGO_URL}}"
                    }
                  },
                  "networking": {
                    "serviceDomains": {
                      "<hasDomain>:8080": {
                        "port": 8080
                      }
                    }
                  }
                },
                "948679d0-8fd0-4e72-b84b-9c4d2f39f988": {
                  "icon": "https://emoji.aranja.com/emojis/apple/1f4da.png",
                  "name": "frontend",
                  "deploy": {
                    "startCommand": "./run.sh aW1wb3J0IHsgSG9ubyB9IGZyb20gImhvbm9ANCI7CmltcG9ydCB7IGNvcnMgfSBmcm9tICJob25vL2NvcnMiOwoKY29uc3QgYXBwID0gbmV3IEhvbm8oKTsKCmFwcC51c2UoIi8qIiwgY29ycygpKTsKCi8vIElubGluZSBSZWFjdCBhcHAgd2l0aCBUYWlsd2luZCBDU1MKY29uc3QgaHRtbCA9IGA8IURPQ1RZUEUgaHRtbD4KPGh0bWwgbGFuZz0iZW4iPgo8aGVhZD4KICA8bWV0YSBjaGFyc2V0PSJVVEYtOCI+CiAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiPgogIDx0aXRsZT5CbG9nIEFwcDwvdGl0bGU+CiAgPHNjcmlwdCBjcm9zc29yaWdpbiBzcmM9Imh0dHBzOi8vdW5wa2cuY29tL3JlYWN0QDE4L3VtZC9yZWFjdC5wcm9kdWN0aW9uLm1pbi5qcyI+PC9zY3JpcHQ+CiAgPHNjcmlwdCBjcm9zc29yaWdpbiBzcmM9Imh0dHBzOi8vdW5wa2cuY29tL3JlYWN0LWRvbUAxOC91bWQvcmVhY3QtZG9tLnByb2R1Y3Rpb24ubWluLmpzIj48L3NjcmlwdD4KICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly91bnBrZy5jb20vQGJhYmVsL3N0YW5kYWxvbmUvYmFiZWwubWluLmpzIj48L3NjcmlwdD4KICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG4udGFpbHdpbmRjc3MuY29tIj48L3NjcmlwdD4KPC9oZWFkPgo8Ym9keSBjbGFzcz0iYmctZ3JhZGllbnQtdG8tYnIgZnJvbS1ibHVlLTYwMCB0by1wdXJwbGUtNzAwIG1pbi1oLXNjcmVlbiBwLTQgZmxleCBmbGV4LWNvbCI+CiAgPGRpdiBpZD0icm9vdCIgY2xhc3M9ImZsZXgtMSI+PC9kaXY+CiAgPHNjcmlwdCB0eXBlPSJ0ZXh0L2JhYmVsIj4KICAgIGNvbnN0IEFQSV9VUkwgPSAiJHtwcm9jZXNzLmVudi5BUElfVVJMfSI7CgogICAgY29uc3QgeyB1c2VTdGF0ZSwgdXNlRWZmZWN0IH0gPSBSZWFjdDsKCiAgICBmdW5jdGlvbiBBcHAoKSB7CiAgICAgIGNvbnN0IFtwb3N0cywgc2V0UG9zdHNdID0gdXNlU3RhdGUoW10pOwogICAgICBjb25zdCBbbG9hZGluZywgc2V0TG9hZGluZ10gPSB1c2VTdGF0ZSh0cnVlKTsKICAgICAgY29uc3QgW3RpdGxlLCBzZXRUaXRsZV0gPSB1c2VTdGF0ZSgiIik7CiAgICAgIGNvbnN0IFtjb250ZW50LCBzZXRDb250ZW50XSA9IHVzZVN0YXRlKCIiKTsKICAgICAgY29uc3QgW3NlbGVjdGVkQXV0aG9yLCBzZXRTZWxlY3RlZEF1dGhvcl0gPSB1c2VTdGF0ZSgiMSIpOwogICAgICBjb25zdCBbdXNlcnMsIHNldFVzZXJzXSA9IHVzZVN0YXRlKFtdKTsKICAgICAgY29uc3QgW3Nob3dDcmVhdGVVc2VyLCBzZXRTaG93Q3JlYXRlVXNlcl0gPSB1c2VTdGF0ZShmYWxzZSk7CiAgICAgIGNvbnN0IFtuZXdVc2VyTmFtZSwgc2V0TmV3VXNlck5hbWVdID0gdXNlU3RhdGUoIiIpOwogICAgICBjb25zdCBbbmV3VXNlckVtYWlsLCBzZXROZXdVc2VyRW1haWxdID0gdXNlU3RhdGUoIiIpOwoKICAgICAgLy8gRmV0Y2ggcG9zdHMgb24gbW91bnQKICAgICAgdXNlRWZmZWN0KCgpID0+IHsKICAgICAgICBmZXRjaFBvc3RzKCk7CiAgICAgICAgZmV0Y2hVc2VycygpOwogICAgICB9LCBbXSk7CgogICAgICBjb25zdCBmZXRjaFBvc3RzID0gYXN5bmMgKCkgPT4gewogICAgICAgIHRyeSB7CiAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKEFQSV9VUkwsIHsKICAgICAgICAgICAgbWV0aG9kOiAiUE9TVCIsCiAgICAgICAgICAgIGhlYWRlcnM6IHsgIkNvbnRlbnQtVHlwZSI6ICJhcHBsaWNhdGlvbi9qc29uIiB9LAogICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7CiAgICAgICAgICAgICAgcXVlcnk6IFxgCiAgICAgICAgICAgICAgICBxdWVyeSB7CiAgICAgICAgICAgICAgICAgIHBvc3RzIHsKICAgICAgICAgICAgICAgICAgICBfaWQKICAgICAgICAgICAgICAgICAgICB0aXRsZQogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQKICAgICAgICAgICAgICAgICAgICBhdXRob3IgewogICAgICAgICAgICAgICAgICAgICAgbmFtZQogICAgICAgICAgICAgICAgICAgICAgZW1haWwKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBcYCwKICAgICAgICAgICAgfSksCiAgICAgICAgICB9KTsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7CiAgICAgICAgICBzZXRQb3N0cyhkYXRhLmRhdGE/LnBvc3RzIHx8IFtdKTsKICAgICAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgICAgIGNvbnNvbGUuZXJyb3IoIkVycm9yIGZldGNoaW5nIHBvc3RzOiIsIGVycik7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIHNldExvYWRpbmcoZmFsc2UpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIGNvbnN0IGZldGNoVXNlcnMgPSBhc3luYyAoKSA9PiB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goQVBJX1VSTCwgewogICAgICAgICAgICBtZXRob2Q6ICJQT1NUIiwKICAgICAgICAgICAgaGVhZGVyczogeyAiQ29udGVudC1UeXBlIjogImFwcGxpY2F0aW9uL2pzb24iIH0sCiAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsKICAgICAgICAgICAgICBxdWVyeTogXGAKICAgICAgICAgICAgICAgIHF1ZXJ5IHsKICAgICAgICAgICAgICAgICAgdXNlcnMgewogICAgICAgICAgICAgICAgICAgIF9pZAogICAgICAgICAgICAgICAgICAgIG5hbWUKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIFxgLAogICAgICAgICAgICB9KSwKICAgICAgICAgIH0pOwogICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTsKICAgICAgICAgIHNldFVzZXJzKGRhdGEuZGF0YT8udXNlcnMgfHwgW10pOwogICAgICAgICAgaWYgKGRhdGEuZGF0YT8udXNlcnMgJiYgZGF0YS5kYXRhLnVzZXJzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgc2V0U2VsZWN0ZWRBdXRob3IoZGF0YS5kYXRhLnVzZXJzWzBdLl9pZCk7CiAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICBjb25zb2xlLmVycm9yKCJFcnJvciBmZXRjaGluZyB1c2VyczoiLCBlcnIpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIGNvbnN0IGNyZWF0ZVBvc3QgPSBhc3luYyAoZSkgPT4gewogICAgICAgIGUucHJldmVudERlZmF1bHQoKTsKICAgICAgICBpZiAoIXRpdGxlIHx8ICFjb250ZW50KSB7CiAgICAgICAgICBhbGVydCgiUGxlYXNlIGZpbGwgaW4gYWxsIGZpZWxkcyIpOwogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goQVBJX1VSTCwgewogICAgICAgICAgICBtZXRob2Q6ICJQT1NUIiwKICAgICAgICAgICAgaGVhZGVyczogeyAiQ29udGVudC1UeXBlIjogImFwcGxpY2F0aW9uL2pzb24iIH0sCiAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsKICAgICAgICAgICAgICBxdWVyeTogXGAKICAgICAgICAgICAgICAgIG11dGF0aW9uIHsKICAgICAgICAgICAgICAgICAgY3JlYXRlUG9zdChpbnB1dDogewogICAgICAgICAgICAgICAgICAgIHRpdGxlOiAiXCR7dGl0bGUucmVwbGFjZSgvIi9nLCAnXFxcXCInKX0iCiAgICAgICAgICAgICAgICAgICAgY29udGVudDogIlwke2NvbnRlbnQucmVwbGFjZSgvIi9nLCAnXFxcXCInKX0iCiAgICAgICAgICAgICAgICAgICAgYXV0aG9ySWQ6ICJcJHtzZWxlY3RlZEF1dGhvcn0iCiAgICAgICAgICAgICAgICAgIH0pIHsKICAgICAgICAgICAgICAgICAgICBfaWQKICAgICAgICAgICAgICAgICAgICB0aXRsZQogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQKICAgICAgICAgICAgICAgICAgICBhdXRob3IgewogICAgICAgICAgICAgICAgICAgICAgbmFtZQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIFxgLAogICAgICAgICAgICB9KSwKICAgICAgICAgIH0pOwogICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTsKICAgICAgICAgIGlmIChkYXRhLmRhdGE/LmNyZWF0ZVBvc3QpIHsKICAgICAgICAgICAgc2V0VGl0bGUoIiIpOwogICAgICAgICAgICBzZXRDb250ZW50KCIiKTsKICAgICAgICAgICAgZmV0Y2hQb3N0cygpOwogICAgICAgICAgfSBlbHNlIGlmIChkYXRhLmVycm9ycykgewogICAgICAgICAgICBhbGVydCgiRXJyb3I6ICIgKyBkYXRhLmVycm9yc1swXS5tZXNzYWdlKTsKICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgICAgIGNvbnNvbGUuZXJyb3IoIkVycm9yIGNyZWF0aW5nIHBvc3Q6IiwgZXJyKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBjb25zdCBjcmVhdGVVc2VyID0gYXN5bmMgKGUpID0+IHsKICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgaWYgKCFuZXdVc2VyTmFtZSB8fCAhbmV3VXNlckVtYWlsKSB7CiAgICAgICAgICBhbGVydCgiUGxlYXNlIGZpbGwgaW4gYWxsIGZpZWxkcyIpOwogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goQVBJX1VSTCwgewogICAgICAgICAgICBtZXRob2Q6ICJQT1NUIiwKICAgICAgICAgICAgaGVhZGVyczogeyAiQ29udGVudC1UeXBlIjogImFwcGxpY2F0aW9uL2pzb24iIH0sCiAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsKICAgICAgICAgICAgICBxdWVyeTogXGAKICAgICAgICAgICAgICAgIG11dGF0aW9uIHsKICAgICAgICAgICAgICAgICAgY3JlYXRlVXNlcihpbnB1dDogewogICAgICAgICAgICAgICAgICAgIG5hbWU6ICJcJHtuZXdVc2VyTmFtZS5yZXBsYWNlKC8iL2csICdcXFxcIicpfSIKICAgICAgICAgICAgICAgICAgICBlbWFpbDogIlwke25ld1VzZXJFbWFpbC5yZXBsYWNlKC8iL2csICdcXFxcIicpfSIKICAgICAgICAgICAgICAgICAgfSkgewogICAgICAgICAgICAgICAgICAgIF9pZAogICAgICAgICAgICAgICAgICAgIG5hbWUKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIFxgLAogICAgICAgICAgICB9KSwKICAgICAgICAgIH0pOwogICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTsKICAgICAgICAgIGlmIChkYXRhLmRhdGE/LmNyZWF0ZVVzZXIpIHsKICAgICAgICAgICAgc2V0TmV3VXNlck5hbWUoIiIpOwogICAgICAgICAgICBzZXROZXdVc2VyRW1haWwoIiIpOwogICAgICAgICAgICBzZXRTaG93Q3JlYXRlVXNlcihmYWxzZSk7CiAgICAgICAgICAgIGZldGNoVXNlcnMoKTsKICAgICAgICAgIH0gZWxzZSBpZiAoZGF0YS5lcnJvcnMpIHsKICAgICAgICAgICAgYWxlcnQoIkVycm9yOiAiICsgZGF0YS5lcnJvcnNbMF0ubWVzc2FnZSk7CiAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICBjb25zb2xlLmVycm9yKCJFcnJvciBjcmVhdGluZyB1c2VyOiIsIGVycik7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgY29uc3QgZGVsZXRlUG9zdCA9IGFzeW5jIChpZCkgPT4gewogICAgICAgIGlmICghY29uZmlybSgiQXJlIHlvdSBzdXJlPyIpKSByZXR1cm47CgogICAgICAgIHRyeSB7CiAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKEFQSV9VUkwsIHsKICAgICAgICAgICAgbWV0aG9kOiAiUE9TVCIsCiAgICAgICAgICAgIGhlYWRlcnM6IHsgIkNvbnRlbnQtVHlwZSI6ICJhcHBsaWNhdGlvbi9qc29uIiB9LAogICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7CiAgICAgICAgICAgICAgcXVlcnk6IFxgCiAgICAgICAgICAgICAgICBtdXRhdGlvbiB7CiAgICAgICAgICAgICAgICAgIGRlbGV0ZVBvc3QoaWQ6ICJcJHtpZH0iKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIFxgLAogICAgICAgICAgICB9KSwKICAgICAgICAgIH0pOwogICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTsKICAgICAgICAgIGlmIChkYXRhLmRhdGE/LmRlbGV0ZVBvc3QpIHsKICAgICAgICAgICAgZmV0Y2hQb3N0cygpOwogICAgICAgICAgfSBlbHNlIGlmIChkYXRhLmVycm9ycykgewogICAgICAgICAgICBhbGVydCgiRXJyb3I6ICIgKyBkYXRhLmVycm9yc1swXS5tZXNzYWdlKTsKICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgICAgIGNvbnNvbGUuZXJyb3IoIkVycm9yIGRlbGV0aW5nIHBvc3Q6IiwgZXJyKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICByZXR1cm4gKAogICAgICAgIDw+CiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ibWF4LXctNHhsIG14LWF1dG8iPgogICAgICAgICAgICA8aDEgY2xhc3NOYW1lPSJ0ZXh0LTR4bCBmb250LWJvbGQgbWItOCB0ZXh0LXdoaXRlIj5CbG9nIFBvc3RzPC9oMT4KCiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSJiZy13aGl0ZSByb3VuZGVkLWxnIHNoYWRvdy14bCBwLTYgbWItOCI+CiAgICAgICAgICAgICAgPGgyIGNsYXNzTmFtZT0idGV4dC0yeGwgZm9udC1ib2xkIG1iLTQgdGV4dC1ncmF5LTgwMCI+Q3JlYXRlIFBvc3Q8L2gyPgogICAgICAgICAgICAgIDxmb3JtIG9uU3VibWl0PXtjcmVhdGVQb3N0fSBjbGFzc05hbWU9InNwYWNlLXktNCI+CiAgICAgICAgICAgICAgICA8aW5wdXQKICAgICAgICAgICAgICAgICAgdHlwZT0idGV4dCIKICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9IlRpdGxlIgogICAgICAgICAgICAgICAgICB2YWx1ZT17dGl0bGV9CiAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXsoZSkgPT4gc2V0VGl0bGUoZS50YXJnZXQudmFsdWUpfQogICAgICAgICAgICAgICAgICBjbGFzc05hbWU9InctZnVsbCBweC00IHB5LTIgYm9yZGVyIGJvcmRlci1ncmF5LTMwMCByb3VuZGVkLWxnIGZvY3VzOm91dGxpbmUtbm9uZSBmb2N1czpyaW5nLTIgZm9jdXM6cmluZy1ibHVlLTYwMCIKICAgICAgICAgICAgICAgIC8+CiAgICAgICAgICAgICAgICA8dGV4dGFyZWEKICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9IkNvbnRlbnQiCiAgICAgICAgICAgICAgICAgIHZhbHVlPXtjb250ZW50fQogICAgICAgICAgICAgICAgICBvbkNoYW5nZT17KGUpID0+IHNldENvbnRlbnQoZS50YXJnZXQudmFsdWUpfQogICAgICAgICAgICAgICAgICBjbGFzc05hbWU9InctZnVsbCBweC00IHB5LTIgYm9yZGVyIGJvcmRlci1ncmF5LTMwMCByb3VuZGVkLWxnIGZvY3VzOm91dGxpbmUtbm9uZSBmb2N1czpyaW5nLTIgZm9jdXM6cmluZy1ibHVlLTYwMCBoLTI0IgogICAgICAgICAgICAgICAgLz4KICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSJmbGV4IGdhcC0yIj4KICAgICAgICAgICAgICAgICAgPHNlbGVjdAogICAgICAgICAgICAgICAgICAgIHZhbHVlPXtzZWxlY3RlZEF1dGhvcn0KICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZT17KGUpID0+IHNldFNlbGVjdGVkQXV0aG9yKGUudGFyZ2V0LnZhbHVlKX0KICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9ImZsZXgtMSBweC00IHB5LTIgYm9yZGVyIGJvcmRlci1ncmF5LTMwMCByb3VuZGVkLWxnIGZvY3VzOm91dGxpbmUtbm9uZSBmb2N1czpyaW5nLTIgZm9jdXM6cmluZy1ibHVlLTYwMCIKICAgICAgICAgICAgICAgICAgPgogICAgICAgICAgICAgICAgICAgIHt1c2Vycy5tYXAoKHVzZXIpID0+ICgKICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24ga2V5PXt1c2VyLl9pZH0gdmFsdWU9e3VzZXIuX2lkfT4KICAgICAgICAgICAgICAgICAgICAgICAge3VzZXIubmFtZX0KICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPgogICAgICAgICAgICAgICAgICAgICkpfQogICAgICAgICAgICAgICAgICA8L3NlbGVjdD4KICAgICAgICAgICAgICAgICAgPGJ1dHRvbgogICAgICAgICAgICAgICAgICAgIHR5cGU9ImJ1dHRvbiIKICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBzZXRTaG93Q3JlYXRlVXNlcighc2hvd0NyZWF0ZVVzZXIpfQogICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT0icHgtNCBweS0yIGJnLWdyYXktNjAwIGhvdmVyOmJnLWdyYXktNzAwIHRleHQtd2hpdGUgZm9udC1ib2xkIHJvdW5kZWQtbGcgdHJhbnNpdGlvbi1jb2xvcnMiCiAgICAgICAgICAgICAgICAgID4KICAgICAgICAgICAgICAgICAgICArIFVzZXIKICAgICAgICAgICAgICAgICAgPC9idXR0b24+CiAgICAgICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgICAgIDxidXR0b24KICAgICAgICAgICAgICAgICAgdHlwZT0ic3VibWl0IgogICAgICAgICAgICAgICAgICBjbGFzc05hbWU9InctZnVsbCBweC02IHB5LTMgYmctYmx1ZS02MDAgaG92ZXI6YmctYmx1ZS03MDAgdGV4dC13aGl0ZSBmb250LWJvbGQgcm91bmRlZC1sZyB0cmFuc2l0aW9uLWNvbG9ycyIKICAgICAgICAgICAgICAgID4KICAgICAgICAgICAgICAgICAgQ3JlYXRlIFBvc3QKICAgICAgICAgICAgICAgIDwvYnV0dG9uPgogICAgICAgICAgICAgIDwvZm9ybT4KICAgICAgICAgICAgPC9kaXY+CgogICAgICAgICAgICB7c2hvd0NyZWF0ZVVzZXIgJiYgKAogICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSJiZy15ZWxsb3ctNTAgYm9yZGVyLWwtNCBib3JkZXIteWVsbG93LTQwMCBwLTQgbWItOCByb3VuZGVkIj4KICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0idGV4dC15ZWxsb3ctNzAwIHRleHQtc20gbWItNCI+CiAgICAgICAgICAgICAgICAgIOKaoO+4jyA8c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IFVzZXIgZGF0YSBpcyBwdWJsaWMuIFBsZWFzZSBkb24ndCBlbnRlciBzZW5zaXRpdmUgaW5mb3JtYXRpb24uCiAgICAgICAgICAgICAgICA8L3A+CiAgICAgICAgICAgICAgICA8Zm9ybSBvblN1Ym1pdD17Y3JlYXRlVXNlcn0gY2xhc3NOYW1lPSJzcGFjZS15LTMiPgogICAgICAgICAgICAgICAgICA8aW5wdXQKICAgICAgICAgICAgICAgICAgICB0eXBlPSJ0ZXh0IgogICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPSJOYW1lIgogICAgICAgICAgICAgICAgICAgIHZhbHVlPXtuZXdVc2VyTmFtZX0KICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZT17KGUpID0+IHNldE5ld1VzZXJOYW1lKGUudGFyZ2V0LnZhbHVlKX0KICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9InctZnVsbCBweC00IHB5LTIgYm9yZGVyIGJvcmRlci15ZWxsb3ctMzAwIHJvdW5kZWQtbGcgZm9jdXM6b3V0bGluZS1ub25lIGZvY3VzOnJpbmctMiBmb2N1czpyaW5nLXllbGxvdy00MDAiCiAgICAgICAgICAgICAgICAgIC8+CiAgICAgICAgICAgICAgICAgIDxpbnB1dAogICAgICAgICAgICAgICAgICAgIHR5cGU9ImVtYWlsIgogICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPSJFbWFpbCIKICAgICAgICAgICAgICAgICAgICB2YWx1ZT17bmV3VXNlckVtYWlsfQogICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXsoZSkgPT4gc2V0TmV3VXNlckVtYWlsKGUudGFyZ2V0LnZhbHVlKX0KICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9InctZnVsbCBweC00IHB5LTIgYm9yZGVyIGJvcmRlci15ZWxsb3ctMzAwIHJvdW5kZWQtbGcgZm9jdXM6b3V0bGluZS1ub25lIGZvY3VzOnJpbmctMiBmb2N1czpyaW5nLXllbGxvdy00MDAiCiAgICAgICAgICAgICAgICAgIC8+CiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSJmbGV4IGdhcC0yIj4KICAgICAgICAgICAgICAgICAgICA8YnV0dG9uCiAgICAgICAgICAgICAgICAgICAgICB0eXBlPSJzdWJtaXQiCiAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9ImZsZXgtMSBweC00IHB5LTIgYmcteWVsbG93LTYwMCBob3ZlcjpiZy15ZWxsb3ctNzAwIHRleHQtd2hpdGUgZm9udC1ib2xkIHJvdW5kZWQtbGcgdHJhbnNpdGlvbi1jb2xvcnMiCiAgICAgICAgICAgICAgICAgICAgPgogICAgICAgICAgICAgICAgICAgICAgQ3JlYXRlIFVzZXIKICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj4KICAgICAgICAgICAgICAgICAgICA8YnV0dG9uCiAgICAgICAgICAgICAgICAgICAgICB0eXBlPSJidXR0b24iCiAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBzZXRTaG93Q3JlYXRlVXNlcihmYWxzZSl9CiAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9ImZsZXgtMSBweC00IHB5LTIgYmctZ3JheS00MDAgaG92ZXI6YmctZ3JheS01MDAgdGV4dC13aGl0ZSBmb250LWJvbGQgcm91bmRlZC1sZyB0cmFuc2l0aW9uLWNvbG9ycyIKICAgICAgICAgICAgICAgICAgICA+CiAgICAgICAgICAgICAgICAgICAgICBDYW5jZWwKICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj4KICAgICAgICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgICAgICA8L2Zvcm0+CiAgICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgICl9CgogICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ic3BhY2UteS00Ij4KICAgICAgICAgICAgICB7bG9hZGluZyA/ICgKICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0idGV4dC13aGl0ZSB0ZXh0LWNlbnRlciI+TG9hZGluZyBwb3N0cy4uLjwvcD4KICAgICAgICAgICAgICApIDogcG9zdHMubGVuZ3RoID09PSAwID8gKAogICAgICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSJ0ZXh0LXdoaXRlIHRleHQtY2VudGVyIj5ObyBwb3N0cyB5ZXQ8L3A+CiAgICAgICAgICAgICAgKSA6ICgKICAgICAgICAgICAgICAgIHBvc3RzLm1hcCgocG9zdCkgPT4gKAogICAgICAgICAgICAgICAgICA8ZGl2IGtleT17cG9zdC5faWR9IGNsYXNzTmFtZT0iYmctd2hpdGUgcm91bmRlZC1sZyBzaGFkb3cteGwgcC02Ij4KICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3NOYW1lPSJ0ZXh0LTJ4bCBmb250LWJvbGQgbWItMiB0ZXh0LWdyYXktODAwIj4KICAgICAgICAgICAgICAgICAgICAgIHtwb3N0LnRpdGxlfQogICAgICAgICAgICAgICAgICAgIDwvaDM+CiAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSJ0ZXh0LWdyYXktNjAwIG1iLTMiPntwb3N0LmNvbnRlbnR9PC9wPgogICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0idGV4dC1zbSB0ZXh0LWdyYXktNTAwIG1iLTQiPgogICAgICAgICAgICAgICAgICAgICAgQnkge3Bvc3QuYXV0aG9yLm5hbWV9ICh7cG9zdC5hdXRob3IuZW1haWx9KQogICAgICAgICAgICAgICAgICAgIDwvcD4KICAgICAgICAgICAgICAgICAgICA8YnV0dG9uCiAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBkZWxldGVQb3N0KHBvc3QuX2lkKX0KICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT0icHgtNCBweS0yIGJnLXJlZC02MDAgaG92ZXI6YmctcmVkLTcwMCB0ZXh0LXdoaXRlIGZvbnQtYm9sZCByb3VuZGVkLWxnIHRyYW5zaXRpb24tY29sb3JzIgogICAgICAgICAgICAgICAgICAgID4KICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZQogICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPgogICAgICAgICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgICAgICkpCiAgICAgICAgICAgICAgKX0KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICA8L2Rpdj4KCiAgICAgICAgICA8Zm9vdGVyIGNsYXNzTmFtZT0idGV4dC1jZW50ZXIgdGV4dC13aGl0ZSBtdC0xNiBtYi00IHRleHQtc20gc3BhY2UteS0yIj4KICAgICAgICAgICAgPHA+CiAgICAgICAgICAgICAgTWFkZSB3aXRoIOKdpO+4jyBieSA8YSBocmVmPSJodHRwczovL2l0c3JlbXMuY29tIiB0YXJnZXQ9Il9ibGFuayIgcmVsPSJub29wZW5lciBub3JlZmVycmVyIiBjbGFzc05hbWU9InVuZGVybGluZSBob3Zlcjp0ZXh0LWdyYXktMjAwIj5OaWNvPC9hPgogICAgICAgICAgICA8L3A+CiAgICAgICAgICAgIDxkaXY+CiAgICAgICAgICAgICAgPHA+CiAgICAgICAgICAgICAgICA8YSBocmVmPXtBUElfVVJMfSB0YXJnZXQ9Il9ibGFuayIgcmVsPSJub29wZW5lciBub3JlZmVycmVyIiBjbGFzc05hbWU9InVuZGVybGluZSBob3Zlcjp0ZXh0LWdyYXktMjAwIj4KICAgICAgICAgICAgICAgICAgRXhwbG9yZSB0aGUgR3JhcGhRTCBBUEkKICAgICAgICAgICAgICAgIDwvYT4KICAgICAgICAgICAgICA8L3A+CiAgICAgICAgICAgICAgPHA+CiAgICAgICAgICAgICAgICA8YSBocmVmPSJodHRwczovL3JhaWx3YXkuY29tL2RlcGxveS9yYWlsd2F5LWZ1bmN0aW9ucy1ncmFwaHFsLWJsb2c/cmVmZXJyYWxDb2RlPUFpTml3NiZ1dG1fbWVkaXVtPWludGVncmF0aW9uJnV0bV9zb3VyY2U9dGVtcGxhdGUmdXRtX2NhbXBhaWduPWdlbmVyaWMiIHRhcmdldD0iX2JsYW5rIiByZWw9Im5vb3BlbmVyIG5vcmVmZXJyZXIiIGNsYXNzTmFtZT0idW5kZXJsaW5lIGhvdmVyOnRleHQtZ3JheS0yMDAiPgogICAgICAgICAgICAgICAgICBEZXBsb3kgb24gUmFpbHdheQogICAgICAgICAgICAgICAgPC9hPgogICAgICAgICAgICAgIDwvcD4KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICA8L2Zvb3Rlcj4KICAgICAgICA8Lz4KICAgICAgKTsKICAgIH0KCiAgICBjb25zdCByb290ID0gUmVhY3RET00uY3JlYXRlUm9vdChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncm9vdCcpKTsKICAgIHJvb3QucmVuZGVyKDxBcHAgLz4pOwogIDwvc2NyaXB0Pgo8L2JvZHk+CjwvaHRtbD5gOwoKYXBwLmdldCgiKiIsIChjKSA9PiBjLmh0bWwoaHRtbCkpOwoKY29uc3QgcG9ydCA9IEJ1bi5lbnYuUE9SVCA/PyA4MDgwOwoKQnVuLnNlcnZlKHsKICBwb3J0LAogIGZldGNoOiBhcHAuZmV0Y2gsCn0pOwoKY29uc29sZS5sb2coYExpc3RlbmluZyBvbiBwb3J0ICR7cG9ydH1gKTsK",
                    "healthcheckPath": "/health"
                  },
                  "source": {
                    "image": "ghcr.io/railwayapp/function-bun:1.3.0"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "",
                      "defaultValue": "3000"
                    },
                    "API_URL": {
                      "isOptional": false,
                      "description": "A reference-based URL of your api",
                      "defaultValue": "https://${{graphql-api.RAILWAY_PUBLIC_DOMAIN}}/graphql"
                    }
                  },
                  "networking": {
                    "serviceDomains": {
                      "<hasDomain>:3000": {
                        "port": 3000
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "post_deploy": {
    "healthcheck": {
      "service": "graphql-api",
      "method": "GET",
      "path": "/graphql",
      "expect_status": 200
    }
  },
  "resources": {
    "expected_services": 3,
    "needs_volume": true
  },
  "generated_at": "2026-09-21T22:14:44.200Z",
  "generator_version": "0.1.0",
  "status": "degraded",
  "validated_at": "2026-09-21T02:01:08.464Z",
  "success_rate_30d": 0,
  "validation": {
    "last_run_id": "run_100cefb9c91341bcbd86",
    "checks": [
      {
        "name": "workflow_completed",
        "passed": true
      },
      {
        "name": "all_services_deployed",
        "passed": false,
        "detail": "DEPLOYING,SUCCESS,FAILED"
      }
    ]
  }
}
