@dyrected/sdk 2.5.28 → 2.5.30

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/dist/index.cjs CHANGED
@@ -250,6 +250,7 @@ COLLECTION OPTIONS:
250
250
  - upload: true \u2014 media library with file upload support
251
251
  - auth: true \u2014 adds login/me endpoints; password field is auto-managed
252
252
  - audit: true \u2014 enables activity logging
253
+ - admin.icon \u2014 valid Lucide component name for sidebar navigation (e.g. 'Newspaper')
253
254
  - admin.useAsTitle \u2014 field used as display title in admin list view
254
255
  - admin.group \u2014 groups collection under a sidebar heading
255
256
  - admin.hidden \u2014 hides collection from the sidebar (internal/system use)
@@ -292,7 +293,7 @@ const media = defineCollection({
292
293
 
293
294
  const pages = defineCollection({
294
295
  slug: 'pages',
295
- admin: { useAsTitle: 'title', group: 'Content' },
296
+ admin: { icon: 'FileText', useAsTitle: 'title', group: 'Content' },
296
297
  fields: [
297
298
  { name: 'title', label: 'Title', type: 'text', required: true },
298
299
  { name: 'slug', label: 'URL Slug', type: 'text', required: true, unique: true },
@@ -1103,7 +1104,34 @@ var DyrectedClient = class {
1103
1104
  resetPassword: (token, password) => this.request(`/api/collections/${slug}/reset-password`, {
1104
1105
  method: "POST",
1105
1106
  body: JSON.stringify({ token, password })
1106
- })
1107
+ }),
1108
+ /**
1109
+ * Perform a workflow transition on a single document.
1110
+ *
1111
+ * @param id - Document ID to transition.
1112
+ * @param transitionName - The transition key (e.g. `'submit'`, `'publish'`, `'reject'`).
1113
+ * @param opts - Optional `expectedRevision` (optimistic concurrency) and `comment`.
1114
+ * @returns The updated document with refreshed `_workflow` metadata.
1115
+ *
1116
+ * @example
1117
+ * // Publisher approves a submission
1118
+ * const updated = await client.collection('posts').transition(id, 'publish')
1119
+ *
1120
+ * // Editor requests changes with a comment
1121
+ * const updated = await client.collection('posts').transition(id, 'reject', {
1122
+ * expectedRevision: doc._workflow.revision,
1123
+ * comment: 'Please add more detail to section 2.',
1124
+ * })
1125
+ */
1126
+ transition: (id, transitionName, opts) => this.transition(slug, id, transitionName, opts),
1127
+ /**
1128
+ * Fetch the workflow history for a single document — every transition that
1129
+ * has ever been performed, newest first.
1130
+ *
1131
+ * @param id - Document ID.
1132
+ * @param args - Optional `limit` (default 50, max 100).
1133
+ */
1134
+ workflowHistory: (id, args = {}) => this.workflowHistory(slug, id, args)
1107
1135
  };
1108
1136
  }
1109
1137
  /**
@@ -1152,6 +1180,42 @@ var DyrectedClient = class {
1152
1180
  method: "DELETE"
1153
1181
  });
1154
1182
  }
1183
+ /**
1184
+ * Perform a workflow transition on a document.
1185
+ *
1186
+ * Sends `POST /api/collections/:collection/:id/transitions/:transition`.
1187
+ * Requires the client to have a valid bearer token set via `setToken()`.
1188
+ *
1189
+ * @param collection - Collection slug.
1190
+ * @param id - Document ID.
1191
+ * @param transitionName - Transition key defined in `WorkflowConfig.transitions`.
1192
+ * @param opts - Optional concurrency guard and comment.
1193
+ *
1194
+ * @example
1195
+ * const updated = await client.transition('posts', postId, 'publish')
1196
+ */
1197
+ async transition(collection, id, transitionName, opts = {}) {
1198
+ return this.request(
1199
+ `/api/collections/${collection}/${id}/transitions/${encodeURIComponent(transitionName)}`,
1200
+ {
1201
+ method: "POST",
1202
+ body: JSON.stringify(opts)
1203
+ }
1204
+ );
1205
+ }
1206
+ /**
1207
+ * Fetch the workflow history for a document.
1208
+ *
1209
+ * Sends `GET /api/collections/:collection/:id/workflow-history`.
1210
+ *
1211
+ * @param collection - Collection slug.
1212
+ * @param id - Document ID.
1213
+ * @param args - Optional `limit` (max 100).
1214
+ */
1215
+ async workflowHistory(collection, id, args = {}) {
1216
+ const query = args.limit ? `?limit=${args.limit}` : "";
1217
+ return this.request(`/api/collections/${collection}/${id}/workflow-history${query}`);
1218
+ }
1155
1219
  async deleteMany(collection, ids) {
1156
1220
  return this.request(`/api/collections/${collection}/delete-many`, {
1157
1221
  method: "DELETE",
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { PaginatedResult, FileData, CollectionConfig, GlobalConfig } from '@dyrected/core';
2
- export { Block, CollectionConfig, Field, FieldType, GlobalConfig, FileData as Media, PaginatedResult } from '@dyrected/core';
1
+ import { PaginatedResult, WorkflowMetadata, FileData, CollectionConfig, GlobalConfig } from '@dyrected/core';
2
+ export { AdminIconName, Block, CollectionConfig, Field, FieldType, GlobalConfig, LifecycleEvent, FileData as Media, PaginatedResult, WorkflowMetadata } from '@dyrected/core';
3
3
 
4
4
  interface QueryArgs {
5
5
  limit?: number;
@@ -36,6 +36,36 @@ interface SetupPromptConfig {
36
36
  declare function generateFreshSetupPrompt(activeTab: "next" | "nuxt" | "react" | "vue", config: SetupPromptConfig): string;
37
37
  declare function generateAIPrompt(activeTab: "next" | "nuxt" | "react" | "vue", config: SetupPromptConfig): string;
38
38
 
39
+ /** Shape of a document returned from a workflow-enabled collection. */
40
+ interface WorkflowDocument {
41
+ id: string;
42
+ _workflow: WorkflowMetadata;
43
+ [key: string]: unknown;
44
+ }
45
+ /** Options accepted by `client.transition()`. */
46
+ interface TransitionOptions {
47
+ /**
48
+ * The revision number currently shown to the user. When provided, the server
49
+ * rejects the transition if the document has changed since it was loaded,
50
+ * preventing lost-update races.
51
+ */
52
+ expectedRevision?: number;
53
+ /** Required for transitions that have `requireComment: true` (e.g. `reject`). */
54
+ comment?: string;
55
+ }
56
+ /** A single workflow history entry returned by `client.workflowHistory()`. */
57
+ interface WorkflowHistoryEntry {
58
+ id: string;
59
+ collection: string;
60
+ documentId: string;
61
+ transition: string;
62
+ from: string;
63
+ to: string;
64
+ revision: number;
65
+ comment: string | null;
66
+ actorId: string | null;
67
+ createdAt: string;
68
+ }
39
69
  type ExtractDoc<T> = T extends CollectionConfig<infer TDoc> ? TDoc : T extends GlobalConfig<infer TDoc> ? TDoc : never;
40
70
  /**
41
71
  * Derives a typed `TSchema` from your exported collection and global config constants.
@@ -228,6 +258,35 @@ declare class DyrectedClient<TSchema extends BaseSchema = any> {
228
258
  success: boolean;
229
259
  message: string;
230
260
  }>;
261
+ /**
262
+ * Perform a workflow transition on a single document.
263
+ *
264
+ * @param id - Document ID to transition.
265
+ * @param transitionName - The transition key (e.g. `'submit'`, `'publish'`, `'reject'`).
266
+ * @param opts - Optional `expectedRevision` (optimistic concurrency) and `comment`.
267
+ * @returns The updated document with refreshed `_workflow` metadata.
268
+ *
269
+ * @example
270
+ * // Publisher approves a submission
271
+ * const updated = await client.collection('posts').transition(id, 'publish')
272
+ *
273
+ * // Editor requests changes with a comment
274
+ * const updated = await client.collection('posts').transition(id, 'reject', {
275
+ * expectedRevision: doc._workflow.revision,
276
+ * comment: 'Please add more detail to section 2.',
277
+ * })
278
+ */
279
+ transition: (id: string, transitionName: string, opts?: TransitionOptions) => Promise<TSchema["collections"][K]>;
280
+ /**
281
+ * Fetch the workflow history for a single document — every transition that
282
+ * has ever been performed, newest first.
283
+ *
284
+ * @param id - Document ID.
285
+ * @param args - Optional `limit` (default 50, max 100).
286
+ */
287
+ workflowHistory: (id: string, args?: {
288
+ limit?: number;
289
+ }) => Promise<PaginatedResult<WorkflowHistoryEntry>>;
231
290
  };
232
291
  /**
233
292
  * Access a global by its slug with a fluent builder.
@@ -250,6 +309,33 @@ declare class DyrectedClient<TSchema extends BaseSchema = any> {
250
309
  delete(collection: string, id: string): Promise<{
251
310
  message: string;
252
311
  }>;
312
+ /**
313
+ * Perform a workflow transition on a document.
314
+ *
315
+ * Sends `POST /api/collections/:collection/:id/transitions/:transition`.
316
+ * Requires the client to have a valid bearer token set via `setToken()`.
317
+ *
318
+ * @param collection - Collection slug.
319
+ * @param id - Document ID.
320
+ * @param transitionName - Transition key defined in `WorkflowConfig.transitions`.
321
+ * @param opts - Optional concurrency guard and comment.
322
+ *
323
+ * @example
324
+ * const updated = await client.transition('posts', postId, 'publish')
325
+ */
326
+ transition<T = WorkflowDocument>(collection: string, id: string, transitionName: string, opts?: TransitionOptions): Promise<T>;
327
+ /**
328
+ * Fetch the workflow history for a document.
329
+ *
330
+ * Sends `GET /api/collections/:collection/:id/workflow-history`.
331
+ *
332
+ * @param collection - Collection slug.
333
+ * @param id - Document ID.
334
+ * @param args - Optional `limit` (max 100).
335
+ */
336
+ workflowHistory(collection: string, id: string, args?: {
337
+ limit?: number;
338
+ }): Promise<PaginatedResult<WorkflowHistoryEntry>>;
253
339
  deleteMany(collection: string, ids: string[]): Promise<{
254
340
  message: string;
255
341
  }>;
@@ -275,4 +361,4 @@ declare function createClient<TSchema extends {
275
361
  globals: any;
276
362
  } = any>(config: DyrectedClientConfig): DyrectedClient<TSchema>;
277
363
 
278
- export { type BaseSchema, DyrectedClient, type DyrectedClientConfig, DyrectedError, type InferSchema, type SetupPromptConfig, createClient, generateAIPrompt, generateFreshSetupPrompt };
364
+ export { type BaseSchema, DyrectedClient, type DyrectedClientConfig, DyrectedError, type InferSchema, type SetupPromptConfig, type TransitionOptions, type WorkflowDocument, type WorkflowHistoryEntry, createClient, generateAIPrompt, generateFreshSetupPrompt };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { PaginatedResult, FileData, CollectionConfig, GlobalConfig } from '@dyrected/core';
2
- export { Block, CollectionConfig, Field, FieldType, GlobalConfig, FileData as Media, PaginatedResult } from '@dyrected/core';
1
+ import { PaginatedResult, WorkflowMetadata, FileData, CollectionConfig, GlobalConfig } from '@dyrected/core';
2
+ export { AdminIconName, Block, CollectionConfig, Field, FieldType, GlobalConfig, LifecycleEvent, FileData as Media, PaginatedResult, WorkflowMetadata } from '@dyrected/core';
3
3
 
4
4
  interface QueryArgs {
5
5
  limit?: number;
@@ -36,6 +36,36 @@ interface SetupPromptConfig {
36
36
  declare function generateFreshSetupPrompt(activeTab: "next" | "nuxt" | "react" | "vue", config: SetupPromptConfig): string;
37
37
  declare function generateAIPrompt(activeTab: "next" | "nuxt" | "react" | "vue", config: SetupPromptConfig): string;
38
38
 
39
+ /** Shape of a document returned from a workflow-enabled collection. */
40
+ interface WorkflowDocument {
41
+ id: string;
42
+ _workflow: WorkflowMetadata;
43
+ [key: string]: unknown;
44
+ }
45
+ /** Options accepted by `client.transition()`. */
46
+ interface TransitionOptions {
47
+ /**
48
+ * The revision number currently shown to the user. When provided, the server
49
+ * rejects the transition if the document has changed since it was loaded,
50
+ * preventing lost-update races.
51
+ */
52
+ expectedRevision?: number;
53
+ /** Required for transitions that have `requireComment: true` (e.g. `reject`). */
54
+ comment?: string;
55
+ }
56
+ /** A single workflow history entry returned by `client.workflowHistory()`. */
57
+ interface WorkflowHistoryEntry {
58
+ id: string;
59
+ collection: string;
60
+ documentId: string;
61
+ transition: string;
62
+ from: string;
63
+ to: string;
64
+ revision: number;
65
+ comment: string | null;
66
+ actorId: string | null;
67
+ createdAt: string;
68
+ }
39
69
  type ExtractDoc<T> = T extends CollectionConfig<infer TDoc> ? TDoc : T extends GlobalConfig<infer TDoc> ? TDoc : never;
40
70
  /**
41
71
  * Derives a typed `TSchema` from your exported collection and global config constants.
@@ -228,6 +258,35 @@ declare class DyrectedClient<TSchema extends BaseSchema = any> {
228
258
  success: boolean;
229
259
  message: string;
230
260
  }>;
261
+ /**
262
+ * Perform a workflow transition on a single document.
263
+ *
264
+ * @param id - Document ID to transition.
265
+ * @param transitionName - The transition key (e.g. `'submit'`, `'publish'`, `'reject'`).
266
+ * @param opts - Optional `expectedRevision` (optimistic concurrency) and `comment`.
267
+ * @returns The updated document with refreshed `_workflow` metadata.
268
+ *
269
+ * @example
270
+ * // Publisher approves a submission
271
+ * const updated = await client.collection('posts').transition(id, 'publish')
272
+ *
273
+ * // Editor requests changes with a comment
274
+ * const updated = await client.collection('posts').transition(id, 'reject', {
275
+ * expectedRevision: doc._workflow.revision,
276
+ * comment: 'Please add more detail to section 2.',
277
+ * })
278
+ */
279
+ transition: (id: string, transitionName: string, opts?: TransitionOptions) => Promise<TSchema["collections"][K]>;
280
+ /**
281
+ * Fetch the workflow history for a single document — every transition that
282
+ * has ever been performed, newest first.
283
+ *
284
+ * @param id - Document ID.
285
+ * @param args - Optional `limit` (default 50, max 100).
286
+ */
287
+ workflowHistory: (id: string, args?: {
288
+ limit?: number;
289
+ }) => Promise<PaginatedResult<WorkflowHistoryEntry>>;
231
290
  };
232
291
  /**
233
292
  * Access a global by its slug with a fluent builder.
@@ -250,6 +309,33 @@ declare class DyrectedClient<TSchema extends BaseSchema = any> {
250
309
  delete(collection: string, id: string): Promise<{
251
310
  message: string;
252
311
  }>;
312
+ /**
313
+ * Perform a workflow transition on a document.
314
+ *
315
+ * Sends `POST /api/collections/:collection/:id/transitions/:transition`.
316
+ * Requires the client to have a valid bearer token set via `setToken()`.
317
+ *
318
+ * @param collection - Collection slug.
319
+ * @param id - Document ID.
320
+ * @param transitionName - Transition key defined in `WorkflowConfig.transitions`.
321
+ * @param opts - Optional concurrency guard and comment.
322
+ *
323
+ * @example
324
+ * const updated = await client.transition('posts', postId, 'publish')
325
+ */
326
+ transition<T = WorkflowDocument>(collection: string, id: string, transitionName: string, opts?: TransitionOptions): Promise<T>;
327
+ /**
328
+ * Fetch the workflow history for a document.
329
+ *
330
+ * Sends `GET /api/collections/:collection/:id/workflow-history`.
331
+ *
332
+ * @param collection - Collection slug.
333
+ * @param id - Document ID.
334
+ * @param args - Optional `limit` (max 100).
335
+ */
336
+ workflowHistory(collection: string, id: string, args?: {
337
+ limit?: number;
338
+ }): Promise<PaginatedResult<WorkflowHistoryEntry>>;
253
339
  deleteMany(collection: string, ids: string[]): Promise<{
254
340
  message: string;
255
341
  }>;
@@ -275,4 +361,4 @@ declare function createClient<TSchema extends {
275
361
  globals: any;
276
362
  } = any>(config: DyrectedClientConfig): DyrectedClient<TSchema>;
277
363
 
278
- export { type BaseSchema, DyrectedClient, type DyrectedClientConfig, DyrectedError, type InferSchema, type SetupPromptConfig, createClient, generateAIPrompt, generateFreshSetupPrompt };
364
+ export { type BaseSchema, DyrectedClient, type DyrectedClientConfig, DyrectedError, type InferSchema, type SetupPromptConfig, type TransitionOptions, type WorkflowDocument, type WorkflowHistoryEntry, createClient, generateAIPrompt, generateFreshSetupPrompt };
package/dist/index.js CHANGED
@@ -220,6 +220,7 @@ COLLECTION OPTIONS:
220
220
  - upload: true \u2014 media library with file upload support
221
221
  - auth: true \u2014 adds login/me endpoints; password field is auto-managed
222
222
  - audit: true \u2014 enables activity logging
223
+ - admin.icon \u2014 valid Lucide component name for sidebar navigation (e.g. 'Newspaper')
223
224
  - admin.useAsTitle \u2014 field used as display title in admin list view
224
225
  - admin.group \u2014 groups collection under a sidebar heading
225
226
  - admin.hidden \u2014 hides collection from the sidebar (internal/system use)
@@ -262,7 +263,7 @@ const media = defineCollection({
262
263
 
263
264
  const pages = defineCollection({
264
265
  slug: 'pages',
265
- admin: { useAsTitle: 'title', group: 'Content' },
266
+ admin: { icon: 'FileText', useAsTitle: 'title', group: 'Content' },
266
267
  fields: [
267
268
  { name: 'title', label: 'Title', type: 'text', required: true },
268
269
  { name: 'slug', label: 'URL Slug', type: 'text', required: true, unique: true },
@@ -1073,7 +1074,34 @@ var DyrectedClient = class {
1073
1074
  resetPassword: (token, password) => this.request(`/api/collections/${slug}/reset-password`, {
1074
1075
  method: "POST",
1075
1076
  body: JSON.stringify({ token, password })
1076
- })
1077
+ }),
1078
+ /**
1079
+ * Perform a workflow transition on a single document.
1080
+ *
1081
+ * @param id - Document ID to transition.
1082
+ * @param transitionName - The transition key (e.g. `'submit'`, `'publish'`, `'reject'`).
1083
+ * @param opts - Optional `expectedRevision` (optimistic concurrency) and `comment`.
1084
+ * @returns The updated document with refreshed `_workflow` metadata.
1085
+ *
1086
+ * @example
1087
+ * // Publisher approves a submission
1088
+ * const updated = await client.collection('posts').transition(id, 'publish')
1089
+ *
1090
+ * // Editor requests changes with a comment
1091
+ * const updated = await client.collection('posts').transition(id, 'reject', {
1092
+ * expectedRevision: doc._workflow.revision,
1093
+ * comment: 'Please add more detail to section 2.',
1094
+ * })
1095
+ */
1096
+ transition: (id, transitionName, opts) => this.transition(slug, id, transitionName, opts),
1097
+ /**
1098
+ * Fetch the workflow history for a single document — every transition that
1099
+ * has ever been performed, newest first.
1100
+ *
1101
+ * @param id - Document ID.
1102
+ * @param args - Optional `limit` (default 50, max 100).
1103
+ */
1104
+ workflowHistory: (id, args = {}) => this.workflowHistory(slug, id, args)
1077
1105
  };
1078
1106
  }
1079
1107
  /**
@@ -1122,6 +1150,42 @@ var DyrectedClient = class {
1122
1150
  method: "DELETE"
1123
1151
  });
1124
1152
  }
1153
+ /**
1154
+ * Perform a workflow transition on a document.
1155
+ *
1156
+ * Sends `POST /api/collections/:collection/:id/transitions/:transition`.
1157
+ * Requires the client to have a valid bearer token set via `setToken()`.
1158
+ *
1159
+ * @param collection - Collection slug.
1160
+ * @param id - Document ID.
1161
+ * @param transitionName - Transition key defined in `WorkflowConfig.transitions`.
1162
+ * @param opts - Optional concurrency guard and comment.
1163
+ *
1164
+ * @example
1165
+ * const updated = await client.transition('posts', postId, 'publish')
1166
+ */
1167
+ async transition(collection, id, transitionName, opts = {}) {
1168
+ return this.request(
1169
+ `/api/collections/${collection}/${id}/transitions/${encodeURIComponent(transitionName)}`,
1170
+ {
1171
+ method: "POST",
1172
+ body: JSON.stringify(opts)
1173
+ }
1174
+ );
1175
+ }
1176
+ /**
1177
+ * Fetch the workflow history for a document.
1178
+ *
1179
+ * Sends `GET /api/collections/:collection/:id/workflow-history`.
1180
+ *
1181
+ * @param collection - Collection slug.
1182
+ * @param id - Document ID.
1183
+ * @param args - Optional `limit` (max 100).
1184
+ */
1185
+ async workflowHistory(collection, id, args = {}) {
1186
+ const query = args.limit ? `?limit=${args.limit}` : "";
1187
+ return this.request(`/api/collections/${collection}/${id}/workflow-history${query}`);
1188
+ }
1125
1189
  async deleteMany(collection, ids) {
1126
1190
  return this.request(`/api/collections/${collection}/delete-many`, {
1127
1191
  method: "DELETE",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dyrected/sdk",
3
- "version": "2.5.28",
3
+ "version": "2.5.30",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -30,7 +30,7 @@
30
30
  "tsup": "^8.5.1",
31
31
  "typescript": "^5.4.5",
32
32
  "vitest": "^1.0.0",
33
- "@dyrected/core": "2.5.28"
33
+ "@dyrected/core": "2.5.30"
34
34
  },
35
35
  "license": "BSL-1.1",
36
36
  "author": "Busola Okeowo <busolaokemoney@gmail.com>",