nohead 0.4.0 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 747275a28bad0e0410f52109f1bac03d8d703fedccafe3110f21ae904421d511
4
- data.tar.gz: 696d827a38b169e1a047b38a40d9263417cff3f111cec74d825a77236072a62c
3
+ metadata.gz: e94f698ee3cb6906c1b21535666bdefc57f6d864dbad5eb3436c9e0a7a4bff2f
4
+ data.tar.gz: a47d275d02c1b5111b0eadc5f14dedf2a201c5fdcf01ae0eaba306c3bdb87ad2
5
5
  SHA512:
6
- metadata.gz: e82adbab22c4ea949feccc1c347926b5c2a6795f087b02a8915255f4c7a49f56b53e088ae4b8579374c3db27a59c8bf12c428970d28f83124f047f120c08c7bb
7
- data.tar.gz: 6c0c8b4dfc63a7eb8d89cc76030e7cf9797ba28541bd677b1da117b7975039d5b3742677230057ff29c4826ac7abf47acd1e3cfba3b38bb84809c4fa4cf233da
6
+ metadata.gz: bbac1644f34a8ea9ff5b41b342facdfea9df8de606cca48e00fcbde9adcb0d3564c65973f43f087d8d6acc4f9443057107c7eb244ab47f557d96bb6b1f1d14cb
7
+ data.tar.gz: e650ba515324f59b5cd141534be18d49ae4530e5fe89d7d19bf3aac1e2a6c97fc502b6094b06e43e580b771391d110ad72e32c166235eab6492b8592aaba4a0c
data/CHANGELOG.md CHANGED
@@ -5,6 +5,25 @@ Changes to the `nohead` gem 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.5.0
9
+
10
+ - **Breaking:** field migrations are created under their collection:
11
+ `migrations.create(collection, field_id:, ..., dry_run: true)`
12
+ (`POST /v1/collections/{collection_id}/migrations`) replaces
13
+ `fields.migrate(field, ...)`. It returns a preview for a dry run, and the
14
+ FieldMigration otherwise.
15
+ - **Breaking:** `drafts.list` no longer takes `record_id:`; a record's draft
16
+ is `records.drafts(record)`.
17
+ - **Breaking:** `assets.list(content_type:)` takes one MIME type or `type/*`
18
+ wildcard (`"image/*"`), or an Array of them, sent as
19
+ `filter[content_type][in]` (an empty Array is any type). A
20
+ comma-separated string is no longer several types.
21
+ - **Breaking:** `audit_events.list` sorts by `created_at` or `-created_at`
22
+ (the default; was `id` and `-id`), and `records.list` no longer sorts by
23
+ `id`.
24
+ - Webhook events always carry `actor` and `via`, and `via` is no longer
25
+ `import` or `migration`.
26
+
8
27
  ## 0.4.0
9
28
 
10
29
  - **Breaking:** a field's `api_key` is its `key` (in fields, their aliases,
data/README.md CHANGED
@@ -95,7 +95,7 @@ nohead.drafts.merge(draft.id) # or drafts.schedule(draft.id, merge_at: ...)
95
95
 
96
96
  - A record has at most one draft; starting a second raises `Nohead::ConflictError` (detail code `draft_exists`, with its `draft_id`).
97
97
  - A merge changes content only: a live record stays live, an unpublished one unpublished. Publishing a live record with a pending draft raises `ConflictError` (`draft_pending`).
98
- - `records.drafts(id)` lists a record's draft, and `drafts.list(collection, record_id: ...)` a collection's (`record_id` takes up to 100 IDs).
98
+ - `records.drafts(id)` lists a record's draft, and `drafts.list(collection)` a collection's.
99
99
  - `drafts.discard` deletes one for good.
100
100
 
101
101
  ## Pagination
