@open-mercato/cli 0.6.4-develop.4382.1.6b4f656b77 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/dist/agentic/guides/core.customers.md +1 -1
- package/dist/agentic/shared/AGENTS.md.template +56 -33
- package/dist/agentic/shared/ai/skills/{auto-continue-pr → om-auto-continue-pr}/SKILL.md +19 -19
- package/dist/agentic/shared/ai/skills/{auto-create-pr → om-auto-continue-pr}/STANDALONE.md +1 -1
- package/dist/agentic/shared/ai/skills/{auto-continue-pr-loop → om-auto-continue-pr-loop}/SKILL.md +32 -32
- package/dist/agentic/shared/ai/skills/{auto-create-pr → om-auto-create-pr}/SKILL.md +24 -24
- package/dist/agentic/shared/ai/skills/{auto-fix-github → om-auto-create-pr}/STANDALONE.md +1 -1
- package/dist/agentic/shared/ai/skills/{auto-create-pr-loop → om-auto-create-pr-loop}/SKILL.md +40 -40
- package/dist/agentic/shared/ai/skills/{auto-fix-github → om-auto-fix-github}/SKILL.md +3 -3
- package/dist/agentic/shared/ai/skills/{auto-continue-pr → om-auto-fix-github}/STANDALONE.md +1 -1
- package/dist/agentic/shared/ai/skills/{auto-review-pr → om-auto-review-pr}/SKILL.md +5 -5
- package/dist/agentic/shared/ai/skills/{auto-review-pr → om-auto-review-pr}/STANDALONE.md +1 -1
- package/dist/agentic/shared/ai/skills/{auto-upgrade-0.4.10-to-0.5.0 → om-auto-upgrade-0.4.10-to-0.5.0}/SKILL.md +1 -1
- package/dist/agentic/shared/ai/skills/{backend-ui-design → om-backend-ui-design}/SKILL.md +2 -2
- package/dist/agentic/shared/ai/skills/{code-review → om-code-review}/SKILL.md +1 -1
- package/dist/agentic/shared/ai/skills/{code-review → om-code-review}/references/review-checklist.md +3 -0
- package/dist/agentic/shared/ai/skills/{data-model-design → om-data-model-design}/SKILL.md +4 -2
- package/dist/agentic/shared/ai/skills/{eject-and-customize → om-eject-and-customize}/SKILL.md +2 -2
- package/dist/agentic/shared/ai/skills/{implement-spec → om-implement-spec}/SKILL.md +6 -6
- package/dist/agentic/shared/ai/skills/{integration-builder → om-integration-builder}/SKILL.md +1 -1
- package/dist/agentic/shared/ai/skills/{integration-tests → om-integration-tests}/SKILL.md +1 -1
- package/dist/agentic/shared/ai/skills/{module-scaffold → om-module-scaffold}/SKILL.md +5 -3
- package/dist/agentic/shared/ai/skills/{module-scaffold → om-module-scaffold}/references/naming-conventions.md +7 -8
- package/dist/agentic/shared/ai/skills/om-prepare-issue/SKILL.md +202 -0
- package/dist/agentic/shared/ai/skills/{spec-writing → om-spec-writing}/SKILL.md +6 -6
- package/dist/agentic/shared/ai/skills/{spec-writing → om-spec-writing}/references/spec-checklist.md +3 -3
- package/dist/agentic/shared/ai/skills/{system-extension → om-system-extension}/SKILL.md +1 -1
- package/dist/agentic/shared/ai/skills/{trim-unused-modules → om-trim-unused-modules}/SKILL.md +1 -1
- package/dist/agentic/shared/ai/skills/{troubleshooter → om-troubleshooter}/SKILL.md +1 -1
- package/dist/bin.js +1 -0
- package/dist/bin.js.map +2 -2
- package/dist/lib/__integration__/TC-INT-008.spec.js +1 -1
- package/dist/lib/__integration__/TC-INT-008.spec.js.map +2 -2
- package/dist/lib/agentic-setup.js +52 -51
- package/dist/lib/agentic-setup.js.map +2 -2
- package/dist/lib/deploy/railway/__integration__/TC-CLI-RAILWAY-001.meta.js +7 -0
- package/dist/lib/deploy/railway/__integration__/TC-CLI-RAILWAY-001.meta.js.map +7 -0
- package/dist/lib/deploy/railway/__integration__/TC-CLI-RAILWAY-001.spec.js +63 -0
- package/dist/lib/deploy/railway/__integration__/TC-CLI-RAILWAY-001.spec.js.map +7 -0
- package/dist/lib/deploy/railway/env.js +98 -0
- package/dist/lib/deploy/railway/env.js.map +7 -0
- package/dist/lib/deploy/railway/graphql-client.js +99 -0
- package/dist/lib/deploy/railway/graphql-client.js.map +7 -0
- package/dist/lib/deploy/railway/index.js +1115 -0
- package/dist/lib/deploy/railway/index.js.map +7 -0
- package/dist/lib/deploy/railway/operations.js +249 -0
- package/dist/lib/deploy/railway/operations.js.map +7 -0
- package/dist/lib/deploy/railway/options.js +155 -0
- package/dist/lib/deploy/railway/options.js.map +7 -0
- package/dist/lib/deploy/railway/railway-cli.js +61 -0
- package/dist/lib/deploy/railway/railway-cli.js.map +7 -0
- package/dist/lib/deploy/railway/redaction.js +88 -0
- package/dist/lib/deploy/railway/redaction.js.map +7 -0
- package/dist/lib/deploy/railway/source.js +128 -0
- package/dist/lib/deploy/railway/source.js.map +7 -0
- package/dist/lib/deploy/railway/state.js +41 -0
- package/dist/lib/deploy/railway/state.js.map +7 -0
- package/dist/lib/deploy/railway/token.js +46 -0
- package/dist/lib/deploy/railway/token.js.map +7 -0
- package/dist/lib/deploy/railway/types.js +1 -0
- package/dist/lib/deploy/railway/types.js.map +7 -0
- package/dist/lib/generators/openapi.js +4 -0
- package/dist/lib/generators/openapi.js.map +2 -2
- package/dist/lib/testing/integration.js +57 -26
- package/dist/lib/testing/integration.js.map +2 -2
- package/dist/lib/testing/runtime-utils.js +16 -8
- package/dist/lib/testing/runtime-utils.js.map +2 -2
- package/dist/mercato.js +23 -8
- package/dist/mercato.js.map +2 -2
- package/package.json +11 -12
- package/src/bin.ts +1 -0
- package/src/lib/__integration__/TC-INT-008.spec.ts +1 -1
- package/src/lib/agentic-setup.ts +52 -51
- package/src/lib/deploy/railway/__integration__/TC-CLI-RAILWAY-001.meta.ts +3 -0
- package/src/lib/deploy/railway/__integration__/TC-CLI-RAILWAY-001.spec.ts +71 -0
- package/src/lib/deploy/railway/__tests__/dry-run.test.ts +61 -0
- package/src/lib/deploy/railway/__tests__/env.test.ts +55 -0
- package/src/lib/deploy/railway/__tests__/graphql-client.test.ts +80 -0
- package/src/lib/deploy/railway/__tests__/operations.test.ts +21 -0
- package/src/lib/deploy/railway/__tests__/options.test.ts +78 -0
- package/src/lib/deploy/railway/__tests__/redaction.test.ts +62 -0
- package/src/lib/deploy/railway/__tests__/source.test.ts +130 -0
- package/src/lib/deploy/railway/__tests__/state.test.ts +24 -0
- package/src/lib/deploy/railway/__tests__/token.test.ts +39 -0
- package/src/lib/deploy/railway/env.ts +112 -0
- package/src/lib/deploy/railway/graphql-client.ts +128 -0
- package/src/lib/deploy/railway/index.ts +1454 -0
- package/src/lib/deploy/railway/operations.ts +248 -0
- package/src/lib/deploy/railway/options.ts +167 -0
- package/src/lib/deploy/railway/railway-cli.ts +65 -0
- package/src/lib/deploy/railway/redaction.ts +91 -0
- package/src/lib/deploy/railway/source.ts +143 -0
- package/src/lib/deploy/railway/state.ts +45 -0
- package/src/lib/deploy/railway/token.ts +49 -0
- package/src/lib/deploy/railway/types.ts +87 -0
- package/src/lib/generators/openapi.ts +3 -0
- package/src/lib/testing/__tests__/integration.test.ts +79 -0
- package/src/lib/testing/__tests__/runtime-utils.test.ts +45 -1
- package/src/lib/testing/integration.ts +74 -28
- package/src/lib/testing/runtime-utils.ts +17 -8
- package/src/mercato.ts +33 -8
- /package/dist/agentic/shared/ai/skills/{backend-ui-design → om-backend-ui-design}/references/ui-components.md +0 -0
- /package/dist/agentic/shared/ai/skills/{data-model-design → om-data-model-design}/references/mikro-orm-cheatsheet.md +0 -0
- /package/dist/agentic/shared/ai/skills/{integration-builder → om-integration-builder}/references/adapter-contracts.md +0 -0
- /package/dist/agentic/shared/ai/skills/{module-scaffold → om-module-scaffold}/references/navigation-patterns.md +0 -0
- /package/dist/agentic/shared/ai/skills/{spec-writing → om-spec-writing}/references/spec-template.md +0 -0
- /package/dist/agentic/shared/ai/skills/{system-extension → om-system-extension}/references/extension-contracts.md +0 -0
- /package/dist/agentic/shared/ai/skills/{troubleshooter → om-troubleshooter}/references/diagnostic-commands.md +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/lib/deploy/railway/index.ts"],
|
|
4
|
+
"sourcesContent": ["import { createInterface } from 'node:readline/promises'\nimport { existsSync, readFileSync, unlinkSync } from 'node:fs'\nimport { basename, resolve } from 'node:path'\nimport { stdin as input, stdout as output } from 'node:process'\nimport { satisfies } from 'semver'\nimport {\n computeRailwayVariables,\n formatVariablePlan,\n generateProtectedSecrets,\n parseEnvFile,\n resolveEnvFile,\n writeGeneratedSecrets,\n} from './env'\nimport { createRailwayGraphqlClient, RailwayGraphqlError } from './graphql-client'\nimport { railwayOperations } from './operations'\nimport { parseRailwayDeployOptions, railwayDeployHelp } from './options'\nimport { collectSensitiveStructuredValues, redactText } from './redaction'\nimport { uploadLocalSource } from './railway-cli'\nimport {\n assertLocalUploadSafe,\n resolveRailwaySource,\n} from './source'\nimport {\n createRailwayState,\n loadRailwayState,\n railwayStatePath,\n saveRailwayState,\n} from './state'\nimport {\n railwayTokenConfigPath,\n resolveRailwayToken,\n writeCachedRailwayToken,\n} from './token'\nimport type {\n RailwayDeployOptions,\n RailwayDeployment,\n RailwayEnvironmentState,\n RailwayGraphqlClient,\n RailwayService,\n RailwaySource,\n RailwayState,\n} from './types'\n\ntype Connection<T> = {\n edges?: Array<{ node?: T | null } | null>\n}\n\ntype Prompt = {\n ask(question: string): Promise<string>\n close(): void\n}\n\nconst SUCCESS_STATUSES = new Set(['SUCCESS', 'COMPLETED'])\nconst FAILURE_STATUSES = new Set(['FAILED', 'CRASHED', 'REMOVED'])\n\nfunction isNotFoundError(error: unknown): boolean {\n return error instanceof RailwayGraphqlError\n && (\n error.status === 404\n || error.code === 'NOT_FOUND'\n || error.code?.endsWith('_NOT_FOUND') === true\n )\n}\n\nfunction isAmbiguousMutationError(error: unknown): boolean {\n if (!(error instanceof RailwayGraphqlError)) return true\n return (\n error.status === undefined\n || error.status >= 500\n || error.code === 'INTERNAL_ERROR'\n )\n}\n\nfunction createPrompt(): Prompt {\n const readline = createInterface({ input, output })\n return {\n ask: (question) => readline.question(question),\n close: () => readline.close(),\n }\n}\n\nfunction nodes<T>(connection?: Connection<T> | null): T[] {\n return (connection?.edges ?? [])\n .map((edge) => edge?.node)\n .filter((node): node is T => node !== null && node !== undefined)\n}\n\nfunction wait(milliseconds: number): Promise<void> {\n return new Promise((resolveWait) => setTimeout(resolveWait, milliseconds))\n}\n\nfunction normalizeProjectName(value: string): string {\n const normalized = value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9-]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .replace(/-{2,}/g, '-')\n .slice(0, 48)\n .replace(/-+$/g, '')\n if (!normalized) throw new Error('Unable to derive a valid Railway project name.')\n return normalized\n}\n\nfunction readAppPackage(cwd: string): {\n name: string\n dependencies: Record<string, string>\n nodeEngine?: string\n} {\n const packagePath = resolve(cwd, 'package.json')\n if (!existsSync(packagePath)) throw new Error('Run this command from an Open Mercato app root.')\n const parsed: unknown = JSON.parse(readFileSync(packagePath, 'utf8'))\n if (!parsed || typeof parsed !== 'object') throw new Error('Invalid package.json.')\n const record = parsed as Record<string, unknown>\n const dependencies = {\n ...(record.dependencies && typeof record.dependencies === 'object'\n ? record.dependencies as Record<string, string>\n : {}),\n ...(record.devDependencies && typeof record.devDependencies === 'object'\n ? record.devDependencies as Record<string, string>\n : {}),\n }\n if (!Object.keys(dependencies).some((key) => key.startsWith('@open-mercato/'))) {\n throw new Error('The current package does not declare Open Mercato dependencies.')\n }\n return {\n name: typeof record.name === 'string' && record.name.trim() ? record.name : basename(cwd),\n dependencies,\n nodeEngine: record.engines && typeof record.engines === 'object'\n && typeof (record.engines as Record<string, unknown>).node === 'string'\n ? (record.engines as Record<string, string>).node\n : undefined,\n }\n}\n\nfunction assertSupportedNodeVersion(nodeEngine?: string): void {\n if (!nodeEngine) return\n if (!satisfies(process.version, nodeEngine)) {\n throw new Error(\n `Node ${process.version} does not satisfy this app's required version \"${nodeEngine}\".`,\n )\n }\n}\n\nfunction ensureEnvironmentState(state: RailwayState, name: string): RailwayEnvironmentState {\n state.environments[name] ??= {}\n return state.environments[name] as RailwayEnvironmentState\n}\n\nfunction persistState(path: string, state: RailwayState): void {\n saveRailwayState(path, state)\n}\n\nasync function resolveTokenInteractively(\n options: RailwayDeployOptions,\n prompt: Prompt | null,\n): Promise<{ token: string; cached: boolean }> {\n const configPath = railwayTokenConfigPath()\n const resolved = resolveRailwayToken({ flagToken: options.token, configPath })\n if (resolved.token) return { token: resolved.token, cached: resolved.source === 'cache' }\n if (options.nonInteractive || !prompt) {\n const compatibilityHint = process.env.RAILWAY_TOKEN\n ? ' RAILWAY_TOKEN is project-scoped; use RAILWAY_API_TOKEN for account/workspace operations.'\n : ''\n throw new Error(`Railway Account token is required.${compatibilityHint}`)\n }\n console.log('Create a token at https://railway.com/account/tokens (Account Settings -> Tokens).')\n const token = (await prompt.ask('Railway Account token: ')).trim()\n if (!token) throw new Error('Railway Account token is required.')\n const persist = (await prompt.ask('Cache this token in ~/.config/open-mercato/railway.json? [y/N] ')).trim().toLowerCase()\n if (persist === 'y' || persist === 'yes') {\n writeCachedRailwayToken(configPath, token)\n return { token, cached: true }\n }\n return { token, cached: false }\n}\n\nasync function resolveWorkspace(\n client: RailwayGraphqlClient,\n preferredWorkspaceId?: string,\n): Promise<{ userId: string; workspaceId: string }> {\n let data: {\n me: { id: string; workspaces?: Array<{ id: string; name: string }> }\n }\n try {\n data = await client.request(railwayOperations.me)\n } catch (error) {\n if (\n error instanceof RailwayGraphqlError\n && (error.status === 401 || error.status === 403 || error.code === 'UNAUTHORIZED')\n ) {\n throw new Error(\n 'Token rejected. Generate a Railway Account token at https://railway.com/account/tokens.',\n )\n }\n throw error\n }\n const workspaces = data.me.workspaces ?? []\n const workspace = preferredWorkspaceId\n ? workspaces.find((candidate) => candidate.id === preferredWorkspaceId)\n : workspaces[0]\n if (preferredWorkspaceId && !workspace) {\n throw new Error('The recorded Railway workspace is no longer accessible to this Account token.')\n }\n if (!workspace) throw new Error('The Railway account has no accessible workspace.')\n return { userId: data.me.id, workspaceId: workspace.id }\n}\n\nasync function findProjectByName(\n client: RailwayGraphqlClient,\n workspaceId: string,\n projectName: string,\n): Promise<{ id: string; name: string } | null> {\n const data = await client.request<{\n projects: Connection<{ id: string; name: string }>\n }>(railwayOperations.projects, { workspaceId })\n return nodes(data.projects).find((project) => project.name === projectName) ?? null\n}\n\nasync function ensureProject(input: {\n client: RailwayGraphqlClient\n state: RailwayState\n statePath: string\n workspaceId: string\n options: RailwayDeployOptions\n}): Promise<string> {\n if (input.state.projectId) {\n try {\n const data = await input.client.request<{\n project: { id: string; name: string; workspaceId?: string | null }\n }>(\n railwayOperations.project,\n { id: input.state.projectId },\n )\n if (data.project.workspaceId && data.project.workspaceId !== input.workspaceId) {\n throw new Error('Recorded Railway project belongs to a different workspace.')\n }\n if (data.project.name !== input.state.projectName) {\n if (!input.options.forceRename) {\n throw new Error(\n `Recorded Railway project is named \"${data.project.name}\". Use --force-rename to rename it.`,\n )\n }\n await input.client.request(railwayOperations.projectUpdate, {\n id: data.project.id,\n input: { name: input.state.projectName },\n })\n }\n return data.project.id\n } catch (error) {\n if (!isNotFoundError(error)) throw error\n input.state.projectId = undefined\n }\n }\n\n const existing = await findProjectByName(\n input.client,\n input.workspaceId,\n input.state.projectName,\n )\n if (existing) {\n input.state.projectId = existing.id\n persistState(input.statePath, input.state)\n return existing.id\n }\n\n try {\n const data = await input.client.request<{\n projectCreate: { id: string }\n }>(railwayOperations.projectCreate, {\n input: {\n name: input.state.projectName,\n description: 'Open Mercato deployment managed by mercato deploy railway',\n workspaceId: input.workspaceId,\n },\n })\n input.state.projectId = data.projectCreate.id\n } catch (error) {\n const discovered = await findProjectByName(\n input.client,\n input.workspaceId,\n input.state.projectName,\n )\n if (!discovered) throw error\n input.state.projectId = discovered.id\n }\n persistState(input.statePath, input.state)\n return input.state.projectId as string\n}\n\nasync function ensureEnvironment(input: {\n client: RailwayGraphqlClient\n projectId: string\n name: string\n environmentState: RailwayEnvironmentState\n persist: () => void\n}): Promise<string> {\n if (input.environmentState.environmentId) {\n try {\n const data = await input.client.request<{ environment: { id: string } }>(\n railwayOperations.environment,\n { id: input.environmentState.environmentId, projectId: input.projectId },\n )\n return data.environment.id\n } catch (error) {\n if (!isNotFoundError(error)) throw error\n input.environmentState.environmentId = undefined\n }\n }\n const data = await input.client.request<{\n environments: Connection<{ id: string; name: string }>\n }>(railwayOperations.environments, { projectId: input.projectId })\n const existing = nodes(data.environments).find((environment) => environment.name === input.name)\n if (existing) {\n input.environmentState.environmentId = existing.id\n input.persist()\n return existing.id\n }\n try {\n const created = await input.client.request<{ environmentCreate: { id: string } }>(\n railwayOperations.environmentCreate,\n { input: { projectId: input.projectId, name: input.name } },\n )\n input.environmentState.environmentId = created.environmentCreate.id\n } catch (error) {\n const retryLookup = await input.client.request<{\n environments: Connection<{ id: string; name: string }>\n }>(railwayOperations.environments, { projectId: input.projectId })\n const discovered = nodes(retryLookup.environments).find((environment) => environment.name === input.name)\n if (!discovered) throw error\n input.environmentState.environmentId = discovered.id\n }\n input.persist()\n return input.environmentState.environmentId as string\n}\n\nasync function listServices(client: RailwayGraphqlClient, projectId: string): Promise<RailwayService[]> {\n const data = await client.request<{\n project: { services: Connection<RailwayService> }\n }>(railwayOperations.services, { projectId })\n return nodes(data.project.services)\n}\n\nasync function waitForService(\n client: RailwayGraphqlClient,\n projectId: string,\n name: string,\n timeoutMs = 180_000,\n): Promise<RailwayService> {\n const deadline = Date.now() + timeoutMs\n while (Date.now() < deadline) {\n const service = (await listServices(client, projectId)).find((candidate) => candidate.name === name)\n if (service) return service\n await wait(5_000)\n }\n throw new Error(`Timed out waiting for Railway service \"${name}\". Re-run the command to resume.`)\n}\n\nasync function ensureDatabaseReady(input: {\n client: RailwayGraphqlClient\n projectId: string\n environmentId: string\n serviceId: string\n name: string\n}): Promise<void> {\n const previous = await latestDeployment(\n input.client,\n input.projectId,\n input.environmentId,\n input.serviceId,\n )\n if (previous && SUCCESS_STATUSES.has(previous.status)) return\n if (previous && !FAILURE_STATUSES.has(previous.status)) {\n await waitForDeployment({\n client: input.client,\n deploymentId: previous.id,\n timeoutSeconds: 180,\n prefix: input.name,\n secrets: [],\n })\n return\n }\n\n let triggerError: unknown\n try {\n await input.client.request(railwayOperations.deploy, {\n environmentId: input.environmentId,\n serviceId: input.serviceId,\n commitSha: null,\n })\n } catch (error) {\n if (!isAmbiguousMutationError(error)) throw error\n triggerError = error\n }\n\n const deadline = Date.now() + 30_000\n while (Date.now() < deadline) {\n const current = await latestDeployment(\n input.client,\n input.projectId,\n input.environmentId,\n input.serviceId,\n )\n if (current && current.id !== previous?.id) {\n await waitForDeployment({\n client: input.client,\n deploymentId: current.id,\n timeoutSeconds: 180,\n prefix: input.name,\n secrets: [],\n })\n return\n }\n await wait(2_000)\n }\n if (triggerError) throw triggerError\n throw new Error(`Railway did not expose a ${input.name} deployment in this environment.`)\n}\n\nasync function ensureDatabase(input: {\n client: RailwayGraphqlClient\n projectId: string\n environmentId: string\n workspaceId: string\n name: 'Postgres' | 'Redis'\n code: 'postgres' | 'redis'\n currentId?: string\n previousSource?: RailwaySource\n onResolved: (id: string) => void\n}): Promise<string> {\n if (input.currentId) {\n try {\n const data = await input.client.request<{\n service: { id: string; projectId: string }\n }>(\n railwayOperations.service,\n { id: input.currentId },\n )\n if (data.service.projectId !== input.projectId) {\n throw new Error(`Recorded ${input.name} service belongs to a different Railway project.`)\n }\n await ensureDatabaseReady({\n client: input.client,\n projectId: input.projectId,\n environmentId: input.environmentId,\n serviceId: data.service.id,\n name: input.name,\n })\n return data.service.id\n } catch (error) {\n if (!isNotFoundError(error)) throw error\n }\n }\n const existing = (await listServices(input.client, input.projectId))\n .find((service) => service.name === input.name)\n if (existing) {\n await ensureDatabaseReady({\n client: input.client,\n projectId: input.projectId,\n environmentId: input.environmentId,\n serviceId: existing.id,\n name: input.name,\n })\n input.onResolved(existing.id)\n return existing.id\n }\n const templateData = await input.client.request<{\n template: { id: string; serializedConfig?: string | null }\n }>(railwayOperations.template, { code: input.code })\n if (!templateData.template.serializedConfig) {\n throw new Error(`Railway template \"${input.code}\" does not expose a deployable configuration.`)\n }\n try {\n await input.client.request(railwayOperations.templateDeploy, {\n input: {\n projectId: input.projectId,\n environmentId: input.environmentId,\n workspaceId: input.workspaceId,\n templateId: templateData.template.id,\n serializedConfig: templateData.template.serializedConfig,\n },\n })\n } catch (error) {\n const discovered = (await listServices(input.client, input.projectId))\n .find((service) => service.name === input.name)\n if (!discovered) throw error\n }\n const created = await waitForService(input.client, input.projectId, input.name)\n const readinessDeadline = Date.now() + 180_000\n let ready = false\n while (Date.now() < readinessDeadline) {\n const deployment = await latestDeployment(\n input.client,\n input.projectId,\n input.environmentId,\n created.id,\n )\n if (deployment && SUCCESS_STATUSES.has(deployment.status)) {\n ready = true\n break\n }\n if (deployment && FAILURE_STATUSES.has(deployment.status)) {\n throw new Error(`${input.name} provisioning failed with status ${deployment.status}.`)\n }\n await wait(5_000)\n }\n if (!ready) {\n throw new Error(`Timed out waiting for ${input.name} to become ready. Re-run the command to resume.`)\n }\n input.onResolved(created.id)\n return created.id\n}\n\nasync function ensureService(input: {\n client: RailwayGraphqlClient\n projectId: string\n environmentId: string\n name: string\n source: RailwaySource\n currentId?: string\n previousSource?: RailwaySource\n startCommand?: string\n region?: string\n railwayConfigFile?: string\n onResolved: (id: string) => void\n}): Promise<string> {\n let serviceId: string | undefined\n let createdService = false\n if (input.currentId) {\n try {\n const data = await input.client.request<{\n service: { id: string; projectId: string }\n }>(\n railwayOperations.service,\n { id: input.currentId },\n )\n if (data.service.projectId !== input.projectId) {\n throw new Error(`Recorded ${input.name} service belongs to a different Railway project.`)\n }\n serviceId = data.service.id\n } catch (error) {\n if (!isNotFoundError(error)) throw error\n }\n }\n if (!serviceId) {\n const existing = (await listServices(input.client, input.projectId))\n .find((service) => service.name === input.name)\n serviceId = existing?.id\n }\n if (!serviceId) {\n const serviceInput: Record<string, unknown> = {\n projectId: input.projectId,\n name: input.name,\n }\n if (input.source.mode === 'git') {\n serviceInput.source = { repo: input.source.repo }\n serviceInput.branch = input.source.branch\n }\n try {\n const created = await input.client.request<{ serviceCreate: { id: string } }>(\n railwayOperations.serviceCreate,\n { input: serviceInput },\n )\n serviceId = created.serviceCreate.id\n createdService = true\n } catch (error) {\n const discovered = (await listServices(input.client, input.projectId))\n .find((service) => service.name === input.name)\n if (!discovered) throw error\n serviceId = discovered.id\n }\n }\n if (input.source.mode === 'git' && !createdService) {\n await input.client.request(railwayOperations.serviceConnect, {\n id: serviceId,\n input: {\n repo: input.source.repo,\n branch: input.source.branch,\n },\n })\n } else if (input.source.mode === 'local' && input.previousSource?.mode === 'git') {\n await input.client.request(railwayOperations.serviceDisconnect, { id: serviceId })\n }\n if (input.startCommand || input.region || input.railwayConfigFile) {\n await input.client.request(railwayOperations.serviceInstanceUpdate, {\n environmentId: input.environmentId,\n serviceId,\n input: {\n ...(input.startCommand ? { startCommand: input.startCommand } : {}),\n ...(input.region ? { region: input.region } : {}),\n ...(input.railwayConfigFile ? { railwayConfigFile: input.railwayConfigFile } : {}),\n },\n })\n }\n input.onResolved(serviceId)\n return serviceId\n}\n\nasync function removeDisabledWorker(input: {\n client: RailwayGraphqlClient\n projectId: string\n environmentId: string\n workerServiceId?: string\n}): Promise<void> {\n if (!input.workerServiceId) return\n try {\n const data = await input.client.request<{\n service: { id: string; name: string; projectId: string }\n }>(railwayOperations.service, { id: input.workerServiceId })\n if (data.service.projectId !== input.projectId || data.service.name !== 'mercato-worker') {\n throw new Error('Recorded worker service does not match the managed Railway project.')\n }\n } catch (error) {\n if (isNotFoundError(error)) return\n throw error\n }\n try {\n await input.client.request(railwayOperations.serviceDelete, {\n id: input.workerServiceId,\n environmentId: input.environmentId,\n })\n } catch (error) {\n try {\n await input.client.request(railwayOperations.service, { id: input.workerServiceId })\n } catch (lookupError) {\n if (isNotFoundError(lookupError)) return\n throw lookupError\n }\n throw error\n }\n}\n\nasync function upsertVariables(input: {\n client: RailwayGraphqlClient\n projectId: string\n environmentId: string\n serviceId: string\n variables: Record<string, string>\n}): Promise<void> {\n await input.client.request(railwayOperations.variableUpsert, {\n input: {\n projectId: input.projectId,\n environmentId: input.environmentId,\n serviceId: input.serviceId,\n variables: input.variables,\n replace: false,\n skipDeploys: true,\n },\n })\n}\n\nasync function loadVariables(input: {\n client: RailwayGraphqlClient\n projectId: string\n environmentId: string\n serviceId: string\n}): Promise<Record<string, string>> {\n const data = await input.client.request<{ variables: unknown }>(\n railwayOperations.variables,\n {\n projectId: input.projectId,\n environmentId: input.environmentId,\n serviceId: input.serviceId,\n },\n )\n if (!data.variables || typeof data.variables !== 'object' || Array.isArray(data.variables)) return {}\n return Object.fromEntries(\n Object.entries(data.variables as Record<string, unknown>)\n .filter((entry): entry is [string, string] => typeof entry[1] === 'string'),\n )\n}\n\nasync function latestDeployment(\n client: RailwayGraphqlClient,\n projectId: string,\n environmentId: string,\n serviceId: string,\n): Promise<RailwayDeployment | null> {\n const data = await client.request<{\n deployments: Connection<RailwayDeployment>\n }>(railwayOperations.deployments, { projectId, environmentId, serviceId })\n return nodes(data.deployments)[0] ?? null\n}\n\nasync function printDeploymentLogs(\n client: RailwayGraphqlClient,\n deploymentId: string,\n prefix: string,\n secrets: string[],\n): Promise<void> {\n for (const operation of [railwayOperations.buildLogs, railwayOperations.deploymentLogs]) {\n try {\n const data = await client.request<Record<string, Array<{ message?: string }>>>(\n operation,\n { deploymentId, limit: 100 },\n )\n const logKey = operation === railwayOperations.buildLogs ? 'buildLogs' : 'deploymentLogs'\n for (const entry of data[logKey] ?? []) {\n if (entry.message) console.log(`[${prefix}] ${redactText(entry.message, secrets)}`)\n }\n } catch {\n // Log retrieval is best-effort; deployment status remains authoritative.\n }\n }\n}\n\nasync function waitForDeployment(input: {\n client: RailwayGraphqlClient\n deploymentId: string\n timeoutSeconds: number\n prefix: string\n secrets: string[]\n}): Promise<RailwayDeployment> {\n const deadline = Date.now() + input.timeoutSeconds * 1_000\n let lastStatus = 'UNKNOWN'\n while (Date.now() < deadline) {\n const data = await input.client.request<{ deployment: RailwayDeployment }>(\n railwayOperations.deployment,\n { id: input.deploymentId },\n )\n lastStatus = data.deployment.status\n if (SUCCESS_STATUSES.has(lastStatus)) return data.deployment\n if (FAILURE_STATUSES.has(lastStatus)) {\n await printDeploymentLogs(\n input.client,\n input.deploymentId,\n input.prefix,\n input.secrets,\n )\n throw new Error(`${input.prefix} deployment failed with status ${lastStatus}.`)\n }\n await wait(5_000)\n }\n throw new Error(\n `Timed out waiting for ${input.prefix} deployment. Last status: ${lastStatus}. Re-run the command to resume.`,\n )\n}\n\nasync function deployService(input: {\n client: RailwayGraphqlClient\n cwd: string\n source: RailwaySource\n projectId: string\n environmentId: string\n serviceId: string\n serviceName: string\n timeoutSeconds: number\n token: string\n secrets: string[]\n}): Promise<RailwayDeployment> {\n const previous = await latestDeployment(\n input.client,\n input.projectId,\n input.environmentId,\n input.serviceId,\n )\n let deploymentId: string | null = null\n let triggerError: unknown\n try {\n if (input.source.mode === 'git') {\n await input.client.request(railwayOperations.deploy, {\n environmentId: input.environmentId,\n serviceId: input.serviceId,\n commitSha: input.source.commitSha,\n })\n } else {\n deploymentId = uploadLocalSource({\n cwd: input.cwd,\n projectId: input.projectId,\n environmentId: input.environmentId,\n serviceId: input.serviceId,\n serviceName: input.serviceName,\n token: input.token,\n })\n }\n } catch (error) {\n if (!isAmbiguousMutationError(error)) throw error\n triggerError = error\n }\n if (!deploymentId) {\n const deadline = Date.now() + 30_000\n while (Date.now() < deadline) {\n const current = await latestDeployment(\n input.client,\n input.projectId,\n input.environmentId,\n input.serviceId,\n )\n if (current && current.id !== previous?.id) {\n deploymentId = current.id\n break\n }\n await wait(2_000)\n }\n }\n if (!deploymentId) {\n if (triggerError) throw triggerError\n throw new Error(`Railway did not expose a new deployment for ${input.serviceName}.`)\n }\n return waitForDeployment({\n client: input.client,\n deploymentId,\n timeoutSeconds: input.timeoutSeconds,\n prefix: input.serviceName,\n secrets: [input.token, ...input.secrets],\n })\n}\n\nfunction collectSensitiveValues(variables: Record<string, string>): string[] {\n return collectSensitiveStructuredValues(variables)\n}\n\nasync function ensureDomain(input: {\n client: RailwayGraphqlClient\n projectId: string\n environmentId: string\n serviceId: string\n customDomain?: string\n waitForVerification: boolean\n currentDomainId?: string\n}): Promise<{ id: string; url: string }> {\n type DnsRecord = {\n hostlabel?: string\n requiredValue?: string\n recordType?: string\n }\n type CustomDomain = {\n id: string\n domain: string\n status?: {\n verified?: boolean\n dnsRecords?: DnsRecord[]\n }\n }\n type ServiceDomain = {\n id: string\n domain: string\n }\n\n const existingData = await input.client.request<{\n domains: {\n customDomains?: CustomDomain[]\n serviceDomains?: ServiceDomain[]\n }\n }>(railwayOperations.domains, {\n projectId: input.projectId,\n environmentId: input.environmentId,\n serviceId: input.serviceId,\n })\n\n if (!input.customDomain && input.currentDomainId) {\n const existingCustomDomain = existingData.domains.customDomains?.find(\n (candidate) => candidate.id === input.currentDomainId,\n )\n if (existingCustomDomain) {\n return {\n id: existingCustomDomain.id,\n url: `https://${existingCustomDomain.domain}`,\n }\n }\n const existingRecordedServiceDomain = existingData.domains.serviceDomains?.find(\n (candidate) => candidate.id === input.currentDomainId,\n )\n if (existingRecordedServiceDomain) {\n return {\n id: existingRecordedServiceDomain.id,\n url: `https://${existingRecordedServiceDomain.domain}`,\n }\n }\n }\n\n if (input.customDomain) {\n const existingDomain = existingData.domains.customDomains?.find(\n (candidate) => candidate.domain === input.customDomain,\n )\n let domain: CustomDomain\n if (existingDomain) {\n domain = existingDomain\n } else {\n try {\n const data = await input.client.request<{ customDomainCreate: CustomDomain }>(\n railwayOperations.customDomainCreate,\n {\n input: {\n projectId: input.projectId,\n environmentId: input.environmentId,\n serviceId: input.serviceId,\n domain: input.customDomain,\n targetPort: 3000,\n },\n },\n )\n domain = data.customDomainCreate\n } catch (error) {\n const discovered = await input.client.request<{\n domains: { customDomains?: CustomDomain[] }\n }>(railwayOperations.domains, {\n projectId: input.projectId,\n environmentId: input.environmentId,\n serviceId: input.serviceId,\n })\n const created = discovered.domains.customDomains?.find(\n (candidate) => candidate.domain === input.customDomain,\n )\n if (!created) throw error\n domain = created\n }\n }\n const records = domain.status?.dnsRecords ?? []\n if (records.length > 0) {\n console.log('Configure these DNS records:')\n for (const record of records) {\n console.log(` ${record.recordType ?? 'DNS'} ${record.hostlabel ?? '@'} -> ${record.requiredValue ?? ''}`)\n }\n }\n if (input.waitForVerification && !domain.status?.verified) {\n const deadline = Date.now() + 300_000\n while (Date.now() < deadline) {\n await wait(10_000)\n const refreshed: { customDomain: CustomDomain } = await input.client.request(\n railwayOperations.customDomain,\n { id: domain.id, projectId: input.projectId },\n )\n domain = refreshed.customDomain\n if (domain.status?.verified) break\n }\n if (!domain.status?.verified) {\n console.warn('DNS not yet propagated. The deployment succeeded; re-run later to verify the domain.')\n }\n }\n return {\n id: domain.id,\n url: `https://${domain.domain}`,\n }\n }\n const existingServiceDomain = existingData.domains.serviceDomains?.[0]\n if (existingServiceDomain) {\n return {\n id: existingServiceDomain.id,\n url: `https://${existingServiceDomain.domain}`,\n }\n }\n let createdDomain: ServiceDomain\n try {\n const data = await input.client.request<{\n serviceDomainCreate: ServiceDomain\n }>(railwayOperations.serviceDomainCreate, {\n input: {\n environmentId: input.environmentId,\n serviceId: input.serviceId,\n targetPort: 3000,\n },\n })\n createdDomain = data.serviceDomainCreate\n } catch (error) {\n const discovered = await input.client.request<{\n domains: { serviceDomains?: ServiceDomain[] }\n }>(railwayOperations.domains, {\n projectId: input.projectId,\n environmentId: input.environmentId,\n serviceId: input.serviceId,\n })\n const created = discovered.domains.serviceDomains?.[0]\n if (!created) throw error\n createdDomain = created\n }\n return {\n id: createdDomain.id,\n url: `https://${createdDomain.domain}`,\n }\n}\n\nasync function cleanupProject(input: {\n client: RailwayGraphqlClient\n state: RailwayState\n statePath: string\n options: RailwayDeployOptions\n prompt: Prompt | null\n workspaceId: string\n}): Promise<void> {\n if (!input.state.projectId) throw new Error('The Railway state file does not contain a project ID.')\n if (input.state.workspaceId && input.state.workspaceId !== input.workspaceId) {\n throw new Error('Recorded Railway project belongs to a different workspace.')\n }\n const projectData = await input.client.request<{\n project: { id: string; name: string; workspaceId?: string | null }\n }>(railwayOperations.project, { id: input.state.projectId })\n if (\n projectData.project.name !== input.state.projectName\n || (projectData.project.workspaceId && projectData.project.workspaceId !== input.workspaceId)\n ) {\n throw new Error('Recorded Railway project identity does not match the cleanup target.')\n }\n if (!input.options.yes) {\n if (input.options.nonInteractive || !input.prompt) {\n throw new Error('--cleanup requires --yes in non-interactive mode.')\n }\n console.log(`Project: ${input.state.projectName} (${input.state.projectId})`)\n for (const [name, environment] of Object.entries(input.state.environments)) {\n console.log(` ${name}: ${environment.appUrl ?? 'no recorded URL'}`)\n }\n const confirmation = await input.prompt.ask(`Type \"${input.state.projectName}\" to delete this project: `)\n if (confirmation.trim() !== input.state.projectName) throw new Error('Cleanup cancelled.')\n }\n await input.client.request(railwayOperations.projectDelete, { id: input.state.projectId })\n if (existsSync(input.statePath)) unlinkSync(input.statePath)\n console.log(`Deleted Railway project ${input.state.projectName}.`)\n}\n\nfunction printDryRun(input: {\n state: RailwayState\n options: RailwayDeployOptions\n source: RailwaySource\n envFile: string\n appVariables: Record<string, string>\n workerVariables?: Record<string, string>\n}): void {\n console.log('Railway deployment plan (dry run)')\n console.log(` Project: ${input.state.projectName}`)\n console.log(` Environment: ${input.options.environment}`)\n console.log(` Source: ${input.source.mode} (${input.source.reason})`)\n console.log(` Env file: ${input.envFile}`)\n console.log(' Operations:')\n console.log(' - validate Railway account and workspace')\n console.log(' - create or reuse project and environment')\n console.log(' - provision Postgres and Redis from Railway templates')\n console.log(` - create or reuse ${input.options.service}`)\n if (input.options.worker) console.log(' - create or reuse mercato-worker')\n if (\n !input.options.worker\n && input.state.environments[input.options.environment]?.workerServiceId\n ) {\n console.log(' - delete the recorded managed mercato-worker service')\n }\n console.log(' - upsert service variables')\n console.log(` - deploy via ${input.source.mode === 'git' ? 'Railway Git source' : 'railway up'}`)\n console.log(' - create a Railway or custom domain and redeploy the app')\n if (input.options.volume) console.log(` - create volume mounted at ${input.options.volume}`)\n console.log(' App variables:')\n for (const line of formatVariablePlan(input.appVariables, input.options.token)) console.log(` ${line}`)\n if (input.workerVariables) {\n console.log(' Worker variables:')\n for (const line of formatVariablePlan(input.workerVariables, input.options.token)) console.log(` ${line}`)\n }\n}\n\nexport async function runRailwayDeploy(\n args: string[],\n dependencies: {\n cwd?: string\n prompt?: Prompt | null\n resolveSource?: typeof resolveRailwaySource\n } = {},\n): Promise<void> {\n const options = parseRailwayDeployOptions(args)\n if (options.help) {\n console.log(railwayDeployHelp())\n return\n }\n const cwd = dependencies.cwd ?? process.cwd()\n const appPackage = readAppPackage(cwd)\n assertSupportedNodeVersion(appPackage.nodeEngine)\n const statePath = railwayStatePath(cwd, options.track)\n const loadedState = loadRailwayState(statePath)\n const requestedName = normalizeProjectName(options.project || appPackage.name)\n const state = loadedState ?? createRailwayState(requestedName, process.env.npm_package_version || 'unknown')\n if (options.cleanup && !state.projectId) {\n throw new Error('The Railway state file does not contain a project ID.')\n }\n if (loadedState && options.project && requestedName !== loadedState.projectName) {\n if (!options.forceRename) {\n throw new Error(\n `State records project \"${loadedState.projectName}\". Pass --force-rename to use \"${requestedName}\".`,\n )\n }\n state.projectName = requestedName\n }\n const environmentState = ensureEnvironmentState(state, options.environment)\n const source = options.cleanup\n ? { mode: 'local' as const, reason: 'cleanup does not deploy source' }\n : (dependencies.resolveSource ?? resolveRailwaySource)(options.source, cwd)\n if (options.cleanup && options.dryRun) {\n console.log('Railway cleanup plan (dry run)')\n console.log(` Project: ${state.projectName} (${state.projectId})`)\n console.log(` State: ${statePath}`)\n console.log(' Operation: projectDelete')\n return\n }\n if (!options.cleanup && !options.dryRun) {\n console.log(`Source: ${source.mode} (${source.reason})`)\n }\n if (!options.cleanup && source.mode === 'local') assertLocalUploadSafe(cwd)\n const envFile = options.cleanup ? '' : resolveEnvFile(cwd, options.envFile)\n const localEnv = options.cleanup ? {} : parseEnvFile(readFileSync(envFile, 'utf8'))\n let protectedSecrets = options.dryRun\n ? {\n AUTH_SECRET: 'generated-at-deploy',\n JWT_SECRET: 'generated-at-deploy',\n TENANT_DATA_ENCRYPTION_FALLBACK_KEY: 'generated-at-deploy',\n }\n : generateProtectedSecrets(localEnv)\n let appVariables = computeRailwayVariables({\n env: localEnv,\n role: 'app',\n workerEnabled: options.worker,\n protectedSecrets,\n railwayToken: options.token || process.env.RAILWAY_API_TOKEN,\n allowedSecretKeys: options.allowedSecretKeys,\n })\n let workerVariables = options.worker\n ? computeRailwayVariables({\n env: localEnv,\n role: 'worker',\n workerEnabled: true,\n protectedSecrets,\n railwayToken: options.token || process.env.RAILWAY_API_TOKEN,\n allowedSecretKeys: options.allowedSecretKeys,\n })\n : undefined\n\n if (options.dryRun) {\n printDryRun({ state, options, source, envFile, appVariables, workerVariables })\n return\n }\n\n const ownsPrompt = dependencies.prompt === undefined\n const prompt = dependencies.prompt === undefined\n ? (!options.nonInteractive && process.stdin.isTTY ? createPrompt() : null)\n : dependencies.prompt\n try {\n const tokenResult = await resolveTokenInteractively(options, prompt)\n const client = createRailwayGraphqlClient({\n token: tokenResult.token,\n verbose: options.verbose,\n })\n console.log('Step 1: Authenticate with Railway')\n const { workspaceId } = await resolveWorkspace(client, state.workspaceId)\n\n if (options.cleanup) {\n await cleanupProject({ client, state, statePath, options, prompt, workspaceId })\n return\n }\n state.workspaceId = workspaceId\n persistState(statePath, state)\n\n console.log('Step 2: Resolve workspace')\n console.log(`Step 3: Create or look up project \"${state.projectName}\"`)\n const projectId = await ensureProject({ client, state, statePath, workspaceId, options })\n console.log(`Step 4: Create or look up environment \"${options.environment}\"`)\n const environmentId = await ensureEnvironment({\n client,\n projectId,\n name: options.environment,\n environmentState,\n persist: () => persistState(statePath, state),\n })\n\n if (options.region) {\n const regionData = await client.request<{\n regions: Array<{ id?: string | null; name: string; region?: string | null }>\n }>(\n railwayOperations.regions,\n { projectId },\n )\n if (!regionData.regions.some(\n (region) => region.id === options.region || region.region === options.region,\n )) {\n throw new Error(`Unknown Railway region \"${options.region}\".`)\n }\n }\n\n console.log('Step 5: Provision managed Postgres and Redis')\n await ensureDatabase({\n client,\n projectId,\n environmentId,\n workspaceId,\n name: 'Postgres',\n code: 'postgres',\n currentId: environmentState.postgresServiceId,\n onResolved: (id) => {\n environmentState.postgresServiceId = id\n persistState(statePath, state)\n },\n })\n await ensureDatabase({\n client,\n projectId,\n environmentId,\n workspaceId,\n name: 'Redis',\n code: 'redis',\n currentId: environmentState.redisServiceId,\n onResolved: (id) => {\n environmentState.redisServiceId = id\n persistState(statePath, state)\n },\n })\n\n console.log('Step 6: Create app and worker services')\n const previousSource = environmentState.source\n const appServiceId = await ensureService({\n client,\n projectId,\n environmentId,\n name: options.service,\n source,\n currentId: environmentState.appServiceId,\n previousSource,\n startCommand: 'sh ./scripts/railway-start.sh',\n region: options.region,\n railwayConfigFile: 'railway.toml',\n onResolved: (id) => {\n environmentState.appServiceId = id\n environmentState.source = source\n persistState(statePath, state)\n },\n })\n const workerServiceId = options.worker\n ? await ensureService({\n client,\n projectId,\n environmentId,\n name: 'mercato-worker',\n source,\n currentId: environmentState.workerServiceId,\n previousSource,\n startCommand: 'sh ./scripts/railway-worker.sh',\n region: options.region,\n railwayConfigFile: 'railway.worker.toml',\n onResolved: (id) => {\n environmentState.workerServiceId = id\n persistState(statePath, state)\n },\n })\n : undefined\n if (!options.worker && environmentState.workerServiceId) {\n await removeDisabledWorker({\n client,\n projectId,\n environmentId,\n workerServiceId: environmentState.workerServiceId,\n })\n environmentState.workerServiceId = undefined\n if (environmentState.lastDeployIds) {\n delete environmentState.lastDeployIds.worker\n }\n persistState(statePath, state)\n }\n\n if (options.volume) {\n if (environmentState.volumeId) {\n const volumeData = await client.request<{\n project: {\n volumes: Connection<{\n id: string\n volumeInstances: Connection<{\n environmentId: string\n serviceId?: string | null\n mountPath: string\n }>\n }>\n }\n }>(railwayOperations.volumes, { projectId })\n const recordedVolume = nodes(volumeData.project.volumes).find(\n (volume) => volume.id === environmentState.volumeId\n && nodes(volume.volumeInstances).some((instance) =>\n instance.environmentId === environmentId\n && instance.serviceId === appServiceId\n && instance.mountPath === options.volume,\n ),\n )\n if (!recordedVolume) environmentState.volumeId = undefined\n }\n }\n if (options.volume && !environmentState.volumeId) {\n try {\n const volumeData = await client.request<{ volumeCreate: { id: string } }>(\n railwayOperations.volumeCreate,\n {\n input: {\n projectId,\n environmentId,\n serviceId: appServiceId,\n mountPath: options.volume,\n },\n },\n )\n environmentState.volumeId = volumeData.volumeCreate.id\n } catch (error) {\n const volumeData = await client.request<{\n project: {\n volumes: Connection<{\n id: string\n volumeInstances: Connection<{\n environmentId: string\n serviceId?: string | null\n mountPath: string\n }>\n }>\n }\n }>(railwayOperations.volumes, { projectId })\n const discovered = nodes(volumeData.project.volumes).find((volume) =>\n nodes(volume.volumeInstances).some((instance) =>\n instance.environmentId === environmentId\n && instance.serviceId === appServiceId\n && instance.mountPath === options.volume,\n ),\n )\n if (!discovered) throw error\n environmentState.volumeId = discovered.id\n }\n persistState(statePath, state)\n }\n if (!options.volume) {\n console.warn(\n 'Attachments uploaded to this deployment will be lost on redeploy. Re-run with --volume /app/storage to enable persistent storage.',\n )\n }\n\n console.log('Step 7: Compute and upload environment variables')\n const existingVariables = await loadVariables({\n client,\n projectId,\n environmentId,\n serviceId: appServiceId,\n })\n protectedSecrets = generateProtectedSecrets({ ...localEnv, ...existingVariables })\n appVariables = computeRailwayVariables({\n env: localEnv,\n role: 'app',\n workerEnabled: options.worker,\n protectedSecrets,\n railwayToken: tokenResult.token,\n allowedSecretKeys: options.allowedSecretKeys,\n })\n workerVariables = options.worker\n ? computeRailwayVariables({\n env: localEnv,\n role: 'worker',\n workerEnabled: true,\n protectedSecrets,\n railwayToken: tokenResult.token,\n allowedSecretKeys: options.allowedSecretKeys,\n })\n : undefined\n await upsertVariables({ client, projectId, environmentId, serviceId: appServiceId, variables: appVariables })\n if (workerServiceId && workerVariables) {\n await upsertVariables({\n client,\n projectId,\n environmentId,\n serviceId: workerServiceId,\n variables: workerVariables,\n })\n }\n if (options.writeEnv) writeGeneratedSecrets(envFile, protectedSecrets)\n\n console.log('Step 8: Trigger deployment and monitor status')\n const appDeployment = await deployService({\n client,\n cwd,\n source,\n projectId,\n environmentId,\n serviceId: appServiceId,\n serviceName: options.service,\n timeoutSeconds: options.timeoutSeconds,\n token: tokenResult.token,\n secrets: collectSensitiveValues(appVariables),\n })\n environmentState.lastDeployIds ??= {}\n environmentState.lastDeployIds.app = appDeployment.id\n persistState(statePath, state)\n if (workerServiceId) {\n const workerDeployment = await deployService({\n client,\n cwd,\n source,\n projectId,\n environmentId,\n serviceId: workerServiceId,\n serviceName: 'mercato-worker',\n timeoutSeconds: options.timeoutSeconds,\n token: tokenResult.token,\n secrets: collectSensitiveValues(workerVariables ?? {}),\n })\n environmentState.lastDeployIds.worker = workerDeployment.id\n persistState(statePath, state)\n }\n\n console.log('Step 9: Provision public domain')\n const domain = await ensureDomain({\n client,\n projectId,\n environmentId,\n serviceId: appServiceId,\n customDomain: options.domain,\n waitForVerification: options.waitDomain,\n currentDomainId: environmentState.domainId,\n })\n environmentState.domainId = domain.id\n environmentState.appUrl = domain.url\n persistState(statePath, state)\n const finalAppVariables = { ...appVariables, APP_URL: domain.url, NEXT_PUBLIC_APP_URL: domain.url }\n await upsertVariables({\n client,\n projectId,\n environmentId,\n serviceId: appServiceId,\n variables: finalAppVariables,\n })\n const finalDeployment = await deployService({\n client,\n cwd,\n source,\n projectId,\n environmentId,\n serviceId: appServiceId,\n serviceName: options.service,\n timeoutSeconds: options.timeoutSeconds,\n token: tokenResult.token,\n secrets: collectSensitiveValues(finalAppVariables),\n })\n environmentState.lastDeployIds.app = finalDeployment.id\n persistState(statePath, state)\n\n console.log('Step 10: Deployment complete')\n console.log('')\n console.log('Open Mercato deployed to Railway')\n console.log(` Project: https://railway.com/project/${projectId}`)\n console.log(` Environment: ${options.environment}`)\n console.log(` Source: ${source.mode}`)\n console.log(` App URL: ${domain.url}`)\n console.log(` Health: ${domain.url}/api/healthz`)\n if (workerServiceId) console.log(' Worker: mercato-worker (running)')\n console.log(` State: ${statePath}`)\n if (tokenResult.cached) console.log(` Token cache: ${railwayTokenConfigPath()}`)\n console.log('')\n console.log(`DEPLOY_URL=${domain.url}`)\n } finally {\n if (ownsPrompt) prompt?.close()\n }\n}\n\nexport {\n parseRailwayDeployOptions,\n railwayDeployHelp,\n computeRailwayVariables,\n formatVariablePlan,\n generateProtectedSecrets,\n parseEnvFile,\n resolveEnvFile,\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["input", "data"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
const railwayOperations = {
|
|
2
|
+
me: {
|
|
3
|
+
name: "RailwayMe",
|
|
4
|
+
query: `query RailwayMe {
|
|
5
|
+
me { id name email workspaces { id name } }
|
|
6
|
+
}`
|
|
7
|
+
},
|
|
8
|
+
project: {
|
|
9
|
+
name: "RailwayProject",
|
|
10
|
+
query: `query RailwayProject($id: String!) {
|
|
11
|
+
project(id: $id) { id name workspaceId }
|
|
12
|
+
}`
|
|
13
|
+
},
|
|
14
|
+
projects: {
|
|
15
|
+
name: "RailwayProjects",
|
|
16
|
+
query: `query RailwayProjects($workspaceId: String!) {
|
|
17
|
+
projects(workspaceId: $workspaceId, first: 100, includeDeleted: false) {
|
|
18
|
+
edges { node { id name } }
|
|
19
|
+
}
|
|
20
|
+
}`
|
|
21
|
+
},
|
|
22
|
+
projectCreate: {
|
|
23
|
+
name: "RailwayProjectCreate",
|
|
24
|
+
mutation: true,
|
|
25
|
+
query: `mutation RailwayProjectCreate($input: ProjectCreateInput!) {
|
|
26
|
+
projectCreate(input: $input) { id name }
|
|
27
|
+
}`
|
|
28
|
+
},
|
|
29
|
+
projectUpdate: {
|
|
30
|
+
name: "RailwayProjectUpdate",
|
|
31
|
+
mutation: true,
|
|
32
|
+
query: `mutation RailwayProjectUpdate($id: String!, $input: ProjectUpdateInput!) {
|
|
33
|
+
projectUpdate(id: $id, input: $input) { id name }
|
|
34
|
+
}`
|
|
35
|
+
},
|
|
36
|
+
projectDelete: {
|
|
37
|
+
name: "RailwayProjectDelete",
|
|
38
|
+
mutation: true,
|
|
39
|
+
query: `mutation RailwayProjectDelete($id: String!) {
|
|
40
|
+
projectDelete(id: $id)
|
|
41
|
+
}`
|
|
42
|
+
},
|
|
43
|
+
environments: {
|
|
44
|
+
name: "RailwayEnvironments",
|
|
45
|
+
query: `query RailwayEnvironments($projectId: String!) {
|
|
46
|
+
environments(projectId: $projectId, first: 100) {
|
|
47
|
+
edges { node { id name } }
|
|
48
|
+
}
|
|
49
|
+
}`
|
|
50
|
+
},
|
|
51
|
+
environment: {
|
|
52
|
+
name: "RailwayEnvironment",
|
|
53
|
+
query: `query RailwayEnvironment($id: String!, $projectId: String!) {
|
|
54
|
+
environment(id: $id, projectId: $projectId) { id name }
|
|
55
|
+
}`
|
|
56
|
+
},
|
|
57
|
+
environmentCreate: {
|
|
58
|
+
name: "RailwayEnvironmentCreate",
|
|
59
|
+
mutation: true,
|
|
60
|
+
query: `mutation RailwayEnvironmentCreate($input: EnvironmentCreateInput!) {
|
|
61
|
+
environmentCreate(input: $input) { id name }
|
|
62
|
+
}`
|
|
63
|
+
},
|
|
64
|
+
regions: {
|
|
65
|
+
name: "RailwayRegions",
|
|
66
|
+
query: `query RailwayRegions($projectId: String!) {
|
|
67
|
+
regions(projectId: $projectId) { id name region location }
|
|
68
|
+
}`
|
|
69
|
+
},
|
|
70
|
+
template: {
|
|
71
|
+
name: "RailwayTemplate",
|
|
72
|
+
query: `query RailwayTemplate($code: String!) {
|
|
73
|
+
template(code: $code) { id code serializedConfig }
|
|
74
|
+
}`
|
|
75
|
+
},
|
|
76
|
+
templateDeploy: {
|
|
77
|
+
name: "RailwayTemplateDeploy",
|
|
78
|
+
mutation: true,
|
|
79
|
+
query: `mutation RailwayTemplateDeploy($input: TemplateDeployV2Input!) {
|
|
80
|
+
templateDeployV2(input: $input) { workflowId }
|
|
81
|
+
}`
|
|
82
|
+
},
|
|
83
|
+
services: {
|
|
84
|
+
name: "RailwayServices",
|
|
85
|
+
query: `query RailwayServices($projectId: String!) {
|
|
86
|
+
project(id: $projectId) { services { edges { node { id name } } } }
|
|
87
|
+
}`
|
|
88
|
+
},
|
|
89
|
+
volumes: {
|
|
90
|
+
name: "RailwayVolumes",
|
|
91
|
+
query: `query RailwayVolumes($projectId: String!) {
|
|
92
|
+
project(id: $projectId) {
|
|
93
|
+
volumes {
|
|
94
|
+
edges {
|
|
95
|
+
node {
|
|
96
|
+
id
|
|
97
|
+
volumeInstances {
|
|
98
|
+
edges { node { environmentId serviceId mountPath } }
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}`
|
|
105
|
+
},
|
|
106
|
+
service: {
|
|
107
|
+
name: "RailwayService",
|
|
108
|
+
query: `query RailwayService($id: String!) {
|
|
109
|
+
service(id: $id) { id name projectId }
|
|
110
|
+
}`
|
|
111
|
+
},
|
|
112
|
+
serviceCreate: {
|
|
113
|
+
name: "RailwayServiceCreate",
|
|
114
|
+
mutation: true,
|
|
115
|
+
query: `mutation RailwayServiceCreate($input: ServiceCreateInput!) {
|
|
116
|
+
serviceCreate(input: $input) { id name }
|
|
117
|
+
}`
|
|
118
|
+
},
|
|
119
|
+
serviceDelete: {
|
|
120
|
+
name: "RailwayServiceDelete",
|
|
121
|
+
mutation: true,
|
|
122
|
+
query: `mutation RailwayServiceDelete($id: String!, $environmentId: String!) {
|
|
123
|
+
serviceDelete(id: $id, environmentId: $environmentId)
|
|
124
|
+
}`
|
|
125
|
+
},
|
|
126
|
+
serviceConnect: {
|
|
127
|
+
name: "RailwayServiceConnect",
|
|
128
|
+
mutation: true,
|
|
129
|
+
query: `mutation RailwayServiceConnect($id: String!, $input: ServiceConnectInput!) {
|
|
130
|
+
serviceConnect(id: $id, input: $input) { id }
|
|
131
|
+
}`
|
|
132
|
+
},
|
|
133
|
+
serviceDisconnect: {
|
|
134
|
+
name: "RailwayServiceDisconnect",
|
|
135
|
+
mutation: true,
|
|
136
|
+
query: `mutation RailwayServiceDisconnect($id: String!) {
|
|
137
|
+
serviceDisconnect(id: $id) { id }
|
|
138
|
+
}`
|
|
139
|
+
},
|
|
140
|
+
serviceInstanceUpdate: {
|
|
141
|
+
name: "RailwayServiceInstanceUpdate",
|
|
142
|
+
mutation: true,
|
|
143
|
+
query: `mutation RailwayServiceInstanceUpdate(
|
|
144
|
+
$environmentId: String!,
|
|
145
|
+
$serviceId: String!,
|
|
146
|
+
$input: ServiceInstanceUpdateInput!
|
|
147
|
+
) {
|
|
148
|
+
serviceInstanceUpdate(environmentId: $environmentId, serviceId: $serviceId, input: $input)
|
|
149
|
+
}`
|
|
150
|
+
},
|
|
151
|
+
variables: {
|
|
152
|
+
name: "RailwayVariables",
|
|
153
|
+
query: `query RailwayVariables($projectId: String!, $environmentId: String!, $serviceId: String!) {
|
|
154
|
+
variables(projectId: $projectId, environmentId: $environmentId, serviceId: $serviceId)
|
|
155
|
+
}`
|
|
156
|
+
},
|
|
157
|
+
variableUpsert: {
|
|
158
|
+
name: "RailwayVariableCollectionUpsert",
|
|
159
|
+
mutation: true,
|
|
160
|
+
query: `mutation RailwayVariableCollectionUpsert($input: VariableCollectionUpsertInput!) {
|
|
161
|
+
variableCollectionUpsert(input: $input)
|
|
162
|
+
}`
|
|
163
|
+
},
|
|
164
|
+
deploy: {
|
|
165
|
+
name: "RailwayServiceDeploy",
|
|
166
|
+
mutation: true,
|
|
167
|
+
query: `mutation RailwayServiceDeploy($environmentId: String!, $serviceId: String!, $commitSha: String) {
|
|
168
|
+
serviceInstanceDeployV2(environmentId: $environmentId, serviceId: $serviceId, commitSha: $commitSha)
|
|
169
|
+
}`
|
|
170
|
+
},
|
|
171
|
+
deployments: {
|
|
172
|
+
name: "RailwayDeployments",
|
|
173
|
+
query: `query RailwayDeployments($projectId: String!, $environmentId: String!, $serviceId: String!) {
|
|
174
|
+
deployments(
|
|
175
|
+
input: { projectId: $projectId, environmentId: $environmentId, serviceId: $serviceId },
|
|
176
|
+
first: 10
|
|
177
|
+
) {
|
|
178
|
+
edges { node { id status staticUrl url serviceId environmentId createdAt } }
|
|
179
|
+
}
|
|
180
|
+
}`
|
|
181
|
+
},
|
|
182
|
+
deployment: {
|
|
183
|
+
name: "RailwayDeployment",
|
|
184
|
+
query: `query RailwayDeployment($id: String!) {
|
|
185
|
+
deployment(id: $id) { id status staticUrl url serviceId environmentId }
|
|
186
|
+
}`
|
|
187
|
+
},
|
|
188
|
+
buildLogs: {
|
|
189
|
+
name: "RailwayBuildLogs",
|
|
190
|
+
query: `query RailwayBuildLogs($deploymentId: String!, $limit: Int!) {
|
|
191
|
+
buildLogs(deploymentId: $deploymentId, limit: $limit) { timestamp message severity }
|
|
192
|
+
}`
|
|
193
|
+
},
|
|
194
|
+
deploymentLogs: {
|
|
195
|
+
name: "RailwayDeploymentLogs",
|
|
196
|
+
query: `query RailwayDeploymentLogs($deploymentId: String!, $limit: Int!) {
|
|
197
|
+
deploymentLogs(deploymentId: $deploymentId, limit: $limit) { timestamp message severity }
|
|
198
|
+
}`
|
|
199
|
+
},
|
|
200
|
+
domains: {
|
|
201
|
+
name: "RailwayDomains",
|
|
202
|
+
query: `query RailwayDomains($projectId: String!, $environmentId: String!, $serviceId: String!) {
|
|
203
|
+
domains(projectId: $projectId, environmentId: $environmentId, serviceId: $serviceId) {
|
|
204
|
+
customDomains { id domain status { verified dnsRecords { hostlabel requiredValue recordType } } }
|
|
205
|
+
serviceDomains { id domain }
|
|
206
|
+
}
|
|
207
|
+
}`
|
|
208
|
+
},
|
|
209
|
+
customDomain: {
|
|
210
|
+
name: "RailwayCustomDomain",
|
|
211
|
+
query: `query RailwayCustomDomain($id: String!, $projectId: String!) {
|
|
212
|
+
customDomain(id: $id, projectId: $projectId) {
|
|
213
|
+
id
|
|
214
|
+
domain
|
|
215
|
+
status { verified dnsRecords { hostlabel requiredValue recordType } }
|
|
216
|
+
}
|
|
217
|
+
}`
|
|
218
|
+
},
|
|
219
|
+
serviceDomainCreate: {
|
|
220
|
+
name: "RailwayServiceDomainCreate",
|
|
221
|
+
mutation: true,
|
|
222
|
+
query: `mutation RailwayServiceDomainCreate($input: ServiceDomainCreateInput!) {
|
|
223
|
+
serviceDomainCreate(input: $input) { id domain }
|
|
224
|
+
}`
|
|
225
|
+
},
|
|
226
|
+
customDomainCreate: {
|
|
227
|
+
name: "RailwayCustomDomainCreate",
|
|
228
|
+
mutation: true,
|
|
229
|
+
query: `mutation RailwayCustomDomainCreate($input: CustomDomainCreateInput!) {
|
|
230
|
+
customDomainCreate(input: $input) { id domain status { dnsRecords { hostlabel requiredValue recordType } } }
|
|
231
|
+
}`
|
|
232
|
+
},
|
|
233
|
+
volumeCreate: {
|
|
234
|
+
name: "RailwayVolumeCreate",
|
|
235
|
+
mutation: true,
|
|
236
|
+
query: `mutation RailwayVolumeCreate($input: VolumeCreateInput!) {
|
|
237
|
+
volumeCreate(input: $input) { id name }
|
|
238
|
+
}`
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
function railwaySchemaFingerprintSource() {
|
|
242
|
+
return Object.values(railwayOperations).map((operation) => `${operation.name}
|
|
243
|
+
${operation.query.trim()}`).join("\n\n");
|
|
244
|
+
}
|
|
245
|
+
export {
|
|
246
|
+
railwayOperations,
|
|
247
|
+
railwaySchemaFingerprintSource
|
|
248
|
+
};
|
|
249
|
+
//# sourceMappingURL=operations.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/lib/deploy/railway/operations.ts"],
|
|
4
|
+
"sourcesContent": ["import type { RailwayGraphqlOperation } from './types'\n\nexport const railwayOperations = {\n me: {\n name: 'RailwayMe',\n query: `query RailwayMe {\n me { id name email workspaces { id name } }\n}`,\n },\n project: {\n name: 'RailwayProject',\n query: `query RailwayProject($id: String!) {\n project(id: $id) { id name workspaceId }\n}`,\n },\n projects: {\n name: 'RailwayProjects',\n query: `query RailwayProjects($workspaceId: String!) {\n projects(workspaceId: $workspaceId, first: 100, includeDeleted: false) {\n edges { node { id name } }\n }\n}`,\n },\n projectCreate: {\n name: 'RailwayProjectCreate',\n mutation: true,\n query: `mutation RailwayProjectCreate($input: ProjectCreateInput!) {\n projectCreate(input: $input) { id name }\n}`,\n },\n projectUpdate: {\n name: 'RailwayProjectUpdate',\n mutation: true,\n query: `mutation RailwayProjectUpdate($id: String!, $input: ProjectUpdateInput!) {\n projectUpdate(id: $id, input: $input) { id name }\n}`,\n },\n projectDelete: {\n name: 'RailwayProjectDelete',\n mutation: true,\n query: `mutation RailwayProjectDelete($id: String!) {\n projectDelete(id: $id)\n}`,\n },\n environments: {\n name: 'RailwayEnvironments',\n query: `query RailwayEnvironments($projectId: String!) {\n environments(projectId: $projectId, first: 100) {\n edges { node { id name } }\n }\n}`,\n },\n environment: {\n name: 'RailwayEnvironment',\n query: `query RailwayEnvironment($id: String!, $projectId: String!) {\n environment(id: $id, projectId: $projectId) { id name }\n}`,\n },\n environmentCreate: {\n name: 'RailwayEnvironmentCreate',\n mutation: true,\n query: `mutation RailwayEnvironmentCreate($input: EnvironmentCreateInput!) {\n environmentCreate(input: $input) { id name }\n}`,\n },\n regions: {\n name: 'RailwayRegions',\n query: `query RailwayRegions($projectId: String!) {\n regions(projectId: $projectId) { id name region location }\n}`,\n },\n template: {\n name: 'RailwayTemplate',\n query: `query RailwayTemplate($code: String!) {\n template(code: $code) { id code serializedConfig }\n}`,\n },\n templateDeploy: {\n name: 'RailwayTemplateDeploy',\n mutation: true,\n query: `mutation RailwayTemplateDeploy($input: TemplateDeployV2Input!) {\n templateDeployV2(input: $input) { workflowId }\n}`,\n },\n services: {\n name: 'RailwayServices',\n query: `query RailwayServices($projectId: String!) {\n project(id: $projectId) { services { edges { node { id name } } } }\n}`,\n },\n volumes: {\n name: 'RailwayVolumes',\n query: `query RailwayVolumes($projectId: String!) {\n project(id: $projectId) {\n volumes {\n edges {\n node {\n id\n volumeInstances {\n edges { node { environmentId serviceId mountPath } }\n }\n }\n }\n }\n }\n}`,\n },\n service: {\n name: 'RailwayService',\n query: `query RailwayService($id: String!) {\n service(id: $id) { id name projectId }\n}`,\n },\n serviceCreate: {\n name: 'RailwayServiceCreate',\n mutation: true,\n query: `mutation RailwayServiceCreate($input: ServiceCreateInput!) {\n serviceCreate(input: $input) { id name }\n}`,\n },\n serviceDelete: {\n name: 'RailwayServiceDelete',\n mutation: true,\n query: `mutation RailwayServiceDelete($id: String!, $environmentId: String!) {\n serviceDelete(id: $id, environmentId: $environmentId)\n}`,\n },\n serviceConnect: {\n name: 'RailwayServiceConnect',\n mutation: true,\n query: `mutation RailwayServiceConnect($id: String!, $input: ServiceConnectInput!) {\n serviceConnect(id: $id, input: $input) { id }\n}`,\n },\n serviceDisconnect: {\n name: 'RailwayServiceDisconnect',\n mutation: true,\n query: `mutation RailwayServiceDisconnect($id: String!) {\n serviceDisconnect(id: $id) { id }\n}`,\n },\n serviceInstanceUpdate: {\n name: 'RailwayServiceInstanceUpdate',\n mutation: true,\n query: `mutation RailwayServiceInstanceUpdate(\n $environmentId: String!,\n $serviceId: String!,\n $input: ServiceInstanceUpdateInput!\n ) {\n serviceInstanceUpdate(environmentId: $environmentId, serviceId: $serviceId, input: $input)\n }`,\n },\n variables: {\n name: 'RailwayVariables',\n query: `query RailwayVariables($projectId: String!, $environmentId: String!, $serviceId: String!) {\n variables(projectId: $projectId, environmentId: $environmentId, serviceId: $serviceId)\n}`,\n },\n variableUpsert: {\n name: 'RailwayVariableCollectionUpsert',\n mutation: true,\n query: `mutation RailwayVariableCollectionUpsert($input: VariableCollectionUpsertInput!) {\n variableCollectionUpsert(input: $input)\n}`,\n },\n deploy: {\n name: 'RailwayServiceDeploy',\n mutation: true,\n query: `mutation RailwayServiceDeploy($environmentId: String!, $serviceId: String!, $commitSha: String) {\n serviceInstanceDeployV2(environmentId: $environmentId, serviceId: $serviceId, commitSha: $commitSha)\n}`,\n },\n deployments: {\n name: 'RailwayDeployments',\n query: `query RailwayDeployments($projectId: String!, $environmentId: String!, $serviceId: String!) {\n deployments(\n input: { projectId: $projectId, environmentId: $environmentId, serviceId: $serviceId },\n first: 10\n ) {\n edges { node { id status staticUrl url serviceId environmentId createdAt } }\n }\n}`,\n },\n deployment: {\n name: 'RailwayDeployment',\n query: `query RailwayDeployment($id: String!) {\n deployment(id: $id) { id status staticUrl url serviceId environmentId }\n}`,\n },\n buildLogs: {\n name: 'RailwayBuildLogs',\n query: `query RailwayBuildLogs($deploymentId: String!, $limit: Int!) {\n buildLogs(deploymentId: $deploymentId, limit: $limit) { timestamp message severity }\n}`,\n },\n deploymentLogs: {\n name: 'RailwayDeploymentLogs',\n query: `query RailwayDeploymentLogs($deploymentId: String!, $limit: Int!) {\n deploymentLogs(deploymentId: $deploymentId, limit: $limit) { timestamp message severity }\n}`,\n },\n domains: {\n name: 'RailwayDomains',\n query: `query RailwayDomains($projectId: String!, $environmentId: String!, $serviceId: String!) {\n domains(projectId: $projectId, environmentId: $environmentId, serviceId: $serviceId) {\n customDomains { id domain status { verified dnsRecords { hostlabel requiredValue recordType } } }\n serviceDomains { id domain }\n }\n}`,\n },\n customDomain: {\n name: 'RailwayCustomDomain',\n query: `query RailwayCustomDomain($id: String!, $projectId: String!) {\n customDomain(id: $id, projectId: $projectId) {\n id\n domain\n status { verified dnsRecords { hostlabel requiredValue recordType } }\n }\n}`,\n },\n serviceDomainCreate: {\n name: 'RailwayServiceDomainCreate',\n mutation: true,\n query: `mutation RailwayServiceDomainCreate($input: ServiceDomainCreateInput!) {\n serviceDomainCreate(input: $input) { id domain }\n}`,\n },\n customDomainCreate: {\n name: 'RailwayCustomDomainCreate',\n mutation: true,\n query: `mutation RailwayCustomDomainCreate($input: CustomDomainCreateInput!) {\n customDomainCreate(input: $input) { id domain status { dnsRecords { hostlabel requiredValue recordType } } }\n}`,\n },\n volumeCreate: {\n name: 'RailwayVolumeCreate',\n mutation: true,\n query: `mutation RailwayVolumeCreate($input: VolumeCreateInput!) {\n volumeCreate(input: $input) { id name }\n}`,\n },\n} satisfies Record<string, RailwayGraphqlOperation>\n\nexport function railwaySchemaFingerprintSource(): string {\n return Object.values(railwayOperations)\n .map((operation) => `${operation.name}\\n${operation.query.trim()}`)\n .join('\\n\\n')\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
const VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
2
|
+
"--project",
|
|
3
|
+
"--env",
|
|
4
|
+
"--service",
|
|
5
|
+
"--source",
|
|
6
|
+
"--region",
|
|
7
|
+
"--env-file",
|
|
8
|
+
"--domain",
|
|
9
|
+
"--volume",
|
|
10
|
+
"--token",
|
|
11
|
+
"--timeout",
|
|
12
|
+
"--allow-secret-passthrough"
|
|
13
|
+
]);
|
|
14
|
+
const BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
15
|
+
"--worker",
|
|
16
|
+
"--no-worker",
|
|
17
|
+
"--no-wait-domain",
|
|
18
|
+
"--non-interactive",
|
|
19
|
+
"--dry-run",
|
|
20
|
+
"--cleanup",
|
|
21
|
+
"--yes",
|
|
22
|
+
"--write-env",
|
|
23
|
+
"--no-track",
|
|
24
|
+
"--force-rename",
|
|
25
|
+
"--verbose",
|
|
26
|
+
"--help",
|
|
27
|
+
"-h"
|
|
28
|
+
]);
|
|
29
|
+
function readFlagValue(args, index) {
|
|
30
|
+
const argument = args[index] ?? "";
|
|
31
|
+
const equalsIndex = argument.indexOf("=");
|
|
32
|
+
if (equalsIndex > 0) {
|
|
33
|
+
const flag = argument.slice(0, equalsIndex);
|
|
34
|
+
const value2 = argument.slice(equalsIndex + 1);
|
|
35
|
+
if (!value2) throw new Error(`Missing value for ${flag}.`);
|
|
36
|
+
return { flag, value: value2, consumed: 1 };
|
|
37
|
+
}
|
|
38
|
+
const value = args[index + 1];
|
|
39
|
+
if (!value || value.startsWith("-")) {
|
|
40
|
+
throw new Error(`Missing value for ${argument}.`);
|
|
41
|
+
}
|
|
42
|
+
return { flag: argument, value, consumed: 2 };
|
|
43
|
+
}
|
|
44
|
+
function parseSourceMode(value) {
|
|
45
|
+
if (value === "auto" || value === "git" || value === "local") return value;
|
|
46
|
+
throw new Error(`Invalid --source value "${value}". Expected auto, git, or local.`);
|
|
47
|
+
}
|
|
48
|
+
function parseTimeout(value) {
|
|
49
|
+
const timeout = Number.parseInt(value, 10);
|
|
50
|
+
if (!Number.isFinite(timeout) || timeout <= 0) {
|
|
51
|
+
throw new Error("--timeout must be a positive number of seconds.");
|
|
52
|
+
}
|
|
53
|
+
return timeout;
|
|
54
|
+
}
|
|
55
|
+
function parseRailwayDeployOptions(args, environment = process.env) {
|
|
56
|
+
const options = {
|
|
57
|
+
environment: "production",
|
|
58
|
+
service: "mercato-app",
|
|
59
|
+
worker: true,
|
|
60
|
+
source: "auto",
|
|
61
|
+
waitDomain: true,
|
|
62
|
+
nonInteractive: environment.CI === "true",
|
|
63
|
+
dryRun: false,
|
|
64
|
+
cleanup: false,
|
|
65
|
+
yes: false,
|
|
66
|
+
writeEnv: false,
|
|
67
|
+
track: true,
|
|
68
|
+
forceRename: false,
|
|
69
|
+
timeoutSeconds: 900,
|
|
70
|
+
allowedSecretKeys: [],
|
|
71
|
+
verbose: false,
|
|
72
|
+
help: false
|
|
73
|
+
};
|
|
74
|
+
for (let index = 0; index < args.length; ) {
|
|
75
|
+
const argument = args[index] ?? "";
|
|
76
|
+
const normalizedFlag = argument.includes("=") ? argument.slice(0, argument.indexOf("=")) : argument;
|
|
77
|
+
if (VALUE_FLAGS.has(normalizedFlag)) {
|
|
78
|
+
const { flag, value, consumed } = readFlagValue(args, index);
|
|
79
|
+
if (flag === "--project") options.project = value;
|
|
80
|
+
else if (flag === "--env") options.environment = value;
|
|
81
|
+
else if (flag === "--service") options.service = value;
|
|
82
|
+
else if (flag === "--source") options.source = parseSourceMode(value);
|
|
83
|
+
else if (flag === "--region") options.region = value;
|
|
84
|
+
else if (flag === "--env-file") options.envFile = value;
|
|
85
|
+
else if (flag === "--domain") options.domain = value;
|
|
86
|
+
else if (flag === "--volume") options.volume = value;
|
|
87
|
+
else if (flag === "--token") options.token = value;
|
|
88
|
+
else if (flag === "--timeout") options.timeoutSeconds = parseTimeout(value);
|
|
89
|
+
else if (flag === "--allow-secret-passthrough") options.allowedSecretKeys.push(value);
|
|
90
|
+
index += consumed;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (!BOOLEAN_FLAGS.has(argument)) {
|
|
94
|
+
throw new Error(`Unknown Railway deploy option "${argument}".`);
|
|
95
|
+
}
|
|
96
|
+
if (argument === "--worker") options.worker = true;
|
|
97
|
+
else if (argument === "--no-worker") options.worker = false;
|
|
98
|
+
else if (argument === "--no-wait-domain") options.waitDomain = false;
|
|
99
|
+
else if (argument === "--non-interactive") options.nonInteractive = true;
|
|
100
|
+
else if (argument === "--dry-run") options.dryRun = true;
|
|
101
|
+
else if (argument === "--cleanup") options.cleanup = true;
|
|
102
|
+
else if (argument === "--yes") options.yes = true;
|
|
103
|
+
else if (argument === "--write-env") options.writeEnv = true;
|
|
104
|
+
else if (argument === "--no-track") options.track = false;
|
|
105
|
+
else if (argument === "--force-rename") options.forceRename = true;
|
|
106
|
+
else if (argument === "--verbose") options.verbose = true;
|
|
107
|
+
else if (argument === "--help" || argument === "-h") options.help = true;
|
|
108
|
+
index += 1;
|
|
109
|
+
}
|
|
110
|
+
if (options.cleanup && !options.dryRun && options.nonInteractive && !options.yes) {
|
|
111
|
+
throw new Error("--cleanup --non-interactive requires --yes.");
|
|
112
|
+
}
|
|
113
|
+
if (options.environment.trim().length === 0) throw new Error("--env cannot be empty.");
|
|
114
|
+
if (options.service.trim().length === 0) throw new Error("--service cannot be empty.");
|
|
115
|
+
return options;
|
|
116
|
+
}
|
|
117
|
+
function railwayDeployHelp() {
|
|
118
|
+
return `Usage: mercato deploy railway [options]
|
|
119
|
+
|
|
120
|
+
Deploy an Open Mercato standalone app to Railway.
|
|
121
|
+
|
|
122
|
+
--project <name> Railway project name
|
|
123
|
+
--env <name> Environment name (default: production)
|
|
124
|
+
--service <name> App service name (default: mercato-app)
|
|
125
|
+
--worker / --no-worker Enable or disable the dedicated worker
|
|
126
|
+
--source <auto|git|local> Source strategy (default: auto)
|
|
127
|
+
--region <id> Railway region
|
|
128
|
+
--env-file <path> Environment file
|
|
129
|
+
--domain <fqdn> Custom domain
|
|
130
|
+
--no-wait-domain Do not wait for DNS verification
|
|
131
|
+
--volume <mountPath> Create an attachments volume
|
|
132
|
+
--token <value> Railway Account token
|
|
133
|
+
--non-interactive Disable prompts
|
|
134
|
+
--dry-run Print the plan without mutations
|
|
135
|
+
--cleanup --yes Delete the recorded Railway project
|
|
136
|
+
--write-env Persist generated secrets locally
|
|
137
|
+
--no-track Use .mercato/railway.json.local
|
|
138
|
+
--force-rename Allow renaming a recorded project
|
|
139
|
+
--timeout <seconds> Deployment timeout (default: 900)
|
|
140
|
+
--allow-secret-passthrough <key> Allow one credential-like env value
|
|
141
|
+
--verbose Print redacted GraphQL diagnostics`;
|
|
142
|
+
}
|
|
143
|
+
function redactRailwayCliArgs(args) {
|
|
144
|
+
return args.map((argument, index) => {
|
|
145
|
+
if (argument.startsWith("--token=")) return "--token=****";
|
|
146
|
+
if (args[index - 1] === "--token") return "****";
|
|
147
|
+
return argument;
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
export {
|
|
151
|
+
parseRailwayDeployOptions,
|
|
152
|
+
railwayDeployHelp,
|
|
153
|
+
redactRailwayCliArgs
|
|
154
|
+
};
|
|
155
|
+
//# sourceMappingURL=options.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/lib/deploy/railway/options.ts"],
|
|
4
|
+
"sourcesContent": ["import type { RailwayDeployOptions, RailwaySourceMode } from './types'\n\nconst VALUE_FLAGS = new Set([\n '--project',\n '--env',\n '--service',\n '--source',\n '--region',\n '--env-file',\n '--domain',\n '--volume',\n '--token',\n '--timeout',\n '--allow-secret-passthrough',\n])\n\nconst BOOLEAN_FLAGS = new Set([\n '--worker',\n '--no-worker',\n '--no-wait-domain',\n '--non-interactive',\n '--dry-run',\n '--cleanup',\n '--yes',\n '--write-env',\n '--no-track',\n '--force-rename',\n '--verbose',\n '--help',\n '-h',\n])\n\nfunction readFlagValue(args: string[], index: number): { flag: string; value: string; consumed: number } {\n const argument = args[index] ?? ''\n const equalsIndex = argument.indexOf('=')\n if (equalsIndex > 0) {\n const flag = argument.slice(0, equalsIndex)\n const value = argument.slice(equalsIndex + 1)\n if (!value) throw new Error(`Missing value for ${flag}.`)\n return { flag, value, consumed: 1 }\n }\n\n const value = args[index + 1]\n if (!value || value.startsWith('-')) {\n throw new Error(`Missing value for ${argument}.`)\n }\n return { flag: argument, value, consumed: 2 }\n}\n\nfunction parseSourceMode(value: string): RailwaySourceMode {\n if (value === 'auto' || value === 'git' || value === 'local') return value\n throw new Error(`Invalid --source value \"${value}\". Expected auto, git, or local.`)\n}\n\nfunction parseTimeout(value: string): number {\n const timeout = Number.parseInt(value, 10)\n if (!Number.isFinite(timeout) || timeout <= 0) {\n throw new Error('--timeout must be a positive number of seconds.')\n }\n return timeout\n}\n\nexport function parseRailwayDeployOptions(\n args: string[],\n environment: NodeJS.ProcessEnv = process.env,\n): RailwayDeployOptions {\n const options: RailwayDeployOptions = {\n environment: 'production',\n service: 'mercato-app',\n worker: true,\n source: 'auto',\n waitDomain: true,\n nonInteractive: environment.CI === 'true',\n dryRun: false,\n cleanup: false,\n yes: false,\n writeEnv: false,\n track: true,\n forceRename: false,\n timeoutSeconds: 900,\n allowedSecretKeys: [],\n verbose: false,\n help: false,\n }\n\n for (let index = 0; index < args.length;) {\n const argument = args[index] ?? ''\n const normalizedFlag = argument.includes('=') ? argument.slice(0, argument.indexOf('=')) : argument\n\n if (VALUE_FLAGS.has(normalizedFlag)) {\n const { flag, value, consumed } = readFlagValue(args, index)\n if (flag === '--project') options.project = value\n else if (flag === '--env') options.environment = value\n else if (flag === '--service') options.service = value\n else if (flag === '--source') options.source = parseSourceMode(value)\n else if (flag === '--region') options.region = value\n else if (flag === '--env-file') options.envFile = value\n else if (flag === '--domain') options.domain = value\n else if (flag === '--volume') options.volume = value\n else if (flag === '--token') options.token = value\n else if (flag === '--timeout') options.timeoutSeconds = parseTimeout(value)\n else if (flag === '--allow-secret-passthrough') options.allowedSecretKeys.push(value)\n index += consumed\n continue\n }\n\n if (!BOOLEAN_FLAGS.has(argument)) {\n throw new Error(`Unknown Railway deploy option \"${argument}\".`)\n }\n\n if (argument === '--worker') options.worker = true\n else if (argument === '--no-worker') options.worker = false\n else if (argument === '--no-wait-domain') options.waitDomain = false\n else if (argument === '--non-interactive') options.nonInteractive = true\n else if (argument === '--dry-run') options.dryRun = true\n else if (argument === '--cleanup') options.cleanup = true\n else if (argument === '--yes') options.yes = true\n else if (argument === '--write-env') options.writeEnv = true\n else if (argument === '--no-track') options.track = false\n else if (argument === '--force-rename') options.forceRename = true\n else if (argument === '--verbose') options.verbose = true\n else if (argument === '--help' || argument === '-h') options.help = true\n index += 1\n }\n\n if (options.cleanup && !options.dryRun && options.nonInteractive && !options.yes) {\n throw new Error('--cleanup --non-interactive requires --yes.')\n }\n if (options.environment.trim().length === 0) throw new Error('--env cannot be empty.')\n if (options.service.trim().length === 0) throw new Error('--service cannot be empty.')\n return options\n}\n\nexport function railwayDeployHelp(): string {\n return `Usage: mercato deploy railway [options]\n\nDeploy an Open Mercato standalone app to Railway.\n\n --project <name> Railway project name\n --env <name> Environment name (default: production)\n --service <name> App service name (default: mercato-app)\n --worker / --no-worker Enable or disable the dedicated worker\n --source <auto|git|local> Source strategy (default: auto)\n --region <id> Railway region\n --env-file <path> Environment file\n --domain <fqdn> Custom domain\n --no-wait-domain Do not wait for DNS verification\n --volume <mountPath> Create an attachments volume\n --token <value> Railway Account token\n --non-interactive Disable prompts\n --dry-run Print the plan without mutations\n --cleanup --yes Delete the recorded Railway project\n --write-env Persist generated secrets locally\n --no-track Use .mercato/railway.json.local\n --force-rename Allow renaming a recorded project\n --timeout <seconds> Deployment timeout (default: 900)\n --allow-secret-passthrough <key> Allow one credential-like env value\n --verbose Print redacted GraphQL diagnostics`\n}\n\nexport function redactRailwayCliArgs(args: string[]): string[] {\n return args.map((argument, index) => {\n if (argument.startsWith('--token=')) return '--token=****'\n if (args[index - 1] === '--token') return '****'\n return argument\n })\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["value"]
|
|
7
|
+
}
|