Skip to content

Commit eb5787a

Browse files
docs: rebrand QURL → qURL across user-facing surfaces (#58)
## Summary Updates the brand spelling to **qURL** (case-sensitive) across user-visible strings, documentation, and JSDoc comments. ## Why The product brand is `qURL`. README, the npm-published `package.json` `description`, JSDoc surfaces (which IDEs and TypeDoc render verbatim), and the test reporter output were inconsistently spelled `QURL`. This brings them in line. ## What changed - `README.md`, `CLAUDE.md`, `package.json` description - JSDoc `/** … */` comments in `src/{client,errors,types}.ts` - Test description strings (`it("creates a qURL", …)`) for consistent reporter output - CI workflow Slack notify header ## What was intentionally not changed Identifier-style references kept as-is to preserve the public API: - Class names: `QURL`, `QURLClient`, `QURLError`, `QURLErrorData`, plus all error subclasses (`AuthenticationError`, `AuthorizationError`, `NotFoundError`, `ValidationError`, `RateLimitError`, `ServerError`, `NetworkError`, `TimeoutError`) - Field names: `qurl_id`, `qurl_link`, `qurl_site`, `qurl_count`, `qurls`, plus quota fields - npm package name (`@layerv/qurl`) - Import statements and CJS/ESM smoke tests (which assert on `typeof QURLClient === "function"`) - `contract/openapi.snapshot.yaml` — synced from upstream OpenAPI spec; will pick up the rebrand when upstream lands A few test mock fixtures keep `"detail": "QURL not found"` because they mirror upstream API responses; these will be updated alongside the upstream qurl-service rebrand to keep mocks accurate. ## Test plan - [x] `npm run build` passes (ESM + CJS) - [x] `npm run format:check` clean - [x] `npm test` — 67/67 vitest tests pass - [x] Grep verification: no `QURL` / `Qurl` left in prose contexts --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
1 parent ae96ad7 commit eb5787a

8 files changed

Lines changed: 42 additions & 40 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ jobs:
6666
*) TRIGGER_TEXT="$GH_EVENT_NAME" ;;
6767
esac
6868
69-
HEADER="QURL TypeScript SDK Build"
69+
HEADER="qURL TypeScript SDK Build"
7070
case "$TEST_RESULT" in
7171
success) COLOR="#36a64f"; EMOJI=":white_check_mark:"; STATUS_TEXT="successful" ;;
7272
failure) COLOR="#dc3545"; EMOJI=":x:"; STATUS_TEXT="failed" ;;

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
## Project
99

10-
TypeScript SDK for the QURL API (`npm install @layerv/qurl`). Extracted from `layervai/qurl-integrations`.
10+
TypeScript SDK for the qURL API (`npm install @layerv/qurl`). Extracted from `layervai/qurl-integrations`.
1111

1212
## Commands
1313

