@newhomestar/sdk 0.7.16 → 0.7.17

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/next.d.ts CHANGED
@@ -102,6 +102,50 @@ export interface NovaEndpointEventDef {
102
102
  /** Whether this event should trigger a push notification. Defaults to false. */
103
103
  triggers_notification?: boolean;
104
104
  }
105
+ /**
106
+ * Human-readable metadata for a single permission slug.
107
+ * Defined inline in `novaEndpoint()` alongside `requiredPermissions` and
108
+ * auto-embedded into the IAM permission registry when `nova services push` runs.
109
+ *
110
+ * This drives hierarchical/grouped rendering in the Odyssey UI permission
111
+ * assignment views — permissions in the same `group` are displayed together
112
+ * under a shared parent label with friendly titles and descriptions.
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * requiredPermissions: 'iam_admin:roles_view',
117
+ * permissionMeta: {
118
+ * slug: 'iam_admin:roles_view',
119
+ * title: 'View Roles',
120
+ * description: 'Read access to role definitions and listings',
121
+ * group: 'Roles',
122
+ * },
123
+ * ```
124
+ */
125
+ export interface PermissionMeta {
126
+ /**
127
+ * The exact permission slug this metadata describes.
128
+ * Must match a value in `requiredPermissions`.
129
+ * e.g. `'iam_admin:roles_view'`
130
+ */
131
+ slug: string;
132
+ /**
133
+ * Human-friendly label shown in the Odyssey UI.
134
+ * e.g. `'View Roles'`
135
+ */
136
+ title: string;
137
+ /**
138
+ * Optional description of what this permission grants.
139
+ * e.g. `'Read access to role definitions and listings'`
140
+ */
141
+ description?: string;
142
+ /**
143
+ * Parent group label used for hierarchical rendering in the UI.
144
+ * All permissions with the same `group` value are displayed together.
145
+ * e.g. `'Roles'`
146
+ */
147
+ group: string;
148
+ }
105
149
  export interface NovaEndpointDef<I extends ZodTypeAny = ZodTypeAny, O extends ZodTypeAny = ZodTypeAny> {
106
150
  /** HTTP method */
107
151
  method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
@@ -139,6 +183,29 @@ export interface NovaEndpointDef<I extends ZodTypeAny = ZodTypeAny, O extends Zo
139
183
  * DELETE → `'hris_admin:manage'`
140
184
  */
141
185
  requiredPermissions?: string | string[];
186
+ /**
187
+ * Human-readable metadata for the permission slug(s) in `requiredPermissions`.
188
+ * Used to generate hierarchical, grouped permission views in the Odyssey UI.
189
+ *
190
+ * Provide one entry per unique permission slug used on this endpoint.
191
+ * Metadata is deduplicated by slug — defining the same slug on multiple
192
+ * endpoints is fine; the first definition wins.
193
+ *
194
+ * `nova services push` reads this field and embeds title, description,
195
+ * and group into the IAM permission registry automatically.
196
+ *
197
+ * @example
198
+ * ```ts
199
+ * requiredPermissions: 'iam_admin:roles_view',
200
+ * permissionMeta: {
201
+ * slug: 'iam_admin:roles_view',
202
+ * title: 'View Roles',
203
+ * description: 'Read access to role definitions and listings',
204
+ * group: 'Roles',
205
+ * },
206
+ * ```
207
+ */
208
+ permissionMeta?: PermissionMeta | PermissionMeta[];
142
209
  /**
143
210
  * Event types emitted by this endpoint.
144
211
  * Defined here and auto-registered in the platform event_types registry
@@ -428,6 +495,51 @@ export declare const CURSOR_PAGE_PARAMS: Record<string, ParamMeta>;
428
495
  * Spread into `novaEndpoint({ params: { ...OFFSET_PAGE_PARAMS, ...yourParams } })`.
429
496
  */
430
497
  export declare const OFFSET_PAGE_PARAMS: Record<string, ParamMeta>;
498
+ /**
499
+ * Metadata for a Nova service — passed to `defineService()`.
500
+ */
501
+ export interface ServiceDef {
502
+ /** Unique service slug (snake_case). e.g. "nova_ticketing_service" */
503
+ slug: string;
504
+ /** Human-readable service name */
505
+ name: string;
506
+ /** Short service description */
507
+ description?: string;
508
+ /** Service category for Odyssey UI grouping (e.g. "support", "hris") */
509
+ category?: string;
510
+ /** Semver version string — defaults to "1.0.0" */
511
+ version?: string;
512
+ }
513
+ /**
514
+ * defineService() — declare Nova service identity and auto-set NOVA_SERVICE_SLUG.
515
+ *
516
+ * Call this once in a shared module (e.g. `src/lib/service.ts`) and import it
517
+ * early in your app entrypoint. At import time it sets `process.env.NOVA_SERVICE_SLUG`
518
+ * so `withServiceEventOutbox()` can stamp `source_service` on all outbound events.
519
+ *
520
+ * `nova services push` also detects this export (the `__novaService` marker) to
521
+ * cross-validate the slug against `nova-service.yaml` during the build scan.
522
+ *
523
+ * **Usage:**
524
+ * ```ts
525
+ * // src/lib/service.ts
526
+ * import { defineService } from '@newhomestar/sdk/next';
527
+ *
528
+ * export const service = defineService({
529
+ * slug: 'nova_ticketing_service',
530
+ * name: 'Nova Ticketing Service',
531
+ * category: 'support',
532
+ * });
533
+ * ```
534
+ *
535
+ * Then import it early — e.g. in `src/instrumentation.ts` (Next.js) or your app entry:
536
+ * ```ts
537
+ * import '@/lib/service'; // ensures NOVA_SERVICE_SLUG is set before any route runs
538
+ * ```
539
+ */
540
+ export declare function defineService<T extends ServiceDef>(def: T): T & {
541
+ readonly __novaService: true;
542
+ };
431
543
  /** @deprecated Use `buildPageResponse` instead */
432
544
  export declare function buildPaginatedResponse<T extends {
433
545
  id: string;
package/dist/next.js CHANGED
@@ -323,6 +323,42 @@ export const OFFSET_PAGE_PARAMS = {
323
323
  sort_dir: { in: 'query', uiType: 'select', label: 'Sort Dir', description: 'asc or desc', options: [{ label: 'Ascending', value: 'asc' }, { label: 'Descending', value: 'desc' }] },
324
324
  filters: { in: 'query', uiType: 'json', label: 'Filters', description: 'JSON array of FilterCondition objects' },
325
325
  };
326
+ /**
327
+ * defineService() — declare Nova service identity and auto-set NOVA_SERVICE_SLUG.
328
+ *
329
+ * Call this once in a shared module (e.g. `src/lib/service.ts`) and import it
330
+ * early in your app entrypoint. At import time it sets `process.env.NOVA_SERVICE_SLUG`
331
+ * so `withServiceEventOutbox()` can stamp `source_service` on all outbound events.
332
+ *
333
+ * `nova services push` also detects this export (the `__novaService` marker) to
334
+ * cross-validate the slug against `nova-service.yaml` during the build scan.
335
+ *
336
+ * **Usage:**
337
+ * ```ts
338
+ * // src/lib/service.ts
339
+ * import { defineService } from '@newhomestar/sdk/next';
340
+ *
341
+ * export const service = defineService({
342
+ * slug: 'nova_ticketing_service',
343
+ * name: 'Nova Ticketing Service',
344
+ * category: 'support',
345
+ * });
346
+ * ```
347
+ *
348
+ * Then import it early — e.g. in `src/instrumentation.ts` (Next.js) or your app entry:
349
+ * ```ts
350
+ * import '@/lib/service'; // ensures NOVA_SERVICE_SLUG is set before any route runs
351
+ * ```
352
+ */
353
+ export function defineService(def) {
354
+ // Set NOVA_SERVICE_SLUG at import time so withServiceEventOutbox() always has
355
+ // access to source_service without requiring a separate env var. Only sets it
356
+ // if not already set — explicit env var overrides (e.g. in tests) still work.
357
+ if (!process.env.NOVA_SERVICE_SLUG) {
358
+ process.env.NOVA_SERVICE_SLUG = def.slug;
359
+ }
360
+ return { ...def, __novaService: true };
361
+ }
326
362
  // ─── Legacy re-exports (backward compat) ─────────────────────────────────────
327
363
  /** @deprecated Use `buildPageResponse` instead */
328
364
  export function buildPaginatedResponse(data, count, pageSize) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newhomestar/sdk",
3
- "version": "0.7.16",
3
+ "version": "0.7.17",
4
4
  "description": "Type-safe SDK for building Nova pipelines (workers & functions)",
5
5
  "homepage": "https://github.com/newhomestar/nova-node-sdk#readme",
6
6
  "bugs": {