-
Notifications
You must be signed in to change notification settings - Fork 6
feat(dns): manage Scriptable DNS scripts with ambient runtime types #104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| --- | ||
| "@bunny.net/cli": patch | ||
| "@bunny.net/scriptable-dns-types": patch | ||
| --- | ||
|
|
||
| feat(dns): manage Scriptable DNS scripts (`bunny dns scripts` init/create/deploy/attach/link/list) with ambient runtime types in `@bunny.net/scriptable-dns-types`; `dns records add` offers a static or script-computed answer for A/AAAA/CNAME/TXT |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,12 @@ | ||
| import { defineNamespace } from "../../core/define-namespace.ts"; | ||
| import { dnsRecordNamespace } from "./record/index.ts"; | ||
| import { dnsScriptsNamespace } from "./scripts/index.ts"; | ||
| import { dnsZoneHiddenAliases, dnsZoneNamespace } from "./zone/index.ts"; | ||
|
|
||
| // Hidden from help while experimental, matching the apps and registries namespaces. | ||
| export const dnsNamespace = defineNamespace("dns", false, [ | ||
| dnsRecordNamespace, | ||
| dnsZoneNamespace, | ||
| dnsScriptsNamespace, | ||
| ...dnsZoneHiddenAliases, | ||
| ]); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| import type { createComputeClient } from "@bunny.net/openapi-client"; | ||
| import type { components } from "@bunny.net/openapi-client/generated/compute.d.ts"; | ||
| import { UserError } from "../../../core/errors.ts"; | ||
| import { SCRIPT_TYPE_DNS } from "./constants.ts"; | ||
|
|
||
| export type ComputeClient = ReturnType<typeof createComputeClient>; | ||
| export type EdgeScript = components["schemas"]["EdgeScriptModel"]; | ||
|
|
||
| /** Fetch a single script by ID, throwing a UserError if it doesn't exist. */ | ||
| export async function fetchDnsScript( | ||
| client: ComputeClient, | ||
| id: number, | ||
| ): Promise<EdgeScript> { | ||
| const { data } = await client.GET("/compute/script/{id}", { | ||
| params: { path: { id } }, | ||
| }); | ||
| if (!data) throw new UserError(`DNS script ${id} not found.`); | ||
| return data; | ||
| } | ||
|
|
||
| /** Fetch all DNS scripts on the account, sorted by name. */ | ||
| export async function fetchDnsScripts( | ||
| client: ComputeClient, | ||
| ): Promise<EdgeScript[]> { | ||
| const { data } = await client.GET("/compute/script", { | ||
| params: { query: { type: [SCRIPT_TYPE_DNS] } }, | ||
| }); | ||
|
Comment on lines
+25
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The compute script list endpoint is paginated, but this call only reads the first page. Accounts past the API page size will see incomplete Context Used: CLAUDE.md (source)
Comment on lines
+25
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The compute list endpoint is paginated, but this helper only issues one GET with the DNS type filter. Accounts with more scripts than the first page will have Useful? React with 👍 / 👎. |
||
|
|
||
| return (data?.Items ?? []).sort((a, b) => | ||
| (a.Name ?? "").localeCompare(b.Name ?? ""), | ||
| ); | ||
| } | ||
|
|
||
| /** Create a DNS script (no linked pull zone), returning its ID and name. */ | ||
| export async function createDnsScript( | ||
| client: ComputeClient, | ||
| name: string, | ||
| ): Promise<{ id: number; name: string }> { | ||
| const { data } = await client.POST("/compute/script", { | ||
| body: { | ||
| Name: name, | ||
| ScriptType: SCRIPT_TYPE_DNS, | ||
| CreateLinkedPullZone: false, | ||
| }, | ||
| }); | ||
|
|
||
| if (!data || data.Id == null) { | ||
| throw new UserError("Failed to create DNS script."); | ||
| } | ||
| return { id: data.Id, name: data.Name ?? name }; | ||
| } | ||
|
|
||
| /** Upload code to a DNS script, creating an unpublished deployment. */ | ||
| export async function uploadCode( | ||
| client: ComputeClient, | ||
| id: number, | ||
| code: string, | ||
| ): Promise<void> { | ||
| await client.POST("/compute/script/{id}/code", { | ||
| params: { path: { id } }, | ||
| body: { Code: code }, | ||
| }); | ||
| } | ||
|
|
||
| /** Publish the latest uploaded code as the live release. */ | ||
| export async function publishScript( | ||
| client: ComputeClient, | ||
| id: number, | ||
| ): Promise<void> { | ||
| await client.POST("/compute/script/{id}/publish", { | ||
| params: { path: { id, uuid: null } }, | ||
| body: {}, | ||
| }); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fetchDnsScriptonly checks that the compute script exists.dns scripts link <id>can therefore write a regular Edge Script id into.bunny/dns-script.json, and laterdns scripts deploywill upload DNS code to that non-DNS script whiledns scripts attachcan create a SCRIPT record pointing at it. The helper should reject scripts whoseScriptTypeis notSCRIPT_TYPE_DNSbefore callers treat the id as a Scriptable DNS script.