@nohead/sdk 0.7.0 → 0.8.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/CHANGELOG.md CHANGED
@@ -5,6 +5,20 @@ Changes to `@nohead/sdk` that you can notice. Versions follow
5
5
  releases; a change that could break your code is a major one. Each release's
6
6
  section is its GitHub release's notes.
7
7
 
8
+ ## 0.8.0
9
+
10
+ - `Asset` has `file_url`, the file as uploaded, which downloads under its
11
+ filename, and for video and audio `media_url`, which plays it inline (in
12
+ `<video>` and `<audio>`, with range requests). Both are open, never expire
13
+ and are cached on a CDN, like `image_url`.
14
+
15
+ - `assets.downloadUrl` is removed, with the API's
16
+ `GET /v1/assets/{asset_id}/download-url` and its 2-minute links: use the
17
+ asset's `file_url`.
18
+
19
+ - An upload larger than the plan allows (10 MB a file on Free, 100 MB on paid
20
+ plans) is refused with a `PlanLimitExceededError` when it starts.
21
+
8
22
  ## 0.7.0
9
23
 
10
24
  - `assets.list({ q, kind })`: `q` finds assets whose filename or alt text
package/README.md CHANGED
@@ -372,6 +372,8 @@ Verify a webhook request, then use its event:
372
372
 
373
373
  ```ts
374
374
  // e.g. a Next.js route handler
375
+ import { revalidateTag } from "next/cache"
376
+
375
377
  export async function POST(request: Request) {
376
378
  const event = await nohead.webhooks.unwrap(
377
379
  await request.text(),
@@ -381,12 +383,14 @@ export async function POST(request: Request) {
381
383
  }
382
384
  )
383
385
  if (event.type === "record.published" && event.data.record) {
384
- revalidateTag(event.data.record.collection)
386
+ revalidateTag(event.data.record.collection, "max")
385
387
  }
386
388
  return new Response(null, { status: 204 })
387
389
  }
388
390
  ```
389
391
 
392
+ With `"max"`, Next.js serves the old version to the next request while it fetches the new one; pass `{ expire: 0 }` instead to drop it at once.
393
+
390
394
  Event types are those of the activity log (`record.published`, `record.restored`, `field.updated`, `asset.purged`, …), and a webhook subscribes to types or wildcards (`record.*`, `*`). Narrowing by `type` types `event.data`, and `unwrap<Post>` types the records and drafts in it. `unwrap` checks the signature and the timestamp (Standard Webhooks), and throws `WebhookVerificationError` if either is off. After `rotateSecret`, requests carry a signature for the old secret and the new one for 24 hours, so switch the receiver's secret within that day (or end it sooner with `webhooks.secrets.retire`). Pass the raw body: parsing and re-serializing JSON changes the bytes.
391
395
 
392
396
  A receiver that never calls the API can use `unwrapWebhook` from `@nohead/sdk/webhooks` without a client. Events can arrive more than once, so deduplicate by the `webhook-id` header.
@@ -414,7 +418,7 @@ response.headers.get("RateLimit-Remaining")
414
418
  | `collections.searchIndex` | `get`, `rebuild` |
415
419
  | `fields` | `list`, `get`, `create`, `update`, `delete`, `restore`, `order`, `reorder`, `removeAlias` |
416
420
  | `migrations` | `create`, `list`, `get`, `cancel` |
417
- | `assets` | `upload`, `createUpload`, `complete`, `list`, `get`, `update`, `delete`, `restore`, `purge`, `usage`, `downloadUrl` |
421
+ | `assets` | `upload`, `createUpload`, `complete`, `list`, `get`, `update`, `delete`, `restore`, `purge`, `usage` |
418
422
  | `webhooks` | `list`, `get`, `create`, `update`, `delete`, `restore`, `rotateSecret`, `test`, `unwrap` |
419
423
  | `webhooks.secrets` | `list`, `retire` |
420
424
  | `webhooks.deliveries` | `list`, `get`, `retry` |
@@ -8,10 +8,6 @@ export declare const OPERATIONS: {
8
8
  readonly method: "DELETE";
9
9
  readonly path: "/v1/assets/{asset_id}";
10
10
  };
