Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { createHash } from "node:crypto"
import path from "node:path"

import { readRepositoryName } from "../read-repository-name/index.mjs"
import { runCommand } from "../run-command/index.mjs"

export async function createCanvasContext({
prototypeUrl,
name,
Expand All @@ -25,7 +23,6 @@ export async function createCanvasContext({
"This Copilot session has no working directory, so repository status cannot be read.",
)
}

const normalizedUrl = normalizePrototypeUrl(prototypeUrl)
const stateUrl = new URL(normalizedUrl)
stateUrl.hash = ""
Expand All @@ -50,7 +47,6 @@ export async function createCanvasContext({
.digest("hex")
.slice(0, 24)
const stateDirectory = path.join(sessionWorkspacePath, "replica-prototype")

return {
name: normalizeName(name, normalizedUrl),
normalizedUrl,
Expand All @@ -64,7 +60,6 @@ export async function createCanvasContext({
urlHost: new URL(normalizedUrl).host,
}
}

// Keep stored publish state tied to the branch currently shown in the canvas.
export async function currentCanvasContext(context) {
const [repository, branch] = await Promise.all([
Expand All @@ -81,7 +76,6 @@ export async function currentCanvasContext(context) {
const currentBranch = branch.ok ? branch.stdout.replace(/\r?\n$/, "") || null : null
if (currentRepository === context.target.repository && currentBranch === context.target.branch)
return context

return createCanvasContext({
prototypeUrl: context.normalizedUrl,
name: context.name,
Expand All @@ -93,7 +87,6 @@ export async function currentCanvasContext(context) {
repositoryPath: context.repositoryPath,
})
}

function normalizePrototypeUrl(value) {
let url
try {
Expand All @@ -104,29 +97,24 @@ function normalizePrototypeUrl(value) {
if (url.protocol !== "http:" && url.protocol !== "https:") {
throw new Error("prototypeUrl must use HTTP or HTTPS.")
}

url.hostname = url.hostname.toLowerCase()
if (
(url.protocol === "http:" && url.port === "80") ||
(url.protocol === "https:" && url.port === "443")
) {
url.port = ""
}

return url.toString()
}

function normalizeName(name, normalizedUrl) {
if (name === undefined) {
return new URL(normalizedUrl).hostname
}
if (typeof name !== "string" || name.trim() === "") {
throw new Error("name must contain visible text.")
}

return name.trim()
}

async function resolvePublishTarget({
repository,
branch,
Expand All @@ -147,15 +135,13 @@ async function resolvePublishTarget({
if (branch != null && branchResult.ok && hintedBranch !== checkoutBranch) {
throw new Error("branch does not match the current checkout.")
}

return {
repository: resolvedRepository,
branch: hintedBranch ?? checkoutBranch,
commitSha: normalizeCommitSha(commitSha),
publishedUrl: normalizeOptionalUrl(publishedUrl, "publishedUrl"),
}
}

export async function resolveRepository(hint, repositoryPath) {
const repository = normalizeRepository(hint)
const checkout = await readRepositoryName(repositoryPath)
Expand All @@ -174,7 +160,6 @@ export async function resolveRepository(hint, repositoryPath) {
}
return repository ?? checkoutRepository
}

function isLocalRepositoryCheckout(repository, repositoryPath) {
const localRoot = path.dirname(repositoryPath)
return (
Expand All @@ -183,7 +168,6 @@ function isLocalRepositoryCheckout(repository, repositoryPath) {
path.basename(path.dirname(localRoot)) === ".local"
)
}

function normalizeRepository(value) {
if (value == null) {
return null
Expand All @@ -206,10 +190,8 @@ function normalizeRepository(value) {
) {
throw new Error("repository must use GitHub owner/name format.")
}

return value.toLowerCase()
}

export async function normalizeBranch(value, repositoryPath) {
if (value === "HEAD") return null
if (value == null) {
Expand All @@ -235,23 +217,19 @@ export async function normalizeBranch(value, repositoryPath) {
}
return value
}

function normalizeCommitSha(value) {
if (value == null) {
return null
}
if (typeof value !== "string" || !/^[0-9a-f]{40}$/.test(value)) {
throw new Error("commitSha must be a full lowercase Git commit SHA.")
}

return value
}

function normalizeOptionalUrl(value, name) {
if (value == null) {
return null
}

let url
try {
url = new URL(value)
Expand All @@ -261,6 +239,5 @@ function normalizeOptionalUrl(value, name) {
if (url.protocol !== "http:" && url.protocol !== "https:") {
throw new Error(`${name} must use HTTP or HTTPS.`)
}

return url.toString()
}
Loading
Loading