@@ -233,8 +233,8 @@ nohead.collections.create(name: "Posts", slug: "posts",
233
233
  nohead.fields.create("posts", name: "Summary", key: "summary", type: "long_text")
234
234
 
235
235
  # Changes that rewrite records go through a migration; preview first
236
- preview = nohead.fields.migrate("fld_...", type: "long_text", dry_run: true)
237
- migration = nohead.fields.migrate("fld_...", type: "long_text")
236
+ preview = nohead.migrations.create("posts", field_id: "fld_...", type: "long_text", dry_run: true)
237
+ migration = nohead.migrations.create("posts", field_id: "fld_...", type: "long_text")
238
238
  nohead.migrations.get(migration.id)
239
239
  ```
240
240
 
@@ -279,8 +279,8 @@ The API's resources come back as `Nohead::NoheadObject`s.
279
279
  | `collections` | `list`, `get`, `create`, `update`, `delete`, `restore`, `schema` |
280
280
  | `collections.schema_changes` | `list`, `get` |
281
281
  | `collections.search_index` | `get`, `rebuild` |
282
- | `fields` | `list`, `get`, `create`, `update`, `delete`, `restore`, `order`, `reorder`, `remove_alias`, `migrate` |
283
- | `migrations` | `list`, `get`, `cancel` |
282
+ | `fields` | `list`, `get`, `create`, `update`, `delete`, `restore`, `order`, `reorder`, `remove_alias` |
283
+ | `migrations` | `create`, `list`, `get`, `cancel` |
284
284
  | `assets` | `upload`, `create_upload`, `complete`, `list`, `get`, `delete`, `restore`, `purge`, `usage`, `image_url`, `download_url` |
285
285
  | `webhooks` | `list`, `get`, `create`, `update`, `delete`, `restore`, `rotate_secret`, `test`, `unwrap` |
286
286
  | `webhooks.secrets` | `list`, `retire` |
@@ -37,7 +37,6 @@ module Nohead
37
37
  "fields_get" => ["GET", "/v1/fields/{field_id}"],
38
38
  "fields_get_order" => ["GET", "/v1/collections/{collection_id}/field-order"],
39
39
  "fields_list" => ["GET", "/v1/collections/{collection_id}/fields"],
40
- "fields_migrate" => ["POST", "/v1/fields/{field_id}/migrations"],
41
40
  "fields_remove_alias" => ["DELETE", "/v1/fields/{field_id}/aliases/{alias}"],
42
41
  "fields_reorder" => ["PUT", "/v1/collections/{collection_id}/field-order"],
43
42
  "fields_restore" => ["POST", "/v1/fields/{field_id}/restore"],
@@ -45,6 +44,7 @@ module Nohead
45
44
  "health_check" => ["GET", "/v1/health"],
46
45
  "me_get" => ["GET", "/v1/me"],
47
46
  "migrations_cancel" => ["POST", "/v1/migrations/{migration_id}/cancel"],
47
+ "migrations_create" => ["POST", "/v1/collections/{collection_id}/migrations"],
48
48
  "migrations_get" => ["GET", "/v1/migrations/{migration_id}"],
49
49
  "migrations_list" => ["GET", "/v1/collections/{collection_id}/migrations"],
50
50
  "projects_search" => ["GET", "/v1/projects/{project_id}/search"],
@@ -54,10 +54,12 @@ module Nohead
54
54
  @client.request("assets_complete", path: { asset_id: asset }, idempotency_key: idempotency_key)
55
55
  end
56
56
 
57
- # `content_type` lists only assets of those MIME types or `type/*`
58
- # wildcards (["image/*", "application/pdf"]), for example the ones an
59
- # asset field accepts (its `accepted_types`).
57
+ # `content_type` lists only assets of a MIME type or `type/*` wildcard
58
+ # ("image/*"), or of several (["image/*", "application/pdf"]), for
59
+ # example the ones an asset field accepts (its `accepted_types`; an
60
+ # empty list, like a field's, means any type).
60
61
  def list(content_type: nil, deleted: nil, limit: nil, cursor: nil)
62
+ content_type = (content_type.empty? ? nil : { in: content_type }) if content_type.is_a?(Array)
61
63
  @client.paginate("assets_list", query: { filter: { content_type: content_type, deleted: deleted },
62
64
  limit: limit, cursor: cursor })
63
65
  end
@@ -16,16 +16,11 @@ module Nohead
16
16
  idempotency_key: idempotency_key)
17
17
  end
18
18
 
19
- # A collection's drafts, most recently changed first. `record_id`
20
- # narrows them to one record, or to several (an Array of 1 to 100; an
21
- # empty one raises ArgumentError, since it would match no record).
22
- def list(collection, record_id: nil, sort: nil, limit: nil, cursor: nil)
23
- raise ArgumentError, "record_id needs at least one record ID" if record_id == []
24
-
25
- record_filter = record_id.is_a?(Array) ? { in: record_id } : record_id
19
+ # A collection's drafts, most recently changed first. One record's
20
+ # draft is `records.drafts(record)`.
21
+ def list(collection, sort: nil, limit: nil, cursor: nil)
26
22
  @client.paginate("drafts_list", path: { collection_id: collection },
27
- query: { filter: { record_id: record_filter }, sort: sort,
28
- limit: limit, cursor: cursor })
23
+ query: { sort: sort, limit: limit, cursor: cursor })
29
24
  end
30
25
 
31
26
  # With `data` as the record reads after the merge, for previews.
@@ -10,6 +10,8 @@ module Nohead
10
10
  #
11
11
  # audit_events.list(filter: { type: "record.*", resource_type: %w[record draft],
12
12
  # created_at: { gte: Time.utc(2026, 10, 1) } })
13
+ #
14
+ # `sort` is "-created_at" (the default) or "created_at".
13
15
  def list(filter: nil, sort: nil, limit: nil, cursor: nil)
14
16
  filter = filter&.transform_keys(&:to_sym)
15
17
  types = filter&.[](:resource_type)
@@ -95,7 +95,7 @@ module Nohead
95
95
  end
96
96
 
97
97
  # Renames, describes or loosens a field. Changes that rewrite record
98
- # values (type, multiple, tighter rules) are `migrate`.
98
+ # values (type, multiple, tighter rules) are `migrations.create`.
99
99
  def update(field, idempotency_key: nil, change_note: nil, **params)
100
100
  @client.request("fields_update", path: { field_id: field }, body: body_of(params),
101
101
  idempotency_key: idempotency_key, change_note: change_note)
@@ -125,23 +125,26 @@ module Nohead
125
125
  idempotency_key: idempotency_key, change_note: change_note)
126
126
  end
127
127
 
128
- # Stops accepting a renamed field's old API key before its 6 months end.
128
+ # Stops accepting a renamed field's old key before its 6 months end.
129
129
  def remove_alias(field, alias_key, idempotency_key: nil)
130
130
  @client.request("fields_remove_alias", path: { field_id: field, alias: alias_key },
131
131
  idempotency_key: idempotency_key)
132
132
  end
133
-
134
- # Starts a field migration (type, multiple, tighter configuration or a
135
- # backfill) that rewrites every record. With dry_run: true, previews it.
136
- def migrate(field, dry_run: false, idempotency_key: nil, change_note: nil, **params)
137
- @client.request("fields_migrate", path: { field_id: field }, query: { dry_run: dry_run || nil },
138
- body: body_of(params), idempotency_key: idempotency_key,
139
- change_note: change_note)
140
- end
141
133
  end
142
134
 
143
135
  # Field migrations. While one runs, its collection is read-only.
144
136
  class Migrations < Resource
137
+ # Starts a migration of one of the collection's fields (`field_id`):
138
+ # its type, multiple, a tighter configuration or a backfill, which
139
+ # rewrites every record. Returns the FieldMigration, or with
140
+ # dry_run: true a preview (counts and sample records, nothing written).
141
+ def create(collection, field_id:, dry_run: false, idempotency_key: nil, change_note: nil, **params)
142
+ @client.request("migrations_create", path: { collection_id: collection },
143
+ query: { dry_run: dry_run || nil },
144
+ body: { field_id: field_id, **body_of(params) },
145
+ idempotency_key: idempotency_key, change_note: change_note)
146
+ end
147
+
145
148
  def list(collection, limit: nil, cursor: nil)
146
149
  @client.paginate("migrations_list", path: { collection_id: collection },
147
150
  query: { limit: limit, cursor: cursor })
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nohead
4
- VERSION = "0.4.0"
4
+ VERSION = "0.5.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nohead
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nohead