11
- readonly assets_download_url: {
12
- readonly method: "GET";
13
- readonly path: "/v1/assets/{asset_id}/download-url";
14
- };
15
11
  readonly assets_get: {
16
12
  readonly method: "GET";
17
13
  readonly path: "/v1/assets/{asset_id}";
@@ -339,10 +335,6 @@ export interface Operations {
339
335
  data: T.AssetsDeleteData;
340
336
  response: T.AssetsDeleteResponse;
341
337
  };
342
- assets_download_url: {
343
- data: T.AssetsDownloadUrlData;
344
- response: T.AssetsDownloadUrlResponse;
345
- };
346
338
  assets_get: {
347
339
  data: T.AssetsGetData;
348
340
  response: T.AssetsGetResponse;
@@ -1,7 +1,6 @@
1
1
  export const OPERATIONS = {
2
2
  assets_complete: { method: "POST", path: "/v1/assets/{asset_id}/complete" },
3
3
  assets_delete: { method: "DELETE", path: "/v1/assets/{asset_id}" },
4
- assets_download_url: { method: "GET", path: "/v1/assets/{asset_id}/download-url" },
5
4
  assets_get: { method: "GET", path: "/v1/assets/{asset_id}" },
6
5
  assets_list: { method: "GET", path: "/v1/projects/{project_id}/assets" },
7
6
  assets_purge: { method: "POST", path: "/v1/assets/{asset_id}/purge" },
@@ -1 +1 @@
1
- export type { Actor, ApiKeyScope, Asset, AssetEventData, AssetField, AssetFieldConfiguration, AssetFieldCreate, AssetKind, AssetList, AssetProperties, AssetUpdate, AssetUploadCreate, AssetUploadTarget, AssetUsage, AssetWithUpload, AuditEvent, AuditEventList, BooleanField, BooleanFieldConfiguration, BooleanFieldCreate, Change, Collection, CollectionCreate, CollectionList, CollectionUpdate, DateField, DateFieldConfiguration, DateFieldCreate, DecimalField, DecimalFieldConfiguration, DecimalFieldCreate, DownloadUrl, Draft, DraftCreate, DraftEventData, DraftList, DraftSchedule, DraftScheduleUpdate, EnumField, EnumFieldConfiguration, EnumFieldCreate, Error, ErrorDetail, ErrorType, FeatureFlags, Field, FieldAliasEventData, FieldConfiguration, FieldCreate, FieldCreateProperties, FieldDefinition, FieldList, FieldMigration, FieldMigrationCounts, FieldMigrationList, FieldMigrationPreview, FieldMigrationRequest, FieldOrder, FieldProperties, FieldType, FieldUpdate, Health, IntegerField, IntegerFieldConfiguration, IntegerFieldCreate, JsonField, JsonFieldConfiguration, JsonFieldCreate, ListMeta, LongTextField, LongTextFieldConfiguration, LongTextFieldCreate, MergedDraft, NullableTimestamp, Principal, PublishedOnly, RecordBatch, RecordBatchRequest, RecordCount, RecordCreate, RecordData, RecordDiff, RecordEventData, RecordFilterValue, RecordList, RecordPublication, RecordRevision, RecordRevisionDetail, RecordRevisionList, RecordRevisionOperation, RecordRevisionProperties, RecordSchedule, RecordScheduleUpdate, RecordWrite, RelationField, RelationFieldConfiguration, RelationFieldCreate, RequestId, RevertPreview, RichTextField, RichTextFieldConfiguration, RichTextFieldCreate, ScheduledChange, ScheduledChangeList, Schema, SchemaChange, SchemaChangeDetail, SchemaChangeList, SchemaChangeProperties, SchemaDefinition, SchemaEventData, SearchIndex, SearchResults, TextField, TextFieldConfiguration, TextFieldCreate, TimeFilter, Timestamp, Via, Webhook, WebhookCreate, WebhookDelivery, WebhookDeliveryDetail, WebhookDeliveryList, WebhookDeliveryProperties, WebhookEventPayload, WebhookEventType, WebhookList, WebhookProperties, WebhookSecret, WebhookSecretList, WebhookSecretProperties, WebhookSecretWithValue, WebhookSubscription, WebhookTestEventData, WebhookUpdate, WebhookWithSecret, } from "./types.gen.ts";
1
+ export type { Actor, ApiKeyScope, Asset, AssetEventData, AssetField, AssetFieldConfiguration, AssetFieldCreate, AssetKind, AssetList, AssetProperties, AssetUpdate, AssetUploadCreate, AssetUploadTarget, AssetUsage, AssetWithUpload, AuditEvent, AuditEventList, BooleanField, BooleanFieldConfiguration, BooleanFieldCreate, Change, Collection, CollectionCreate, CollectionList, CollectionUpdate, DateField, DateFieldConfiguration, DateFieldCreate, DecimalField, DecimalFieldConfiguration, DecimalFieldCreate, Draft, DraftCreate, DraftEventData, DraftList, DraftSchedule, DraftScheduleUpdate, EnumField, EnumFieldConfiguration, EnumFieldCreate, Error, ErrorDetail, ErrorType, FeatureFlags, Field, FieldAliasEventData, FieldConfiguration, FieldCreate, FieldCreateProperties, FieldDefinition, FieldList, FieldMigration, FieldMigrationCounts, FieldMigrationList, FieldMigrationPreview, FieldMigrationRequest, FieldOrder, FieldProperties, FieldType, FieldUpdate, Health, IntegerField, IntegerFieldConfiguration, IntegerFieldCreate, JsonField, JsonFieldConfiguration, JsonFieldCreate, ListMeta, LongTextField, LongTextFieldConfiguration, LongTextFieldCreate, MergedDraft, NullableTimestamp, Principal, PublishedOnly, RecordBatch, RecordBatchRequest, RecordCount, RecordCreate, RecordData, RecordDiff, RecordEventData, RecordFilterValue, RecordList, RecordPublication, RecordRevision, RecordRevisionDetail, RecordRevisionList, RecordRevisionOperation, RecordRevisionProperties, RecordSchedule, RecordScheduleUpdate, RecordWrite, RelationField, RelationFieldConfiguration, RelationFieldCreate, RequestId, RevertPreview, RichTextField, RichTextFieldConfiguration, RichTextFieldCreate, ScheduledChange, ScheduledChangeList, Schema, SchemaChange, SchemaChangeDetail, SchemaChangeList, SchemaChangeProperties, SchemaDefinition, SchemaEventData, SearchIndex, SearchResults, TextField, TextFieldConfiguration, TextFieldCreate, TimeFilter, Timestamp, Via, Webhook, WebhookCreate, WebhookDelivery, WebhookDeliveryDetail, WebhookDeliveryList, WebhookDeliveryProperties, WebhookEventPayload, WebhookEventType, WebhookList, WebhookProperties, WebhookSecret, WebhookSecretList, WebhookSecretProperties, WebhookSecretWithValue, WebhookSubscription, WebhookTestEventData, WebhookUpdate, WebhookWithSecret, } from "./types.gen.ts";
@@ -1539,6 +1539,22 @@ export type AssetProperties = {
1539
1539
  * The URL of a small rendition (fits in 640×640, WebP), for ready images and SVGs (rasterized; SVGs have no `image_url`), deleted ones included until they are purged; null otherwise.
1540
1540
  */
1541
1541
  preview_url: string | null;
1542
+ /**
1543
+ * The URL of the file as uploaded, for ready assets of any type,
1544
+ * deleted ones included until they are purged; null otherwise. It
1545
+ * downloads the file under its `filename` (a rename applies within a
1546
+ * minute or so), is open and never expires, and is cached on a CDN.
1547
+ *
1548
+ */
1549
+ file_url: string | null;
1550
+ /**
1551
+ * The URL that plays a ready video or audio file inline, for
1552
+ * `<video>` and `<audio>` (with range requests, so players can seek),
1553
+ * deleted ones included until they are purged; null for other types.
1554
+ * Open, never expiring and cached on a CDN, like `file_url`.
1555
+ *
1556
+ */
1557
+ media_url: string | null;
1542
1558
  uploaded_at: NullableTimestamp;
1543
1559
  created_at: Timestamp;
1544
1560
  updated_at: Timestamp;
@@ -1569,17 +1585,11 @@ export type AssetUsage = {
1569
1585
  fields: Array<string>;
1570
1586
  }>;
1571
1587
  };
1572
- export type DownloadUrl = {
1573
- object: 'download_url';
1574
- asset_id: string;
1575
- url: string;
1576
- expires_at: Timestamp;
1577
- };
1578
1588
  export type AssetUploadCreate = {
1579
1589
  filename: string;
1580
1590
  content_type: string;
1581
1591
  /**
1582
- * Exact size of the file in bytes (at most 100 MB by default).
1592
+ * Exact size of the file in bytes, at most the plan's largest upload (10 MB on Free, 100 MB on paid plans).
1583
1593
  */
1584
1594
  byte_size: number;
1585
1595
  };
@@ -5741,55 +5751,6 @@ export type AssetsUpdateResponses = {
5741
5751
  200: Asset;
5742
5752
  };
5743
5753
  export type AssetsUpdateResponse = AssetsUpdateResponses[keyof AssetsUpdateResponses];
5744
- export type AssetsDownloadUrlData = {
5745
- body?: never;
5746
- path: {
5747
- asset_id: string;
5748
- };
5749
- query?: never;
5750
- url: '/v1/assets/{asset_id}/download-url';
5751
- };
5752
- export type AssetsDownloadUrlErrors = {
5753
- /**
5754
- * The request was malformed: unparseable JSON, an invalid query parameter, or a body key the operation doesn't take (detail code `unknown_parameter`, naming the key).
5755
- */
5756
- 400: Error;
5757
- /**
5758
- * Authentication is missing or invalid.
5759
- */
5760
- 401: Error;
5761
- /**
5762
- * The caller is not allowed to perform this action.
5763
- */
5764
- 403: Error;
5765
- /**
5766
- * The resource does not exist or is not visible to the caller.
5767
- */
5768
- 404: Error;
5769
- /**
5770
- * The request conflicts with current state.
5771
- */
5772
- 409: Error;
5773
- /**
5774
- * Too many requests for this API key or user (or, with failing
5775
- * credentials, this IP address). A published-only key is counted per
5776
- * client IP. Wait `Retry-After` seconds; retries with the same `Idempotency-Key`
5777
- * are safe. On the Free plan, an organization's API keys are also
5778
- * refused once its API requests reach the month's limit, with a
5779
- * `plan_limit` detail (`field` `api_requests`, `usage` and `limit`),
5780
- * until the next month (UTC) or an upgrade.
5781
- *
5782
- */
5783
- 429: Error;
5784
- };
5785
- export type AssetsDownloadUrlError = AssetsDownloadUrlErrors[keyof AssetsDownloadUrlErrors];
5786
- export type AssetsDownloadUrlResponses = {
5787
- /**
5788
- * The download URL.
5789
- */
5790
- 200: DownloadUrl;
5791
- };
5792
- export type AssetsDownloadUrlResponse = AssetsDownloadUrlResponses[keyof AssetsDownloadUrlResponses];
5793
5754
  export type AssetsUsageData = {
5794
5755
  body?: never;
5795
5756
  path: {
@@ -1,6 +1,6 @@
1
1
  import type { APIPromise, PagePromise } from "../api-promise.ts";
2
2
  import type { RequestOptions } from "../core.ts";
3
- import type { Asset, AssetUpdate, AssetUploadCreate, AssetWithUpload, AssetUsage, DownloadUrl } from "../generated/types.gen.ts";
3
+ import type { Asset, AssetUpdate, AssetUploadCreate, AssetWithUpload, AssetUsage } from "../generated/types.gen.ts";
4
4
  import type { AssetListParams } from "../types.ts";
5
5
  import { Resource } from "./resource.ts";
6
6
  /** What `assets.upload` accepts. A stream needs `byte_size`. */
@@ -69,6 +69,4 @@ export declare class Assets extends Resource {
69
69
  * updated with the fields that use it (`uses`). Needs `records:read` too.
70
70
  */
71
71
  usage(asset: string, options?: RequestOptions): APIPromise<AssetUsage>;
72
- /** A link to download the original file (`url`), valid for 2 minutes. */
73
- downloadUrl(asset: string, options?: RequestOptions): APIPromise<DownloadUrl>;
74
72
  }
@@ -159,10 +159,6 @@ export class Assets extends Resource {
159
159
  usage(asset, options) {
160
160
  return this.core.request("assets_usage", { path: { asset_id: asset } }, options);
161
161
  }
162
- /** A link to download the original file (`url`), valid for 2 minutes. */
163
- downloadUrl(asset, options) {
164
- return this.core.request("assets_download_url", { path: { asset_id: asset } }, options);
165
- }
166
162
  }
167
163
  function sizeOf(file) {
168
164
  if (file instanceof Blob)
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "0.7.0";
1
+ export declare const VERSION = "0.8.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "0.7.0";
1
+ export const VERSION = "0.8.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nohead/sdk",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Official TypeScript SDK for the Nohead API",
5
5
  "license": "MIT",
6
6
  "homepage": "https://nohead.io",