@ponharu/pkgflare 1.1.1 → 1.2.0
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 +2 -1
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/worker.js +8 -4
- package/dist/worker.js.map +1 -1
- package/docs/architecture.md +1 -1
- package/docs/operations.md +10 -6
- package/docs/specification.md +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -162,6 +162,7 @@ auth: {
|
|
|
162
162
|
repositoryOwnerId: "987654321",
|
|
163
163
|
ref: "refs/heads/main",
|
|
164
164
|
workflowRef: "acme/example/.github/workflows/publish.yml@refs/heads/main",
|
|
165
|
+
jobWorkflowRef: "acme/example/.github/workflows/publish.yml@*",
|
|
165
166
|
permissions: ["publish"],
|
|
166
167
|
packages: ["@acme/example"],
|
|
167
168
|
}],
|
|
@@ -184,7 +185,7 @@ steps:
|
|
|
184
185
|
run: NPM_TOKEN="$(npx pkgflare auth github --audience 'pkgflare://packages.example.com')" npm publish
|
|
185
186
|
```
|
|
186
187
|
|
|
187
|
-
The package repository's `.npmrc` still points its scope to pkgflare and references `${NPM_TOKEN}`. Use the same command with `npm ci` or another supported client for OIDC-authenticated reads. See [GitHub Actions OIDC](./docs/operations.md#github-actions-oidc) for reusable workflows,
|
|
188
|
+
The package repository's `.npmrc` still points its scope to pkgflare and references `${NPM_TOKEN}`. Use the same command with `npm ci` or another supported client for OIDC-authenticated reads. The `@*` rule fixes the exact job workflow identity while allowing its valid Git ref or full commit SHA to change. See [GitHub Actions OIDC](./docs/operations.md#github-actions-oidc) for reusable workflows, stricter ref rules, and the security model.
|
|
188
189
|
|
|
189
190
|
Versions are immutable. To promote or roll back an existing version, use the publish token with `npm dist-tag`:
|
|
190
191
|
|
package/dist/cli.js
CHANGED
|
@@ -27,7 +27,7 @@ var githubIdPattern = /^[1-9][0-9]{0,19}$/;
|
|
|
27
27
|
var audiencePattern = /^[\x21-\x7e]{1,256}$/;
|
|
28
28
|
var refPattern = /^refs\/(?:heads|tags)\/[A-Za-z0-9._/-]+\*?$/;
|
|
29
29
|
var workflowRefPattern = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/\.github\/workflows\/[A-Za-z0-9_.-]+\.ya?ml@refs\/(?:heads|tags)\/[A-Za-z0-9._/-]+\*?$/;
|
|
30
|
-
var jobWorkflowRefPattern = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/\.github\/workflows\/[A-Za-z0-9_.-]+\.ya?ml@(?:refs\/(?:heads|tags)\/[A-Za-z0-9._/-]+\*?|[0-9a-f]{40})$/;
|
|
30
|
+
var jobWorkflowRefPattern = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/\.github\/workflows\/[A-Za-z0-9_.-]+\.ya?ml@(?:refs\/(?:heads|tags)\/[A-Za-z0-9._/-]+\*?|[0-9a-f]{40}|\*)$/;
|
|
31
31
|
var packageSegmentPattern = /^(?!\.)(?:[a-z0-9._-]+)$/;
|
|
32
32
|
var maximumGithubSubjects = 128;
|
|
33
33
|
var maximumPackagesPerSubject = 128;
|
|
@@ -76,7 +76,7 @@ function normalizeGithubOidc(value, configuredScopes) {
|
|
|
76
76
|
}
|
|
77
77
|
if (jobWorkflowRef !== void 0 && (typeof jobWorkflowRef !== "string" || !isSafePattern(jobWorkflowRef, jobWorkflowRefPattern))) {
|
|
78
78
|
throw new Error(
|
|
79
|
-
`${label} jobWorkflowRef must identify
|
|
79
|
+
`${label} jobWorkflowRef must identify one workflow at any valid ref (@*), a full commit SHA, or an exact/trailing-wildcard branch or tag ref`
|
|
80
80
|
);
|
|
81
81
|
}
|
|
82
82
|
const permissions = normalizePermissions(subjectValue.permissions, label);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/cli/deploy.ts","../src/cli/config-loader.ts","../src/config.ts","../src/cli/runner.ts","../src/cli/github-oidc.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { open } from \"node:fs/promises\";\nimport { relative, resolve } from \"node:path\";\nimport { deploy } from \"./cli/deploy.js\";\nimport { requestGithubOidcToken } from \"./cli/github-oidc.js\";\n\nfunction valueAfter(arguments_: readonly string[], flag: string): string | undefined {\n const index = arguments_.indexOf(flag);\n if (index === -1) return undefined;\n const value = arguments_[index + 1];\n if (value === undefined || value.startsWith(\"--\")) throw new Error(`${flag} requires a value`);\n return value;\n}\n\nfunction help(): void {\n process.stdout.write(\n `pkgflare\\n\\nUsage:\\n pkgflare deploy [--config <path>] [--secrets-file <path>] [--adopt-existing]\\n pkgflare auth github --audience <audience>\\n pkgflare init\\n pkgflare token generate\\n`,\n );\n}\n\nasync function init(cwd: string): Promise<void> {\n const path = resolve(cwd, \"pkgflare.config.ts\");\n const file = await open(path, \"wx\").catch((error: unknown) => {\n if ((error as NodeJS.ErrnoException).code === \"EEXIST\")\n throw new Error(\"pkgflare.config.ts already exists\");\n throw error;\n });\n await file.writeFile(\n `import { defineConfig } from \"@ponharu/pkgflare\";\\n\\nexport default defineConfig({\\n name: \"acme-registry\",\\n scopes: [\"@acme\"],\\n auth: {\\n provider: \"secrets\",\\n tokens: [\\n { binding: \"PKGFLARE_READ_TOKEN\", permissions: [\"read\"] },\\n { binding: \"PKGFLARE_PUBLISH_TOKEN\", permissions: [\"publish\"] },\\n ],\\n },\\n});\\n`,\n );\n await file.close();\n process.stdout.write(\"Created pkgflare.config.ts\\n\");\n}\n\nasync function main(arguments_: string[]): Promise<void> {\n const [command, subcommand] = arguments_;\n if (command === undefined || command === \"--help\" || command === \"-h\") {\n help();\n return;\n }\n if (command === \"deploy\") {\n const configFile = valueAfter(arguments_, \"--config\");\n const secretsFile = valueAfter(arguments_, \"--secrets-file\");\n const adoptExisting = arguments_.includes(\"--adopt-existing\");\n const result = await deploy({\n cwd: process.cwd(),\n ...(configFile === undefined ? {} : { configFile }),\n ...(secretsFile === undefined ? {} : { secretsFile }),\n adoptExisting,\n });\n const statePath = relative(process.cwd(), result.stateFile);\n process.stdout.write(`\\nDeployment state: ${statePath}\\n`);\n if (result.registryUrl !== null) {\n process.stdout.write(`Registry: ${result.registryUrl}\\n`);\n }\n process.stdout.write(\"\\nRegister each token secret if it was not supplied during deploy:\\n\");\n for (const binding of result.secretBindings) {\n process.stdout.write(` npx wrangler secret put ${binding} --config ${statePath}\\n`);\n }\n if (result.registryUrl !== null) {\n const host = new URL(result.registryUrl).host;\n process.stdout.write(\"\\n.npmrc:\\n\");\n for (const scope of result.scopes) {\n process.stdout.write(` ${scope}:registry=${result.registryUrl}\\n`);\n }\n process.stdout.write(` //${host}/:_authToken=\\${NPM_TOKEN}\\n`);\n }\n return;\n }\n if (command === \"init\") {\n await init(process.cwd());\n return;\n }\n if (command === \"auth\" && subcommand === \"github\") {\n const token = await requestGithubOidcToken(valueAfter(arguments_, \"--audience\"));\n process.stdout.write(`${token}\\n`);\n return;\n }\n if (command === \"token\" && subcommand === \"generate\") {\n let binary = \"\";\n for (const byte of randomBytes(32)) binary += String.fromCharCode(byte);\n const token = btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n process.stdout.write(`${token}\\n`);\n return;\n }\n throw new Error(`unknown command: ${arguments_.join(\" \")}`);\n}\n\nmain(process.argv.slice(2)).catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.stderr.write(`pkgflare: ${message}\\n`);\n process.exitCode = 1;\n});\n","import { copyFile, mkdir, readFile, readdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { NormalizedConfig } from \"../config.js\";\nimport { loadConfig } from \"./config-loader.js\";\nimport { createWranglerRunner, type WranglerRunner } from \"./runner.js\";\n\nconst stateDirectoryName = \".pkgflare\";\nconst stateFileName = \"wrangler.json\";\nconst ownershipFileName = \"ownership.json\";\nconst d1Binding = \"PKGFLARE_DB\";\nconst r2Binding = \"PKGFLARE_BUCKET\";\n\ninterface D1Binding {\n binding: string;\n database_name: string;\n database_id: string;\n migrations_dir?: string;\n}\n\ninterface R2Binding {\n binding: string;\n bucket_name: string;\n}\n\ninterface WranglerState {\n $schema: string;\n account_id?: string;\n name: string;\n main: string;\n compatibility_date: string;\n workers_dev: boolean;\n routes?: Array<{ pattern: string; custom_domain: true }>;\n vars: { PKGFLARE_CONFIG: string };\n d1_databases: D1Binding[];\n r2_buckets: R2Binding[];\n}\n\ninterface D1ListEntry {\n name?: unknown;\n uuid?: unknown;\n}\n\ninterface WhoamiResult {\n loggedIn?: unknown;\n accounts?: unknown;\n}\n\ninterface AccountEntry {\n id: string;\n name?: string;\n}\n\ninterface OwnershipState {\n account_id: string;\n worker_name: string;\n}\n\nexport interface DeployOptions {\n cwd: string;\n configFile?: string;\n secretsFile?: string;\n adoptExisting?: boolean;\n runner?: WranglerRunner;\n assetsDirectory?: string;\n}\n\nexport interface DeployResult {\n registryUrl: string | null;\n stateFile: string;\n secretBindings: string[];\n scopes: string[];\n}\n\nfunction packageRoot(): string {\n return dirname(fileURLToPath(import.meta.url));\n}\n\nfunction stateFor(\n config: NormalizedConfig,\n accountId: string,\n previous?: WranglerState,\n): WranglerState {\n if (previous?.account_id !== undefined && previous.account_id !== accountId) {\n throw new Error(\"authenticated Cloudflare account does not match the deployment state\");\n }\n const state: WranglerState = {\n $schema:\n \"https://raw.githubusercontent.com/cloudflare/workers-sdk/main/packages/wrangler/config-schema.json\",\n account_id: accountId,\n name: config.name,\n main: \"runtime/worker.js\",\n compatibility_date: \"2026-08-01\",\n workers_dev: config.hostname === undefined,\n vars: { PKGFLARE_CONFIG: JSON.stringify(config) },\n d1_databases: previous?.d1_databases ?? [],\n r2_buckets: previous?.r2_buckets ?? [],\n };\n if (config.hostname !== undefined) {\n state.routes = [{ pattern: config.hostname, custom_domain: true }];\n }\n return state;\n}\n\nasync function readState(\n path: string,\n config: NormalizedConfig,\n): Promise<WranglerState | undefined> {\n let contents: string;\n try {\n contents = await readFile(path, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n throw error;\n }\n const state = JSON.parse(contents) as WranglerState;\n if (state.name !== config.name) {\n throw new Error(\n `existing deployment state belongs to ${state.name}; remove ${stateDirectoryName} only after verifying the remote resources`,\n );\n }\n return state;\n}\n\nasync function writeState(path: string, state: WranglerState): Promise<void> {\n await writeFile(path, `${JSON.stringify(state, null, 2)}\\n`, \"utf8\");\n}\n\nasync function readWorkerOwnership(\n path: string,\n workerName: string,\n accountId: string,\n): Promise<boolean> {\n let contents: string;\n try {\n contents = await readFile(path, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw error;\n }\n const ownership = JSON.parse(contents) as Partial<OwnershipState>;\n if (ownership.worker_name !== workerName || ownership.account_id !== accountId) {\n throw new Error(\"deployment ownership state does not match the configured Worker and account\");\n }\n return true;\n}\n\nasync function writeWorkerOwnership(\n path: string,\n workerName: string,\n accountId: string,\n): Promise<void> {\n const ownership: OwnershipState = { account_id: accountId, worker_name: workerName };\n await writeFile(path, `${JSON.stringify(ownership, null, 2)}\\n`, \"utf8\");\n}\n\nasync function copyRuntimeFiles(stateDirectory: string, root: string): Promise<void> {\n const runtimeDirectory = join(stateDirectory, \"runtime\");\n const migrationsDirectory = join(stateDirectory, \"migrations\");\n await Promise.all([\n mkdir(runtimeDirectory, { recursive: true }),\n mkdir(migrationsDirectory, { recursive: true }),\n ]);\n const sourceMigrations = resolve(root, \"..\", \"migrations\");\n const migrationFiles = (await readdir(sourceMigrations, { withFileTypes: true }))\n .filter((entry) => entry.isFile() && entry.name.endsWith(\".sql\"))\n .map((entry) => entry.name);\n // oxlint-disable-next-line unicorn/no-array-sort -- this array has just been created locally\n migrationFiles.sort();\n if (migrationFiles.length === 0) throw new Error(\"pkgflare package contains no D1 migrations\");\n await Promise.all([\n copyFile(join(root, \"worker.js\"), join(runtimeDirectory, \"worker.js\")),\n copyFile(join(root, \"worker.js.map\"), join(runtimeDirectory, \"worker.js.map\")),\n ...migrationFiles.map((file) =>\n copyFile(join(sourceMigrations, file), join(migrationsDirectory, file)),\n ),\n ]);\n await writeFile(join(stateDirectory, \".gitignore\"), \"runtime/\\nmigrations/\\n\", {\n flag: \"wx\",\n }).catch((error: unknown) => {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n });\n}\n\nfunction configArguments(stateFile: string, cwd: string): string[] {\n return [\"--config\", relative(cwd, stateFile)];\n}\n\nasync function recoverD1(\n runner: WranglerRunner,\n databaseName: string,\n configArgs: readonly string[],\n): Promise<D1Binding | null> {\n const result = await runner([\"d1\", \"list\", \"--json\", ...configArgs], { silent: true });\n const entries = JSON.parse(result.stdout) as D1ListEntry[];\n const matches = entries.filter(\n (entry) => entry.name === databaseName && typeof entry.uuid === \"string\",\n );\n if (matches.length > 1) throw new Error(`multiple D1 databases are named ${databaseName}`);\n const match = matches[0];\n return match === undefined\n ? null\n : {\n binding: d1Binding,\n database_name: databaseName,\n database_id: match.uuid as string,\n migrations_dir: \"migrations\",\n };\n}\n\nasync function recoverR2(\n runner: WranglerRunner,\n bucketName: string,\n configArgs: readonly string[],\n): Promise<R2Binding | null> {\n const result = await runner([\"r2\", \"bucket\", \"info\", bucketName, \"--json\", ...configArgs], {\n silent: true,\n allowFailure: true,\n });\n if (result.exitCode === 0) return { binding: r2Binding, bucket_name: bucketName };\n if (/not found|does not exist|10006/i.test(result.stderr)) return null;\n throw new Error(`unable to inspect the ${bucketName} R2 bucket with the current credentials`);\n}\n\nfunction accountsFromWhoami(value: unknown): AccountEntry[] {\n if (typeof value !== \"object\" || value === null)\n throw new Error(\"Wrangler returned invalid account information\");\n const accounts = (value as WhoamiResult).accounts;\n if (!Array.isArray(accounts)) throw new Error(\"Wrangler returned invalid account information\");\n return accounts.flatMap((account) => {\n if (\n typeof account !== \"object\" ||\n account === null ||\n !(\"id\" in account) ||\n typeof account.id !== \"string\"\n ) {\n return [];\n }\n return [\n {\n id: account.id,\n ...(typeof (account as { name?: unknown }).name === \"string\"\n ? { name: (account as { name: string }).name }\n : {}),\n },\n ];\n });\n}\n\nasync function resolveAccountId(\n runner: WranglerRunner,\n configuredAccountId: string | undefined,\n): Promise<string> {\n if (configuredAccountId !== undefined) return configuredAccountId;\n const result = await runner([\"whoami\", \"--json\"], { silent: true });\n const accounts = accountsFromWhoami(JSON.parse(result.stdout) as unknown);\n if (accounts.length !== 1) {\n throw new Error(\"accountId is required when Wrangler credentials can access multiple accounts\");\n }\n const account = accounts[0];\n if (account === undefined)\n throw new Error(\"Wrangler credentials do not provide a Cloudflare account\");\n return account.id;\n}\n\nasync function workerExists(\n runner: WranglerRunner,\n workerName: string,\n configArgs: readonly string[],\n): Promise<boolean> {\n const result = await runner([\"versions\", \"list\", \"--name\", workerName, \"--json\", ...configArgs], {\n silent: true,\n allowFailure: true,\n });\n if (result.exitCode === 0) return true;\n if (/not found|does not exist|10007/i.test(result.stderr)) return false;\n throw new Error(`unable to inspect the ${workerName} Worker with the current credentials`);\n}\n\nasync function verifyWorkerOwnership(\n workerName: string,\n configArgs: readonly string[],\n runner: WranglerRunner,\n adoptExisting: boolean,\n): Promise<boolean> {\n const exists = await workerExists(runner, workerName, configArgs);\n if (exists && !adoptExisting) {\n throw new Error(\n `the ${workerName} Worker already exists; verify it, then rerun with --adopt-existing`,\n );\n }\n return exists;\n}\n\nasync function ensureResources(\n state: WranglerState,\n stateFile: string,\n cwd: string,\n runner: WranglerRunner,\n adoptExisting: boolean,\n): Promise<WranglerState> {\n const d1Name = `${state.name}-metadata`;\n const r2Name = `${state.name}-packages`;\n const configArgs = configArguments(stateFile, cwd);\n const configuredD1 = state.d1_databases.filter((database) => database.binding === d1Binding);\n const configuredR2 = state.r2_buckets.filter((bucket) => bucket.binding === r2Binding);\n const selectedD1 = configuredD1[0];\n const selectedR2 = configuredR2[0];\n if (\n configuredD1.length > 1 ||\n (selectedD1 !== undefined && selectedD1.database_name !== d1Name)\n ) {\n throw new Error(`${d1Binding} must reference the ${d1Name} D1 database`);\n }\n if (configuredR2.length > 1 || (selectedR2 !== undefined && selectedR2.bucket_name !== r2Name)) {\n throw new Error(`${r2Binding} must reference the ${r2Name} R2 bucket`);\n }\n\n if (configuredD1.length === 0) {\n const recovered = await recoverD1(runner, d1Name, configArgs);\n if (recovered !== null) {\n if (!adoptExisting) {\n throw new Error(\n `the ${d1Name} D1 database already exists; verify it, then rerun with --adopt-existing`,\n );\n }\n state.d1_databases.push(recovered);\n await writeState(stateFile, state);\n } else {\n await runner([\n \"d1\",\n \"create\",\n d1Name,\n \"--binding\",\n d1Binding,\n \"--update-config\",\n ...configArgs,\n ]);\n state = JSON.parse(await readFile(stateFile, \"utf8\")) as WranglerState;\n }\n }\n\n if (configuredR2.length === 0) {\n const recovered = await recoverR2(runner, r2Name, configArgs);\n if (recovered !== null) {\n if (!adoptExisting) {\n throw new Error(\n `the ${r2Name} R2 bucket already exists; verify it, then rerun with --adopt-existing`,\n );\n }\n state.r2_buckets.push(recovered);\n await writeState(stateFile, state);\n } else {\n await runner([\n \"r2\",\n \"bucket\",\n \"create\",\n r2Name,\n \"--binding\",\n r2Binding,\n \"--update-config\",\n ...configArgs,\n ]);\n state = JSON.parse(await readFile(stateFile, \"utf8\")) as WranglerState;\n }\n }\n\n state.d1_databases = state.d1_databases.map((database) =>\n database.binding === d1Binding ? { ...database, migrations_dir: \"migrations\" } : database,\n );\n await writeState(stateFile, state);\n return state;\n}\n\nfunction deploymentUrl(output: string, config: NormalizedConfig): string | null {\n if (config.hostname !== undefined) return `https://${config.hostname}`;\n return output.match(/https:\\/\\/[^\\s]+\\.workers\\.dev\\b/)?.[0] ?? null;\n}\n\nexport async function deploy(options: DeployOptions): Promise<DeployResult> {\n const cwd = resolve(options.cwd);\n const config = await loadConfig(cwd, options.configFile);\n const stateDirectory = join(cwd, stateDirectoryName);\n const stateFile = join(stateDirectory, stateFileName);\n const ownershipFile = join(stateDirectory, ownershipFileName);\n await mkdir(stateDirectory, { recursive: true });\n\n const previous = await readState(stateFile, config);\n const runner = options.runner ?? createWranglerRunner(cwd);\n const environmentAccountId = process.env.CLOUDFLARE_ACCOUNT_ID;\n const configuredAccountId = config.accountId ?? previous?.account_id;\n if (\n environmentAccountId !== undefined &&\n configuredAccountId !== undefined &&\n environmentAccountId !== configuredAccountId\n ) {\n throw new Error(\"CLOUDFLARE_ACCOUNT_ID does not match the configured deployment account\");\n }\n const accountId = await resolveAccountId(runner, configuredAccountId ?? environmentAccountId);\n const ownsWorker = await readWorkerOwnership(ownershipFile, config.name, accountId);\n let state = stateFor(config, accountId, previous);\n await writeState(stateFile, state);\n await copyRuntimeFiles(stateDirectory, options.assetsDirectory ?? packageRoot());\n\n state = await ensureResources(state, stateFile, cwd, runner, options.adoptExisting ?? false);\n const configArgs = configArguments(stateFile, cwd);\n await runner([\"d1\", \"migrations\", \"apply\", d1Binding, \"--remote\", ...configArgs]);\n\n const adoptedWorker = ownsWorker\n ? false\n : await verifyWorkerOwnership(state.name, configArgs, runner, options.adoptExisting ?? false);\n if (adoptedWorker) await writeWorkerOwnership(ownershipFile, state.name, accountId);\n\n const deployArguments = [\"deploy\", \"--no-bundle\", ...configArgs];\n if (options.secretsFile !== undefined) {\n deployArguments.push(\"--secrets-file\", options.secretsFile);\n }\n const deployed = await runner(deployArguments);\n if (!ownsWorker && !adoptedWorker)\n await writeWorkerOwnership(ownershipFile, state.name, accountId);\n return {\n registryUrl: deploymentUrl(deployed.stdout, config),\n stateFile,\n secretBindings: config.auth.tokens.map((token) => token.binding),\n scopes: config.scopes,\n };\n}\n","import { access } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { createJiti } from \"jiti\";\nimport { normalizeConfig, type NormalizedConfig } from \"../config.js\";\n\nexport const defaultConfigFile = \"pkgflare.config.ts\";\n\nexport async function loadConfig(\n cwd: string,\n configFile = defaultConfigFile,\n): Promise<NormalizedConfig> {\n const path = resolve(cwd, configFile);\n try {\n await access(path);\n } catch {\n throw new Error(`configuration file not found: ${configFile}`);\n }\n\n const jiti = createJiti(pathToFileURL(import.meta.url).href, {\n interopDefault: true,\n moduleCache: false,\n });\n const imported = await jiti.import(path, { default: true });\n return normalizeConfig(imported);\n}\n","export type Permission = \"read\" | \"publish\";\n\nexport interface SecretTokenConfig {\n binding: string;\n permissions: readonly Permission[];\n}\n\nexport interface GitHubOidcSubjectConfig {\n repositoryId: string;\n repositoryOwnerId: string;\n ref: string;\n workflowRef: string;\n jobWorkflowRef?: string;\n permissions: readonly Permission[];\n packages: readonly string[];\n}\n\nexport interface GitHubOidcConfig {\n audience: string;\n subjects: readonly GitHubOidcSubjectConfig[];\n}\n\nexport interface SecretsAuthConfig {\n provider: \"secrets\";\n tokens?: readonly SecretTokenConfig[];\n githubOidc?: GitHubOidcConfig;\n}\n\nexport interface PkgflareConfig {\n name: string;\n scopes: readonly string[];\n accountId?: string;\n hostname?: string;\n auth: SecretsAuthConfig;\n}\n\nexport interface NormalizedConfig {\n name: string;\n scopes: string[];\n accountId?: string;\n hostname?: string;\n auth: {\n provider: \"secrets\";\n tokens: Array<{\n binding: string;\n permissions: Permission[];\n }>;\n githubOidc?: {\n audience: string;\n subjects: Array<{\n repositoryId: string;\n repositoryOwnerId: string;\n ref: string;\n workflowRef: string;\n jobWorkflowRef?: string;\n permissions: Permission[];\n packages: string[];\n }>;\n };\n };\n}\n\nconst workerNamePattern = /^[a-z](?:[a-z0-9-]{0,52}[a-z0-9])?$/;\nconst accountIdPattern = /^[a-f0-9]{32}$/;\nconst scopePattern = /^@[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$/;\nconst bindingPattern = /^[A-Z][A-Z0-9_]*$/;\nconst hostnamePattern =\n /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$/;\nconst reservedBindings = new Set([\"PKGFLARE_DB\", \"PKGFLARE_BUCKET\", \"PKGFLARE_CONFIG\"]);\nconst githubIdPattern = /^[1-9][0-9]{0,19}$/;\nconst audiencePattern = /^[\\x21-\\x7e]{1,256}$/;\nconst refPattern = /^refs\\/(?:heads|tags)\\/[A-Za-z0-9._/-]+\\*?$/;\nconst workflowRefPattern =\n /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+\\/\\.github\\/workflows\\/[A-Za-z0-9_.-]+\\.ya?ml@refs\\/(?:heads|tags)\\/[A-Za-z0-9._/-]+\\*?$/;\nconst jobWorkflowRefPattern =\n /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+\\/\\.github\\/workflows\\/[A-Za-z0-9_.-]+\\.ya?ml@(?:refs\\/(?:heads|tags)\\/[A-Za-z0-9._/-]+\\*?|[0-9a-f]{40})$/;\nconst packageSegmentPattern = /^(?!\\.)(?:[a-z0-9._-]+)$/;\nconst maximumGithubSubjects = 128;\nconst maximumPackagesPerSubject = 128;\nconst maximumRuntimeConfigBytes = 5 * 1024;\n\nexport function defineConfig(config: PkgflareConfig): PkgflareConfig {\n return config;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction normalizePermissions(value: unknown, label: string): Permission[] {\n if (\n !Array.isArray(value) ||\n value.length === 0 ||\n value.some((permission) => permission !== \"read\" && permission !== \"publish\")\n ) {\n throw new Error(`invalid permissions for ${label}`);\n }\n return [...new Set(value)] as Permission[];\n}\n\nfunction isSafePattern(value: string, pattern: RegExp): boolean {\n if (!pattern.test(value)) return false;\n const wildcard = value.indexOf(\"*\");\n return wildcard === -1 || wildcard === value.length - 1;\n}\n\nfunction normalizeGithubOidc(\n value: unknown,\n configuredScopes: readonly string[],\n): NormalizedConfig[\"auth\"][\"githubOidc\"] {\n if (!isObject(value) || typeof value.audience !== \"string\") {\n throw new Error(\"githubOidc must define an audience and trusted subjects\");\n }\n if (!audiencePattern.test(value.audience)) {\n throw new Error(\"githubOidc audience must be 1-256 printable ASCII characters\");\n }\n if (\n !Array.isArray(value.subjects) ||\n value.subjects.length === 0 ||\n value.subjects.length > maximumGithubSubjects\n ) {\n throw new Error(`githubOidc must define 1-${String(maximumGithubSubjects)} subjects`);\n }\n\n const subjects = value.subjects.map((subjectValue, index) => {\n const label = `githubOidc subject ${String(index + 1)}`;\n if (!isObject(subjectValue)) throw new Error(`${label} must be an object`);\n const { repositoryId, repositoryOwnerId, ref, workflowRef, jobWorkflowRef } = subjectValue;\n if (typeof repositoryId !== \"string\" || !githubIdPattern.test(repositoryId)) {\n throw new Error(`${label} repositoryId must be a decimal GitHub repository ID`);\n }\n if (typeof repositoryOwnerId !== \"string\" || !githubIdPattern.test(repositoryOwnerId)) {\n throw new Error(`${label} repositoryOwnerId must be a decimal GitHub owner ID`);\n }\n if (typeof ref !== \"string\" || !isSafePattern(ref, refPattern)) {\n throw new Error(`${label} ref must be an exact branch/tag ref or trailing-wildcard pattern`);\n }\n if (typeof workflowRef !== \"string\" || !isSafePattern(workflowRef, workflowRefPattern)) {\n throw new Error(\n `${label} workflowRef must identify a workflow file at an exact or trailing-wildcard ref`,\n );\n }\n if (\n jobWorkflowRef !== undefined &&\n (typeof jobWorkflowRef !== \"string\" || !isSafePattern(jobWorkflowRef, jobWorkflowRefPattern))\n ) {\n throw new Error(\n `${label} jobWorkflowRef must identify a reusable workflow at a full commit SHA or an exact/trailing-wildcard branch or tag ref`,\n );\n }\n const permissions = normalizePermissions(subjectValue.permissions, label);\n if (\n !Array.isArray(subjectValue.packages) ||\n subjectValue.packages.length === 0 ||\n subjectValue.packages.length > maximumPackagesPerSubject ||\n subjectValue.packages.some((packageName) => typeof packageName !== \"string\")\n ) {\n throw new Error(\n `${label} must define 1-${String(maximumPackagesPerSubject)} package patterns`,\n );\n }\n const packages = [...new Set(subjectValue.packages as string[])];\n for (const packagePattern of packages) {\n const slash = packagePattern.indexOf(\"/\");\n const scope = packagePattern.slice(0, slash);\n const packageSegment = packagePattern.slice(slash + 1);\n if (\n slash === -1 ||\n packagePattern.length > 214 ||\n !configuredScopes.includes(scope) ||\n (packageSegment !== \"*\" && !packageSegmentPattern.test(packageSegment))\n ) {\n throw new Error(`${label} contains an invalid or unconfigured package pattern`);\n }\n }\n return {\n repositoryId,\n repositoryOwnerId,\n ref,\n workflowRef,\n ...(jobWorkflowRef === undefined ? {} : { jobWorkflowRef }),\n permissions,\n packages,\n };\n });\n return { audience: value.audience, subjects };\n}\n\nexport function normalizeConfig(value: unknown): NormalizedConfig {\n if (!isObject(value)) throw new Error(\"configuration must be an object\");\n const { name, scopes: scopeValues, accountId, hostname, auth } = value;\n if (typeof name !== \"string\" || !workerNamePattern.test(name)) {\n throw new Error(\"name must be a lowercase Cloudflare resource name of at most 54 characters\");\n }\n\n if (\n accountId !== undefined &&\n (typeof accountId !== \"string\" || !accountIdPattern.test(accountId))\n ) {\n throw new Error(\"accountId must be a 32-character lowercase hexadecimal Cloudflare account ID\");\n }\n\n if (\n !Array.isArray(scopeValues) ||\n scopeValues.length === 0 ||\n scopeValues.some((scope) => typeof scope !== \"string\")\n ) {\n throw new Error(\"at least one package scope is required\");\n }\n\n const scopes = [...new Set(scopeValues as string[])];\n for (const scope of scopes) {\n if (!scopePattern.test(scope)) {\n throw new Error(`invalid package scope: ${scope}`);\n }\n }\n\n if (hostname !== undefined && (typeof hostname !== \"string\" || !hostnamePattern.test(hostname))) {\n throw new Error(\"hostname must be a valid DNS hostname without a scheme or path\");\n }\n\n if (!isObject(auth) || auth.provider !== \"secrets\") {\n throw new Error(\"unsupported authentication provider\");\n }\n\n const tokenValues = auth.tokens ?? [];\n if (!Array.isArray(tokenValues)) {\n throw new Error(\"authentication token bindings must be an array\");\n }\n\n const seenBindings = new Set<string>();\n const tokens = tokenValues.map((tokenValue) => {\n if (!isObject(tokenValue) || typeof tokenValue.binding !== \"string\") {\n throw new Error(\"authentication token binding must be an object with a binding name\");\n }\n const { binding, permissions: permissionValues } = tokenValue;\n if (!bindingPattern.test(binding)) {\n throw new Error(`invalid secret binding: ${binding}`);\n }\n if (reservedBindings.has(binding)) {\n throw new Error(`secret binding is reserved by pkgflare: ${binding}`);\n }\n if (seenBindings.has(binding)) {\n throw new Error(`duplicate secret binding: ${binding}`);\n }\n seenBindings.add(binding);\n\n const permissions = normalizePermissions(permissionValues, binding);\n\n return { binding, permissions };\n });\n\n const githubOidc =\n auth.githubOidc === undefined ? undefined : normalizeGithubOidc(auth.githubOidc, scopes);\n if (tokens.length === 0 && githubOidc === undefined) {\n throw new Error(\"at least one authentication method is required\");\n }\n\n const normalized: NormalizedConfig = {\n name,\n scopes,\n ...(accountId === undefined ? {} : { accountId }),\n ...(hostname === undefined ? {} : { hostname }),\n auth: {\n provider: \"secrets\",\n tokens,\n ...(githubOidc === undefined ? {} : { githubOidc }),\n },\n };\n if (new TextEncoder().encode(JSON.stringify(normalized)).byteLength > maximumRuntimeConfigBytes) {\n throw new Error(\"normalized configuration exceeds the 5 KiB Worker variable limit\");\n }\n return normalized;\n}\n","import { spawn } from \"node:child_process\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\n\nexport interface CommandResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\nexport type WranglerRunner = (\n arguments_: readonly string[],\n options?: { allowFailure?: boolean; silent?: boolean },\n) => Promise<CommandResult>;\n\nfunction wranglerEntry(): string {\n const require = createRequire(import.meta.url);\n return join(dirname(require.resolve(\"wrangler/package.json\")), \"bin\", \"wrangler.js\");\n}\n\nexport function createWranglerRunner(cwd: string): WranglerRunner {\n return async (arguments_, options = {}) => {\n const result = await new Promise<CommandResult>((resolve, reject) => {\n const child = spawn(process.execPath, [wranglerEntry(), ...arguments_], {\n cwd,\n env: process.env,\n shell: false,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.setEncoding(\"utf8\");\n child.stderr.setEncoding(\"utf8\");\n child.stdout.on(\"data\", (chunk: string) => {\n stdout += chunk;\n if (!options.silent) process.stdout.write(chunk);\n });\n child.stderr.on(\"data\", (chunk: string) => {\n stderr += chunk;\n if (!options.silent) process.stderr.write(chunk);\n });\n child.once(\"error\", reject);\n child.once(\"close\", (code) => resolve({ exitCode: code ?? 1, stdout, stderr }));\n });\n\n if (result.exitCode !== 0 && !options.allowFailure) {\n const operation = arguments_.slice(0, 3).join(\" \");\n throw new Error(\n `Wrangler command ${JSON.stringify(operation)} exited with status ${String(result.exitCode)}`,\n );\n }\n return result;\n };\n}\n","async function readGithubTokenResponse(response: Response): Promise<string> {\n const maximumBytes = 32 * 1024;\n if (response.body === null) throw new Error(\"GitHub OIDC token response is empty\");\n const reader = response.body.getReader();\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n let size = 0;\n let contents = \"\";\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > maximumBytes) {\n await reader.cancel();\n throw new Error(\"GitHub OIDC token response is too large\");\n }\n contents += decoder.decode(value, { stream: true });\n }\n contents += decoder.decode();\n } finally {\n reader.releaseLock();\n }\n\n let value: unknown;\n try {\n value = JSON.parse(contents) as unknown;\n } catch {\n throw new Error(\"GitHub OIDC token response is invalid\");\n }\n if (\n typeof value !== \"object\" ||\n value === null ||\n !(\"value\" in value) ||\n typeof value.value !== \"string\" ||\n value.value.length > 16 * 1024 ||\n !/^[^.]+\\.[^.]+\\.[^.]+$/.test(value.value)\n ) {\n throw new Error(\"GitHub OIDC token response is invalid\");\n }\n return value.value;\n}\n\nexport async function requestGithubOidcToken(\n audience: string | undefined,\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<string> {\n if (audience === undefined) throw new Error(\"--audience is required\");\n if (!/^[\\x21-\\x7e]{1,256}$/.test(audience)) {\n throw new Error(\"--audience must be 1-256 printable ASCII characters\");\n }\n const requestUrlValue = environment.ACTIONS_ID_TOKEN_REQUEST_URL;\n const requestToken = environment.ACTIONS_ID_TOKEN_REQUEST_TOKEN;\n if (requestUrlValue === undefined || requestToken === undefined || requestToken.length === 0) {\n throw new Error(\"GitHub Actions OIDC environment is unavailable\");\n }\n\n let requestUrl: URL;\n try {\n requestUrl = new URL(requestUrlValue);\n } catch {\n throw new Error(\"GitHub Actions OIDC request URL is invalid\");\n }\n if (\n requestUrl.protocol !== \"https:\" ||\n (requestUrl.hostname !== \"token.actions.githubusercontent.com\" &&\n !requestUrl.hostname.endsWith(\".actions.githubusercontent.com\")) ||\n requestUrl.username !== \"\" ||\n requestUrl.password !== \"\"\n ) {\n throw new Error(\"GitHub Actions OIDC request URL is not trusted\");\n }\n requestUrl.searchParams.set(\"audience\", audience);\n\n let response: Response;\n try {\n response = await fetch(requestUrl, {\n headers: { authorization: `bearer ${requestToken}` },\n redirect: \"error\",\n signal: AbortSignal.timeout(5000),\n });\n } catch {\n throw new Error(\"GitHub Actions OIDC token request failed\");\n }\n if (!response.ok) throw new Error(\"GitHub Actions OIDC token request failed\");\n return readGithubTokenResponse(response);\n}\n"],"mappings":"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","names":["relative","resolve","dirname","join","resolve","require","resolve","dirname","join","resolve","value","resolve","relative"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/cli/deploy.ts","../src/cli/config-loader.ts","../src/config.ts","../src/cli/runner.ts","../src/cli/github-oidc.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { open } from \"node:fs/promises\";\nimport { relative, resolve } from \"node:path\";\nimport { deploy } from \"./cli/deploy.js\";\nimport { requestGithubOidcToken } from \"./cli/github-oidc.js\";\n\nfunction valueAfter(arguments_: readonly string[], flag: string): string | undefined {\n const index = arguments_.indexOf(flag);\n if (index === -1) return undefined;\n const value = arguments_[index + 1];\n if (value === undefined || value.startsWith(\"--\")) throw new Error(`${flag} requires a value`);\n return value;\n}\n\nfunction help(): void {\n process.stdout.write(\n `pkgflare\\n\\nUsage:\\n pkgflare deploy [--config <path>] [--secrets-file <path>] [--adopt-existing]\\n pkgflare auth github --audience <audience>\\n pkgflare init\\n pkgflare token generate\\n`,\n );\n}\n\nasync function init(cwd: string): Promise<void> {\n const path = resolve(cwd, \"pkgflare.config.ts\");\n const file = await open(path, \"wx\").catch((error: unknown) => {\n if ((error as NodeJS.ErrnoException).code === \"EEXIST\")\n throw new Error(\"pkgflare.config.ts already exists\");\n throw error;\n });\n await file.writeFile(\n `import { defineConfig } from \"@ponharu/pkgflare\";\\n\\nexport default defineConfig({\\n name: \"acme-registry\",\\n scopes: [\"@acme\"],\\n auth: {\\n provider: \"secrets\",\\n tokens: [\\n { binding: \"PKGFLARE_READ_TOKEN\", permissions: [\"read\"] },\\n { binding: \"PKGFLARE_PUBLISH_TOKEN\", permissions: [\"publish\"] },\\n ],\\n },\\n});\\n`,\n );\n await file.close();\n process.stdout.write(\"Created pkgflare.config.ts\\n\");\n}\n\nasync function main(arguments_: string[]): Promise<void> {\n const [command, subcommand] = arguments_;\n if (command === undefined || command === \"--help\" || command === \"-h\") {\n help();\n return;\n }\n if (command === \"deploy\") {\n const configFile = valueAfter(arguments_, \"--config\");\n const secretsFile = valueAfter(arguments_, \"--secrets-file\");\n const adoptExisting = arguments_.includes(\"--adopt-existing\");\n const result = await deploy({\n cwd: process.cwd(),\n ...(configFile === undefined ? {} : { configFile }),\n ...(secretsFile === undefined ? {} : { secretsFile }),\n adoptExisting,\n });\n const statePath = relative(process.cwd(), result.stateFile);\n process.stdout.write(`\\nDeployment state: ${statePath}\\n`);\n if (result.registryUrl !== null) {\n process.stdout.write(`Registry: ${result.registryUrl}\\n`);\n }\n process.stdout.write(\"\\nRegister each token secret if it was not supplied during deploy:\\n\");\n for (const binding of result.secretBindings) {\n process.stdout.write(` npx wrangler secret put ${binding} --config ${statePath}\\n`);\n }\n if (result.registryUrl !== null) {\n const host = new URL(result.registryUrl).host;\n process.stdout.write(\"\\n.npmrc:\\n\");\n for (const scope of result.scopes) {\n process.stdout.write(` ${scope}:registry=${result.registryUrl}\\n`);\n }\n process.stdout.write(` //${host}/:_authToken=\\${NPM_TOKEN}\\n`);\n }\n return;\n }\n if (command === \"init\") {\n await init(process.cwd());\n return;\n }\n if (command === \"auth\" && subcommand === \"github\") {\n const token = await requestGithubOidcToken(valueAfter(arguments_, \"--audience\"));\n process.stdout.write(`${token}\\n`);\n return;\n }\n if (command === \"token\" && subcommand === \"generate\") {\n let binary = \"\";\n for (const byte of randomBytes(32)) binary += String.fromCharCode(byte);\n const token = btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n process.stdout.write(`${token}\\n`);\n return;\n }\n throw new Error(`unknown command: ${arguments_.join(\" \")}`);\n}\n\nmain(process.argv.slice(2)).catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.stderr.write(`pkgflare: ${message}\\n`);\n process.exitCode = 1;\n});\n","import { copyFile, mkdir, readFile, readdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { NormalizedConfig } from \"../config.js\";\nimport { loadConfig } from \"./config-loader.js\";\nimport { createWranglerRunner, type WranglerRunner } from \"./runner.js\";\n\nconst stateDirectoryName = \".pkgflare\";\nconst stateFileName = \"wrangler.json\";\nconst ownershipFileName = \"ownership.json\";\nconst d1Binding = \"PKGFLARE_DB\";\nconst r2Binding = \"PKGFLARE_BUCKET\";\n\ninterface D1Binding {\n binding: string;\n database_name: string;\n database_id: string;\n migrations_dir?: string;\n}\n\ninterface R2Binding {\n binding: string;\n bucket_name: string;\n}\n\ninterface WranglerState {\n $schema: string;\n account_id?: string;\n name: string;\n main: string;\n compatibility_date: string;\n workers_dev: boolean;\n routes?: Array<{ pattern: string; custom_domain: true }>;\n vars: { PKGFLARE_CONFIG: string };\n d1_databases: D1Binding[];\n r2_buckets: R2Binding[];\n}\n\ninterface D1ListEntry {\n name?: unknown;\n uuid?: unknown;\n}\n\ninterface WhoamiResult {\n loggedIn?: unknown;\n accounts?: unknown;\n}\n\ninterface AccountEntry {\n id: string;\n name?: string;\n}\n\ninterface OwnershipState {\n account_id: string;\n worker_name: string;\n}\n\nexport interface DeployOptions {\n cwd: string;\n configFile?: string;\n secretsFile?: string;\n adoptExisting?: boolean;\n runner?: WranglerRunner;\n assetsDirectory?: string;\n}\n\nexport interface DeployResult {\n registryUrl: string | null;\n stateFile: string;\n secretBindings: string[];\n scopes: string[];\n}\n\nfunction packageRoot(): string {\n return dirname(fileURLToPath(import.meta.url));\n}\n\nfunction stateFor(\n config: NormalizedConfig,\n accountId: string,\n previous?: WranglerState,\n): WranglerState {\n if (previous?.account_id !== undefined && previous.account_id !== accountId) {\n throw new Error(\"authenticated Cloudflare account does not match the deployment state\");\n }\n const state: WranglerState = {\n $schema:\n \"https://raw.githubusercontent.com/cloudflare/workers-sdk/main/packages/wrangler/config-schema.json\",\n account_id: accountId,\n name: config.name,\n main: \"runtime/worker.js\",\n compatibility_date: \"2026-08-01\",\n workers_dev: config.hostname === undefined,\n vars: { PKGFLARE_CONFIG: JSON.stringify(config) },\n d1_databases: previous?.d1_databases ?? [],\n r2_buckets: previous?.r2_buckets ?? [],\n };\n if (config.hostname !== undefined) {\n state.routes = [{ pattern: config.hostname, custom_domain: true }];\n }\n return state;\n}\n\nasync function readState(\n path: string,\n config: NormalizedConfig,\n): Promise<WranglerState | undefined> {\n let contents: string;\n try {\n contents = await readFile(path, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n throw error;\n }\n const state = JSON.parse(contents) as WranglerState;\n if (state.name !== config.name) {\n throw new Error(\n `existing deployment state belongs to ${state.name}; remove ${stateDirectoryName} only after verifying the remote resources`,\n );\n }\n return state;\n}\n\nasync function writeState(path: string, state: WranglerState): Promise<void> {\n await writeFile(path, `${JSON.stringify(state, null, 2)}\\n`, \"utf8\");\n}\n\nasync function readWorkerOwnership(\n path: string,\n workerName: string,\n accountId: string,\n): Promise<boolean> {\n let contents: string;\n try {\n contents = await readFile(path, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw error;\n }\n const ownership = JSON.parse(contents) as Partial<OwnershipState>;\n if (ownership.worker_name !== workerName || ownership.account_id !== accountId) {\n throw new Error(\"deployment ownership state does not match the configured Worker and account\");\n }\n return true;\n}\n\nasync function writeWorkerOwnership(\n path: string,\n workerName: string,\n accountId: string,\n): Promise<void> {\n const ownership: OwnershipState = { account_id: accountId, worker_name: workerName };\n await writeFile(path, `${JSON.stringify(ownership, null, 2)}\\n`, \"utf8\");\n}\n\nasync function copyRuntimeFiles(stateDirectory: string, root: string): Promise<void> {\n const runtimeDirectory = join(stateDirectory, \"runtime\");\n const migrationsDirectory = join(stateDirectory, \"migrations\");\n await Promise.all([\n mkdir(runtimeDirectory, { recursive: true }),\n mkdir(migrationsDirectory, { recursive: true }),\n ]);\n const sourceMigrations = resolve(root, \"..\", \"migrations\");\n const migrationFiles = (await readdir(sourceMigrations, { withFileTypes: true }))\n .filter((entry) => entry.isFile() && entry.name.endsWith(\".sql\"))\n .map((entry) => entry.name);\n // oxlint-disable-next-line unicorn/no-array-sort -- this array has just been created locally\n migrationFiles.sort();\n if (migrationFiles.length === 0) throw new Error(\"pkgflare package contains no D1 migrations\");\n await Promise.all([\n copyFile(join(root, \"worker.js\"), join(runtimeDirectory, \"worker.js\")),\n copyFile(join(root, \"worker.js.map\"), join(runtimeDirectory, \"worker.js.map\")),\n ...migrationFiles.map((file) =>\n copyFile(join(sourceMigrations, file), join(migrationsDirectory, file)),\n ),\n ]);\n await writeFile(join(stateDirectory, \".gitignore\"), \"runtime/\\nmigrations/\\n\", {\n flag: \"wx\",\n }).catch((error: unknown) => {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n });\n}\n\nfunction configArguments(stateFile: string, cwd: string): string[] {\n return [\"--config\", relative(cwd, stateFile)];\n}\n\nasync function recoverD1(\n runner: WranglerRunner,\n databaseName: string,\n configArgs: readonly string[],\n): Promise<D1Binding | null> {\n const result = await runner([\"d1\", \"list\", \"--json\", ...configArgs], { silent: true });\n const entries = JSON.parse(result.stdout) as D1ListEntry[];\n const matches = entries.filter(\n (entry) => entry.name === databaseName && typeof entry.uuid === \"string\",\n );\n if (matches.length > 1) throw new Error(`multiple D1 databases are named ${databaseName}`);\n const match = matches[0];\n return match === undefined\n ? null\n : {\n binding: d1Binding,\n database_name: databaseName,\n database_id: match.uuid as string,\n migrations_dir: \"migrations\",\n };\n}\n\nasync function recoverR2(\n runner: WranglerRunner,\n bucketName: string,\n configArgs: readonly string[],\n): Promise<R2Binding | null> {\n const result = await runner([\"r2\", \"bucket\", \"info\", bucketName, \"--json\", ...configArgs], {\n silent: true,\n allowFailure: true,\n });\n if (result.exitCode === 0) return { binding: r2Binding, bucket_name: bucketName };\n if (/not found|does not exist|10006/i.test(result.stderr)) return null;\n throw new Error(`unable to inspect the ${bucketName} R2 bucket with the current credentials`);\n}\n\nfunction accountsFromWhoami(value: unknown): AccountEntry[] {\n if (typeof value !== \"object\" || value === null)\n throw new Error(\"Wrangler returned invalid account information\");\n const accounts = (value as WhoamiResult).accounts;\n if (!Array.isArray(accounts)) throw new Error(\"Wrangler returned invalid account information\");\n return accounts.flatMap((account) => {\n if (\n typeof account !== \"object\" ||\n account === null ||\n !(\"id\" in account) ||\n typeof account.id !== \"string\"\n ) {\n return [];\n }\n return [\n {\n id: account.id,\n ...(typeof (account as { name?: unknown }).name === \"string\"\n ? { name: (account as { name: string }).name }\n : {}),\n },\n ];\n });\n}\n\nasync function resolveAccountId(\n runner: WranglerRunner,\n configuredAccountId: string | undefined,\n): Promise<string> {\n if (configuredAccountId !== undefined) return configuredAccountId;\n const result = await runner([\"whoami\", \"--json\"], { silent: true });\n const accounts = accountsFromWhoami(JSON.parse(result.stdout) as unknown);\n if (accounts.length !== 1) {\n throw new Error(\"accountId is required when Wrangler credentials can access multiple accounts\");\n }\n const account = accounts[0];\n if (account === undefined)\n throw new Error(\"Wrangler credentials do not provide a Cloudflare account\");\n return account.id;\n}\n\nasync function workerExists(\n runner: WranglerRunner,\n workerName: string,\n configArgs: readonly string[],\n): Promise<boolean> {\n const result = await runner([\"versions\", \"list\", \"--name\", workerName, \"--json\", ...configArgs], {\n silent: true,\n allowFailure: true,\n });\n if (result.exitCode === 0) return true;\n if (/not found|does not exist|10007/i.test(result.stderr)) return false;\n throw new Error(`unable to inspect the ${workerName} Worker with the current credentials`);\n}\n\nasync function verifyWorkerOwnership(\n workerName: string,\n configArgs: readonly string[],\n runner: WranglerRunner,\n adoptExisting: boolean,\n): Promise<boolean> {\n const exists = await workerExists(runner, workerName, configArgs);\n if (exists && !adoptExisting) {\n throw new Error(\n `the ${workerName} Worker already exists; verify it, then rerun with --adopt-existing`,\n );\n }\n return exists;\n}\n\nasync function ensureResources(\n state: WranglerState,\n stateFile: string,\n cwd: string,\n runner: WranglerRunner,\n adoptExisting: boolean,\n): Promise<WranglerState> {\n const d1Name = `${state.name}-metadata`;\n const r2Name = `${state.name}-packages`;\n const configArgs = configArguments(stateFile, cwd);\n const configuredD1 = state.d1_databases.filter((database) => database.binding === d1Binding);\n const configuredR2 = state.r2_buckets.filter((bucket) => bucket.binding === r2Binding);\n const selectedD1 = configuredD1[0];\n const selectedR2 = configuredR2[0];\n if (\n configuredD1.length > 1 ||\n (selectedD1 !== undefined && selectedD1.database_name !== d1Name)\n ) {\n throw new Error(`${d1Binding} must reference the ${d1Name} D1 database`);\n }\n if (configuredR2.length > 1 || (selectedR2 !== undefined && selectedR2.bucket_name !== r2Name)) {\n throw new Error(`${r2Binding} must reference the ${r2Name} R2 bucket`);\n }\n\n if (configuredD1.length === 0) {\n const recovered = await recoverD1(runner, d1Name, configArgs);\n if (recovered !== null) {\n if (!adoptExisting) {\n throw new Error(\n `the ${d1Name} D1 database already exists; verify it, then rerun with --adopt-existing`,\n );\n }\n state.d1_databases.push(recovered);\n await writeState(stateFile, state);\n } else {\n await runner([\n \"d1\",\n \"create\",\n d1Name,\n \"--binding\",\n d1Binding,\n \"--update-config\",\n ...configArgs,\n ]);\n state = JSON.parse(await readFile(stateFile, \"utf8\")) as WranglerState;\n }\n }\n\n if (configuredR2.length === 0) {\n const recovered = await recoverR2(runner, r2Name, configArgs);\n if (recovered !== null) {\n if (!adoptExisting) {\n throw new Error(\n `the ${r2Name} R2 bucket already exists; verify it, then rerun with --adopt-existing`,\n );\n }\n state.r2_buckets.push(recovered);\n await writeState(stateFile, state);\n } else {\n await runner([\n \"r2\",\n \"bucket\",\n \"create\",\n r2Name,\n \"--binding\",\n r2Binding,\n \"--update-config\",\n ...configArgs,\n ]);\n state = JSON.parse(await readFile(stateFile, \"utf8\")) as WranglerState;\n }\n }\n\n state.d1_databases = state.d1_databases.map((database) =>\n database.binding === d1Binding ? { ...database, migrations_dir: \"migrations\" } : database,\n );\n await writeState(stateFile, state);\n return state;\n}\n\nfunction deploymentUrl(output: string, config: NormalizedConfig): string | null {\n if (config.hostname !== undefined) return `https://${config.hostname}`;\n return output.match(/https:\\/\\/[^\\s]+\\.workers\\.dev\\b/)?.[0] ?? null;\n}\n\nexport async function deploy(options: DeployOptions): Promise<DeployResult> {\n const cwd = resolve(options.cwd);\n const config = await loadConfig(cwd, options.configFile);\n const stateDirectory = join(cwd, stateDirectoryName);\n const stateFile = join(stateDirectory, stateFileName);\n const ownershipFile = join(stateDirectory, ownershipFileName);\n await mkdir(stateDirectory, { recursive: true });\n\n const previous = await readState(stateFile, config);\n const runner = options.runner ?? createWranglerRunner(cwd);\n const environmentAccountId = process.env.CLOUDFLARE_ACCOUNT_ID;\n const configuredAccountId = config.accountId ?? previous?.account_id;\n if (\n environmentAccountId !== undefined &&\n configuredAccountId !== undefined &&\n environmentAccountId !== configuredAccountId\n ) {\n throw new Error(\"CLOUDFLARE_ACCOUNT_ID does not match the configured deployment account\");\n }\n const accountId = await resolveAccountId(runner, configuredAccountId ?? environmentAccountId);\n const ownsWorker = await readWorkerOwnership(ownershipFile, config.name, accountId);\n let state = stateFor(config, accountId, previous);\n await writeState(stateFile, state);\n await copyRuntimeFiles(stateDirectory, options.assetsDirectory ?? packageRoot());\n\n state = await ensureResources(state, stateFile, cwd, runner, options.adoptExisting ?? false);\n const configArgs = configArguments(stateFile, cwd);\n await runner([\"d1\", \"migrations\", \"apply\", d1Binding, \"--remote\", ...configArgs]);\n\n const adoptedWorker = ownsWorker\n ? false\n : await verifyWorkerOwnership(state.name, configArgs, runner, options.adoptExisting ?? false);\n if (adoptedWorker) await writeWorkerOwnership(ownershipFile, state.name, accountId);\n\n const deployArguments = [\"deploy\", \"--no-bundle\", ...configArgs];\n if (options.secretsFile !== undefined) {\n deployArguments.push(\"--secrets-file\", options.secretsFile);\n }\n const deployed = await runner(deployArguments);\n if (!ownsWorker && !adoptedWorker)\n await writeWorkerOwnership(ownershipFile, state.name, accountId);\n return {\n registryUrl: deploymentUrl(deployed.stdout, config),\n stateFile,\n secretBindings: config.auth.tokens.map((token) => token.binding),\n scopes: config.scopes,\n };\n}\n","import { access } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { createJiti } from \"jiti\";\nimport { normalizeConfig, type NormalizedConfig } from \"../config.js\";\n\nexport const defaultConfigFile = \"pkgflare.config.ts\";\n\nexport async function loadConfig(\n cwd: string,\n configFile = defaultConfigFile,\n): Promise<NormalizedConfig> {\n const path = resolve(cwd, configFile);\n try {\n await access(path);\n } catch {\n throw new Error(`configuration file not found: ${configFile}`);\n }\n\n const jiti = createJiti(pathToFileURL(import.meta.url).href, {\n interopDefault: true,\n moduleCache: false,\n });\n const imported = await jiti.import(path, { default: true });\n return normalizeConfig(imported);\n}\n","export type Permission = \"read\" | \"publish\";\n\nexport interface SecretTokenConfig {\n binding: string;\n permissions: readonly Permission[];\n}\n\nexport interface GitHubOidcSubjectConfig {\n repositoryId: string;\n repositoryOwnerId: string;\n ref: string;\n workflowRef: string;\n jobWorkflowRef?: string;\n permissions: readonly Permission[];\n packages: readonly string[];\n}\n\nexport interface GitHubOidcConfig {\n audience: string;\n subjects: readonly GitHubOidcSubjectConfig[];\n}\n\nexport interface SecretsAuthConfig {\n provider: \"secrets\";\n tokens?: readonly SecretTokenConfig[];\n githubOidc?: GitHubOidcConfig;\n}\n\nexport interface PkgflareConfig {\n name: string;\n scopes: readonly string[];\n accountId?: string;\n hostname?: string;\n auth: SecretsAuthConfig;\n}\n\nexport interface NormalizedConfig {\n name: string;\n scopes: string[];\n accountId?: string;\n hostname?: string;\n auth: {\n provider: \"secrets\";\n tokens: Array<{\n binding: string;\n permissions: Permission[];\n }>;\n githubOidc?: {\n audience: string;\n subjects: Array<{\n repositoryId: string;\n repositoryOwnerId: string;\n ref: string;\n workflowRef: string;\n jobWorkflowRef?: string;\n permissions: Permission[];\n packages: string[];\n }>;\n };\n };\n}\n\nconst workerNamePattern = /^[a-z](?:[a-z0-9-]{0,52}[a-z0-9])?$/;\nconst accountIdPattern = /^[a-f0-9]{32}$/;\nconst scopePattern = /^@[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$/;\nconst bindingPattern = /^[A-Z][A-Z0-9_]*$/;\nconst hostnamePattern =\n /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$/;\nconst reservedBindings = new Set([\"PKGFLARE_DB\", \"PKGFLARE_BUCKET\", \"PKGFLARE_CONFIG\"]);\nconst githubIdPattern = /^[1-9][0-9]{0,19}$/;\nconst audiencePattern = /^[\\x21-\\x7e]{1,256}$/;\nconst refPattern = /^refs\\/(?:heads|tags)\\/[A-Za-z0-9._/-]+\\*?$/;\nconst workflowRefPattern =\n /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+\\/\\.github\\/workflows\\/[A-Za-z0-9_.-]+\\.ya?ml@refs\\/(?:heads|tags)\\/[A-Za-z0-9._/-]+\\*?$/;\nconst jobWorkflowRefPattern =\n /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+\\/\\.github\\/workflows\\/[A-Za-z0-9_.-]+\\.ya?ml@(?:refs\\/(?:heads|tags)\\/[A-Za-z0-9._/-]+\\*?|[0-9a-f]{40}|\\*)$/;\nconst jobWorkflowRefClaimPattern =\n /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+\\/\\.github\\/workflows\\/[A-Za-z0-9_.-]+\\.ya?ml@(?:refs\\/(?:heads|tags)\\/[A-Za-z0-9._/-]+|[0-9a-f]{40})$/;\nconst packageSegmentPattern = /^(?!\\.)(?:[a-z0-9._-]+)$/;\nconst maximumGithubSubjects = 128;\nconst maximumPackagesPerSubject = 128;\nconst maximumRuntimeConfigBytes = 5 * 1024;\n\nexport function defineConfig(config: PkgflareConfig): PkgflareConfig {\n return config;\n}\n\nexport function isValidGitHubJobWorkflowRefClaim(value: string): boolean {\n return jobWorkflowRefClaimPattern.test(value);\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction normalizePermissions(value: unknown, label: string): Permission[] {\n if (\n !Array.isArray(value) ||\n value.length === 0 ||\n value.some((permission) => permission !== \"read\" && permission !== \"publish\")\n ) {\n throw new Error(`invalid permissions for ${label}`);\n }\n return [...new Set(value)] as Permission[];\n}\n\nfunction isSafePattern(value: string, pattern: RegExp): boolean {\n if (!pattern.test(value)) return false;\n const wildcard = value.indexOf(\"*\");\n return wildcard === -1 || wildcard === value.length - 1;\n}\n\nfunction normalizeGithubOidc(\n value: unknown,\n configuredScopes: readonly string[],\n): NormalizedConfig[\"auth\"][\"githubOidc\"] {\n if (!isObject(value) || typeof value.audience !== \"string\") {\n throw new Error(\"githubOidc must define an audience and trusted subjects\");\n }\n if (!audiencePattern.test(value.audience)) {\n throw new Error(\"githubOidc audience must be 1-256 printable ASCII characters\");\n }\n if (\n !Array.isArray(value.subjects) ||\n value.subjects.length === 0 ||\n value.subjects.length > maximumGithubSubjects\n ) {\n throw new Error(`githubOidc must define 1-${String(maximumGithubSubjects)} subjects`);\n }\n\n const subjects = value.subjects.map((subjectValue, index) => {\n const label = `githubOidc subject ${String(index + 1)}`;\n if (!isObject(subjectValue)) throw new Error(`${label} must be an object`);\n const { repositoryId, repositoryOwnerId, ref, workflowRef, jobWorkflowRef } = subjectValue;\n if (typeof repositoryId !== \"string\" || !githubIdPattern.test(repositoryId)) {\n throw new Error(`${label} repositoryId must be a decimal GitHub repository ID`);\n }\n if (typeof repositoryOwnerId !== \"string\" || !githubIdPattern.test(repositoryOwnerId)) {\n throw new Error(`${label} repositoryOwnerId must be a decimal GitHub owner ID`);\n }\n if (typeof ref !== \"string\" || !isSafePattern(ref, refPattern)) {\n throw new Error(`${label} ref must be an exact branch/tag ref or trailing-wildcard pattern`);\n }\n if (typeof workflowRef !== \"string\" || !isSafePattern(workflowRef, workflowRefPattern)) {\n throw new Error(\n `${label} workflowRef must identify a workflow file at an exact or trailing-wildcard ref`,\n );\n }\n if (\n jobWorkflowRef !== undefined &&\n (typeof jobWorkflowRef !== \"string\" || !isSafePattern(jobWorkflowRef, jobWorkflowRefPattern))\n ) {\n throw new Error(\n `${label} jobWorkflowRef must identify one workflow at any valid ref (@*), a full commit SHA, or an exact/trailing-wildcard branch or tag ref`,\n );\n }\n const permissions = normalizePermissions(subjectValue.permissions, label);\n if (\n !Array.isArray(subjectValue.packages) ||\n subjectValue.packages.length === 0 ||\n subjectValue.packages.length > maximumPackagesPerSubject ||\n subjectValue.packages.some((packageName) => typeof packageName !== \"string\")\n ) {\n throw new Error(\n `${label} must define 1-${String(maximumPackagesPerSubject)} package patterns`,\n );\n }\n const packages = [...new Set(subjectValue.packages as string[])];\n for (const packagePattern of packages) {\n const slash = packagePattern.indexOf(\"/\");\n const scope = packagePattern.slice(0, slash);\n const packageSegment = packagePattern.slice(slash + 1);\n if (\n slash === -1 ||\n packagePattern.length > 214 ||\n !configuredScopes.includes(scope) ||\n (packageSegment !== \"*\" && !packageSegmentPattern.test(packageSegment))\n ) {\n throw new Error(`${label} contains an invalid or unconfigured package pattern`);\n }\n }\n return {\n repositoryId,\n repositoryOwnerId,\n ref,\n workflowRef,\n ...(jobWorkflowRef === undefined ? {} : { jobWorkflowRef }),\n permissions,\n packages,\n };\n });\n return { audience: value.audience, subjects };\n}\n\nexport function normalizeConfig(value: unknown): NormalizedConfig {\n if (!isObject(value)) throw new Error(\"configuration must be an object\");\n const { name, scopes: scopeValues, accountId, hostname, auth } = value;\n if (typeof name !== \"string\" || !workerNamePattern.test(name)) {\n throw new Error(\"name must be a lowercase Cloudflare resource name of at most 54 characters\");\n }\n\n if (\n accountId !== undefined &&\n (typeof accountId !== \"string\" || !accountIdPattern.test(accountId))\n ) {\n throw new Error(\"accountId must be a 32-character lowercase hexadecimal Cloudflare account ID\");\n }\n\n if (\n !Array.isArray(scopeValues) ||\n scopeValues.length === 0 ||\n scopeValues.some((scope) => typeof scope !== \"string\")\n ) {\n throw new Error(\"at least one package scope is required\");\n }\n\n const scopes = [...new Set(scopeValues as string[])];\n for (const scope of scopes) {\n if (!scopePattern.test(scope)) {\n throw new Error(`invalid package scope: ${scope}`);\n }\n }\n\n if (hostname !== undefined && (typeof hostname !== \"string\" || !hostnamePattern.test(hostname))) {\n throw new Error(\"hostname must be a valid DNS hostname without a scheme or path\");\n }\n\n if (!isObject(auth) || auth.provider !== \"secrets\") {\n throw new Error(\"unsupported authentication provider\");\n }\n\n const tokenValues = auth.tokens ?? [];\n if (!Array.isArray(tokenValues)) {\n throw new Error(\"authentication token bindings must be an array\");\n }\n\n const seenBindings = new Set<string>();\n const tokens = tokenValues.map((tokenValue) => {\n if (!isObject(tokenValue) || typeof tokenValue.binding !== \"string\") {\n throw new Error(\"authentication token binding must be an object with a binding name\");\n }\n const { binding, permissions: permissionValues } = tokenValue;\n if (!bindingPattern.test(binding)) {\n throw new Error(`invalid secret binding: ${binding}`);\n }\n if (reservedBindings.has(binding)) {\n throw new Error(`secret binding is reserved by pkgflare: ${binding}`);\n }\n if (seenBindings.has(binding)) {\n throw new Error(`duplicate secret binding: ${binding}`);\n }\n seenBindings.add(binding);\n\n const permissions = normalizePermissions(permissionValues, binding);\n\n return { binding, permissions };\n });\n\n const githubOidc =\n auth.githubOidc === undefined ? undefined : normalizeGithubOidc(auth.githubOidc, scopes);\n if (tokens.length === 0 && githubOidc === undefined) {\n throw new Error(\"at least one authentication method is required\");\n }\n\n const normalized: NormalizedConfig = {\n name,\n scopes,\n ...(accountId === undefined ? {} : { accountId }),\n ...(hostname === undefined ? {} : { hostname }),\n auth: {\n provider: \"secrets\",\n tokens,\n ...(githubOidc === undefined ? {} : { githubOidc }),\n },\n };\n if (new TextEncoder().encode(JSON.stringify(normalized)).byteLength > maximumRuntimeConfigBytes) {\n throw new Error(\"normalized configuration exceeds the 5 KiB Worker variable limit\");\n }\n return normalized;\n}\n","import { spawn } from \"node:child_process\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\n\nexport interface CommandResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\nexport type WranglerRunner = (\n arguments_: readonly string[],\n options?: { allowFailure?: boolean; silent?: boolean },\n) => Promise<CommandResult>;\n\nfunction wranglerEntry(): string {\n const require = createRequire(import.meta.url);\n return join(dirname(require.resolve(\"wrangler/package.json\")), \"bin\", \"wrangler.js\");\n}\n\nexport function createWranglerRunner(cwd: string): WranglerRunner {\n return async (arguments_, options = {}) => {\n const result = await new Promise<CommandResult>((resolve, reject) => {\n const child = spawn(process.execPath, [wranglerEntry(), ...arguments_], {\n cwd,\n env: process.env,\n shell: false,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.setEncoding(\"utf8\");\n child.stderr.setEncoding(\"utf8\");\n child.stdout.on(\"data\", (chunk: string) => {\n stdout += chunk;\n if (!options.silent) process.stdout.write(chunk);\n });\n child.stderr.on(\"data\", (chunk: string) => {\n stderr += chunk;\n if (!options.silent) process.stderr.write(chunk);\n });\n child.once(\"error\", reject);\n child.once(\"close\", (code) => resolve({ exitCode: code ?? 1, stdout, stderr }));\n });\n\n if (result.exitCode !== 0 && !options.allowFailure) {\n const operation = arguments_.slice(0, 3).join(\" \");\n throw new Error(\n `Wrangler command ${JSON.stringify(operation)} exited with status ${String(result.exitCode)}`,\n );\n }\n return result;\n };\n}\n","async function readGithubTokenResponse(response: Response): Promise<string> {\n const maximumBytes = 32 * 1024;\n if (response.body === null) throw new Error(\"GitHub OIDC token response is empty\");\n const reader = response.body.getReader();\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n let size = 0;\n let contents = \"\";\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > maximumBytes) {\n await reader.cancel();\n throw new Error(\"GitHub OIDC token response is too large\");\n }\n contents += decoder.decode(value, { stream: true });\n }\n contents += decoder.decode();\n } finally {\n reader.releaseLock();\n }\n\n let value: unknown;\n try {\n value = JSON.parse(contents) as unknown;\n } catch {\n throw new Error(\"GitHub OIDC token response is invalid\");\n }\n if (\n typeof value !== \"object\" ||\n value === null ||\n !(\"value\" in value) ||\n typeof value.value !== \"string\" ||\n value.value.length > 16 * 1024 ||\n !/^[^.]+\\.[^.]+\\.[^.]+$/.test(value.value)\n ) {\n throw new Error(\"GitHub OIDC token response is invalid\");\n }\n return value.value;\n}\n\nexport async function requestGithubOidcToken(\n audience: string | undefined,\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<string> {\n if (audience === undefined) throw new Error(\"--audience is required\");\n if (!/^[\\x21-\\x7e]{1,256}$/.test(audience)) {\n throw new Error(\"--audience must be 1-256 printable ASCII characters\");\n }\n const requestUrlValue = environment.ACTIONS_ID_TOKEN_REQUEST_URL;\n const requestToken = environment.ACTIONS_ID_TOKEN_REQUEST_TOKEN;\n if (requestUrlValue === undefined || requestToken === undefined || requestToken.length === 0) {\n throw new Error(\"GitHub Actions OIDC environment is unavailable\");\n }\n\n let requestUrl: URL;\n try {\n requestUrl = new URL(requestUrlValue);\n } catch {\n throw new Error(\"GitHub Actions OIDC request URL is invalid\");\n }\n if (\n requestUrl.protocol !== \"https:\" ||\n (requestUrl.hostname !== \"token.actions.githubusercontent.com\" &&\n !requestUrl.hostname.endsWith(\".actions.githubusercontent.com\")) ||\n requestUrl.username !== \"\" ||\n requestUrl.password !== \"\"\n ) {\n throw new Error(\"GitHub Actions OIDC request URL is not trusted\");\n }\n requestUrl.searchParams.set(\"audience\", audience);\n\n let response: Response;\n try {\n response = await fetch(requestUrl, {\n headers: { authorization: `bearer ${requestToken}` },\n redirect: \"error\",\n signal: AbortSignal.timeout(5000),\n });\n } catch {\n throw new Error(\"GitHub Actions OIDC token request failed\");\n }\n if (!response.ok) throw new Error(\"GitHub Actions OIDC token request failed\");\n return readGithubTokenResponse(response);\n}\n"],"mappings":"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","names":["relative","resolve","dirname","join","resolve","require","resolve","dirname","join","resolve","value","resolve","relative"]}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts"],"sourcesContent":["export type Permission = \"read\" | \"publish\";\n\nexport interface SecretTokenConfig {\n binding: string;\n permissions: readonly Permission[];\n}\n\nexport interface GitHubOidcSubjectConfig {\n repositoryId: string;\n repositoryOwnerId: string;\n ref: string;\n workflowRef: string;\n jobWorkflowRef?: string;\n permissions: readonly Permission[];\n packages: readonly string[];\n}\n\nexport interface GitHubOidcConfig {\n audience: string;\n subjects: readonly GitHubOidcSubjectConfig[];\n}\n\nexport interface SecretsAuthConfig {\n provider: \"secrets\";\n tokens?: readonly SecretTokenConfig[];\n githubOidc?: GitHubOidcConfig;\n}\n\nexport interface PkgflareConfig {\n name: string;\n scopes: readonly string[];\n accountId?: string;\n hostname?: string;\n auth: SecretsAuthConfig;\n}\n\nexport interface NormalizedConfig {\n name: string;\n scopes: string[];\n accountId?: string;\n hostname?: string;\n auth: {\n provider: \"secrets\";\n tokens: Array<{\n binding: string;\n permissions: Permission[];\n }>;\n githubOidc?: {\n audience: string;\n subjects: Array<{\n repositoryId: string;\n repositoryOwnerId: string;\n ref: string;\n workflowRef: string;\n jobWorkflowRef?: string;\n permissions: Permission[];\n packages: string[];\n }>;\n };\n };\n}\n\nconst workerNamePattern = /^[a-z](?:[a-z0-9-]{0,52}[a-z0-9])?$/;\nconst accountIdPattern = /^[a-f0-9]{32}$/;\nconst scopePattern = /^@[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$/;\nconst bindingPattern = /^[A-Z][A-Z0-9_]*$/;\nconst hostnamePattern =\n /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$/;\nconst reservedBindings = new Set([\"PKGFLARE_DB\", \"PKGFLARE_BUCKET\", \"PKGFLARE_CONFIG\"]);\nconst githubIdPattern = /^[1-9][0-9]{0,19}$/;\nconst audiencePattern = /^[\\x21-\\x7e]{1,256}$/;\nconst refPattern = /^refs\\/(?:heads|tags)\\/[A-Za-z0-9._/-]+\\*?$/;\nconst workflowRefPattern =\n /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+\\/\\.github\\/workflows\\/[A-Za-z0-9_.-]+\\.ya?ml@refs\\/(?:heads|tags)\\/[A-Za-z0-9._/-]+\\*?$/;\nconst jobWorkflowRefPattern =\n /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+\\/\\.github\\/workflows\\/[A-Za-z0-9_.-]+\\.ya?ml@(?:refs\\/(?:heads|tags)\\/[A-Za-z0-9._/-]+\\*?|[0-9a-f]{40})$/;\nconst packageSegmentPattern = /^(?!\\.)(?:[a-z0-9._-]+)$/;\nconst maximumGithubSubjects = 128;\nconst maximumPackagesPerSubject = 128;\nconst maximumRuntimeConfigBytes = 5 * 1024;\n\nexport function defineConfig(config: PkgflareConfig): PkgflareConfig {\n return config;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction normalizePermissions(value: unknown, label: string): Permission[] {\n if (\n !Array.isArray(value) ||\n value.length === 0 ||\n value.some((permission) => permission !== \"read\" && permission !== \"publish\")\n ) {\n throw new Error(`invalid permissions for ${label}`);\n }\n return [...new Set(value)] as Permission[];\n}\n\nfunction isSafePattern(value: string, pattern: RegExp): boolean {\n if (!pattern.test(value)) return false;\n const wildcard = value.indexOf(\"*\");\n return wildcard === -1 || wildcard === value.length - 1;\n}\n\nfunction normalizeGithubOidc(\n value: unknown,\n configuredScopes: readonly string[],\n): NormalizedConfig[\"auth\"][\"githubOidc\"] {\n if (!isObject(value) || typeof value.audience !== \"string\") {\n throw new Error(\"githubOidc must define an audience and trusted subjects\");\n }\n if (!audiencePattern.test(value.audience)) {\n throw new Error(\"githubOidc audience must be 1-256 printable ASCII characters\");\n }\n if (\n !Array.isArray(value.subjects) ||\n value.subjects.length === 0 ||\n value.subjects.length > maximumGithubSubjects\n ) {\n throw new Error(`githubOidc must define 1-${String(maximumGithubSubjects)} subjects`);\n }\n\n const subjects = value.subjects.map((subjectValue, index) => {\n const label = `githubOidc subject ${String(index + 1)}`;\n if (!isObject(subjectValue)) throw new Error(`${label} must be an object`);\n const { repositoryId, repositoryOwnerId, ref, workflowRef, jobWorkflowRef } = subjectValue;\n if (typeof repositoryId !== \"string\" || !githubIdPattern.test(repositoryId)) {\n throw new Error(`${label} repositoryId must be a decimal GitHub repository ID`);\n }\n if (typeof repositoryOwnerId !== \"string\" || !githubIdPattern.test(repositoryOwnerId)) {\n throw new Error(`${label} repositoryOwnerId must be a decimal GitHub owner ID`);\n }\n if (typeof ref !== \"string\" || !isSafePattern(ref, refPattern)) {\n throw new Error(`${label} ref must be an exact branch/tag ref or trailing-wildcard pattern`);\n }\n if (typeof workflowRef !== \"string\" || !isSafePattern(workflowRef, workflowRefPattern)) {\n throw new Error(\n `${label} workflowRef must identify a workflow file at an exact or trailing-wildcard ref`,\n );\n }\n if (\n jobWorkflowRef !== undefined &&\n (typeof jobWorkflowRef !== \"string\" || !isSafePattern(jobWorkflowRef, jobWorkflowRefPattern))\n ) {\n throw new Error(\n `${label} jobWorkflowRef must identify a reusable workflow at a full commit SHA or an exact/trailing-wildcard branch or tag ref`,\n );\n }\n const permissions = normalizePermissions(subjectValue.permissions, label);\n if (\n !Array.isArray(subjectValue.packages) ||\n subjectValue.packages.length === 0 ||\n subjectValue.packages.length > maximumPackagesPerSubject ||\n subjectValue.packages.some((packageName) => typeof packageName !== \"string\")\n ) {\n throw new Error(\n `${label} must define 1-${String(maximumPackagesPerSubject)} package patterns`,\n );\n }\n const packages = [...new Set(subjectValue.packages as string[])];\n for (const packagePattern of packages) {\n const slash = packagePattern.indexOf(\"/\");\n const scope = packagePattern.slice(0, slash);\n const packageSegment = packagePattern.slice(slash + 1);\n if (\n slash === -1 ||\n packagePattern.length > 214 ||\n !configuredScopes.includes(scope) ||\n (packageSegment !== \"*\" && !packageSegmentPattern.test(packageSegment))\n ) {\n throw new Error(`${label} contains an invalid or unconfigured package pattern`);\n }\n }\n return {\n repositoryId,\n repositoryOwnerId,\n ref,\n workflowRef,\n ...(jobWorkflowRef === undefined ? {} : { jobWorkflowRef }),\n permissions,\n packages,\n };\n });\n return { audience: value.audience, subjects };\n}\n\nexport function normalizeConfig(value: unknown): NormalizedConfig {\n if (!isObject(value)) throw new Error(\"configuration must be an object\");\n const { name, scopes: scopeValues, accountId, hostname, auth } = value;\n if (typeof name !== \"string\" || !workerNamePattern.test(name)) {\n throw new Error(\"name must be a lowercase Cloudflare resource name of at most 54 characters\");\n }\n\n if (\n accountId !== undefined &&\n (typeof accountId !== \"string\" || !accountIdPattern.test(accountId))\n ) {\n throw new Error(\"accountId must be a 32-character lowercase hexadecimal Cloudflare account ID\");\n }\n\n if (\n !Array.isArray(scopeValues) ||\n scopeValues.length === 0 ||\n scopeValues.some((scope) => typeof scope !== \"string\")\n ) {\n throw new Error(\"at least one package scope is required\");\n }\n\n const scopes = [...new Set(scopeValues as string[])];\n for (const scope of scopes) {\n if (!scopePattern.test(scope)) {\n throw new Error(`invalid package scope: ${scope}`);\n }\n }\n\n if (hostname !== undefined && (typeof hostname !== \"string\" || !hostnamePattern.test(hostname))) {\n throw new Error(\"hostname must be a valid DNS hostname without a scheme or path\");\n }\n\n if (!isObject(auth) || auth.provider !== \"secrets\") {\n throw new Error(\"unsupported authentication provider\");\n }\n\n const tokenValues = auth.tokens ?? [];\n if (!Array.isArray(tokenValues)) {\n throw new Error(\"authentication token bindings must be an array\");\n }\n\n const seenBindings = new Set<string>();\n const tokens = tokenValues.map((tokenValue) => {\n if (!isObject(tokenValue) || typeof tokenValue.binding !== \"string\") {\n throw new Error(\"authentication token binding must be an object with a binding name\");\n }\n const { binding, permissions: permissionValues } = tokenValue;\n if (!bindingPattern.test(binding)) {\n throw new Error(`invalid secret binding: ${binding}`);\n }\n if (reservedBindings.has(binding)) {\n throw new Error(`secret binding is reserved by pkgflare: ${binding}`);\n }\n if (seenBindings.has(binding)) {\n throw new Error(`duplicate secret binding: ${binding}`);\n }\n seenBindings.add(binding);\n\n const permissions = normalizePermissions(permissionValues, binding);\n\n return { binding, permissions };\n });\n\n const githubOidc =\n auth.githubOidc === undefined ? undefined : normalizeGithubOidc(auth.githubOidc, scopes);\n if (tokens.length === 0 && githubOidc === undefined) {\n throw new Error(\"at least one authentication method is required\");\n }\n\n const normalized: NormalizedConfig = {\n name,\n scopes,\n ...(accountId === undefined ? {} : { accountId }),\n ...(hostname === undefined ? {} : { hostname }),\n auth: {\n provider: \"secrets\",\n tokens,\n ...(githubOidc === undefined ? {} : { githubOidc }),\n },\n };\n if (new TextEncoder().encode(JSON.stringify(normalized)).byteLength > maximumRuntimeConfigBytes) {\n throw new Error(\"normalized configuration exceeds the 5 KiB Worker variable limit\");\n }\n return normalized;\n}\n"],"mappings":";AA+EA,IAAM,4BAA4B,IAAI;AAE/B,SAAS,aAAa,QAAwC;AACnE,SAAO;AACT;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts"],"sourcesContent":["export type Permission = \"read\" | \"publish\";\n\nexport interface SecretTokenConfig {\n binding: string;\n permissions: readonly Permission[];\n}\n\nexport interface GitHubOidcSubjectConfig {\n repositoryId: string;\n repositoryOwnerId: string;\n ref: string;\n workflowRef: string;\n jobWorkflowRef?: string;\n permissions: readonly Permission[];\n packages: readonly string[];\n}\n\nexport interface GitHubOidcConfig {\n audience: string;\n subjects: readonly GitHubOidcSubjectConfig[];\n}\n\nexport interface SecretsAuthConfig {\n provider: \"secrets\";\n tokens?: readonly SecretTokenConfig[];\n githubOidc?: GitHubOidcConfig;\n}\n\nexport interface PkgflareConfig {\n name: string;\n scopes: readonly string[];\n accountId?: string;\n hostname?: string;\n auth: SecretsAuthConfig;\n}\n\nexport interface NormalizedConfig {\n name: string;\n scopes: string[];\n accountId?: string;\n hostname?: string;\n auth: {\n provider: \"secrets\";\n tokens: Array<{\n binding: string;\n permissions: Permission[];\n }>;\n githubOidc?: {\n audience: string;\n subjects: Array<{\n repositoryId: string;\n repositoryOwnerId: string;\n ref: string;\n workflowRef: string;\n jobWorkflowRef?: string;\n permissions: Permission[];\n packages: string[];\n }>;\n };\n };\n}\n\nconst workerNamePattern = /^[a-z](?:[a-z0-9-]{0,52}[a-z0-9])?$/;\nconst accountIdPattern = /^[a-f0-9]{32}$/;\nconst scopePattern = /^@[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$/;\nconst bindingPattern = /^[A-Z][A-Z0-9_]*$/;\nconst hostnamePattern =\n /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$/;\nconst reservedBindings = new Set([\"PKGFLARE_DB\", \"PKGFLARE_BUCKET\", \"PKGFLARE_CONFIG\"]);\nconst githubIdPattern = /^[1-9][0-9]{0,19}$/;\nconst audiencePattern = /^[\\x21-\\x7e]{1,256}$/;\nconst refPattern = /^refs\\/(?:heads|tags)\\/[A-Za-z0-9._/-]+\\*?$/;\nconst workflowRefPattern =\n /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+\\/\\.github\\/workflows\\/[A-Za-z0-9_.-]+\\.ya?ml@refs\\/(?:heads|tags)\\/[A-Za-z0-9._/-]+\\*?$/;\nconst jobWorkflowRefPattern =\n /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+\\/\\.github\\/workflows\\/[A-Za-z0-9_.-]+\\.ya?ml@(?:refs\\/(?:heads|tags)\\/[A-Za-z0-9._/-]+\\*?|[0-9a-f]{40}|\\*)$/;\nconst jobWorkflowRefClaimPattern =\n /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+\\/\\.github\\/workflows\\/[A-Za-z0-9_.-]+\\.ya?ml@(?:refs\\/(?:heads|tags)\\/[A-Za-z0-9._/-]+|[0-9a-f]{40})$/;\nconst packageSegmentPattern = /^(?!\\.)(?:[a-z0-9._-]+)$/;\nconst maximumGithubSubjects = 128;\nconst maximumPackagesPerSubject = 128;\nconst maximumRuntimeConfigBytes = 5 * 1024;\n\nexport function defineConfig(config: PkgflareConfig): PkgflareConfig {\n return config;\n}\n\nexport function isValidGitHubJobWorkflowRefClaim(value: string): boolean {\n return jobWorkflowRefClaimPattern.test(value);\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction normalizePermissions(value: unknown, label: string): Permission[] {\n if (\n !Array.isArray(value) ||\n value.length === 0 ||\n value.some((permission) => permission !== \"read\" && permission !== \"publish\")\n ) {\n throw new Error(`invalid permissions for ${label}`);\n }\n return [...new Set(value)] as Permission[];\n}\n\nfunction isSafePattern(value: string, pattern: RegExp): boolean {\n if (!pattern.test(value)) return false;\n const wildcard = value.indexOf(\"*\");\n return wildcard === -1 || wildcard === value.length - 1;\n}\n\nfunction normalizeGithubOidc(\n value: unknown,\n configuredScopes: readonly string[],\n): NormalizedConfig[\"auth\"][\"githubOidc\"] {\n if (!isObject(value) || typeof value.audience !== \"string\") {\n throw new Error(\"githubOidc must define an audience and trusted subjects\");\n }\n if (!audiencePattern.test(value.audience)) {\n throw new Error(\"githubOidc audience must be 1-256 printable ASCII characters\");\n }\n if (\n !Array.isArray(value.subjects) ||\n value.subjects.length === 0 ||\n value.subjects.length > maximumGithubSubjects\n ) {\n throw new Error(`githubOidc must define 1-${String(maximumGithubSubjects)} subjects`);\n }\n\n const subjects = value.subjects.map((subjectValue, index) => {\n const label = `githubOidc subject ${String(index + 1)}`;\n if (!isObject(subjectValue)) throw new Error(`${label} must be an object`);\n const { repositoryId, repositoryOwnerId, ref, workflowRef, jobWorkflowRef } = subjectValue;\n if (typeof repositoryId !== \"string\" || !githubIdPattern.test(repositoryId)) {\n throw new Error(`${label} repositoryId must be a decimal GitHub repository ID`);\n }\n if (typeof repositoryOwnerId !== \"string\" || !githubIdPattern.test(repositoryOwnerId)) {\n throw new Error(`${label} repositoryOwnerId must be a decimal GitHub owner ID`);\n }\n if (typeof ref !== \"string\" || !isSafePattern(ref, refPattern)) {\n throw new Error(`${label} ref must be an exact branch/tag ref or trailing-wildcard pattern`);\n }\n if (typeof workflowRef !== \"string\" || !isSafePattern(workflowRef, workflowRefPattern)) {\n throw new Error(\n `${label} workflowRef must identify a workflow file at an exact or trailing-wildcard ref`,\n );\n }\n if (\n jobWorkflowRef !== undefined &&\n (typeof jobWorkflowRef !== \"string\" || !isSafePattern(jobWorkflowRef, jobWorkflowRefPattern))\n ) {\n throw new Error(\n `${label} jobWorkflowRef must identify one workflow at any valid ref (@*), a full commit SHA, or an exact/trailing-wildcard branch or tag ref`,\n );\n }\n const permissions = normalizePermissions(subjectValue.permissions, label);\n if (\n !Array.isArray(subjectValue.packages) ||\n subjectValue.packages.length === 0 ||\n subjectValue.packages.length > maximumPackagesPerSubject ||\n subjectValue.packages.some((packageName) => typeof packageName !== \"string\")\n ) {\n throw new Error(\n `${label} must define 1-${String(maximumPackagesPerSubject)} package patterns`,\n );\n }\n const packages = [...new Set(subjectValue.packages as string[])];\n for (const packagePattern of packages) {\n const slash = packagePattern.indexOf(\"/\");\n const scope = packagePattern.slice(0, slash);\n const packageSegment = packagePattern.slice(slash + 1);\n if (\n slash === -1 ||\n packagePattern.length > 214 ||\n !configuredScopes.includes(scope) ||\n (packageSegment !== \"*\" && !packageSegmentPattern.test(packageSegment))\n ) {\n throw new Error(`${label} contains an invalid or unconfigured package pattern`);\n }\n }\n return {\n repositoryId,\n repositoryOwnerId,\n ref,\n workflowRef,\n ...(jobWorkflowRef === undefined ? {} : { jobWorkflowRef }),\n permissions,\n packages,\n };\n });\n return { audience: value.audience, subjects };\n}\n\nexport function normalizeConfig(value: unknown): NormalizedConfig {\n if (!isObject(value)) throw new Error(\"configuration must be an object\");\n const { name, scopes: scopeValues, accountId, hostname, auth } = value;\n if (typeof name !== \"string\" || !workerNamePattern.test(name)) {\n throw new Error(\"name must be a lowercase Cloudflare resource name of at most 54 characters\");\n }\n\n if (\n accountId !== undefined &&\n (typeof accountId !== \"string\" || !accountIdPattern.test(accountId))\n ) {\n throw new Error(\"accountId must be a 32-character lowercase hexadecimal Cloudflare account ID\");\n }\n\n if (\n !Array.isArray(scopeValues) ||\n scopeValues.length === 0 ||\n scopeValues.some((scope) => typeof scope !== \"string\")\n ) {\n throw new Error(\"at least one package scope is required\");\n }\n\n const scopes = [...new Set(scopeValues as string[])];\n for (const scope of scopes) {\n if (!scopePattern.test(scope)) {\n throw new Error(`invalid package scope: ${scope}`);\n }\n }\n\n if (hostname !== undefined && (typeof hostname !== \"string\" || !hostnamePattern.test(hostname))) {\n throw new Error(\"hostname must be a valid DNS hostname without a scheme or path\");\n }\n\n if (!isObject(auth) || auth.provider !== \"secrets\") {\n throw new Error(\"unsupported authentication provider\");\n }\n\n const tokenValues = auth.tokens ?? [];\n if (!Array.isArray(tokenValues)) {\n throw new Error(\"authentication token bindings must be an array\");\n }\n\n const seenBindings = new Set<string>();\n const tokens = tokenValues.map((tokenValue) => {\n if (!isObject(tokenValue) || typeof tokenValue.binding !== \"string\") {\n throw new Error(\"authentication token binding must be an object with a binding name\");\n }\n const { binding, permissions: permissionValues } = tokenValue;\n if (!bindingPattern.test(binding)) {\n throw new Error(`invalid secret binding: ${binding}`);\n }\n if (reservedBindings.has(binding)) {\n throw new Error(`secret binding is reserved by pkgflare: ${binding}`);\n }\n if (seenBindings.has(binding)) {\n throw new Error(`duplicate secret binding: ${binding}`);\n }\n seenBindings.add(binding);\n\n const permissions = normalizePermissions(permissionValues, binding);\n\n return { binding, permissions };\n });\n\n const githubOidc =\n auth.githubOidc === undefined ? undefined : normalizeGithubOidc(auth.githubOidc, scopes);\n if (tokens.length === 0 && githubOidc === undefined) {\n throw new Error(\"at least one authentication method is required\");\n }\n\n const normalized: NormalizedConfig = {\n name,\n scopes,\n ...(accountId === undefined ? {} : { accountId }),\n ...(hostname === undefined ? {} : { hostname }),\n auth: {\n provider: \"secrets\",\n tokens,\n ...(githubOidc === undefined ? {} : { githubOidc }),\n },\n };\n if (new TextEncoder().encode(JSON.stringify(normalized)).byteLength > maximumRuntimeConfigBytes) {\n throw new Error(\"normalized configuration exceeds the 5 KiB Worker variable limit\");\n }\n return normalized;\n}\n"],"mappings":";AAiFA,IAAM,4BAA4B,IAAI;AAE/B,SAAS,aAAa,QAAwC;AACnE,SAAO;AACT;","names":[]}
|
package/dist/worker.js
CHANGED
|
@@ -2033,11 +2033,15 @@ var githubIdPattern = /^[1-9][0-9]{0,19}$/;
|
|
|
2033
2033
|
var audiencePattern = /^[\x21-\x7e]{1,256}$/;
|
|
2034
2034
|
var refPattern = /^refs\/(?:heads|tags)\/[A-Za-z0-9._/-]+\*?$/;
|
|
2035
2035
|
var workflowRefPattern = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/\.github\/workflows\/[A-Za-z0-9_.-]+\.ya?ml@refs\/(?:heads|tags)\/[A-Za-z0-9._/-]+\*?$/;
|
|
2036
|
-
var jobWorkflowRefPattern = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/\.github\/workflows\/[A-Za-z0-9_.-]+\.ya?ml@(?:refs\/(?:heads|tags)\/[A-Za-z0-9._/-]+\*?|[0-9a-f]{40})$/;
|
|
2036
|
+
var jobWorkflowRefPattern = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/\.github\/workflows\/[A-Za-z0-9_.-]+\.ya?ml@(?:refs\/(?:heads|tags)\/[A-Za-z0-9._/-]+\*?|[0-9a-f]{40}|\*)$/;
|
|
2037
|
+
var jobWorkflowRefClaimPattern = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/\.github\/workflows\/[A-Za-z0-9_.-]+\.ya?ml@(?:refs\/(?:heads|tags)\/[A-Za-z0-9._/-]+|[0-9a-f]{40})$/;
|
|
2037
2038
|
var packageSegmentPattern = /^(?!\.)(?:[a-z0-9._-]+)$/;
|
|
2038
2039
|
var maximumGithubSubjects = 128;
|
|
2039
2040
|
var maximumPackagesPerSubject = 128;
|
|
2040
2041
|
var maximumRuntimeConfigBytes = 5 * 1024;
|
|
2042
|
+
function isValidGitHubJobWorkflowRefClaim(value) {
|
|
2043
|
+
return jobWorkflowRefClaimPattern.test(value);
|
|
2044
|
+
}
|
|
2041
2045
|
function isObject(value) {
|
|
2042
2046
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2043
2047
|
}
|
|
@@ -2082,7 +2086,7 @@ function normalizeGithubOidc(value, configuredScopes) {
|
|
|
2082
2086
|
}
|
|
2083
2087
|
if (jobWorkflowRef !== void 0 && (typeof jobWorkflowRef !== "string" || !isSafePattern(jobWorkflowRef, jobWorkflowRefPattern))) {
|
|
2084
2088
|
throw new Error(
|
|
2085
|
-
`${label} jobWorkflowRef must identify
|
|
2089
|
+
`${label} jobWorkflowRef must identify one workflow at any valid ref (@*), a full commit SHA, or an exact/trailing-wildcard branch or tag ref`
|
|
2086
2090
|
);
|
|
2087
2091
|
}
|
|
2088
2092
|
const permissions = normalizePermissions(subjectValue.permissions, label);
|
|
@@ -3116,7 +3120,7 @@ async function fetchJwks() {
|
|
|
3116
3120
|
try {
|
|
3117
3121
|
response = await fetch(githubJwksUrl, {
|
|
3118
3122
|
headers: { accept: "application/json" },
|
|
3119
|
-
redirect: "
|
|
3123
|
+
redirect: "manual",
|
|
3120
3124
|
signal: AbortSignal.timeout(jwksTimeoutMilliseconds)
|
|
3121
3125
|
});
|
|
3122
3126
|
} catch {
|
|
@@ -3226,7 +3230,7 @@ async function authorizeGitHubOidc(token, context, required, packageName) {
|
|
|
3226
3230
|
}
|
|
3227
3231
|
if (eventName.includes("pull_request") || eventName === "merge_group") return false;
|
|
3228
3232
|
return configuration.subjects.some(
|
|
3229
|
-
(subject) => subject.repositoryId === repositoryId && subject.repositoryOwnerId === repositoryOwnerId && matchesPattern(ref, subject.ref) && matchesPattern(workflowRef, subject.workflowRef) && (subject.jobWorkflowRef === void 0 ? jobWorkflowRef === null : jobWorkflowRef !== null && matchesPattern(jobWorkflowRef, subject.jobWorkflowRef)) && grants(subject.permissions, required) && grantsPackage(subject.packages, packageName)
|
|
3233
|
+
(subject) => subject.repositoryId === repositoryId && subject.repositoryOwnerId === repositoryOwnerId && matchesPattern(ref, subject.ref) && matchesPattern(workflowRef, subject.workflowRef) && (subject.jobWorkflowRef === void 0 ? jobWorkflowRef === null : jobWorkflowRef !== null && isValidGitHubJobWorkflowRefClaim(jobWorkflowRef) && matchesPattern(jobWorkflowRef, subject.jobWorkflowRef)) && grants(subject.permissions, required) && grantsPackage(subject.packages, packageName)
|
|
3230
3234
|
);
|
|
3231
3235
|
}
|
|
3232
3236
|
|