@ebay-dt/bonfire-node 0.1.0-alpha.1 → 0.1.0-alpha.2
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/README.md +10 -2
- package/dist/agent-service.d.ts.map +1 -1
- package/dist/agent-service.js.map +1 -1
- package/dist/claude.d.ts.map +1 -1
- package/dist/claude.js.map +1 -1
- package/dist/cursor.d.ts.map +1 -1
- package/dist/cursor.js.map +1 -1
- package/dist/deployment-provider.d.ts.map +1 -1
- package/dist/deployment-provider.js.map +1 -1
- package/dist/duplicate.d.ts.map +1 -1
- package/dist/duplicate.js.map +1 -1
- package/dist/executable.d.ts.map +1 -1
- package/dist/executable.js.map +1 -1
- package/dist/git-repository.d.ts.map +1 -1
- package/dist/git-repository.js.map +1 -1
- package/dist/github-cli.d.ts.map +1 -1
- package/dist/github-cli.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/owned-destination.d.ts.map +1 -1
- package/dist/internal/owned-destination.js.map +1 -1
- package/dist/internal/prototype-templates.d.ts.map +1 -1
- package/dist/internal/prototype-templates.js.map +1 -1
- package/dist/internal/utils.d.ts.map +1 -1
- package/dist/internal/utils.js.map +1 -1
- package/dist/lifecycle/dirty-state.d.ts.map +1 -1
- package/dist/lifecycle/dirty-state.js.map +1 -1
- package/dist/lifecycle/local-prototype-lifecycle.d.ts.map +1 -1
- package/dist/lifecycle/local-prototype-lifecycle.js.map +1 -1
- package/dist/lifecycle/operation-gate.d.ts.map +1 -1
- package/dist/lifecycle/operation-gate.js.map +1 -1
- package/dist/lifecycle/runtime-context.d.ts.map +1 -1
- package/dist/lifecycle/runtime-context.js.map +1 -1
- package/dist/preferences.d.ts.map +1 -1
- package/dist/preferences.js.map +1 -1
- package/dist/prepare-prototype-files.d.ts.map +1 -1
- package/dist/prepare-prototype-files.js.map +1 -1
- package/dist/process-runner.d.ts.map +1 -1
- package/dist/process-runner.js.map +1 -1
- package/dist/prototype-catalog.d.ts.map +1 -1
- package/dist/prototype-catalog.js.map +1 -1
- package/dist/prototype-paths.d.ts.map +1 -1
- package/dist/prototype-paths.js.map +1 -1
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js.map +1 -1
- package/dist/watcher.d.ts.map +1 -1
- package/dist/watcher.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -46,6 +46,9 @@ const deploymentProvider = createDeploymentProvider({
|
|
|
46
46
|
The provider sends exactly `{ applicationId, login }`. Bonfire supplies the
|
|
47
47
|
application ID from trusted application configuration and the login from the
|
|
48
48
|
verified authenticated identity; instances never provide owner/branch values.
|
|
49
|
+
The application ID must exactly match the application's DT deployment-service
|
|
50
|
+
registration; Bonfire does not validate that registration locally. A mismatch
|
|
51
|
+
is returned as a safe deployment failure rather than exposing provider details.
|
|
49
52
|
The documented success response is returned with HTTP 201 and contains
|
|
50
53
|
`repository`, `ref`, `commitSha`, `sourceFileCount`, `project`, `deployed`,
|
|
51
54
|
`deploymentId`, `url`, and `readyState`. `readyState` is one of `BLOCKED`,
|
|
@@ -59,8 +62,13 @@ The provider preserves the deployment ID and reported ready state, but Bonfire
|
|
|
59
62
|
does not poll for later status. Provider failures are reduced to safe typed
|
|
60
63
|
lifecycle errors; response diagnostics, credentials, Vercel credentials, and
|
|
61
64
|
deployment-target selection remain outside Bonfire in the deployment service.
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
If the deployment service exposes a registration-specific status, hosts may
|
|
66
|
+
map it to a generic message such as “Deployment is not configured for this
|
|
67
|
+
application.” They should not infer that classification from an arbitrary
|
|
68
|
+
failure or forward provider response bodies, endpoint details, repository or
|
|
69
|
+
branch data, or filesystem diagnostics to the browser. The provider validates the endpoint,
|
|
70
|
+
response, HTTPS preview URL, and timeout without exposing service details to the
|
|
71
|
+
browser.
|
|
64
72
|
|
|
65
73
|
## Prototype shape and duplication
|
|
66
74
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-service.d.ts","sourceRoot":"","sources":["../src/agent-service.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAGvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAsB,KAAK,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,gCAAgC,CAAC;AAEvF,MAAM,MAAM,4BAA4B,GAAG;IACzC,OAAO,EAAE,IAAI,CAAC,gCAAgC,EAAE,eAAe,CAAC,CAAC;IACjE,OAAO,EAAE,oBAAoB,CAAC;IAC9B,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,WAAW,CAAC,EAAE,wBAAwB,CAAC;IACvC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,UAAU,CAAC,EAAE,sBAAsB,CAAC;CACrC,CAAC;AAEF,MAAM,WAAW,yBAAyB;IACxC,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC5E,gBAAgB,CACd,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/B;AAiCD,qBAAa,qBAAsB,YAAW,yBAAyB;;IAOrE,YAAY,OAAO,EAAE,4BAA4B,EAUhD;IA4CK,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;;;;;;OASnD;IAEK,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;;;;;;;;;;OA2CvD;CACF"}
|
|
1
|
+
{"version":3,"file":"agent-service.d.ts","sourceRoot":"","sources":["../src/agent-service.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAGvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAsB,KAAK,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,gCAAgC,CAAC;AAEvF,MAAM,MAAM,4BAA4B,GAAG;IACzC,OAAO,EAAE,IAAI,CAAC,gCAAgC,EAAE,eAAe,CAAC,CAAC;IACjE,OAAO,EAAE,oBAAoB,CAAC;IAC9B,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,WAAW,CAAC,EAAE,wBAAwB,CAAC;IACvC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,UAAU,CAAC,EAAE,sBAAsB,CAAC;CACrC,CAAC;AAEF,MAAM,WAAW,yBAAyB;IACxC,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC5E,gBAAgB,CACd,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/B;AAiCD,qBAAa,qBAAsB,YAAW,yBAAyB;;IAOrE,YAAY,OAAO,EAAE,4BAA4B,EAUhD;IA4CK,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;;;;;;OASnD;IAEK,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;;;;;;;;;;OA2CvD;CACF","sourcesContent":["import { join } from \"node:path\";\nimport {\n definePrototypeRef,\n parseBonfireIdentity,\n parseOpenInAgentInput,\n parseOpenInClaudeCodeInput,\n type AgentActionError,\n type AgentActionResult,\n type BonfireIdentity,\n type OpenInAgentInput,\n} from \"@ebay-dt/bonfire-core\";\nimport { ClaudeCodeLauncher, type ClaudeCodeLauncherLike } from \"./claude.js\";\nimport { CursorLauncher, type CursorLauncherLike } from \"./cursor.js\";\nimport {\n PathExecutableResolver,\n type ExecutableResolverLike,\n} from \"./executable.js\";\nimport {\n PrototypePreferences,\n type PrototypePreferencesLike,\n} from \"./preferences.js\";\nimport type { PrototypeCatalogLike } from \"./prototype-catalog.js\";\nimport type { PrototypeLifecycleRuntimeContext } from \"./lifecycle/runtime-context.js\";\n\nexport type PrototypeAgentServiceOptions = {\n runtime: Pick<PrototypeLifecycleRuntimeContext, \"prototypeRoot\">;\n catalog: PrototypeCatalogLike;\n executableResolver?: ExecutableResolverLike;\n preferences?: PrototypePreferencesLike;\n cursor?: CursorLauncherLike;\n claudeCode?: ClaudeCodeLauncherLike;\n};\n\nexport interface PrototypeAgentServiceLike {\n openInCursor(identity: unknown, input: unknown): Promise<AgentActionResult>;\n openInClaudeCode(\n identity: unknown,\n input: unknown,\n ): Promise<AgentActionResult>;\n}\n\ntype AuthorizedInput<Value> =\n | {\n ok: true;\n identity: BonfireIdentity;\n input: Value;\n prototypePath: string;\n }\n | { ok: false; result: AgentActionResult };\n\nfunction failure(\n code: AgentActionError[\"code\"],\n extras: Pick<AgentActionError, \"agent\" | \"terminal\"> = {},\n) {\n return {\n ok: false,\n error: { code, ...extras },\n } satisfies AgentActionResult;\n}\n\nfunction authenticate(identity: unknown) {\n if (identity === null || identity === undefined) return null;\n\n try {\n const parsed = parseBonfireIdentity(identity);\n definePrototypeRef({ login: parsed.login, slug: \"prototype\" });\n return parsed;\n } catch {\n return null;\n }\n}\n\nexport class PrototypeAgentService implements PrototypeAgentServiceLike {\n readonly #runtime: PrototypeAgentServiceOptions[\"runtime\"];\n readonly #catalog: PrototypeCatalogLike;\n readonly #preferences: PrototypePreferencesLike;\n readonly #cursor: CursorLauncherLike;\n readonly #claudeCode: ClaudeCodeLauncherLike;\n\n constructor(options: PrototypeAgentServiceOptions) {\n const executableResolver =\n options.executableResolver ?? new PathExecutableResolver();\n this.#runtime = options.runtime;\n this.#catalog = options.catalog;\n this.#preferences =\n options.preferences ?? new PrototypePreferences(options.runtime);\n this.#cursor = options.cursor ?? new CursorLauncher({ executableResolver });\n this.#claudeCode =\n options.claudeCode ?? new ClaudeCodeLauncher({ executableResolver });\n }\n\n async #authorize<Value extends { ref: OpenInAgentInput[\"ref\"] }>(\n identity: unknown,\n input: unknown,\n parse: (value: unknown) => Value,\n ): Promise<AuthorizedInput<Value>> {\n const authenticated = authenticate(identity);\n if (authenticated === null) {\n return { ok: false, result: failure(\"unauthenticated\") };\n }\n\n let normalizedInput: Value;\n try {\n normalizedInput = parse(input);\n } catch {\n return { ok: false, result: failure(\"invalid-input\") };\n }\n\n let summary;\n try {\n summary = await this.#catalog.getSummary(normalizedInput.ref);\n } catch {\n summary = null;\n }\n if (summary === null) {\n return { ok: false, result: failure(\"not-found\") };\n }\n if (summary.authorLogin !== authenticated.login) {\n return { ok: false, result: failure(\"forbidden\") };\n }\n\n return {\n ok: true,\n identity: authenticated,\n input: normalizedInput,\n prototypePath: join(\n this.#runtime.prototypeRoot,\n normalizedInput.ref.login,\n normalizedInput.ref.slug,\n ),\n };\n }\n\n async openInCursor(identity: unknown, input: unknown) {\n const authorized = await this.#authorize(\n identity,\n input,\n parseOpenInAgentInput,\n );\n if (!authorized.ok) return authorized.result;\n\n return this.#cursor.launch(authorized.prototypePath);\n }\n\n async openInClaudeCode(identity: unknown, input: unknown) {\n const authorized = await this.#authorize(\n identity,\n input,\n parseOpenInClaudeCodeInput,\n );\n if (!authorized.ok) return authorized.result;\n\n const preflight = await this.#claudeCode.preflight(\n authorized.input.terminal,\n );\n if (!preflight.ok) return preflight;\n\n let terminal = authorized.input.terminal;\n if (terminal === undefined) {\n let preferences;\n try {\n preferences = await this.#preferences.read(authorized.identity.login);\n } catch {\n return failure(\"launch-failed\", { agent: \"claude-code\" });\n }\n terminal = preferences.preferredTerminal;\n if (terminal === undefined) {\n return failure(\"needs-terminal\", { agent: \"claude-code\" });\n }\n } else {\n try {\n await this.#preferences.update(authorized.identity.login, {\n preferredTerminal: terminal,\n });\n } catch {\n return failure(\"launch-failed\", {\n agent: \"claude-code\",\n terminal,\n });\n }\n }\n\n return this.#claudeCode.launch(\n terminal,\n authorized.prototypePath,\n preflight,\n );\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-service.js","sourceRoot":"","sources":["../src/agent-service.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent-service.js","sourceRoot":"","sources":["../src/agent-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport {\n definePrototypeRef,\n parseBonfireIdentity,\n parseOpenInAgentInput,\n parseOpenInClaudeCodeInput,\n type AgentActionError,\n type AgentActionResult,\n type BonfireIdentity,\n type OpenInAgentInput,\n} from \"@ebay-dt/bonfire-core\";\nimport { ClaudeCodeLauncher, type ClaudeCodeLauncherLike } from \"./claude.js\";\nimport { CursorLauncher, type CursorLauncherLike } from \"./cursor.js\";\nimport {\n PathExecutableResolver,\n type ExecutableResolverLike,\n} from \"./executable.js\";\nimport {\n PrototypePreferences,\n type PrototypePreferencesLike,\n} from \"./preferences.js\";\nimport type { PrototypeCatalogLike } from \"./prototype-catalog.js\";\nimport type { PrototypeLifecycleRuntimeContext } from \"./lifecycle/runtime-context.js\";\n\nexport type PrototypeAgentServiceOptions = {\n runtime: Pick<PrototypeLifecycleRuntimeContext, \"prototypeRoot\">;\n catalog: PrototypeCatalogLike;\n executableResolver?: ExecutableResolverLike;\n preferences?: PrototypePreferencesLike;\n cursor?: CursorLauncherLike;\n claudeCode?: ClaudeCodeLauncherLike;\n};\n\nexport interface PrototypeAgentServiceLike {\n openInCursor(identity: unknown, input: unknown): Promise<AgentActionResult>;\n openInClaudeCode(\n identity: unknown,\n input: unknown,\n ): Promise<AgentActionResult>;\n}\n\ntype AuthorizedInput<Value> =\n | {\n ok: true;\n identity: BonfireIdentity;\n input: Value;\n prototypePath: string;\n }\n | { ok: false; result: AgentActionResult };\n\nfunction failure(\n code: AgentActionError[\"code\"],\n extras: Pick<AgentActionError, \"agent\" | \"terminal\"> = {},\n) {\n return {\n ok: false,\n error: { code, ...extras },\n } satisfies AgentActionResult;\n}\n\nfunction authenticate(identity: unknown) {\n if (identity === null || identity === undefined) return null;\n\n try {\n const parsed = parseBonfireIdentity(identity);\n definePrototypeRef({ login: parsed.login, slug: \"prototype\" });\n return parsed;\n } catch {\n return null;\n }\n}\n\nexport class PrototypeAgentService implements PrototypeAgentServiceLike {\n readonly #runtime: PrototypeAgentServiceOptions[\"runtime\"];\n readonly #catalog: PrototypeCatalogLike;\n readonly #preferences: PrototypePreferencesLike;\n readonly #cursor: CursorLauncherLike;\n readonly #claudeCode: ClaudeCodeLauncherLike;\n\n constructor(options: PrototypeAgentServiceOptions) {\n const executableResolver =\n options.executableResolver ?? new PathExecutableResolver();\n this.#runtime = options.runtime;\n this.#catalog = options.catalog;\n this.#preferences =\n options.preferences ?? new PrototypePreferences(options.runtime);\n this.#cursor = options.cursor ?? new CursorLauncher({ executableResolver });\n this.#claudeCode =\n options.claudeCode ?? new ClaudeCodeLauncher({ executableResolver });\n }\n\n async #authorize<Value extends { ref: OpenInAgentInput[\"ref\"] }>(\n identity: unknown,\n input: unknown,\n parse: (value: unknown) => Value,\n ): Promise<AuthorizedInput<Value>> {\n const authenticated = authenticate(identity);\n if (authenticated === null) {\n return { ok: false, result: failure(\"unauthenticated\") };\n }\n\n let normalizedInput: Value;\n try {\n normalizedInput = parse(input);\n } catch {\n return { ok: false, result: failure(\"invalid-input\") };\n }\n\n let summary;\n try {\n summary = await this.#catalog.getSummary(normalizedInput.ref);\n } catch {\n summary = null;\n }\n if (summary === null) {\n return { ok: false, result: failure(\"not-found\") };\n }\n if (summary.authorLogin !== authenticated.login) {\n return { ok: false, result: failure(\"forbidden\") };\n }\n\n return {\n ok: true,\n identity: authenticated,\n input: normalizedInput,\n prototypePath: join(\n this.#runtime.prototypeRoot,\n normalizedInput.ref.login,\n normalizedInput.ref.slug,\n ),\n };\n }\n\n async openInCursor(identity: unknown, input: unknown) {\n const authorized = await this.#authorize(\n identity,\n input,\n parseOpenInAgentInput,\n );\n if (!authorized.ok) return authorized.result;\n\n return this.#cursor.launch(authorized.prototypePath);\n }\n\n async openInClaudeCode(identity: unknown, input: unknown) {\n const authorized = await this.#authorize(\n identity,\n input,\n parseOpenInClaudeCodeInput,\n );\n if (!authorized.ok) return authorized.result;\n\n const preflight = await this.#claudeCode.preflight(\n authorized.input.terminal,\n );\n if (!preflight.ok) return preflight;\n\n let terminal = authorized.input.terminal;\n if (terminal === undefined) {\n let preferences;\n try {\n preferences = await this.#preferences.read(authorized.identity.login);\n } catch {\n return failure(\"launch-failed\", { agent: \"claude-code\" });\n }\n terminal = preferences.preferredTerminal;\n if (terminal === undefined) {\n return failure(\"needs-terminal\", { agent: \"claude-code\" });\n }\n } else {\n try {\n await this.#preferences.update(authorized.identity.login, {\n preferredTerminal: terminal,\n });\n } catch {\n return failure(\"launch-failed\", {\n agent: \"claude-code\",\n terminal,\n });\n }\n }\n\n return this.#claudeCode.launch(\n terminal,\n authorized.prototypePath,\n preflight,\n );\n }\n}\n"]}
|
package/dist/claude.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAEtB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,iBAAiB,CAAC;AAOzB,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CACN,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACnC,iBAAiB,CAAC,wBAAwB,CAAC,CAAC;AAE9C,MAAM,MAAM,yBAAyB,GAAG;IACtC,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,OAAO,CAAC,EAAE,uBAAuB,CAAC;CACnC,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACtE,MAAM,CACJ,QAAQ,EAAE,WAAW,EACrB,aAAa,EAAE,MAAM,EACrB,SAAS,CAAC,EAAE,yBAAyB,GACpC,OAAO,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,CAAC;CACjD;AAuCD,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,WAAW,EACrB,aAAa,EAAE,MAAM,UA2BtB;AAoBD,qBAAa,kBAAmB,YAAW,sBAAsB;;IAK/D,YAAY,OAAO,GAAE,yBAA8B,EAKlD;IAEK,SAAS,CAAC,QAAQ,CAAC,EAAE,WAAW;;;;;;;;OAmBrC;IAEK,MAAM,CACV,QAAQ,EAAE,WAAW,EACrB,aAAa,EAAE,MAAM,EACrB,SAAS,CAAC,EAAE,yBAAyB;;;;;;;;OAmBtC;CACF"}
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAEtB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,iBAAiB,CAAC;AAOzB,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CACN,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACnC,iBAAiB,CAAC,wBAAwB,CAAC,CAAC;AAE9C,MAAM,MAAM,yBAAyB,GAAG;IACtC,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,OAAO,CAAC,EAAE,uBAAuB,CAAC;CACnC,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACtE,MAAM,CACJ,QAAQ,EAAE,WAAW,EACrB,aAAa,EAAE,MAAM,EACrB,SAAS,CAAC,EAAE,yBAAyB,GACpC,OAAO,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,CAAC;CACjD;AAuCD,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,WAAW,EACrB,aAAa,EAAE,MAAM,UA2BtB;AAoBD,qBAAa,kBAAmB,YAAW,sBAAsB;;IAK/D,YAAY,OAAO,GAAE,yBAA8B,EAKlD;IAEK,SAAS,CAAC,QAAQ,CAAC,EAAE,WAAW;;;;;;;;OAmBrC;IAEK,MAAM,CACV,QAAQ,EAAE,WAAW,EACrB,aAAa,EAAE,MAAM,EACrB,SAAS,CAAC,EAAE,yBAAyB;;;;;;;;OAmBtC;CACF","sourcesContent":["import { execFile as nodeExecFile } from \"node:child_process\";\nimport {\n type AgentActionError,\n type AgentActionResult,\n type AgentCommand,\n type AgentLaunchValue,\n type TerminalApp,\n} from \"@ebay-dt/bonfire-core\";\nimport {\n PathExecutableResolver,\n type ExecutableResolverLike,\n} from \"./executable.js\";\n\nconst CLAUDE_COMMAND = \"claude\";\nconst OSASCRIPT_COMMAND = \"osascript\";\nconst APPLESCRIPT_TIMEOUT = 10_000;\nconst APPLESCRIPT_MAX_BUFFER = 1024 * 1024;\n\nexport type ClaudeCodeExecOptions = {\n timeout: number;\n maxBuffer: number;\n};\n\nexport type ClaudeCodeExecResult = {\n stdout: string;\n stderr: string;\n};\n\nexport type ClaudeCodeProcessRunner = {\n execFile(\n executable: string,\n args: readonly string[],\n options: ClaudeCodeExecOptions,\n ): Promise<ClaudeCodeExecResult>;\n};\n\nexport type ClaudeCodePreflightValue = {\n osascript: string;\n};\n\nexport type ClaudeCodePreflightResult =\n AgentActionResult<ClaudeCodePreflightValue>;\n\nexport type ClaudeCodeLauncherOptions = {\n executableResolver?: ExecutableResolverLike;\n platform?: NodeJS.Platform;\n process?: ClaudeCodeProcessRunner;\n};\n\nexport interface ClaudeCodeLauncherLike {\n preflight(terminal?: TerminalApp): Promise<ClaudeCodePreflightResult>;\n launch(\n terminal: TerminalApp,\n prototypePath: string,\n preflight?: ClaudeCodePreflightResult,\n ): Promise<AgentActionResult<AgentLaunchValue>>;\n}\n\nconst defaultProcess: ClaudeCodeProcessRunner = {\n execFile(executable, args, options) {\n return new Promise((resolve, reject) => {\n nodeExecFile(\n executable,\n [...args],\n { ...options, encoding: \"utf8\" },\n (error, stdout, stderr) => {\n if (error) {\n Object.assign(error, { stdout, stderr });\n reject(error);\n return;\n }\n\n resolve({ stdout, stderr });\n },\n );\n });\n },\n};\n\nfunction appleScriptString(value: string) {\n return `\"${value\n .replaceAll(\"\\\\\", \"\\\\\\\\\")\n .replaceAll('\"', '\\\\\"')\n .replaceAll(\"\\r\", \"\\\\r\")\n .replaceAll(\"\\n\", \"\\\\n\")}\"`;\n}\n\nfunction shellString(value: string) {\n return `'${value.replaceAll(\"'\", `'\"'\"'`)}'`;\n}\n\nfunction commandForPath(prototypePath: string) {\n return `cd ${shellString(prototypePath)} && ${CLAUDE_COMMAND}`;\n}\n\nexport function buildClaudeCodeAppleScript(\n terminal: TerminalApp,\n prototypePath: string,\n) {\n const command = commandForPath(prototypePath);\n\n switch (terminal) {\n case \"terminal\":\n return `tell application \"Terminal\" to do script ${appleScriptString(command)}`;\n case \"iterm\":\n return [\n 'tell application \"iTerm\"',\n \" create window with default profile\",\n \" tell current session of current window\",\n ` write text ${appleScriptString(command)}`,\n \" end tell\",\n \"end tell\",\n ].join(\"\\n\");\n case \"warp\": {\n const uri = `warp://action/new_tab?path=${encodeURIComponent(prototypePath)}`;\n return [\n `do shell script ${appleScriptString(`open ${shellString(uri)}`)}`,\n \"delay 1\",\n 'tell application \"Warp\" to activate',\n `tell application \"System Events\" to keystroke ${appleScriptString(command)}`,\n 'tell application \"System Events\" to key code 36',\n ].join(\"\\n\");\n }\n }\n}\n\nfunction actionFailure(\n code: \"missing-command\" | \"launch-failed\" | \"unsupported-platform\",\n terminal?: TerminalApp,\n command?: AgentCommand,\n) {\n const error: AgentActionError = {\n code,\n agent: \"claude-code\",\n ...(command ? { command } : {}),\n ...(terminal ? { terminal } : {}),\n };\n\n return {\n ok: false,\n error,\n } satisfies AgentActionResult;\n}\n\nexport class ClaudeCodeLauncher implements ClaudeCodeLauncherLike {\n readonly #executableResolver: ExecutableResolverLike;\n readonly #platform: NodeJS.Platform;\n readonly #process: ClaudeCodeProcessRunner;\n\n constructor(options: ClaudeCodeLauncherOptions = {}) {\n this.#executableResolver =\n options.executableResolver ?? new PathExecutableResolver();\n this.#platform = options.platform ?? process.platform;\n this.#process = options.process ?? defaultProcess;\n }\n\n async preflight(terminal?: TerminalApp) {\n if (this.#platform !== \"darwin\") {\n return actionFailure(\"unsupported-platform\", terminal);\n }\n\n const claude = await this.#executableResolver.resolve(CLAUDE_COMMAND);\n if (claude === null) {\n return actionFailure(\"missing-command\", terminal, CLAUDE_COMMAND);\n }\n\n const osascript = await this.#executableResolver.resolve(OSASCRIPT_COMMAND);\n if (osascript === null) {\n return actionFailure(\"missing-command\", terminal, OSASCRIPT_COMMAND);\n }\n\n return {\n ok: true,\n value: { osascript },\n } satisfies ClaudeCodePreflightResult;\n }\n\n async launch(\n terminal: TerminalApp,\n prototypePath: string,\n preflight?: ClaudeCodePreflightResult,\n ) {\n const checked = preflight ?? (await this.preflight(terminal));\n if (!checked.ok) return checked;\n\n const script = buildClaudeCodeAppleScript(terminal, prototypePath);\n try {\n await this.#process.execFile(checked.value.osascript, [\"-e\", script], {\n timeout: APPLESCRIPT_TIMEOUT,\n maxBuffer: APPLESCRIPT_MAX_BUFFER,\n });\n } catch {\n return actionFailure(\"launch-failed\", terminal);\n }\n\n return {\n ok: true,\n value: { agent: \"claude-code\" },\n } satisfies AgentActionResult;\n }\n}\n"]}
|
package/dist/claude.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile as nodeExecFile } from \"node:child_process\";\nimport {\n type AgentActionError,\n type AgentActionResult,\n type AgentCommand,\n type AgentLaunchValue,\n type TerminalApp,\n} from \"@ebay-dt/bonfire-core\";\nimport {\n PathExecutableResolver,\n type ExecutableResolverLike,\n} from \"./executable.js\";\n\nconst CLAUDE_COMMAND = \"claude\";\nconst OSASCRIPT_COMMAND = \"osascript\";\nconst APPLESCRIPT_TIMEOUT = 10_000;\nconst APPLESCRIPT_MAX_BUFFER = 1024 * 1024;\n\nexport type ClaudeCodeExecOptions = {\n timeout: number;\n maxBuffer: number;\n};\n\nexport type ClaudeCodeExecResult = {\n stdout: string;\n stderr: string;\n};\n\nexport type ClaudeCodeProcessRunner = {\n execFile(\n executable: string,\n args: readonly string[],\n options: ClaudeCodeExecOptions,\n ): Promise<ClaudeCodeExecResult>;\n};\n\nexport type ClaudeCodePreflightValue = {\n osascript: string;\n};\n\nexport type ClaudeCodePreflightResult =\n AgentActionResult<ClaudeCodePreflightValue>;\n\nexport type ClaudeCodeLauncherOptions = {\n executableResolver?: ExecutableResolverLike;\n platform?: NodeJS.Platform;\n process?: ClaudeCodeProcessRunner;\n};\n\nexport interface ClaudeCodeLauncherLike {\n preflight(terminal?: TerminalApp): Promise<ClaudeCodePreflightResult>;\n launch(\n terminal: TerminalApp,\n prototypePath: string,\n preflight?: ClaudeCodePreflightResult,\n ): Promise<AgentActionResult<AgentLaunchValue>>;\n}\n\nconst defaultProcess: ClaudeCodeProcessRunner = {\n execFile(executable, args, options) {\n return new Promise((resolve, reject) => {\n nodeExecFile(\n executable,\n [...args],\n { ...options, encoding: \"utf8\" },\n (error, stdout, stderr) => {\n if (error) {\n Object.assign(error, { stdout, stderr });\n reject(error);\n return;\n }\n\n resolve({ stdout, stderr });\n },\n );\n });\n },\n};\n\nfunction appleScriptString(value: string) {\n return `\"${value\n .replaceAll(\"\\\\\", \"\\\\\\\\\")\n .replaceAll('\"', '\\\\\"')\n .replaceAll(\"\\r\", \"\\\\r\")\n .replaceAll(\"\\n\", \"\\\\n\")}\"`;\n}\n\nfunction shellString(value: string) {\n return `'${value.replaceAll(\"'\", `'\"'\"'`)}'`;\n}\n\nfunction commandForPath(prototypePath: string) {\n return `cd ${shellString(prototypePath)} && ${CLAUDE_COMMAND}`;\n}\n\nexport function buildClaudeCodeAppleScript(\n terminal: TerminalApp,\n prototypePath: string,\n) {\n const command = commandForPath(prototypePath);\n\n switch (terminal) {\n case \"terminal\":\n return `tell application \"Terminal\" to do script ${appleScriptString(command)}`;\n case \"iterm\":\n return [\n 'tell application \"iTerm\"',\n \" create window with default profile\",\n \" tell current session of current window\",\n ` write text ${appleScriptString(command)}`,\n \" end tell\",\n \"end tell\",\n ].join(\"\\n\");\n case \"warp\": {\n const uri = `warp://action/new_tab?path=${encodeURIComponent(prototypePath)}`;\n return [\n `do shell script ${appleScriptString(`open ${shellString(uri)}`)}`,\n \"delay 1\",\n 'tell application \"Warp\" to activate',\n `tell application \"System Events\" to keystroke ${appleScriptString(command)}`,\n 'tell application \"System Events\" to key code 36',\n ].join(\"\\n\");\n }\n }\n}\n\nfunction actionFailure(\n code: \"missing-command\" | \"launch-failed\" | \"unsupported-platform\",\n terminal?: TerminalApp,\n command?: AgentCommand,\n) {\n const error: AgentActionError = {\n code,\n agent: \"claude-code\",\n ...(command ? { command } : {}),\n ...(terminal ? { terminal } : {}),\n };\n\n return {\n ok: false,\n error,\n } satisfies AgentActionResult;\n}\n\nexport class ClaudeCodeLauncher implements ClaudeCodeLauncherLike {\n readonly #executableResolver: ExecutableResolverLike;\n readonly #platform: NodeJS.Platform;\n readonly #process: ClaudeCodeProcessRunner;\n\n constructor(options: ClaudeCodeLauncherOptions = {}) {\n this.#executableResolver =\n options.executableResolver ?? new PathExecutableResolver();\n this.#platform = options.platform ?? process.platform;\n this.#process = options.process ?? defaultProcess;\n }\n\n async preflight(terminal?: TerminalApp) {\n if (this.#platform !== \"darwin\") {\n return actionFailure(\"unsupported-platform\", terminal);\n }\n\n const claude = await this.#executableResolver.resolve(CLAUDE_COMMAND);\n if (claude === null) {\n return actionFailure(\"missing-command\", terminal, CLAUDE_COMMAND);\n }\n\n const osascript = await this.#executableResolver.resolve(OSASCRIPT_COMMAND);\n if (osascript === null) {\n return actionFailure(\"missing-command\", terminal, OSASCRIPT_COMMAND);\n }\n\n return {\n ok: true,\n value: { osascript },\n } satisfies ClaudeCodePreflightResult;\n }\n\n async launch(\n terminal: TerminalApp,\n prototypePath: string,\n preflight?: ClaudeCodePreflightResult,\n ) {\n const checked = preflight ?? (await this.preflight(terminal));\n if (!checked.ok) return checked;\n\n const script = buildClaudeCodeAppleScript(terminal, prototypePath);\n try {\n await this.#process.execFile(checked.value.osascript, [\"-e\", script], {\n timeout: APPLESCRIPT_TIMEOUT,\n maxBuffer: APPLESCRIPT_MAX_BUFFER,\n });\n } catch {\n return actionFailure(\"launch-failed\", terminal);\n }\n\n return {\n ok: true,\n value: { agent: \"claude-code\" },\n } satisfies AgentActionResult;\n }\n}\n"]}
|
package/dist/cursor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../src/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,iBAAiB,CAAC;AAIzB,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,QAAQ,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;AAEtE,MAAM,MAAM,WAAW,GAAG,CACxB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,kBAAkB,KACxB,kBAAkB,CAAC;AAExB,MAAM,MAAM,qBAAqB,GAAG;IAClC,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,CAAC;CAC7E;AAgBD,qBAAa,cAAe,YAAW,kBAAkB;;IAIvD,YAAY,OAAO,GAAE,qBAA0B,EAI9C;IAEK,MAAM,CAAC,aAAa,EAAE,MAAM;;;;;;;2BAiCjC;CACF"}
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../src/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,iBAAiB,CAAC;AAIzB,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,QAAQ,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;AAEtE,MAAM,MAAM,WAAW,GAAG,CACxB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,kBAAkB,KACxB,kBAAkB,CAAC;AAExB,MAAM,MAAM,qBAAqB,GAAG;IAClC,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,CAAC;CAC7E;AAgBD,qBAAa,cAAe,YAAW,kBAAkB;;IAIvD,YAAY,OAAO,GAAE,qBAA0B,EAI9C;IAEK,MAAM,CAAC,aAAa,EAAE,MAAM;;;;;;;2BAiCjC;CACF","sourcesContent":["import { spawn as nodeSpawn, type ChildProcess } from \"node:child_process\";\nimport {\n type AgentActionResult,\n type AgentLaunchValue,\n} from \"@ebay-dt/bonfire-core\";\nimport {\n PathExecutableResolver,\n type ExecutableResolverLike,\n} from \"./executable.js\";\n\nconst CURSOR_COMMAND = \"cursor\";\n\nexport type CursorSpawnOptions = {\n detached: true;\n shell: false;\n stdio: \"ignore\";\n};\n\nexport type CursorChildProcess = Pick<ChildProcess, \"once\" | \"unref\">;\n\nexport type CursorSpawn = (\n executable: string,\n args: readonly string[],\n options: CursorSpawnOptions,\n) => CursorChildProcess;\n\nexport type CursorLauncherOptions = {\n executableResolver?: ExecutableResolverLike;\n spawn?: CursorSpawn;\n};\n\nexport interface CursorLauncherLike {\n launch(prototypePath: string): Promise<AgentActionResult<AgentLaunchValue>>;\n}\n\nconst defaultSpawn: CursorSpawn = (executable, args, options) =>\n nodeSpawn(executable, [...args], options);\n\nfunction launchFailure() {\n return {\n ok: false,\n error: {\n code: \"launch-failed\",\n agent: \"cursor\",\n command: CURSOR_COMMAND,\n },\n } satisfies AgentActionResult;\n}\n\nexport class CursorLauncher implements CursorLauncherLike {\n readonly #executableResolver: ExecutableResolverLike;\n readonly #spawn: CursorSpawn;\n\n constructor(options: CursorLauncherOptions = {}) {\n this.#executableResolver =\n options.executableResolver ?? new PathExecutableResolver();\n this.#spawn = options.spawn ?? defaultSpawn;\n }\n\n async launch(prototypePath: string) {\n const executable = await this.#executableResolver.resolve(CURSOR_COMMAND);\n if (executable === null) {\n return {\n ok: false,\n error: {\n code: \"missing-command\",\n agent: \"cursor\",\n command: CURSOR_COMMAND,\n },\n } satisfies AgentActionResult;\n }\n\n let child: CursorChildProcess;\n try {\n child = this.#spawn(executable, [prototypePath], {\n detached: true,\n shell: false,\n stdio: \"ignore\",\n });\n child.unref();\n } catch {\n return launchFailure();\n }\n\n return new Promise<AgentActionResult>((resolve) => {\n child.once(\"spawn\", () => {\n resolve({ ok: true, value: { agent: \"cursor\" } });\n });\n child.once(\"error\", () => {\n resolve(launchFailure());\n });\n });\n }\n}\n"]}
|
package/dist/cursor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../src/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,SAAS,EAAqB,MAAM,oBAAoB,CAAC;AAK3E,OAAO,EACL,sBAAsB,GAEvB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,cAAc,GAAG,QAAQ,CAAC;AAyBhC,MAAM,YAAY,GAAgB,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAC9D,SAAS,CAAC,UAAU,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AAE5C,SAAS,aAAa;IACpB,OAAO;QACL,EAAE,EAAE,KAAK;QACT,KAAK,EAAE;YACL,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,cAAc;SACxB;KAC0B,CAAC;AAChC,CAAC;AAED,MAAM,OAAO,cAAc;IAChB,mBAAmB,CAAyB;IAC5C,MAAM,CAAc;IAE7B,YAAY,OAAO,GAA0B,EAAE;QAC7C,IAAI,CAAC,mBAAmB;YACtB,OAAO,CAAC,kBAAkB,IAAI,IAAI,sBAAsB,EAAE,CAAC;QAC7D,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,aAAqB;QAChC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC1E,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE;oBACL,IAAI,EAAE,iBAAiB;oBACvB,KAAK,EAAE,QAAQ;oBACf,OAAO,EAAE,cAAc;iBACxB;aAC0B,CAAC;QAChC,CAAC;QAED,IAAI,KAAyB,CAAC;QAC9B,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,aAAa,CAAC,EAAE;gBAC/C,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,QAAQ;aAChB,CAAC,CAAC;YACH,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,aAAa,EAAE,CAAC;QACzB,CAAC;QAED,OAAO,IAAI,OAAO,CAAoB,CAAC,OAAO,EAAE,EAAE;YAChD,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;gBACvB,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;gBACvB,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../src/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,SAAS,EAAqB,MAAM,oBAAoB,CAAC;AAK3E,OAAO,EACL,sBAAsB,GAEvB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,cAAc,GAAG,QAAQ,CAAC;AAyBhC,MAAM,YAAY,GAAgB,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAC9D,SAAS,CAAC,UAAU,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AAE5C,SAAS,aAAa;IACpB,OAAO;QACL,EAAE,EAAE,KAAK;QACT,KAAK,EAAE;YACL,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,cAAc;SACxB;KAC0B,CAAC;AAChC,CAAC;AAED,MAAM,OAAO,cAAc;IAChB,mBAAmB,CAAyB;IAC5C,MAAM,CAAc;IAE7B,YAAY,OAAO,GAA0B,EAAE;QAC7C,IAAI,CAAC,mBAAmB;YACtB,OAAO,CAAC,kBAAkB,IAAI,IAAI,sBAAsB,EAAE,CAAC;QAC7D,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,aAAqB;QAChC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC1E,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE;oBACL,IAAI,EAAE,iBAAiB;oBACvB,KAAK,EAAE,QAAQ;oBACf,OAAO,EAAE,cAAc;iBACxB;aAC0B,CAAC;QAChC,CAAC;QAED,IAAI,KAAyB,CAAC;QAC9B,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,aAAa,CAAC,EAAE;gBAC/C,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,QAAQ;aAChB,CAAC,CAAC;YACH,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,aAAa,EAAE,CAAC;QACzB,CAAC;QAED,OAAO,IAAI,OAAO,CAAoB,CAAC,OAAO,EAAE,EAAE;YAChD,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;gBACvB,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;gBACvB,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import { spawn as nodeSpawn, type ChildProcess } from \"node:child_process\";\nimport {\n type AgentActionResult,\n type AgentLaunchValue,\n} from \"@ebay-dt/bonfire-core\";\nimport {\n PathExecutableResolver,\n type ExecutableResolverLike,\n} from \"./executable.js\";\n\nconst CURSOR_COMMAND = \"cursor\";\n\nexport type CursorSpawnOptions = {\n detached: true;\n shell: false;\n stdio: \"ignore\";\n};\n\nexport type CursorChildProcess = Pick<ChildProcess, \"once\" | \"unref\">;\n\nexport type CursorSpawn = (\n executable: string,\n args: readonly string[],\n options: CursorSpawnOptions,\n) => CursorChildProcess;\n\nexport type CursorLauncherOptions = {\n executableResolver?: ExecutableResolverLike;\n spawn?: CursorSpawn;\n};\n\nexport interface CursorLauncherLike {\n launch(prototypePath: string): Promise<AgentActionResult<AgentLaunchValue>>;\n}\n\nconst defaultSpawn: CursorSpawn = (executable, args, options) =>\n nodeSpawn(executable, [...args], options);\n\nfunction launchFailure() {\n return {\n ok: false,\n error: {\n code: \"launch-failed\",\n agent: \"cursor\",\n command: CURSOR_COMMAND,\n },\n } satisfies AgentActionResult;\n}\n\nexport class CursorLauncher implements CursorLauncherLike {\n readonly #executableResolver: ExecutableResolverLike;\n readonly #spawn: CursorSpawn;\n\n constructor(options: CursorLauncherOptions = {}) {\n this.#executableResolver =\n options.executableResolver ?? new PathExecutableResolver();\n this.#spawn = options.spawn ?? defaultSpawn;\n }\n\n async launch(prototypePath: string) {\n const executable = await this.#executableResolver.resolve(CURSOR_COMMAND);\n if (executable === null) {\n return {\n ok: false,\n error: {\n code: \"missing-command\",\n agent: \"cursor\",\n command: CURSOR_COMMAND,\n },\n } satisfies AgentActionResult;\n }\n\n let child: CursorChildProcess;\n try {\n child = this.#spawn(executable, [prototypePath], {\n detached: true,\n shell: false,\n stdio: \"ignore\",\n });\n child.unref();\n } catch {\n return launchFailure();\n }\n\n return new Promise<AgentActionResult>((resolve) => {\n child.once(\"spawn\", () => {\n resolve({ ok: true, value: { agent: \"cursor\" } });\n });\n child.once(\"error\", () => {\n resolve(launchFailure());\n });\n });\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deployment-provider.d.ts","sourceRoot":"","sources":["../src/deployment-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAQlE;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,oBAAoB,CAAC;CAClC,CAAC;AAEF,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,KAAK,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;CACvC;AAED,MAAM,MAAM,+BAA+B,GAAG;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GACnC,SAAS,GACT,iBAAiB,GACjB,kBAAkB,GAClB,aAAa,GACb,uBAAuB,CAAC;AAE5B;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,IAAI,EAAE,2BAA2B,CAAC;IAE3C,YAAY,IAAI,EAAE,2BAA2B,EAI5C;CACF;AA8KD,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EAAE,kBAAkB,EAC5B,SAAS,EAAE,iBAAiB,GAC7B,EAAE,+BAA+B,GAAG,kBAAkB,CA2CtD"}
|
|
1
|
+
{"version":3,"file":"deployment-provider.d.ts","sourceRoot":"","sources":["../src/deployment-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAQlE;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,oBAAoB,CAAC;CAClC,CAAC;AAEF,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,KAAK,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;CACvC;AAED,MAAM,MAAM,+BAA+B,GAAG;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GACnC,SAAS,GACT,iBAAiB,GACjB,kBAAkB,GAClB,aAAa,GACb,uBAAuB,CAAC;AAE5B;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,IAAI,EAAE,2BAA2B,CAAC;IAE3C,YAAY,IAAI,EAAE,2BAA2B,EAI5C;CACF;AA8KD,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EAAE,kBAAkB,EAC5B,SAAS,EAAE,iBAAiB,GAC7B,EAAE,+BAA+B,GAAG,kBAAkB,CA2CtD","sourcesContent":["import type { DeploymentReadyState } from \"@ebay-dt/bonfire-core\";\nimport { isDeploymentReadyState } from \"@ebay-dt/bonfire-core\";\nimport { isRecord } from \"./internal/utils.js\";\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst MAX_RESPONSE_STRING_LENGTH = 2_000;\nconst MAX_RESPONSE_URL_LENGTH = 8_192;\n\n/**\n * The normalized result returned by a deployment provider. `url` is the\n * deployment-root URL; the lifecycle service adds the active prototype route.\n */\nexport type DeploymentProviderResult = {\n url: string;\n deploymentId: string;\n readyState: DeploymentReadyState;\n};\n\n/** Server-side transport boundary for creating an application deployment. */\nexport interface DeploymentProvider {\n deploy(input: {\n applicationId: string;\n login: string;\n }): Promise<DeploymentProviderResult>;\n}\n\nexport type CreateDeploymentProviderOptions = {\n endpoint: string;\n timeoutMs?: number;\n};\n\nexport type DeploymentProviderErrorKind =\n | \"timeout\"\n | \"service-failure\"\n | \"invalid-response\"\n | \"invalid-url\"\n | \"invalid-configuration\";\n\n/**\n * Safe provider failure classification. It intentionally carries no response\n * body, endpoint credentials, or unbounded service diagnostics.\n */\nexport class DeploymentProviderError extends Error {\n readonly kind: DeploymentProviderErrorKind;\n\n constructor(kind: DeploymentProviderErrorKind) {\n super(\"Deployment provider request failed\");\n this.name = \"DeploymentProviderError\";\n this.kind = kind;\n }\n}\n\n/**\n * Internal DT deployment success wire shape. The service diagnostics are\n * validated at the transport boundary but are not exposed as client data.\n */\ntype DeploymentServiceSuccessResponse = {\n repository: string;\n ref: string;\n commitSha: string;\n sourceFileCount: number;\n project: string;\n deployed: true;\n deploymentId: string;\n url: string;\n readyState: DeploymentReadyState;\n};\n\n/** Internal DT deployment failure wire shape. */\ntype DeploymentServiceFailureResponse = {\n repository: string;\n ref?: string;\n commitSha?: string;\n project?: string;\n stage?: string;\n deployed: false;\n statusCode: number;\n details: string;\n};\n\ntype DeploymentServiceResponse =\n DeploymentServiceSuccessResponse | DeploymentServiceFailureResponse;\n\nfunction isBoundedString(\n value: unknown,\n options: { allowEmpty?: boolean; maxLength?: number } = {},\n): value is string {\n if (typeof value !== \"string\") return false;\n if (!options.allowEmpty && value.length === 0) return false;\n return value.length <= (options.maxLength ?? MAX_RESPONSE_STRING_LENGTH);\n}\n\nfunction validateEndpoint(value: unknown): string {\n if (\n typeof value !== \"string\" ||\n value.length === 0 ||\n value.trim() !== value\n ) {\n throw new DeploymentProviderError(\"invalid-configuration\");\n }\n\n let endpoint: URL;\n try {\n endpoint = new URL(value);\n } catch {\n throw new DeploymentProviderError(\"invalid-configuration\");\n }\n\n if (\n (endpoint.protocol !== \"http:\" && endpoint.protocol !== \"https:\") ||\n endpoint.username !== \"\" ||\n endpoint.password !== \"\" ||\n endpoint.search !== \"\" ||\n endpoint.hash !== \"\"\n ) {\n throw new DeploymentProviderError(\"invalid-configuration\");\n }\n\n return value;\n}\n\nfunction validateTimeout(value: unknown): number {\n if (\n value === undefined ||\n (typeof value === \"number\" &&\n Number.isFinite(value) &&\n Number.isInteger(value) &&\n value > 0)\n ) {\n return value ?? DEFAULT_TIMEOUT_MS;\n }\n\n throw new DeploymentProviderError(\"invalid-configuration\");\n}\n\nfunction parseDeploymentUrl(value: unknown): string | null {\n if (!isBoundedString(value, { maxLength: MAX_RESPONSE_URL_LENGTH })) {\n return null;\n }\n\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n return null;\n }\n\n if (url.protocol !== \"https:\" || url.username !== \"\" || url.password !== \"\") {\n return null;\n }\n\n return url.toString().replace(/\\/$/, \"\");\n}\n\nfunction isDeploymentServiceSuccessResponse(\n value: unknown,\n): value is DeploymentServiceSuccessResponse {\n if (!isRecord(value)) return false;\n\n return (\n isBoundedString(value.repository) &&\n isBoundedString(value.ref) &&\n isBoundedString(value.commitSha) &&\n Number.isInteger(value.sourceFileCount) &&\n Number(value.sourceFileCount) >= 0 &&\n isBoundedString(value.project) &&\n value.deployed === true &&\n isBoundedString(value.deploymentId) &&\n isBoundedString(value.url, { maxLength: MAX_RESPONSE_URL_LENGTH }) &&\n isDeploymentReadyState(value.readyState)\n );\n}\n\nfunction isDeploymentServiceFailureResponse(\n value: unknown,\n): value is DeploymentServiceFailureResponse {\n if (!isRecord(value)) return false;\n\n const optionalStringFields = [\"ref\", \"commitSha\", \"project\", \"stage\"];\n return (\n isBoundedString(value.repository) &&\n value.deployed === false &&\n Number.isInteger(value.statusCode) &&\n Number(value.statusCode) >= 0 &&\n isBoundedString(value.details) &&\n optionalStringFields.every(\n (field) => !Object.hasOwn(value, field) || isBoundedString(value[field]),\n )\n );\n}\n\nasync function readResponse(response: Response): Promise<unknown> {\n try {\n return await response.json();\n } catch {\n throw new DeploymentProviderError(\"invalid-response\");\n }\n}\n\nfunction parseSuccessResponse(value: unknown): DeploymentProviderResult {\n if (!isDeploymentServiceSuccessResponse(value)) {\n throw new DeploymentProviderError(\"invalid-response\");\n }\n\n const url = parseDeploymentUrl(value.url);\n if (url === null) {\n throw new DeploymentProviderError(\"invalid-url\");\n }\n\n return {\n url,\n deploymentId: value.deploymentId,\n readyState: value.readyState,\n };\n}\n\nfunction parseFailureResponse(value: unknown): never {\n if (!isDeploymentServiceFailureResponse(value)) {\n throw new DeploymentProviderError(\"invalid-response\");\n }\n\n throw new DeploymentProviderError(\"service-failure\");\n}\n\nexport function createDeploymentProvider({\n endpoint: configuredEndpoint,\n timeoutMs: configuredTimeout,\n}: CreateDeploymentProviderOptions): DeploymentProvider {\n const endpoint = validateEndpoint(configuredEndpoint);\n const timeoutMs = validateTimeout(configuredTimeout);\n const fetchImplementation = globalThis.fetch;\n\n if (typeof fetchImplementation !== \"function\") {\n throw new DeploymentProviderError(\"invalid-configuration\");\n }\n\n return {\n async deploy(input) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n let response: Response;\n try {\n response = await fetchImplementation(endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n applicationId: input.applicationId,\n login: input.login,\n }),\n cache: \"no-store\",\n signal: controller.signal,\n });\n } catch {\n if (controller.signal.aborted) {\n throw new DeploymentProviderError(\"timeout\");\n }\n throw new DeploymentProviderError(\"service-failure\");\n } finally {\n clearTimeout(timeout);\n }\n\n const payload = await readResponse(response);\n if (response.status === 201) {\n return parseSuccessResponse(payload);\n }\n\n return parseFailureResponse(payload);\n },\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deployment-provider.js","sourceRoot":"","sources":["../src/deployment-provider.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"deployment-provider.js","sourceRoot":"","sources":["../src/deployment-provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,MAAM,kBAAkB,GAAG,OAAO,CAAC;AACnC,MAAM,0BAA0B,GAAG,KAAK,CAAC;AACzC,MAAM,uBAAuB,GAAG,KAAK,CAAC;AAgCtC;;;GAGG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IACvC,IAAI,CAA8B;IAE3C,YAAY,IAAiC;QAC3C,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAiCD,SAAS,eAAe,CACtB,KAAc,EACd,OAAO,GAAiD,EAAE;IAE1D,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5D,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,0BAA0B,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,CAAC,MAAM,KAAK,CAAC;QAClB,KAAK,CAAC,IAAI,EAAE,KAAK,KAAK,EACtB,CAAC;QACD,MAAM,IAAI,uBAAuB,CAAC,uBAAuB,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,QAAa,CAAC;IAClB,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,uBAAuB,CAAC,uBAAuB,CAAC,CAAC;IAC7D,CAAC;IAED,IACE,CAAC,QAAQ,CAAC,QAAQ,KAAK,OAAO,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC;QACjE,QAAQ,CAAC,QAAQ,KAAK,EAAE;QACxB,QAAQ,CAAC,QAAQ,KAAK,EAAE;QACxB,QAAQ,CAAC,MAAM,KAAK,EAAE;QACtB,QAAQ,CAAC,IAAI,KAAK,EAAE,EACpB,CAAC;QACD,MAAM,IAAI,uBAAuB,CAAC,uBAAuB,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IACE,KAAK,KAAK,SAAS;QACnB,CAAC,OAAO,KAAK,KAAK,QAAQ;YACxB,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YACtB,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;YACvB,KAAK,GAAG,CAAC,CAAC,EACZ,CAAC;QACD,OAAO,KAAK,IAAI,kBAAkB,CAAC;IACrC,CAAC;IAED,MAAM,IAAI,uBAAuB,CAAC,uBAAuB,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,uBAAuB,EAAE,CAAC,EAAE,CAAC;QACpE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,EAAE,IAAI,GAAG,CAAC,QAAQ,KAAK,EAAE,EAAE,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,kCAAkC,CACzC,KAAc;IAEd,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEnC,OAAO,CACL,eAAe,CAAC,KAAK,CAAC,UAAU,CAAC;QACjC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC;QAC1B,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC;QAChC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,eAAe,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC;QAClC,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC;QAC9B,KAAK,CAAC,QAAQ,KAAK,IAAI;QACvB,eAAe,CAAC,KAAK,CAAC,YAAY,CAAC;QACnC,eAAe,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,uBAAuB,EAAE,CAAC;QAClE,sBAAsB,CAAC,KAAK,CAAC,UAAU,CAAC,CACzC,CAAC;AACJ,CAAC;AAED,SAAS,kCAAkC,CACzC,KAAc;IAEd,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEnC,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACtE,OAAO,CACL,eAAe,CAAC,KAAK,CAAC,UAAU,CAAC;QACjC,KAAK,CAAC,QAAQ,KAAK,KAAK;QACxB,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;QAC7B,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC;QAC9B,oBAAoB,CAAC,KAAK,CACxB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CACzE,CACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,QAAkB;IAC5C,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,uBAAuB,CAAC,kBAAkB,CAAC,CAAC;IACxD,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,CAAC,kCAAkC,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,uBAAuB,CAAC,kBAAkB,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,GAAG,GAAG,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,MAAM,IAAI,uBAAuB,CAAC,aAAa,CAAC,CAAC;IACnD,CAAC;IAED,OAAO;QACL,GAAG;QACH,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,UAAU,EAAE,KAAK,CAAC,UAAU;KAC7B,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,CAAC,kCAAkC,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,uBAAuB,CAAC,kBAAkB,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,IAAI,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,EACvC,QAAQ,EAAE,kBAAkB,EAC5B,SAAS,EAAE,iBAAiB,GACI;IAChC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,eAAe,CAAC,iBAAiB,CAAC,CAAC;IACrD,MAAM,mBAAmB,GAAG,UAAU,CAAC,KAAK,CAAC;IAE7C,IAAI,OAAO,mBAAmB,KAAK,UAAU,EAAE,CAAC;QAC9C,MAAM,IAAI,uBAAuB,CAAC,uBAAuB,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO;QACL,KAAK,CAAC,MAAM,CAAC,KAAK;YAChB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;YAEhE,IAAI,QAAkB,CAAC;YACvB,IAAI,CAAC;gBACH,QAAQ,GAAG,MAAM,mBAAmB,CAAC,QAAQ,EAAE;oBAC7C,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;oBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,aAAa,EAAE,KAAK,CAAC,aAAa;wBAClC,KAAK,EAAE,KAAK,CAAC,KAAK;qBACnB,CAAC;oBACF,KAAK,EAAE,UAAU;oBACjB,MAAM,EAAE,UAAU,CAAC,MAAM;iBAC1B,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBAC9B,MAAM,IAAI,uBAAuB,CAAC,SAAS,CAAC,CAAC;gBAC/C,CAAC;gBACD,MAAM,IAAI,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;YACvD,CAAC;oBAAS,CAAC;gBACT,YAAY,CAAC,OAAO,CAAC,CAAC;YACxB,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;YAC7C,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;YACvC,CAAC;YAED,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { DeploymentReadyState } from \"@ebay-dt/bonfire-core\";\nimport { isDeploymentReadyState } from \"@ebay-dt/bonfire-core\";\nimport { isRecord } from \"./internal/utils.js\";\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst MAX_RESPONSE_STRING_LENGTH = 2_000;\nconst MAX_RESPONSE_URL_LENGTH = 8_192;\n\n/**\n * The normalized result returned by a deployment provider. `url` is the\n * deployment-root URL; the lifecycle service adds the active prototype route.\n */\nexport type DeploymentProviderResult = {\n url: string;\n deploymentId: string;\n readyState: DeploymentReadyState;\n};\n\n/** Server-side transport boundary for creating an application deployment. */\nexport interface DeploymentProvider {\n deploy(input: {\n applicationId: string;\n login: string;\n }): Promise<DeploymentProviderResult>;\n}\n\nexport type CreateDeploymentProviderOptions = {\n endpoint: string;\n timeoutMs?: number;\n};\n\nexport type DeploymentProviderErrorKind =\n | \"timeout\"\n | \"service-failure\"\n | \"invalid-response\"\n | \"invalid-url\"\n | \"invalid-configuration\";\n\n/**\n * Safe provider failure classification. It intentionally carries no response\n * body, endpoint credentials, or unbounded service diagnostics.\n */\nexport class DeploymentProviderError extends Error {\n readonly kind: DeploymentProviderErrorKind;\n\n constructor(kind: DeploymentProviderErrorKind) {\n super(\"Deployment provider request failed\");\n this.name = \"DeploymentProviderError\";\n this.kind = kind;\n }\n}\n\n/**\n * Internal DT deployment success wire shape. The service diagnostics are\n * validated at the transport boundary but are not exposed as client data.\n */\ntype DeploymentServiceSuccessResponse = {\n repository: string;\n ref: string;\n commitSha: string;\n sourceFileCount: number;\n project: string;\n deployed: true;\n deploymentId: string;\n url: string;\n readyState: DeploymentReadyState;\n};\n\n/** Internal DT deployment failure wire shape. */\ntype DeploymentServiceFailureResponse = {\n repository: string;\n ref?: string;\n commitSha?: string;\n project?: string;\n stage?: string;\n deployed: false;\n statusCode: number;\n details: string;\n};\n\ntype DeploymentServiceResponse =\n DeploymentServiceSuccessResponse | DeploymentServiceFailureResponse;\n\nfunction isBoundedString(\n value: unknown,\n options: { allowEmpty?: boolean; maxLength?: number } = {},\n): value is string {\n if (typeof value !== \"string\") return false;\n if (!options.allowEmpty && value.length === 0) return false;\n return value.length <= (options.maxLength ?? MAX_RESPONSE_STRING_LENGTH);\n}\n\nfunction validateEndpoint(value: unknown): string {\n if (\n typeof value !== \"string\" ||\n value.length === 0 ||\n value.trim() !== value\n ) {\n throw new DeploymentProviderError(\"invalid-configuration\");\n }\n\n let endpoint: URL;\n try {\n endpoint = new URL(value);\n } catch {\n throw new DeploymentProviderError(\"invalid-configuration\");\n }\n\n if (\n (endpoint.protocol !== \"http:\" && endpoint.protocol !== \"https:\") ||\n endpoint.username !== \"\" ||\n endpoint.password !== \"\" ||\n endpoint.search !== \"\" ||\n endpoint.hash !== \"\"\n ) {\n throw new DeploymentProviderError(\"invalid-configuration\");\n }\n\n return value;\n}\n\nfunction validateTimeout(value: unknown): number {\n if (\n value === undefined ||\n (typeof value === \"number\" &&\n Number.isFinite(value) &&\n Number.isInteger(value) &&\n value > 0)\n ) {\n return value ?? DEFAULT_TIMEOUT_MS;\n }\n\n throw new DeploymentProviderError(\"invalid-configuration\");\n}\n\nfunction parseDeploymentUrl(value: unknown): string | null {\n if (!isBoundedString(value, { maxLength: MAX_RESPONSE_URL_LENGTH })) {\n return null;\n }\n\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n return null;\n }\n\n if (url.protocol !== \"https:\" || url.username !== \"\" || url.password !== \"\") {\n return null;\n }\n\n return url.toString().replace(/\\/$/, \"\");\n}\n\nfunction isDeploymentServiceSuccessResponse(\n value: unknown,\n): value is DeploymentServiceSuccessResponse {\n if (!isRecord(value)) return false;\n\n return (\n isBoundedString(value.repository) &&\n isBoundedString(value.ref) &&\n isBoundedString(value.commitSha) &&\n Number.isInteger(value.sourceFileCount) &&\n Number(value.sourceFileCount) >= 0 &&\n isBoundedString(value.project) &&\n value.deployed === true &&\n isBoundedString(value.deploymentId) &&\n isBoundedString(value.url, { maxLength: MAX_RESPONSE_URL_LENGTH }) &&\n isDeploymentReadyState(value.readyState)\n );\n}\n\nfunction isDeploymentServiceFailureResponse(\n value: unknown,\n): value is DeploymentServiceFailureResponse {\n if (!isRecord(value)) return false;\n\n const optionalStringFields = [\"ref\", \"commitSha\", \"project\", \"stage\"];\n return (\n isBoundedString(value.repository) &&\n value.deployed === false &&\n Number.isInteger(value.statusCode) &&\n Number(value.statusCode) >= 0 &&\n isBoundedString(value.details) &&\n optionalStringFields.every(\n (field) => !Object.hasOwn(value, field) || isBoundedString(value[field]),\n )\n );\n}\n\nasync function readResponse(response: Response): Promise<unknown> {\n try {\n return await response.json();\n } catch {\n throw new DeploymentProviderError(\"invalid-response\");\n }\n}\n\nfunction parseSuccessResponse(value: unknown): DeploymentProviderResult {\n if (!isDeploymentServiceSuccessResponse(value)) {\n throw new DeploymentProviderError(\"invalid-response\");\n }\n\n const url = parseDeploymentUrl(value.url);\n if (url === null) {\n throw new DeploymentProviderError(\"invalid-url\");\n }\n\n return {\n url,\n deploymentId: value.deploymentId,\n readyState: value.readyState,\n };\n}\n\nfunction parseFailureResponse(value: unknown): never {\n if (!isDeploymentServiceFailureResponse(value)) {\n throw new DeploymentProviderError(\"invalid-response\");\n }\n\n throw new DeploymentProviderError(\"service-failure\");\n}\n\nexport function createDeploymentProvider({\n endpoint: configuredEndpoint,\n timeoutMs: configuredTimeout,\n}: CreateDeploymentProviderOptions): DeploymentProvider {\n const endpoint = validateEndpoint(configuredEndpoint);\n const timeoutMs = validateTimeout(configuredTimeout);\n const fetchImplementation = globalThis.fetch;\n\n if (typeof fetchImplementation !== \"function\") {\n throw new DeploymentProviderError(\"invalid-configuration\");\n }\n\n return {\n async deploy(input) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n let response: Response;\n try {\n response = await fetchImplementation(endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n applicationId: input.applicationId,\n login: input.login,\n }),\n cache: \"no-store\",\n signal: controller.signal,\n });\n } catch {\n if (controller.signal.aborted) {\n throw new DeploymentProviderError(\"timeout\");\n }\n throw new DeploymentProviderError(\"service-failure\");\n } finally {\n clearTimeout(timeout);\n }\n\n const payload = await readResponse(response);\n if (response.status === 201) {\n return parseSuccessResponse(payload);\n }\n\n return parseFailureResponse(payload);\n },\n };\n}\n"]}
|
package/dist/duplicate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duplicate.d.ts","sourceRoot":"","sources":["../src/duplicate.ts"],"names":[],"mappings":"AAYA,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,aAAa,EACnB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AAM1E,KAAK,aAAa,GAAG,CACnB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,UAAU,GAAG,MAAM,EAC5B,OAAO,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,KACpB,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,IAAI,CACT,6BAA6B,EAC7B,gBAAgB,GAAG,eAAe,CACnC,CAAC;IACF,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,YAAY,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,2BAA2B,GACrC,kBAAkB,GAAG,gBAAgB,GAAG,WAAW,GAAG,YAAY,CAAC;AAErE,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,IAAI,EAAE,2BAA2B,CAAC;IAE3C,YAAY,IAAI,EAAE,2BAA2B,EAI5C;CACF;AAkSD,wBAAsB,kBAAkB,CAAC,EACvC,KAAK,EACL,MAAM,EACN,WAAW,EAAE,cAAc,EAC3B,KAAK,EACL,WAAW,EACX,UAAU,EACV,aAAa,EACb,KAAwB,EACxB,SAA0B,GAC3B,EAAE,yBAAyB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CA0H7D"}
|
|
1
|
+
{"version":3,"file":"duplicate.d.ts","sourceRoot":"","sources":["../src/duplicate.ts"],"names":[],"mappings":"AAYA,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,aAAa,EACnB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AAM1E,KAAK,aAAa,GAAG,CACnB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,UAAU,GAAG,MAAM,EAC5B,OAAO,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,KACpB,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,IAAI,CACT,6BAA6B,EAC7B,gBAAgB,GAAG,eAAe,CACnC,CAAC;IACF,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,YAAY,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,2BAA2B,GACrC,kBAAkB,GAAG,gBAAgB,GAAG,WAAW,GAAG,YAAY,CAAC;AAErE,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,IAAI,EAAE,2BAA2B,CAAC;IAE3C,YAAY,IAAI,EAAE,2BAA2B,EAI5C;CACF;AAkSD,wBAAsB,kBAAkB,CAAC,EACvC,KAAK,EACL,MAAM,EACN,WAAW,EAAE,cAAc,EAC3B,KAAK,EACL,WAAW,EACX,UAAU,EACV,aAAa,EACb,KAAwB,EACxB,SAA0B,GAC3B,EAAE,yBAAyB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CA0H7D","sourcesContent":["import { constants } from \"node:fs\";\nimport {\n lstat,\n mkdir,\n open,\n readdir,\n rm,\n rmdir,\n writeFile as writeFileAsync,\n} from \"node:fs/promises\";\nimport { dirname, join, relative } from \"node:path\";\nimport type { Dirent } from \"node:fs\";\nimport {\n definePrototypeRef,\n parsePrototypeMetadata,\n type PrototypeMetadata,\n type PrototypeRef,\n type ThemeRegistry,\n} from \"@ebay-dt/bonfire-core\";\nimport {\n buildCssModulesDeclaration,\n buildMetadataJson,\n buildTsConfig,\n COPYABLE_IMPLEMENTATION_FILES,\n} from \"./internal/prototype-templates.js\";\nimport {\n captureOwnedDestination,\n type OwnedDestinationResult,\n} from \"./internal/owned-destination.js\";\nimport type { ResolvedPrototypeCatalogPaths } from \"./prototype-paths.js\";\nimport { isFileNotFound } from \"./internal/utils.js\";\n\nconst FILE_OPEN_FLAGS = constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0);\nconst BLOCKED_COMPONENT_NAMES = new Set([\".next\", \"node_modules\"]);\n\ntype SafeWriteFile = (\n path: string,\n content: Uint8Array | string,\n options: { flag: \"wx\" },\n) => Promise<void>;\n\nexport type DuplicatePrototypeOptions = {\n paths: Pick<\n ResolvedPrototypeCatalogPaths,\n \"repositoryRoot\" | \"prototypeRoot\"\n >;\n source: PrototypeRef;\n destination: PrototypeRef;\n title: string;\n description: string | null;\n authorName: string | null;\n themeRegistry?: ThemeRegistry;\n clock?: () => Date;\n writeFile?: SafeWriteFile;\n};\n\nexport type PrototypeDuplicateErrorKind =\n \"source-not-found\" | \"invalid-source\" | \"collision\" | \"filesystem\";\n\nexport class PrototypeDuplicateError extends Error {\n readonly kind: PrototypeDuplicateErrorKind;\n\n constructor(kind: PrototypeDuplicateErrorKind) {\n super(`Prototype duplication failed: ${kind}`);\n this.name = \"PrototypeDuplicateError\";\n this.kind = kind;\n }\n}\n\ntype OwnedPath = {\n path: string;\n device: number;\n inode: number;\n};\n\nfunction sourcePathFor(root: string, ref: PrototypeRef) {\n return join(root, ref.login, ref.slug);\n}\n\nasync function ownedPath(path: string): Promise<OwnedPath> {\n const stats = await lstat(path);\n return { path, device: stats.dev, inode: stats.ino };\n}\n\nasync function assertDirectory(\n path: string,\n kind: \"source-not-found\" | \"invalid-source\" | \"filesystem\",\n) {\n try {\n const stats = await lstat(path);\n if (stats.isSymbolicLink() || !stats.isDirectory()) {\n throw new PrototypeDuplicateError(kind);\n }\n } catch (error) {\n if (error instanceof PrototypeDuplicateError) throw error;\n if (isFileNotFound(error)) throw new PrototypeDuplicateError(kind);\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n}\n\nasync function readNoFollow(\n path: string,\n kind: \"invalid-source\" | \"filesystem\",\n) {\n try {\n const stats = await lstat(path);\n if (stats.isSymbolicLink() || !stats.isFile()) {\n throw new PrototypeDuplicateError(kind);\n }\n const file = await open(path, FILE_OPEN_FLAGS);\n try {\n return await file.readFile();\n } finally {\n await file.close();\n }\n } catch (error) {\n if (error instanceof PrototypeDuplicateError) throw error;\n if (isFileNotFound(error)) return null;\n throw new PrototypeDuplicateError(kind);\n }\n}\n\nasync function readRequiredSourceFile(path: string) {\n const content = await readNoFollow(path, \"invalid-source\");\n if (content === null) {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n return content;\n}\n\nasync function listComponentFiles(\n root: string,\n current: string,\n): Promise<string[]> {\n let entries: Dirent[];\n try {\n entries = await readdir(current, { withFileTypes: true });\n } catch {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n\n const files: string[] = [];\n for (const entry of entries.sort((left, right) =>\n left.name.localeCompare(right.name),\n )) {\n const path = join(current, entry.name);\n let stats;\n try {\n stats = await lstat(path);\n } catch {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n if (stats.isSymbolicLink()) {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n if (\n entry.name === \".gitkeep\" ||\n BLOCKED_COMPONENT_NAMES.has(entry.name) ||\n entry.name.startsWith(\".env\")\n ) {\n continue;\n }\n if (stats.isDirectory()) {\n files.push(...(await listComponentFiles(root, path)));\n continue;\n }\n if (!stats.isFile()) {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n files.push(relative(root, path));\n }\n return files;\n}\n\nasync function inspectSource(\n sourcePath: string,\n themeRegistry?: ThemeRegistry,\n) {\n await assertDirectory(sourcePath, \"source-not-found\");\n\n try {\n await lstat(join(sourcePath, \"page.module.css\"));\n throw new PrototypeDuplicateError(\"invalid-source\");\n } catch (error) {\n if (error instanceof PrototypeDuplicateError) throw error;\n if (!isFileNotFound(error)) {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n }\n\n const metadataBytes = await readRequiredSourceFile(\n join(sourcePath, \"metadata.json\"),\n );\n let metadata: PrototypeMetadata;\n try {\n metadata = parsePrototypeMetadata(\n JSON.parse(metadataBytes.toString(\"utf8\")),\n { themeRegistry },\n );\n } catch {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n\n const implementationFiles = new Map<string, Uint8Array>();\n for (const name of COPYABLE_IMPLEMENTATION_FILES) {\n implementationFiles.set(\n name,\n await readRequiredSourceFile(join(sourcePath, name)),\n );\n }\n\n const componentsPath = join(sourcePath, \"components\");\n let componentFiles: string[] = [];\n try {\n const stats = await lstat(componentsPath);\n if (stats.isSymbolicLink() || !stats.isDirectory()) {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n componentFiles = await listComponentFiles(componentsPath, componentsPath);\n } catch (error) {\n if (error instanceof PrototypeDuplicateError) throw error;\n if (!isFileNotFound(error)) {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n }\n\n return { metadata, implementationFiles, componentFiles };\n}\n\nasync function reserveDestination(\n path: string,\n paths: Pick<\n ResolvedPrototypeCatalogPaths,\n \"repositoryRoot\" | \"prototypeRoot\"\n >,\n) {\n try {\n await mkdir(path);\n } catch (error) {\n if (\n error !== null &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"EEXIST\"\n ) {\n throw new PrototypeDuplicateError(\"collision\");\n }\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n try {\n return await captureOwnedDestination({\n path,\n repositoryRoot: paths.repositoryRoot,\n prototypeRoot: paths.prototypeRoot,\n });\n } catch {\n // The newly created path is retained because ownership was not proven.\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n}\n\nasync function ensureDirectory(path: string) {\n try {\n await mkdir(path, { recursive: true });\n await assertDirectory(path, \"filesystem\");\n } catch (error) {\n if (error instanceof PrototypeDuplicateError) throw error;\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n}\n\nasync function createDirectory(path: string) {\n try {\n await mkdir(path);\n await assertDirectory(path, \"filesystem\");\n return await ownedPath(path);\n } catch (error) {\n if (error instanceof PrototypeDuplicateError) throw error;\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n}\n\nasync function createNestedDirectories(path: string, existingRoot: string) {\n const missing: string[] = [];\n let current = path;\n while (current !== existingRoot) {\n try {\n const stats = await lstat(current);\n if (stats.isSymbolicLink() || !stats.isDirectory()) {\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n break;\n } catch (error) {\n if (error instanceof PrototypeDuplicateError) throw error;\n if (!isFileNotFound(error)) {\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n missing.push(current);\n const parent = dirname(current);\n if (parent === current) throw new PrototypeDuplicateError(\"filesystem\");\n current = parent;\n }\n }\n\n const owned: OwnedPath[] = [];\n for (const directory of missing.reverse()) {\n owned.push(await createDirectory(directory));\n }\n return owned;\n}\n\nasync function writeExclusive(\n path: string,\n content: Uint8Array | string,\n writeFile: SafeWriteFile,\n) {\n try {\n await writeFile(path, content, { flag: \"wx\" });\n return await ownedPath(path);\n } catch {\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n}\n\nasync function removeOwnedPaths(\n files: readonly OwnedPath[],\n directories: readonly OwnedPath[],\n) {\n try {\n for (const owned of [...files].reverse()) {\n const current = await lstat(owned.path).catch(() => null);\n if (\n current !== null &&\n !current.isSymbolicLink() &&\n current.dev === owned.device &&\n current.ino === owned.inode\n ) {\n await rm(owned.path, { force: true });\n }\n }\n for (const owned of [...directories].reverse()) {\n const current = await lstat(owned.path).catch(() => null);\n if (\n current !== null &&\n current.isDirectory() &&\n !current.isSymbolicLink() &&\n current.dev === owned.device &&\n current.ino === owned.inode\n ) {\n await rmdir(owned.path);\n }\n }\n } catch {\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n}\n\nexport async function duplicatePrototype({\n paths,\n source,\n destination: destinationRef,\n title,\n description,\n authorName,\n themeRegistry,\n clock = () => new Date(),\n writeFile = writeFileAsync,\n}: DuplicatePrototypeOptions): Promise<OwnedDestinationResult> {\n const normalizedSource = definePrototypeRef(source);\n const normalizedDestination = definePrototypeRef(destinationRef);\n const sourcePath = sourcePathFor(paths.prototypeRoot, normalizedSource);\n const destination = sourcePathFor(paths.prototypeRoot, normalizedDestination);\n const sourceDetails = await inspectSource(sourcePath, themeRegistry);\n if (sourceDetails.metadata.authorLogin !== normalizedSource.login) {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n\n const timestamp = clock().toISOString();\n const metadata = buildMetadataJson(\n title,\n description,\n normalizedDestination.login,\n authorName,\n timestamp,\n sourceDetails.metadata.theme,\n );\n parsePrototypeMetadata(JSON.parse(metadata), { themeRegistry });\n\n await ensureDirectory(paths.prototypeRoot);\n await ensureDirectory(dirname(destination));\n const ownedFiles: OwnedPath[] = [];\n const receipt = await reserveDestination(destination, paths);\n const ownedDirectories: OwnedPath[] = [receipt];\n\n try {\n ownedDirectories.push(\n await createDirectory(join(destination, \"components\")),\n );\n\n for (const name of COPYABLE_IMPLEMENTATION_FILES) {\n ownedFiles.push(\n await writeExclusive(\n join(destination, name),\n sourceDetails.implementationFiles.get(name)!,\n writeFile,\n ),\n );\n }\n\n if (sourceDetails.componentFiles.length === 0) {\n ownedFiles.push(\n await writeExclusive(\n join(destination, \"components/.gitkeep\"),\n \"\",\n writeFile,\n ),\n );\n } else {\n for (const file of sourceDetails.componentFiles) {\n const sourceContent = await readRequiredSourceFile(\n join(sourcePath, \"components\", file),\n );\n const target = join(destination, \"components\", file);\n ownedDirectories.push(\n ...(await createNestedDirectories(\n dirname(target),\n join(destination, \"components\"),\n )),\n );\n ownedFiles.push(await writeExclusive(target, sourceContent, writeFile));\n }\n }\n\n ownedFiles.push(\n await writeExclusive(\n join(destination, \"metadata.json\"),\n metadata,\n writeFile,\n ),\n );\n ownedFiles.push(\n await writeExclusive(\n join(destination, \"tsconfig.json\"),\n buildTsConfig(paths.repositoryRoot, destination),\n writeFile,\n ),\n );\n ownedFiles.push(\n await writeExclusive(\n join(destination, \"css-modules.d.ts\"),\n buildCssModulesDeclaration(),\n writeFile,\n ),\n );\n\n const writtenMetadata = await readNoFollow(\n join(destination, \"metadata.json\"),\n \"filesystem\",\n );\n if (writtenMetadata === null) {\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n parsePrototypeMetadata(JSON.parse(writtenMetadata.toString(\"utf8\")), {\n themeRegistry,\n });\n const expectedFiles = [\n ...COPYABLE_IMPLEMENTATION_FILES,\n ...sourceDetails.componentFiles.map((file) => join(\"components\", file)),\n ...(sourceDetails.componentFiles.length === 0\n ? [\"components/.gitkeep\"]\n : []),\n \"metadata.json\",\n \"tsconfig.json\",\n \"css-modules.d.ts\",\n ];\n return {\n destination,\n receipt,\n expectedFiles: Object.freeze(expectedFiles),\n };\n } catch (error) {\n try {\n await removeOwnedPaths(ownedFiles, ownedDirectories);\n } catch {\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n if (error instanceof PrototypeDuplicateError) throw error;\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n}\n"]}
|
package/dist/duplicate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duplicate.js","sourceRoot":"","sources":["../src/duplicate.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"duplicate.js","sourceRoot":"","sources":["../src/duplicate.ts"],"names":[],"mappings":"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","sourcesContent":["import { constants } from \"node:fs\";\nimport {\n lstat,\n mkdir,\n open,\n readdir,\n rm,\n rmdir,\n writeFile as writeFileAsync,\n} from \"node:fs/promises\";\nimport { dirname, join, relative } from \"node:path\";\nimport type { Dirent } from \"node:fs\";\nimport {\n definePrototypeRef,\n parsePrototypeMetadata,\n type PrototypeMetadata,\n type PrototypeRef,\n type ThemeRegistry,\n} from \"@ebay-dt/bonfire-core\";\nimport {\n buildCssModulesDeclaration,\n buildMetadataJson,\n buildTsConfig,\n COPYABLE_IMPLEMENTATION_FILES,\n} from \"./internal/prototype-templates.js\";\nimport {\n captureOwnedDestination,\n type OwnedDestinationResult,\n} from \"./internal/owned-destination.js\";\nimport type { ResolvedPrototypeCatalogPaths } from \"./prototype-paths.js\";\nimport { isFileNotFound } from \"./internal/utils.js\";\n\nconst FILE_OPEN_FLAGS = constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0);\nconst BLOCKED_COMPONENT_NAMES = new Set([\".next\", \"node_modules\"]);\n\ntype SafeWriteFile = (\n path: string,\n content: Uint8Array | string,\n options: { flag: \"wx\" },\n) => Promise<void>;\n\nexport type DuplicatePrototypeOptions = {\n paths: Pick<\n ResolvedPrototypeCatalogPaths,\n \"repositoryRoot\" | \"prototypeRoot\"\n >;\n source: PrototypeRef;\n destination: PrototypeRef;\n title: string;\n description: string | null;\n authorName: string | null;\n themeRegistry?: ThemeRegistry;\n clock?: () => Date;\n writeFile?: SafeWriteFile;\n};\n\nexport type PrototypeDuplicateErrorKind =\n \"source-not-found\" | \"invalid-source\" | \"collision\" | \"filesystem\";\n\nexport class PrototypeDuplicateError extends Error {\n readonly kind: PrototypeDuplicateErrorKind;\n\n constructor(kind: PrototypeDuplicateErrorKind) {\n super(`Prototype duplication failed: ${kind}`);\n this.name = \"PrototypeDuplicateError\";\n this.kind = kind;\n }\n}\n\ntype OwnedPath = {\n path: string;\n device: number;\n inode: number;\n};\n\nfunction sourcePathFor(root: string, ref: PrototypeRef) {\n return join(root, ref.login, ref.slug);\n}\n\nasync function ownedPath(path: string): Promise<OwnedPath> {\n const stats = await lstat(path);\n return { path, device: stats.dev, inode: stats.ino };\n}\n\nasync function assertDirectory(\n path: string,\n kind: \"source-not-found\" | \"invalid-source\" | \"filesystem\",\n) {\n try {\n const stats = await lstat(path);\n if (stats.isSymbolicLink() || !stats.isDirectory()) {\n throw new PrototypeDuplicateError(kind);\n }\n } catch (error) {\n if (error instanceof PrototypeDuplicateError) throw error;\n if (isFileNotFound(error)) throw new PrototypeDuplicateError(kind);\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n}\n\nasync function readNoFollow(\n path: string,\n kind: \"invalid-source\" | \"filesystem\",\n) {\n try {\n const stats = await lstat(path);\n if (stats.isSymbolicLink() || !stats.isFile()) {\n throw new PrototypeDuplicateError(kind);\n }\n const file = await open(path, FILE_OPEN_FLAGS);\n try {\n return await file.readFile();\n } finally {\n await file.close();\n }\n } catch (error) {\n if (error instanceof PrototypeDuplicateError) throw error;\n if (isFileNotFound(error)) return null;\n throw new PrototypeDuplicateError(kind);\n }\n}\n\nasync function readRequiredSourceFile(path: string) {\n const content = await readNoFollow(path, \"invalid-source\");\n if (content === null) {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n return content;\n}\n\nasync function listComponentFiles(\n root: string,\n current: string,\n): Promise<string[]> {\n let entries: Dirent[];\n try {\n entries = await readdir(current, { withFileTypes: true });\n } catch {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n\n const files: string[] = [];\n for (const entry of entries.sort((left, right) =>\n left.name.localeCompare(right.name),\n )) {\n const path = join(current, entry.name);\n let stats;\n try {\n stats = await lstat(path);\n } catch {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n if (stats.isSymbolicLink()) {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n if (\n entry.name === \".gitkeep\" ||\n BLOCKED_COMPONENT_NAMES.has(entry.name) ||\n entry.name.startsWith(\".env\")\n ) {\n continue;\n }\n if (stats.isDirectory()) {\n files.push(...(await listComponentFiles(root, path)));\n continue;\n }\n if (!stats.isFile()) {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n files.push(relative(root, path));\n }\n return files;\n}\n\nasync function inspectSource(\n sourcePath: string,\n themeRegistry?: ThemeRegistry,\n) {\n await assertDirectory(sourcePath, \"source-not-found\");\n\n try {\n await lstat(join(sourcePath, \"page.module.css\"));\n throw new PrototypeDuplicateError(\"invalid-source\");\n } catch (error) {\n if (error instanceof PrototypeDuplicateError) throw error;\n if (!isFileNotFound(error)) {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n }\n\n const metadataBytes = await readRequiredSourceFile(\n join(sourcePath, \"metadata.json\"),\n );\n let metadata: PrototypeMetadata;\n try {\n metadata = parsePrototypeMetadata(\n JSON.parse(metadataBytes.toString(\"utf8\")),\n { themeRegistry },\n );\n } catch {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n\n const implementationFiles = new Map<string, Uint8Array>();\n for (const name of COPYABLE_IMPLEMENTATION_FILES) {\n implementationFiles.set(\n name,\n await readRequiredSourceFile(join(sourcePath, name)),\n );\n }\n\n const componentsPath = join(sourcePath, \"components\");\n let componentFiles: string[] = [];\n try {\n const stats = await lstat(componentsPath);\n if (stats.isSymbolicLink() || !stats.isDirectory()) {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n componentFiles = await listComponentFiles(componentsPath, componentsPath);\n } catch (error) {\n if (error instanceof PrototypeDuplicateError) throw error;\n if (!isFileNotFound(error)) {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n }\n\n return { metadata, implementationFiles, componentFiles };\n}\n\nasync function reserveDestination(\n path: string,\n paths: Pick<\n ResolvedPrototypeCatalogPaths,\n \"repositoryRoot\" | \"prototypeRoot\"\n >,\n) {\n try {\n await mkdir(path);\n } catch (error) {\n if (\n error !== null &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"EEXIST\"\n ) {\n throw new PrototypeDuplicateError(\"collision\");\n }\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n try {\n return await captureOwnedDestination({\n path,\n repositoryRoot: paths.repositoryRoot,\n prototypeRoot: paths.prototypeRoot,\n });\n } catch {\n // The newly created path is retained because ownership was not proven.\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n}\n\nasync function ensureDirectory(path: string) {\n try {\n await mkdir(path, { recursive: true });\n await assertDirectory(path, \"filesystem\");\n } catch (error) {\n if (error instanceof PrototypeDuplicateError) throw error;\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n}\n\nasync function createDirectory(path: string) {\n try {\n await mkdir(path);\n await assertDirectory(path, \"filesystem\");\n return await ownedPath(path);\n } catch (error) {\n if (error instanceof PrototypeDuplicateError) throw error;\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n}\n\nasync function createNestedDirectories(path: string, existingRoot: string) {\n const missing: string[] = [];\n let current = path;\n while (current !== existingRoot) {\n try {\n const stats = await lstat(current);\n if (stats.isSymbolicLink() || !stats.isDirectory()) {\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n break;\n } catch (error) {\n if (error instanceof PrototypeDuplicateError) throw error;\n if (!isFileNotFound(error)) {\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n missing.push(current);\n const parent = dirname(current);\n if (parent === current) throw new PrototypeDuplicateError(\"filesystem\");\n current = parent;\n }\n }\n\n const owned: OwnedPath[] = [];\n for (const directory of missing.reverse()) {\n owned.push(await createDirectory(directory));\n }\n return owned;\n}\n\nasync function writeExclusive(\n path: string,\n content: Uint8Array | string,\n writeFile: SafeWriteFile,\n) {\n try {\n await writeFile(path, content, { flag: \"wx\" });\n return await ownedPath(path);\n } catch {\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n}\n\nasync function removeOwnedPaths(\n files: readonly OwnedPath[],\n directories: readonly OwnedPath[],\n) {\n try {\n for (const owned of [...files].reverse()) {\n const current = await lstat(owned.path).catch(() => null);\n if (\n current !== null &&\n !current.isSymbolicLink() &&\n current.dev === owned.device &&\n current.ino === owned.inode\n ) {\n await rm(owned.path, { force: true });\n }\n }\n for (const owned of [...directories].reverse()) {\n const current = await lstat(owned.path).catch(() => null);\n if (\n current !== null &&\n current.isDirectory() &&\n !current.isSymbolicLink() &&\n current.dev === owned.device &&\n current.ino === owned.inode\n ) {\n await rmdir(owned.path);\n }\n }\n } catch {\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n}\n\nexport async function duplicatePrototype({\n paths,\n source,\n destination: destinationRef,\n title,\n description,\n authorName,\n themeRegistry,\n clock = () => new Date(),\n writeFile = writeFileAsync,\n}: DuplicatePrototypeOptions): Promise<OwnedDestinationResult> {\n const normalizedSource = definePrototypeRef(source);\n const normalizedDestination = definePrototypeRef(destinationRef);\n const sourcePath = sourcePathFor(paths.prototypeRoot, normalizedSource);\n const destination = sourcePathFor(paths.prototypeRoot, normalizedDestination);\n const sourceDetails = await inspectSource(sourcePath, themeRegistry);\n if (sourceDetails.metadata.authorLogin !== normalizedSource.login) {\n throw new PrototypeDuplicateError(\"invalid-source\");\n }\n\n const timestamp = clock().toISOString();\n const metadata = buildMetadataJson(\n title,\n description,\n normalizedDestination.login,\n authorName,\n timestamp,\n sourceDetails.metadata.theme,\n );\n parsePrototypeMetadata(JSON.parse(metadata), { themeRegistry });\n\n await ensureDirectory(paths.prototypeRoot);\n await ensureDirectory(dirname(destination));\n const ownedFiles: OwnedPath[] = [];\n const receipt = await reserveDestination(destination, paths);\n const ownedDirectories: OwnedPath[] = [receipt];\n\n try {\n ownedDirectories.push(\n await createDirectory(join(destination, \"components\")),\n );\n\n for (const name of COPYABLE_IMPLEMENTATION_FILES) {\n ownedFiles.push(\n await writeExclusive(\n join(destination, name),\n sourceDetails.implementationFiles.get(name)!,\n writeFile,\n ),\n );\n }\n\n if (sourceDetails.componentFiles.length === 0) {\n ownedFiles.push(\n await writeExclusive(\n join(destination, \"components/.gitkeep\"),\n \"\",\n writeFile,\n ),\n );\n } else {\n for (const file of sourceDetails.componentFiles) {\n const sourceContent = await readRequiredSourceFile(\n join(sourcePath, \"components\", file),\n );\n const target = join(destination, \"components\", file);\n ownedDirectories.push(\n ...(await createNestedDirectories(\n dirname(target),\n join(destination, \"components\"),\n )),\n );\n ownedFiles.push(await writeExclusive(target, sourceContent, writeFile));\n }\n }\n\n ownedFiles.push(\n await writeExclusive(\n join(destination, \"metadata.json\"),\n metadata,\n writeFile,\n ),\n );\n ownedFiles.push(\n await writeExclusive(\n join(destination, \"tsconfig.json\"),\n buildTsConfig(paths.repositoryRoot, destination),\n writeFile,\n ),\n );\n ownedFiles.push(\n await writeExclusive(\n join(destination, \"css-modules.d.ts\"),\n buildCssModulesDeclaration(),\n writeFile,\n ),\n );\n\n const writtenMetadata = await readNoFollow(\n join(destination, \"metadata.json\"),\n \"filesystem\",\n );\n if (writtenMetadata === null) {\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n parsePrototypeMetadata(JSON.parse(writtenMetadata.toString(\"utf8\")), {\n themeRegistry,\n });\n const expectedFiles = [\n ...COPYABLE_IMPLEMENTATION_FILES,\n ...sourceDetails.componentFiles.map((file) => join(\"components\", file)),\n ...(sourceDetails.componentFiles.length === 0\n ? [\"components/.gitkeep\"]\n : []),\n \"metadata.json\",\n \"tsconfig.json\",\n \"css-modules.d.ts\",\n ];\n return {\n destination,\n receipt,\n expectedFiles: Object.freeze(expectedFiles),\n };\n } catch (error) {\n try {\n await removeOwnedPaths(ownedFiles, ownedDirectories);\n } catch {\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n if (error instanceof PrototypeDuplicateError) throw error;\n throw new PrototypeDuplicateError(\"filesystem\");\n }\n}\n"]}
|
package/dist/executable.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executable.d.ts","sourceRoot":"","sources":["../src/executable.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE7E,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAClD;AAuBD,qBAAa,sBAAuB,YAAW,sBAAsB;;IAMnE,YAAY,OAAO,GAAE,yBAA8B,EAQlD;IAEK,OAAO,CAAC,OAAO,EAAE,MAAM,0BAkC5B;CACF"}
|
|
1
|
+
{"version":3,"file":"executable.d.ts","sourceRoot":"","sources":["../src/executable.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE7E,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAClD;AAuBD,qBAAa,sBAAuB,YAAW,sBAAsB;;IAMnE,YAAY,OAAO,GAAE,yBAA8B,EAQlD;IAEK,OAAO,CAAC,OAAO,EAAE,MAAM,0BAkC5B;CACF","sourcesContent":["import { constants } from \"node:fs\";\nimport { access } from \"node:fs/promises\";\nimport { posix, win32 } from \"node:path\";\n\nconst DEFAULT_WINDOWS_EXTENSIONS = \".COM;.EXE;.BAT;.CMD\";\n\nexport type ExecutableAccess = (path: string, mode: number) => Promise<void>;\n\nexport type ExecutableResolverOptions = {\n path?: string;\n pathExtensions?: string;\n platform?: NodeJS.Platform;\n access?: ExecutableAccess;\n};\n\nexport interface ExecutableResolverLike {\n resolve(command: string): Promise<string | null>;\n}\n\nfunction isWindows(platform: NodeJS.Platform) {\n return platform === \"win32\";\n}\n\nfunction commandCandidates(\n command: string,\n platform: NodeJS.Platform,\n pathExtensions: string,\n) {\n const pathApi = isWindows(platform) ? win32 : posix;\n const hasPath = command.includes(\"/\") || command.includes(\"\\\\\");\n if (hasPath || pathApi.extname(command) !== \"\") return [command];\n\n if (!isWindows(platform)) return [command];\n\n return pathExtensions\n .split(\";\")\n .filter(Boolean)\n .map((extension) => `${command}${extension}`);\n}\n\nexport class PathExecutableResolver implements ExecutableResolverLike {\n readonly #path: string;\n readonly #pathExtensions: string;\n readonly #platform: NodeJS.Platform;\n readonly #access: ExecutableAccess;\n\n constructor(options: ExecutableResolverOptions = {}) {\n this.#platform = options.platform ?? process.platform;\n this.#path = options.path ?? process.env.PATH ?? \"\";\n this.#pathExtensions =\n options.pathExtensions ??\n process.env.PATHEXT ??\n DEFAULT_WINDOWS_EXTENSIONS;\n this.#access = options.access ?? access;\n }\n\n async resolve(command: string) {\n if (command.length === 0) return null;\n\n const pathApi = isWindows(this.#platform) ? win32 : posix;\n const hasPath = command.includes(\"/\") || command.includes(\"\\\\\");\n if (pathApi.isAbsolute(command) || hasPath) {\n try {\n await this.#access(command, constants.X_OK);\n return command;\n } catch {\n return null;\n }\n }\n\n const candidates = commandCandidates(\n command,\n this.#platform,\n this.#pathExtensions,\n );\n const directories = this.#path.split(isWindows(this.#platform) ? \";\" : \":\");\n\n for (const directory of directories) {\n for (const candidate of candidates) {\n const executablePath = pathApi.join(directory || \".\", candidate);\n try {\n await this.#access(executablePath, constants.X_OK);\n return executablePath;\n } catch {\n // Keep searching the remaining PATH entries.\n }\n }\n }\n\n return null;\n }\n}\n"]}
|
package/dist/executable.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executable.js","sourceRoot":"","sources":["../src/executable.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"executable.js","sourceRoot":"","sources":["../src/executable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,0BAA0B,GAAG,qBAAqB,CAAC;AAezD,SAAS,SAAS,CAAC,QAAyB;IAC1C,OAAO,QAAQ,KAAK,OAAO,CAAC;AAC9B,CAAC;AAED,SAAS,iBAAiB,CACxB,OAAe,EACf,QAAyB,EACzB,cAAsB;IAEtB,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IACpD,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAChE,IAAI,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE;QAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3C,OAAO,cAAc;SAClB,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,OAAO,GAAG,SAAS,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,OAAO,sBAAsB;IACxB,KAAK,CAAS;IACd,eAAe,CAAS;IACxB,SAAS,CAAkB;IAC3B,OAAO,CAAmB;IAEnC,YAAY,OAAO,GAA8B,EAAE;QACjD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;QACtD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;QACpD,IAAI,CAAC,eAAe;YAClB,OAAO,CAAC,cAAc;gBACtB,OAAO,CAAC,GAAG,CAAC,OAAO;gBACnB,0BAA0B,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAe;QAC3B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEtC,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAChE,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,OAAO,EAAE,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;gBAC5C,OAAO,OAAO,CAAC;YACjB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAAG,iBAAiB,CAClC,OAAO,EACP,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,eAAe,CACrB,CAAC;QACF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAE5E,KAAK,MAAM,SAAS,IAAI,WAAW,EAAE,CAAC;YACpC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gBACnC,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,IAAI,GAAG,EAAE,SAAS,CAAC,CAAC;gBACjE,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;oBACnD,OAAO,cAAc,CAAC;gBACxB,CAAC;gBAAC,MAAM,CAAC;oBACP,6CAA6C;gBAC/C,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import { constants } from \"node:fs\";\nimport { access } from \"node:fs/promises\";\nimport { posix, win32 } from \"node:path\";\n\nconst DEFAULT_WINDOWS_EXTENSIONS = \".COM;.EXE;.BAT;.CMD\";\n\nexport type ExecutableAccess = (path: string, mode: number) => Promise<void>;\n\nexport type ExecutableResolverOptions = {\n path?: string;\n pathExtensions?: string;\n platform?: NodeJS.Platform;\n access?: ExecutableAccess;\n};\n\nexport interface ExecutableResolverLike {\n resolve(command: string): Promise<string | null>;\n}\n\nfunction isWindows(platform: NodeJS.Platform) {\n return platform === \"win32\";\n}\n\nfunction commandCandidates(\n command: string,\n platform: NodeJS.Platform,\n pathExtensions: string,\n) {\n const pathApi = isWindows(platform) ? win32 : posix;\n const hasPath = command.includes(\"/\") || command.includes(\"\\\\\");\n if (hasPath || pathApi.extname(command) !== \"\") return [command];\n\n if (!isWindows(platform)) return [command];\n\n return pathExtensions\n .split(\";\")\n .filter(Boolean)\n .map((extension) => `${command}${extension}`);\n}\n\nexport class PathExecutableResolver implements ExecutableResolverLike {\n readonly #path: string;\n readonly #pathExtensions: string;\n readonly #platform: NodeJS.Platform;\n readonly #access: ExecutableAccess;\n\n constructor(options: ExecutableResolverOptions = {}) {\n this.#platform = options.platform ?? process.platform;\n this.#path = options.path ?? process.env.PATH ?? \"\";\n this.#pathExtensions =\n options.pathExtensions ??\n process.env.PATHEXT ??\n DEFAULT_WINDOWS_EXTENSIONS;\n this.#access = options.access ?? access;\n }\n\n async resolve(command: string) {\n if (command.length === 0) return null;\n\n const pathApi = isWindows(this.#platform) ? win32 : posix;\n const hasPath = command.includes(\"/\") || command.includes(\"\\\\\");\n if (pathApi.isAbsolute(command) || hasPath) {\n try {\n await this.#access(command, constants.X_OK);\n return command;\n } catch {\n return null;\n }\n }\n\n const candidates = commandCandidates(\n command,\n this.#platform,\n this.#pathExtensions,\n );\n const directories = this.#path.split(isWindows(this.#platform) ? \";\" : \":\");\n\n for (const directory of directories) {\n for (const candidate of candidates) {\n const executablePath = pathApi.join(directory || \".\", candidate);\n try {\n await this.#access(executablePath, constants.X_OK);\n return executablePath;\n } catch {\n // Keep searching the remaining PATH entries.\n }\n }\n }\n\n return null;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-repository.d.ts","sourceRoot":"","sources":["../src/git-repository.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"git-repository.d.ts","sourceRoot":"","sources":["../src/git-repository.ts"],"names":[],"mappings":"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","sourcesContent":["import { isAbsolute } from \"node:path\";\nimport { simpleGit } from \"simple-git\";\nimport {\n asFailure,\n isNonEmptyString,\n isPositiveInteger,\n isRecord,\n} from \"./internal/utils.js\";\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_MAX_CONCURRENT_PROCESSES = 1;\nconst DEFAULT_COMMIT_IDENTITY = {\n name: \"Bonfire\",\n email: \"bonfire@localhost\",\n};\nconst NOTHING_TO_COMMIT_MESSAGES = [\n \"nothing to commit\",\n \"nothing added to commit\",\n];\n\nexport type GitCommitIdentity = {\n name: string;\n email: string;\n};\n\nexport type GitRepositoryOptions = {\n repositoryRoot: string;\n timeoutMs?: number;\n maxConcurrentProcesses?: number;\n commitIdentity?: GitCommitIdentity;\n};\n\nexport type GitStatusFile = {\n path: string;\n index: string;\n workingDirectory: string;\n from?: string;\n};\n\nexport type GitStatusSnapshot = {\n current: string | null;\n files: readonly GitStatusFile[];\n clean: boolean;\n};\n\nexport type GitRemoteSnapshot = {\n name: string;\n fetchUrl: string | null;\n pushUrl: string | null;\n};\n\nexport type GitBranchSnapshot = {\n current: string | null;\n all: readonly string[];\n};\n\nexport type GitCommitSnapshot = {\n branch: string;\n commit: string;\n root: boolean;\n};\n\nexport type GitCommitResult = GitCommitSnapshot | null;\n\nexport type GitPushResult = {\n remoteStatus: \"pushed\" | \"local-only\";\n};\n\nexport type GitRepositoryErrorKind =\n | \"missing-git\"\n | \"timeout\"\n | \"conflict\"\n | \"command-failure\"\n | \"malformed-output\"\n | \"invalid-configuration\"\n | \"unexpected\";\n\nexport class GitRepositoryError extends Error {\n readonly kind: GitRepositoryErrorKind;\n readonly operation: string;\n\n constructor(kind: GitRepositoryErrorKind, operation: string) {\n super(`Git operation failed: ${operation}`);\n this.name = \"GitRepositoryError\";\n this.kind = kind;\n this.operation = operation;\n }\n}\n\nexport interface GitRepository {\n readonly repositoryRoot: string;\n currentBranch(): Promise<string>;\n status(pathspecs?: readonly string[]): Promise<GitStatusSnapshot>;\n remotes(): Promise<readonly GitRemoteSnapshot[]>;\n branches(): Promise<GitBranchSnapshot>;\n fetch(remote: string, branch: string): Promise<void>;\n checkout(args: readonly string[]): Promise<void>;\n checkoutLocalBranch(branch: string): Promise<void>;\n merge(args: readonly string[]): Promise<void>;\n add(pathspecs: readonly string[]): Promise<void>;\n commit(\n message: string,\n pathspecs?: readonly string[],\n ): Promise<GitCommitResult>;\n push(\n remote: string,\n branch: string,\n options?: readonly string[],\n ): Promise<void>;\n restore(pathspecs: readonly string[]): Promise<void>;\n clean(mode: string, pathspecs: readonly string[]): Promise<void>;\n raw(args: readonly string[]): Promise<string>;\n}\n\nfunction classifyError(error: unknown): GitRepositoryErrorKind {\n if (error instanceof GitRepositoryError) return error.kind;\n\n const failure = asFailure(error);\n const message = typeof failure.message === \"string\" ? failure.message : \"\";\n const normalized = message.toLowerCase();\n\n if (failure.code === \"ENOENT\" || normalized.includes(\"enoent\")) {\n return \"missing-git\";\n }\n\n if (\n failure.code === \"ETIMEDOUT\" ||\n failure.killed === true ||\n failure.signal === \"SIGTERM\" ||\n normalized.includes(\"timed out\") ||\n normalized.includes(\"timeout\")\n ) {\n return \"timeout\";\n }\n\n if (\n normalized.includes(\"conflict\") ||\n normalized.includes(\"would be overwritten\") ||\n normalized.includes(\"unmerged paths\")\n ) {\n return \"conflict\";\n }\n\n if (isRecord(error) || error instanceof Error) return \"command-failure\";\n return \"unexpected\";\n}\n\nfunction normalizeError(operation: string, error: unknown) {\n if (error instanceof GitRepositoryError) return error;\n return new GitRepositoryError(classifyError(error), operation);\n}\n\nfunction assertValidPositiveInteger(value: number, option: string) {\n if (!isPositiveInteger(value)) {\n throw new GitRepositoryError(\"invalid-configuration\", option);\n }\n}\n\nfunction assertValidBranchName(value: string, option: string) {\n if (\n !isNonEmptyString(value) ||\n value.startsWith(\"-\") ||\n value.includes(\"\\0\") ||\n /\\s/u.test(value) ||\n value.includes(\"@{\") ||\n value.split(/[\\\\/]/u).some((segment) => segment === \"..\")\n ) {\n throw new GitRepositoryError(\"invalid-configuration\", option);\n }\n}\n\nfunction assertValidPathspec(pathspec: string) {\n if (\n !isNonEmptyString(pathspec) ||\n isAbsolute(pathspec) ||\n /^[A-Za-z]:[\\\\/]/u.test(pathspec) ||\n pathspec.startsWith(\"\\\\\") ||\n pathspec.startsWith(\"-\") ||\n pathspec.startsWith(\":\") ||\n pathspec.includes(\"\\0\") ||\n pathspec.includes(\"*\") ||\n pathspec.includes(\"?\") ||\n pathspec.includes(\"[\") ||\n pathspec.includes(\"]\") ||\n pathspec === \".\" ||\n pathspec.split(/[\\\\/]/u).some((segment) => segment === \"..\")\n ) {\n throw new GitRepositoryError(\"invalid-configuration\", \"pathspec\");\n }\n}\n\nfunction assertValidPathspecs(pathspecs: readonly string[]) {\n if (pathspecs.length === 0) {\n throw new GitRepositoryError(\"invalid-configuration\", \"pathspec\");\n }\n for (const pathspec of pathspecs) assertValidPathspec(pathspec);\n return [...pathspecs];\n}\n\nfunction assertValidArguments(args: readonly string[], operation: string) {\n if (\n args.some(\n (argument) => !isNonEmptyString(argument) || argument.includes(\"\\0\"),\n )\n ) {\n throw new GitRepositoryError(\"invalid-configuration\", operation);\n }\n return [...args];\n}\n\nfunction isNothingToCommit(error: unknown) {\n const failure = asFailure(error);\n const message = typeof failure.message === \"string\" ? failure.message : \"\";\n return NOTHING_TO_COMMIT_MESSAGES.some((needle) =>\n message.toLowerCase().includes(needle),\n );\n}\n\nclass SimpleGitRepository implements GitRepository {\n readonly repositoryRoot: string;\n readonly #git;\n\n constructor(options: Required<GitRepositoryOptions>) {\n this.repositoryRoot = options.repositoryRoot;\n this.#git = simpleGit(options.repositoryRoot, {\n baseDir: options.repositoryRoot,\n maxConcurrentProcesses: options.maxConcurrentProcesses,\n config: [\n `user.name=${options.commitIdentity.name}`,\n `user.email=${options.commitIdentity.email}`,\n ],\n timeout: { block: options.timeoutMs },\n });\n }\n\n async #execute<Value>(operation: string, action: () => Promise<Value>) {\n try {\n return await action();\n } catch (error) {\n throw normalizeError(operation, error);\n }\n }\n\n async currentBranch() {\n const result = await this.#execute(\"current-branch\", () =>\n this.#git.revparse([\"--abbrev-ref\", \"HEAD\"]),\n );\n if (!isNonEmptyString(result) || result.trim().length === 0) {\n throw new GitRepositoryError(\"malformed-output\", \"current-branch\");\n }\n return result.trim();\n }\n\n async status(pathspecs?: readonly string[]) {\n const validatedPathspecs =\n pathspecs === undefined ? undefined : assertValidPathspecs(pathspecs);\n const result = await this.#execute(\"status\", () =>\n validatedPathspecs === undefined\n ? this.#git.status()\n : this.#git.status([\"--\", ...validatedPathspecs]),\n );\n\n if (\n !isRecord(result) ||\n !Array.isArray(result.files) ||\n (typeof result.current !== \"string\" && result.current !== null) ||\n typeof result.isClean !== \"function\"\n ) {\n throw new GitRepositoryError(\"malformed-output\", \"status\");\n }\n\n const files: GitStatusFile[] = [];\n for (const file of result.files) {\n if (!isRecord(file)) {\n throw new GitRepositoryError(\"malformed-output\", \"status\");\n }\n if (\n typeof file.path !== \"string\" ||\n typeof file.index !== \"string\" ||\n typeof file.working_dir !== \"string\"\n ) {\n throw new GitRepositoryError(\"malformed-output\", \"status\");\n }\n\n files.push({\n path: file.path,\n index: file.index,\n workingDirectory: file.working_dir,\n ...(typeof file.from === \"string\" ? { from: file.from } : {}),\n });\n }\n\n let clean: boolean;\n try {\n clean = result.isClean();\n } catch {\n throw new GitRepositoryError(\"malformed-output\", \"status\");\n }\n if (typeof clean !== \"boolean\") {\n throw new GitRepositoryError(\"malformed-output\", \"status\");\n }\n\n return {\n current: result.current,\n files,\n clean,\n } satisfies GitStatusSnapshot;\n }\n\n async remotes() {\n const result = await this.#execute(\"remotes\", () =>\n this.#git.getRemotes(true),\n );\n if (!Array.isArray(result)) {\n throw new GitRepositoryError(\"malformed-output\", \"remotes\");\n }\n\n const remotes: GitRemoteSnapshot[] = [];\n for (const remote of result) {\n if (!isRecord(remote) || typeof remote.name !== \"string\") {\n throw new GitRepositoryError(\"malformed-output\", \"remotes\");\n }\n const refs = remote.refs;\n if (!isRecord(refs)) {\n throw new GitRepositoryError(\"malformed-output\", \"remotes\");\n }\n if (typeof refs.fetch !== \"string\" || typeof refs.push !== \"string\") {\n throw new GitRepositoryError(\"malformed-output\", \"remotes\");\n }\n\n remotes.push({\n name: remote.name,\n fetchUrl: refs.fetch,\n pushUrl: refs.push,\n });\n }\n return remotes;\n }\n\n async branches() {\n const result = await this.#execute(\"branches\", () =>\n this.#git.branch([\"-a\"]),\n );\n if (\n !isRecord(result) ||\n !Array.isArray(result.all) ||\n (typeof result.current !== \"string\" && result.current !== null) ||\n !result.all.every((branch) => typeof branch === \"string\")\n ) {\n throw new GitRepositoryError(\"malformed-output\", \"branches\");\n }\n\n return {\n current: result.current,\n all: [...result.all],\n } satisfies GitBranchSnapshot;\n }\n\n async fetch(remote: string, branch: string) {\n assertValidBranchName(remote, \"remote\");\n assertValidBranchName(branch, \"branch\");\n await this.#execute(\"fetch\", () => this.#git.fetch(remote, branch));\n }\n\n async checkout(args: readonly string[]) {\n const validatedArgs = assertValidArguments(args, \"checkout\");\n await this.#execute(\"checkout\", () => this.#git.checkout(validatedArgs));\n }\n\n async checkoutLocalBranch(branch: string) {\n assertValidBranchName(branch, \"branch\");\n await this.#execute(\"checkout-local-branch\", () =>\n this.#git.checkoutLocalBranch(branch),\n );\n }\n\n async merge(args: readonly string[]) {\n const validatedArgs = assertValidArguments(args, \"merge\");\n await this.#execute(\"merge\", () => this.#git.merge(validatedArgs));\n }\n\n async add(pathspecs: readonly string[]) {\n const validatedPathspecs = assertValidPathspecs(pathspecs);\n await this.#execute(\"add\", () => this.#git.add(validatedPathspecs));\n }\n\n async commit(message: string, pathspecs?: readonly string[]) {\n if (!isNonEmptyString(message)) {\n throw new GitRepositoryError(\"invalid-configuration\", \"commit-message\");\n }\n const validatedPathspecs =\n pathspecs === undefined ? undefined : assertValidPathspecs(pathspecs);\n\n let result: unknown;\n try {\n result =\n validatedPathspecs === undefined\n ? await this.#git.commit(message)\n : await this.#git.commit(message, [...validatedPathspecs]);\n } catch (error) {\n if (isNothingToCommit(error)) return null;\n throw normalizeError(\"commit\", error);\n }\n if (\n !isRecord(result) ||\n typeof result.branch !== \"string\" ||\n typeof result.commit !== \"string\" ||\n typeof result.root !== \"boolean\"\n ) {\n throw new GitRepositoryError(\"malformed-output\", \"commit\");\n }\n\n return {\n branch: result.branch,\n commit: result.commit,\n root: result.root,\n } satisfies GitCommitSnapshot;\n }\n\n async push(remote: string, branch: string, options: readonly string[] = []) {\n assertValidBranchName(remote, \"remote\");\n assertValidBranchName(branch, \"branch\");\n const validatedOptions = assertValidArguments(options, \"push\");\n await this.#execute(\"push\", () =>\n this.#git.push(remote, branch, validatedOptions),\n );\n }\n\n async restore(pathspecs: readonly string[]) {\n const validatedPathspecs = assertValidPathspecs(pathspecs);\n await this.#execute(\"restore\", () =>\n this.#git.checkout([\"--\", ...validatedPathspecs]),\n );\n }\n\n async clean(mode: string, pathspecs: readonly string[]) {\n if (!/^[a-z]+$/u.test(mode)) {\n throw new GitRepositoryError(\"invalid-configuration\", \"clean-mode\");\n }\n const validatedPathspecs = assertValidPathspecs(pathspecs);\n await this.#execute(\"clean\", () =>\n this.#git.clean(mode, validatedPathspecs),\n );\n }\n\n async raw(args: readonly string[]) {\n const validatedArgs = assertValidArguments(args, \"raw\");\n const result = await this.#execute(\"raw\", () =>\n this.#git.raw(validatedArgs),\n );\n if (typeof result !== \"string\") {\n throw new GitRepositoryError(\"malformed-output\", \"raw\");\n }\n return result;\n }\n}\n\nexport type PrepareIdentityBranchOptions = {\n identityBranch: string;\n primaryBranch: string;\n remote: string;\n};\n\nexport async function prepareIdentityBranch(\n repository: GitRepository,\n options: PrepareIdentityBranchOptions,\n): Promise<void> {\n assertValidBranchName(options.identityBranch, \"identity-branch\");\n assertValidBranchName(options.primaryBranch, \"primary-branch\");\n assertValidBranchName(options.remote, \"remote\");\n\n const currentBranch = await repository.currentBranch();\n if (currentBranch === options.identityBranch) return;\n\n const status = await repository.status();\n if (!status.clean) {\n throw new GitRepositoryError(\"conflict\", \"prepare-identity-branch\");\n }\n\n const remotes = await repository.remotes();\n const configuredRemote = remotes.some(\n (remote) => remote.name === options.remote,\n );\n if (configuredRemote) {\n await repository.fetch(options.remote, options.primaryBranch);\n }\n\n const branches = await repository.branches();\n const hasLocalPrimary = branches.all.includes(options.primaryBranch);\n const remotePrimary = `remotes/${options.remote}/${options.primaryBranch}`;\n const hasRemotePrimary =\n configuredRemote && branches.all.includes(remotePrimary);\n if (!hasLocalPrimary && !hasRemotePrimary) {\n throw new GitRepositoryError(\"command-failure\", \"primary-branch\");\n }\n\n if (hasLocalPrimary) {\n await repository.checkout([options.primaryBranch]);\n } else {\n await repository.checkout([\n \"-b\",\n options.primaryBranch,\n \"--track\",\n `${options.remote}/${options.primaryBranch}`,\n ]);\n }\n if (configuredRemote) {\n await repository.merge([\n `${options.remote}/${options.primaryBranch}`,\n \"--ff-only\",\n ]);\n }\n\n if (branches.all.includes(options.identityBranch)) {\n await repository.checkout([options.identityBranch]);\n return;\n }\n\n const remoteBranch = `remotes/${options.remote}/${options.identityBranch}`;\n if (branches.all.includes(remoteBranch)) {\n await repository.checkout([\n \"-b\",\n options.identityBranch,\n \"--track\",\n `${options.remote}/${options.identityBranch}`,\n ]);\n return;\n }\n\n await repository.checkoutLocalBranch(options.identityBranch);\n}\n\nexport async function commitPath(\n repository: GitRepository,\n pathspec: string,\n message: string,\n): Promise<GitCommitResult> {\n const validatedPathspecs = assertValidPathspecs([pathspec]);\n await repository.add(validatedPathspecs);\n return repository.commit(message, validatedPathspecs);\n}\n\nexport async function discardPath(\n repository: GitRepository,\n pathspec: string,\n): Promise<void> {\n const validatedPathspec = assertValidPathspecs([pathspec])[0]!;\n await repository.raw([\"reset\", \"HEAD\", \"--\", validatedPathspec]);\n await repository.restore([validatedPathspec]);\n await repository.clean(\"fd\", [validatedPathspec]);\n}\n\nexport async function pushBranch(\n repository: GitRepository,\n remote: string,\n branch: string,\n): Promise<GitPushResult> {\n assertValidBranchName(remote, \"remote\");\n assertValidBranchName(branch, \"branch\");\n\n const hasRemote = (await repository.remotes()).some(\n (configuredRemote) => configuredRemote.name === remote,\n );\n if (!hasRemote) return { remoteStatus: \"local-only\" };\n\n await repository.push(remote, branch, [\"--set-upstream\"]);\n return { remoteStatus: \"pushed\" };\n}\n\nexport function createGitRepository(\n options: GitRepositoryOptions,\n): GitRepository {\n if (!isAbsolute(options.repositoryRoot)) {\n throw new GitRepositoryError(\"invalid-configuration\", \"repository-root\");\n }\n\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const maxConcurrentProcesses =\n options.maxConcurrentProcesses ?? DEFAULT_MAX_CONCURRENT_PROCESSES;\n const commitIdentity = options.commitIdentity ?? DEFAULT_COMMIT_IDENTITY;\n\n assertValidPositiveInteger(timeoutMs, \"timeout\");\n assertValidPositiveInteger(\n maxConcurrentProcesses,\n \"max-concurrent-processes\",\n );\n\n return new SimpleGitRepository({\n repositoryRoot: options.repositoryRoot,\n timeoutMs,\n maxConcurrentProcesses,\n commitIdentity,\n });\n}\n"]}
|