README.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
[![CI](https://github.com/layervai/qurl-typescript/actions/workflows/ci.yml/badge.svg)](https://github.com/layervai/qurl-typescript/actions/workflows/ci.yml)
55
[![License](https://img.shields.io/github/license/layervai/qurl-typescript)](LICENSE)
66

7-
TypeScript SDK for the [QURL API](https://docs.layerv.ai) — secure, time-limited access links for AI agents.
7+
TypeScript SDK for the [qURL™ API](https://docs.layerv.ai) — secure, time-limited access links for AI agents.
88

9-
## Why QURL?
9+
> **Quantum URL (qURL)** · The internet has a hidden layer. This is how you enter.
1010
11-
AI agents need to access protected resources — APIs, databases, internal tools — but giving them permanent credentials is a security risk. QURL creates time-limited, auditable access links that expire automatically. The SDK handles authentication, retries, pagination, and error handling so you can focus on your agent logic.
11+
## Why qURL?
12+
13+
AI agents need to access protected resources — APIs, databases, internal tools — but giving them permanent credentials is a security risk. qURL creates time-limited, auditable access links that expire automatically. The SDK handles authentication, retries, pagination, and error handling so you can focus on your agent logic.
1214

1315
## Installation
1416

@@ -57,12 +59,12 @@ console.log(`Access granted to ${access.target_url} for ${access.access_grant?.e
5759
| Method | Description |
5860
|--------|-------------|
5961
| `create(input)` | Create a protected link |
60-
| `get(id)` | Get QURL details |
61-
| `list(input?)` | List QURLs (single page) |
62-
| `listAll(input?)` | Iterate all QURLs (auto-paginating) |
63-
| `delete(id)` | Revoke a QURL |
62+
| `get(id)` | Get qURL details |
63+
| `list(input?)` | List qURLs (single page) |
64+
| `listAll(input?)` | Iterate all qURLs (auto-paginating) |
65+
| `delete(id)` | Revoke a qURL |
6466
| `extend(id, input)` | Extend expiration |
65-
| `update(id, input)` | Update QURL properties |
67+
| `update(id, input)` | Update qURL properties |
6668
| `mintLink(id, input?)` | Mint a new access link |
6769
| `resolve(input)` | Resolve token + open firewall |
6870
| `getQuota()` | Get quota/usage info |

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@layerv/qurl",
33
"version": "0.1.0",
4-
"description": "TypeScript SDK for the QURL API - secure, time-limited access links",
4+
"description": "TypeScript SDK for the qURL™ API secure, time-limited access links. Quantum URL is how you enter the hidden layer of the internet.",
55
"type": "module",
66
"sideEffects": false,
77
"main": "./dist/cjs/index.js",

src/client.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
import { mockFetch, createClient } from "./__tests__/test-helpers.js";
1515

1616
describe("QURLClient", () => {
17-
it("creates a QURL", async () => {
17+
it("creates a qURL", async () => {
1818
const fetch = mockFetch({
1919
status: 201,
2020
body: {
@@ -42,7 +42,7 @@ describe("QURLClient", () => {
4242
);
4343
});
4444

45-
it("gets a QURL with access tokens", async () => {
45+
it("gets a qURL with access tokens", async () => {
4646
const fetch = mockFetch({
4747
status: 200,
4848
body: {
@@ -93,7 +93,7 @@ describe("QURLClient", () => {
9393
expect(result.access_tokens![1].one_time_use).toBe(true);
9494
});
9595

96-
it("gets a QURL without access tokens", async () => {
96+
it("gets a qURL without access tokens", async () => {
9797
const fetch = mockFetch({
9898
status: 200,
9999
body: {
@@ -115,7 +115,7 @@ describe("QURLClient", () => {
115115
expect(result.access_tokens).toBeUndefined();
116116
});
117117

118-
it("lists QURLs", async () => {
118+
it("lists qURLs", async () => {
119119
const fetch = mockFetch({
120120
status: 200,
121121
body: {
@@ -157,14 +157,14 @@ describe("QURLClient", () => {
157157
);
158158
});
159159

160-
it("deletes a QURL", async () => {
160+
it("deletes a qURL", async () => {
161161
const fetch = mockFetch({ status: 204 });
162162
const client = createClient(fetch);
163163

164164
await expect(client.delete("r_abc123def45")).resolves.toBeUndefined();
165165
});
166166

167-
it("extends a QURL", async () => {
167+
it("extends a qURL", async () => {
168168
const fetch = mockFetch({
169169
status: 200,
170170
body: {
@@ -184,7 +184,7 @@ describe("QURLClient", () => {
184184
expect(result.expires_at).toBe("2026-03-20T10:00:00Z");
185185
});
186186

187-
it("updates a QURL description", async () => {
187+
it("updates a qURL description", async () => {
188188
const fetch = mockFetch({
189189
status: 200,
190190
body: {
@@ -248,7 +248,7 @@ describe("QURLClient", () => {
248248
expect((result as Record<string, unknown>).qurls).toBeUndefined();
249249
});
250250

251-
it("resolves a QURL token", async () => {
251+
it("resolves a qURL token", async () => {
252252
const fetch = mockFetch({
253253
status: 200,
254254
body: {

src/client.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ interface ApiErrorEnvelope {
4848
meta?: { request_id?: string };
4949
}
5050

51-
/** QURL API client. */
51+
/** qURL API client. */
5252
export class QURLClient {
5353
private readonly baseUrl: string;
5454
private readonly apiKey: string;
@@ -113,7 +113,7 @@ export class QURLClient {
113113

114114
// --- Public API ---
115115

116-
/** Create a new QURL. */
116+
/** Create a new qURL. */
117117
async create(input: CreateInput): Promise<CreateOutput> {
118118
return this.request<CreateOutput>("POST", "/v1/qurls", input);
119119
}
@@ -128,7 +128,7 @@ export class QURLClient {
128128
}
129129

130130
/**
131-
* Lists protected URLs. Each QURL groups access tokens sharing the same target URL.
131+
* Lists protected URLs. Each qURL groups access tokens sharing the same target URL.
132132
* Note: list items include qurl_count but not access_tokens (too expensive at scale).
133133
*/
134134
async list(input: ListInput = {}): Promise<ListOutput> {
@@ -149,7 +149,7 @@ export class QURLClient {
149149
};
150150
}
151151

152-
/** Iterate over all QURLs, automatically paginating. */
152+
/** Iterate over all qURLs, automatically paginating. */
153153
async *listAll(input: Omit<ListInput, "cursor"> = {}): AsyncGenerator<QURL, void, undefined> {
154154
let cursor: string | undefined;
155155
do {
@@ -161,21 +161,21 @@ export class QURLClient {
161161
} while (cursor);
162162
}
163163

164-
/** Delete (revoke) a QURL. */
164+
/** Delete (revoke) a qURL. */
165165
async delete(id: string): Promise<void> {
166166
await this.rawRequest("DELETE", `/v1/qurls/${encodeURIComponent(id)}`);
167167
}
168168

169169
/**
170-
* Extend a QURL's expiration.
170+
* Extend a qURL's expiration.
171171
*
172172
* Convenience method — equivalent to `update(id, input)`.
173173
*/
174174
async extend(id: string, input: ExtendInput): Promise<QURL> {
175175
return this.update(id, input);
176176
}
177177

178-
/** Update a QURL — extend expiration, change description, etc. */
178+
/** Update a qURL — extend expiration, change description, etc. */
179179
async update(id: string, input: UpdateInput): Promise<QURL> {
180180
const raw = await this.request<QURL & { qurls?: AccessToken[] }>(
181181
"PATCH",
@@ -185,13 +185,13 @@ export class QURLClient {
185185
return QURLClient.mapQurlsField(raw);
186186
}
187187

188-
/** Mint a new access link for a QURL. */
188+
/** Mint a new access link for a qURL. */
189189
async mintLink(id: string, input?: MintInput): Promise<MintOutput> {
190190
return this.request<MintOutput>("POST", `/v1/qurls/${encodeURIComponent(id)}/mint_link`, input);
191191
}
192192

193193
/**
194-
* Resolve a QURL access token (headless).
194+
* Resolve a qURL access token (headless).
195195
*
196196
* Triggers an NHP knock to open firewall access for the caller's IP.
197197
* Requires `qurl:resolve` scope on the API key.

src/errors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { QURLErrorData } from "./types.js";
22

3-
/** Base error thrown by the QURL API client. Catch this to handle all SDK errors. */
3+
/** Base error thrown by the qURL API client. Catch this to handle all SDK errors. */
44
export class QURLError extends Error {
55
readonly status: number;
66
readonly code: string;

src/types.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** Access control policy for a QURL. */
1+
/** Access control policy for a qURL. */
22
export interface AccessPolicy {
33
ip_allowlist?: string[];
44
ip_denylist?: string[];
@@ -8,7 +8,7 @@ export interface AccessPolicy {
88
user_agent_deny_regex?: string;
99
}
1010

11-
/** An individual access token within a QURL. */
11+
/** An individual access token within a qURL. */
1212
export interface AccessToken {
1313
/** Display identifier for this token (q_ prefix). */
1414
qurl_id: string;
@@ -24,7 +24,7 @@ export interface AccessToken {
2424
expires_at: string;
2525
}
2626

27-
/** A QURL resource as returned by the API. */
27+
/** A qURL resource as returned by the API. */
2828
export interface QURL {
2929
resource_id: string;
3030
target_url: string;
@@ -39,7 +39,7 @@ export interface QURL {
3939
expires_at?: string;
4040
}
4141

42-
/** Input for creating a QURL. */
42+
/** Input for creating a qURL. */
4343
export interface CreateInput {
4444
target_url: string;
4545
expires_in?: string;
@@ -51,7 +51,7 @@ export interface CreateInput {
5151
custom_domain?: string;
5252
}
5353

54-
/** Response from creating a QURL. */
54+
/** Response from creating a qURL. */
5555
export interface CreateOutput {
5656
resource_id: string;
5757
qurl_link: string;
@@ -60,7 +60,7 @@ export interface CreateOutput {
6060
one_time_use?: boolean;
6161
}
6262

63-
/** Input for listing QURLs. */
63+
/** Input for listing qURLs. */
6464
export interface ListInput {
6565
limit?: number;
6666
cursor?: string;
@@ -69,20 +69,20 @@ export interface ListInput {
6969
sort?: string;
7070
}
7171

72-
/** Response from listing QURLs. */
72+
/** Response from listing qURLs. */
7373
export interface ListOutput {
7474
qurls: QURL[];
7575
next_cursor?: string;
7676
has_more: boolean;
7777
}
7878

79-
/** Input for extending a QURL. */
79+
/** Input for extending a qURL. */
8080
export interface ExtendInput {
8181
extend_by?: string;
8282
expires_at?: string;
8383
}
8484

85-
/** Input for updating a QURL — extend expiration, change description, etc. */
85+
/** Input for updating a qURL — extend expiration, change description, etc. */
8686
export interface UpdateInput {
8787
extend_by?: string;
8888
expires_at?: string;
@@ -101,7 +101,7 @@ export interface MintOutput {
101101
expires_at?: string;
102102
}
103103

104-
/** Input for headless QURL resolution. */
104+
/** Input for headless qURL resolution. */
105105
export interface ResolveInput {
106106
access_token: string;
107107
}
@@ -141,7 +141,7 @@ export interface Quota {
141141
};
142142
}
143143

144-
/** API error from the QURL service (RFC 7807). */
144+
/** API error from the qURL service (RFC 7807). */
145145
export interface QURLErrorData {
146146
status: number;
147147
code: string;

0 commit comments

Comments
 (0)