@scout9/app 1.0.0-alpha.0.1.85 → 1.0.0-alpha.0.1.87

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.
@@ -1,184 +1,57 @@
1
-
2
- // export type Scout9Response =
3
- // export type RequestHandler<
4
- // RequestBody = unknown,
5
- // ResponseBody = Record<string | number, any> | Record<string | number, any>[],
6
- // Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
7
- // RouteId extends string | null = string | null,
8
- // SearchParams extends Partial<Record<string, string | string[]>> = Partial<Record<string, string>>
9
- // > = (event: EventRequest<RequestBody, Params, RouteId, SearchParams>) => MaybePromise<EventResponse<ResponseBody>>;
10
- //
11
- // /**
12
- // * For QUERY entity api calls, this is used for getting multiple entities
13
- // */
14
- // export type QueryRequestHandler<
15
- // ResponseBody = Record<string | number, any>,
16
- // Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
17
- // RouteId extends string | null = string | null,
18
- // > = RequestHandler<unknown, ResponseBody[], Params, RouteId, {q?: string, page?: string, limit?: string, orderBy?: string, endAt?: string, startAt?: string}>;
19
- //
20
- // /**
21
- // * For GET entity api calls, this is used for getting one entity
22
- // */
23
- // export type GetRequestHandler<
24
- // ResponseBody = Record<string | number, any>,
25
- // Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
26
- // RouteId extends string | null = string | null,
27
- // > = RequestHandler<unknown, ResponseBody, Params, RouteId>;
28
- //
29
- // /**
30
- // * For POST entity api calls, this is used for creating an entity
31
- // */
32
- // export type PostRequestHandler<
33
- // RequestBody = Record<string | number, any>,
34
- // Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
35
- // RouteId extends string | null = string | null
36
- // > = RequestHandler<RequestBody, {success: boolean, id: string, error?: string | object, [key: string]: any}, Params, RouteId>;
37
- //
38
- // export type CreatedRequestHandler<
39
- // RequestBody = Record<string | number, any>,
40
- // Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
41
- // RouteId extends string | null = string | null
42
- // > = PostRequestHandler<RequestBody, Params, RouteId>;
43
- //
44
- //
45
- // /**
46
- // * For PUT entity api calls, this is used for creating an entity
47
- // */
48
- // export type PutRequestHandler<
49
- // RequestBody = Record<string | number, any>,
50
- // Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
51
- // RouteId extends string | null = string | null
52
- // > = RequestHandler<Partial<RequestBody>, {success: boolean, error?: string | object, [key: string]: any}, Params, RouteId>;
53
- //
54
- //
55
- // /**
56
- // * For PUT entity api calls, this is used for creating an entity
57
- // */
58
- // export type PatchRequestHandler<
59
- // RequestBody = Record<string | number, any>,
60
- // Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
61
- // RouteId extends string | null = string | null
62
- // > = PutRequestHandler<RequestBody, Params, RouteId>;
63
- //
64
- // /**
65
- // * For PUT entity api calls, this is used for creating an entity
66
- // */
67
- // export type UpdateRequestHandler<
68
- // RequestBody = Record<string | number, any>,
69
- // Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
70
- // RouteId extends string | null = string | null
71
- // > = PutRequestHandler<RequestBody, Params, RouteId>;
72
- //
73
- // /**
74
- // * For PUT entity api calls, this is used for creating an entity
75
- // */
76
- // export type DeleteRequestHandler<
77
- // Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
78
- // RouteId extends string | null = string | null
79
- // > = RequestHandler<unknown, {success: boolean, error?: string | object, [key: string]: any}, Params, RouteId>;
80
- //
81
- //
82
- // export interface EventRequest<
83
- // Body = unknown,
84
- // Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
85
- // RouteId extends string | null = string | null,
86
- // SearchParams extends Partial<Record<string, string | string[]>> = Partial<Record<string, string>>,
87
- // > {
88
- //
89
- // /**
90
- // * `fetch` is equivalent to the [native `fetch` web API](https://developer.mozilla.org/en-US/docs/Web/API/fetch), with a few additional features:
91
- // *
92
- // * - It can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request.
93
- // * - It can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context).
94
- // * - Internal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call.
95
- // * - During server-side rendering, the response will be captured and inlined into the rendered HTML by hooking into the `text` and `json` methods of the `Response` object. Note that headers will _not_ be serialized, unless explicitly included
96
- // * - During hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request.
97
- // *
98
- // */
99
- // fetch: typeof fetch;
100
- //
101
- // /**
102
- // * The parameters of the current route - e.g. for a route like `/blog/[slug]`, a `{ slug: string }` object
103
- // */
104
- // params: Params;
105
- //
106
- // /**
107
- // * The requested URL.
108
- // */
109
- // url: URL;
110
- //
111
- // /**
112
- // * The anticipated searchParams inside `const { searchParams } = new URL(req.url)`
113
- // */
114
- // searchParams: SearchParams;
115
- //
116
- // /**
117
- // * The anticipated parsed body inside `request.body`
118
- // */
119
- // body: Body;
120
- //
121
- // /**
122
- // * The original request object
123
- // */
124
- // request: Request;
125
- //
126
- // /**
127
- // * If you need to set headers for the response, you can do so using the this method. This is useful if you want the page to be cached, for example:
128
- // *
129
- // * ```js
130
- // * /// file: src/routes/blog/+page.js
131
- // * export async function load({ fetch, setHeaders }) {
132
- // * const url = `https://cms.example.com/articles.json`;
133
- // * const response = await fetch(url);
134
- // *
135
- // * setHeaders({
136
- // * age: response.headers.get('age'),
137
- // * 'cache-control': response.headers.get('cache-control')
138
- // * });
139
- // *
140
- // * return response.json();
141
- // * }
142
- // * ```
143
- // *
144
- // * Setting the same header multiple times (even in separate `load` functions) is an error — you can only set a given header once.
145
- // *
146
- // * You cannot add a `set-cookie` header with `setHeaders` API instead.
147
- // */
148
- // setHeaders(headers: Record<string, string>): void;
149
- //
150
- // /**
151
- // * Info about the current route
152
- // */
153
- // route: {
154
- // /**
155
- // * The ID of the current route - e.g. for `src/routes/blog/[slug]`, it would be `/blog/[slug]`
156
- // */
157
- // id: RouteId;
158
- // };
159
- // }
1
+ import { z } from 'zod';
160
2
 
161
3
  /**
162
4
  * Utility runtime class used to guide event output
5
+ * @template T
163
6
  */
164
7
  export class EventResponse {
165
8
 
9
+ /**
10
+ * Create a new EventResponse instance with a JSON body.
11
+ * @template T
12
+ * @param {T} body - The body of the response.
13
+ * @param {ResponseInit} [options] - Additional options for the response.
14
+ * @returns {EventResponse<T>} A new EventResponse instance.
15
+ */
166
16
  static json(body, options) {
167
17
  return new EventResponse(body, options);
168
18
  }
169
19
 
20
+ /**
21
+ * Create an EventResponse.
22
+ * @param {T} body - The body of the response.
23
+ * @param {ResponseInit} [init] - Additional options for the response.
24
+ * @throws {Error} If the body is not a valid object.
25
+ */
170
26
  constructor(body, init) {
27
+ /**
28
+ * @type {T}
29
+ * @private
30
+ */
171
31
  this.body = body;
32
+
33
+ /**
34
+ * @type {ResponseInit}
35
+ * @private
36
+ */
172
37
  this.init = init;
173
38
  if (typeof this.body !== 'object') {
174
39
  throw new Error(`EventResponse body in not a valid object:\n"${JSON.stringify(body, null, 2)}"`);
175
40
  }
176
41
  }
177
42
 
43
+ /**
44
+ * Get the response object.
45
+ * @returns {Response} The response object.
46
+ */
178
47
  get response() {
179
48
  return Response.json(this.body, this.init);
180
49
  }
181
50
 
51
+ /**
52
+ * Get the data of the response.
53
+ * @returns {T} The body of the response.
54
+ */
182
55
  get data() {
183
56
  return this.body;
184
57
  }
@@ -186,3 +59,22 @@ export class EventResponse {
186
59
  }
187
60
 
188
61
 
62
+
63
+ const responseInitSchema = z.object({
64
+ status: z.number().optional(),
65
+ statusText: z.string().optional(),
66
+ headers: z.any().optional() // Headers can be complex; adjust as needed
67
+ });
68
+
69
+ /**
70
+ * @template T
71
+ * @typedef {object} IEventResponse
72
+ * @property {T} body - The body of the response.
73
+ * @property {ResponseInit} [init] - Additional options for the response.
74
+ * @property {Response} response - The response object.
75
+ * @property {T} data - The body of the response.
76
+ */
77
+ export const eventResponseSchema = z.object({
78
+ body: z.any(), // Adjust as per your actual body structure
79
+ init: responseInitSchema.optional()
80
+ });
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { agentsConfigurationSchema, agentsBaseConfigurationSchema } from './agent.js';
2
+ import { agentsConfigurationSchema, agentsBaseConfigurationSchema } from './users.js';
3
3
  import { entitiesRootProjectConfigurationSchema } from './entity.js';
4
4
  import { WorkflowsConfigurationSchema } from './workflow.js';
5
5
 
@@ -40,21 +40,46 @@ const bardSchema = z.object({
40
40
  model: z.string()
41
41
  });
42
42
 
43
+ /**
44
+ * Configure personal model transformer (PMT) settings to align auto replies the agent's tone
45
+ */
43
46
  const pmtSchema = z.object({
44
47
  engine: z.literal('scout9'),
45
48
  // model: pmtModelOptions
46
49
  model: z.string()
50
+ }, {
51
+ description: 'Configure personal model transformer (PMT) settings to align auto replies the agent\'s tone'
47
52
  });
48
53
 
49
- export const Scout9ProjectBuildConfigSchema = z.object({
54
+ /**
55
+ * Represents the configuration provided in src/index.{js | ts} in a project
56
+ * @typedef {import('zod').infer<typeof Scout9ProjectConfigSchema>} IScout9ProjectConfig
57
+ */
58
+ export const Scout9ProjectConfigSchema = z.object({
59
+ /**
60
+ * Tag to reference this application
61
+ * @defaut your local package.json name + version, or scout9-app-v1.0.0
62
+ */
50
63
  tag: z.string().optional(), // Defaults to scout9-app-v1.0.0
51
- agents: agentsBaseConfigurationSchema,
52
- entities: entitiesRootProjectConfigurationSchema,
53
- workflows: WorkflowsConfigurationSchema,
54
64
  llm: z.union([llmSchema, llamaSchema, bardSchema]),
65
+ /**
66
+ * Configure personal model transformer (PMT) settings to align auto replies the agent's tone
67
+ */
55
68
  pmt: pmtSchema,
56
- initialContext: z.array(z.string()),
57
- maxLockAttempts: z.number().min(0).max(20).optional(),
69
+
70
+ /**
71
+ * Determines the max auto replies without further conversation progression (defined by new context data gathered)
72
+ * before the conversation is locked and requires manual intervention
73
+ * @default 3
74
+ */
75
+ maxLockAttempts: z.number({
76
+ description: 'Determines the max auto replies without further conversation progression (defined by new context data gathered), before the conversation is locked and requires manual intervention'
77
+ }).min(0).max(20).default(3).optional(),
78
+
79
+ initialContext: z.array(z.string(), {
80
+ description: 'Configure the initial contexts for every conversation'
81
+ }),
82
+
58
83
  organization: z.object({
59
84
  name: z.string(),
60
85
  description: z.string(),
@@ -66,4 +91,15 @@ export const Scout9ProjectBuildConfigSchema = z.object({
66
91
  email: z.string().email().optional(),
67
92
  phone: z.string().optional(),
68
93
  }).optional()
94
+ })
95
+
96
+ /**
97
+ * @typedef {import('zod').infer<typeof Scout9ProjectBuildConfigSchema>} IScout9ProjectBuildConfig
98
+ */
99
+ export const Scout9ProjectBuildConfigSchema = Scout9ProjectConfigSchema.extend({
100
+ agents: agentsBaseConfigurationSchema,
101
+ entities: entitiesRootProjectConfigurationSchema,
102
+ workflows: WorkflowsConfigurationSchema
69
103
  });
104
+
105
+
@@ -2,7 +2,10 @@ import { z } from 'zod';
2
2
  import { zId } from './utils.js';
3
3
 
4
4
 
5
- export const _entityApiConfigurationSchema = z.object({
5
+ /**
6
+ * @typedef {import('zod').infer<typeof entityApiConfigurationSchema>} IEntityApiConfiguration
7
+ */
8
+ export const entityApiConfigurationSchema = z.object({
6
9
  // path: z.string(),
7
10
  GET: z.boolean().optional(),
8
11
  UPDATE: z.boolean().optional(),
@@ -10,9 +13,7 @@ export const _entityApiConfigurationSchema = z.object({
10
13
  PUT: z.boolean().optional(),
11
14
  PATCH: z.boolean().optional(),
12
15
  DELETE: z.boolean().optional()
13
- })
14
-
15
- export const entityApiConfigurationSchema = _entityApiConfigurationSchema.nullable();
16
+ }).nullable();
16
17
 
17
18
  const entityConfigurationDefinitionSchema = z.object({
18
19
  utterance: zId('Utterance', z.string({description: 'What entity utterance this represents, if not provided, it will default to the entity id'}))
@@ -39,6 +40,9 @@ const _entityConfigurationSchema = z.object({
39
40
  tests: z.array(entityConfigurationTestSchema).optional()
40
41
  }).strict();
41
42
 
43
+ /**
44
+ * @typedef {import('zod').infer<typeof entityConfigurationSchema>} IEntityConfiguration
45
+ */
42
46
  export const entityConfigurationSchema = _entityConfigurationSchema.refine((data) => {
43
47
  // If 'definitions' is provided, then 'training' must also be provided
44
48
  if (data.definitions !== undefined) {
@@ -51,6 +55,9 @@ export const entityConfigurationSchema = _entityConfigurationSchema.refine((data
51
55
  message: "If 'definitions' is provided, then 'training' must also be provided",
52
56
  });
53
57
 
58
+ /**
59
+ * @typedef {import('zod').infer<typeof entitiesRootConfigurationSchema>} IEntitiesRootConfiguration
60
+ */
54
61
  export const entitiesRootConfigurationSchema = z.array(entityConfigurationSchema);
55
62
 
56
63
 
@@ -65,7 +72,10 @@ const entityExtendedProjectConfigurationSchema = z.object({
65
72
  const _entityRootProjectConfigurationSchema = _entityConfigurationSchema.extend(entityExtendedProjectConfigurationSchema.shape);
66
73
  const _entitiesRootProjectConfigurationSchema = z.array(_entityRootProjectConfigurationSchema);
67
74
 
68
- // @TODO why type extend not valid?
75
+ /**
76
+ * @TODO why type extend not valid?
77
+ * @typedef {import('zod').infer<typeof entityRootProjectConfigurationSchema>} IEntityRootProjectConfiguration
78
+ */
69
79
  export const entityRootProjectConfigurationSchema = _entityConfigurationSchema.extend(entityExtendedProjectConfigurationSchema.shape).refine((data) => {
70
80
  // If 'definitions' is provided, then 'training' must also be provided
71
81
  if (data.definitions !== undefined) {
@@ -77,4 +87,8 @@ export const entityRootProjectConfigurationSchema = _entityConfigurationSchema.e
77
87
  // Custom error message
78
88
  message: "If 'definitions' is provided, then 'training' must also be provided",
79
89
  });
90
+
91
+ /**
92
+ * @typedef {import('zod').infer<typeof entitiesRootProjectConfigurationSchema>} IEntitiesRootProjectConfiguration
93
+ */
80
94
  export const entitiesRootProjectConfigurationSchema = z.array(entityRootProjectConfigurationSchema);
@@ -1,7 +1,8 @@
1
- export * from './agent.js';
1
+ export * from './users.js';
2
2
  export * from './api.js';
3
3
  export * from './config.js';
4
4
  export * from './entity.js';
5
5
  export * from './message.js';
6
6
  export * from './workflow.js';
7
+ export * from './platform.js';
7
8
 
@@ -1,8 +1,17 @@
1
1
  import { z } from 'zod';
2
+ import { zId } from './utils.js';
2
3
 
4
+ /**
5
+ * @typedef {import('zod').infer<typeof MessageSchema>} IMessage
6
+ */
3
7
  export const MessageSchema = z.object({
4
- content: z.string(),
8
+ id: zId('Message ID', {description: 'Unique ID for the message'}),
5
9
  role: z.enum(['agent', 'customer', 'system']),
6
- time: z.string(),
7
- name: z.string().optional()
10
+ content: z.string(),
11
+ time: z.string({description: 'Datetime ISO 8601 timestamp'}),
12
+ name: z.string().optional(),
13
+ scheduled: z.string({description: 'Datetime ISO 8601 timestamp'}).optional(),
14
+ context: z.any({description: 'The context generated from the message'}).optional(),
15
+ intent: z.string({description: 'Detected intent'}).optional().nullable(),
16
+ intentScore: z.number({description: 'Confidence score of the assigned intent'}).nullable().optional(),
8
17
  });
@@ -0,0 +1,86 @@
1
+ import { z } from 'zod';
2
+ import { eventResponseSchema, EventResponse } from './api.js';
3
+
4
+
5
+ /**
6
+ * @typedef {object} IApiFunctionParams
7
+ * @property {Object.<string, string|string[]>} searchParams
8
+ * @property {Record<string, string>} params
9
+ */
10
+ const apiFunctionParamsSchema = z.object({
11
+ searchParams: z.record(z.union([z.string(), z.array(z.string())])),
12
+ params: z.record(z.string())
13
+ });
14
+
15
+ /**
16
+ * @typedef {IApiFunctionParams & { id: string }} IApiEntityFunctionParams
17
+ */
18
+ const apiEntityFunctionParamsSchema = apiFunctionParamsSchema.extend({
19
+ id: z.string()
20
+ });
21
+
22
+ /**
23
+ * @template Params
24
+ * @template Response
25
+ * @typedef {function(IApiFunctionParams): Promise<EventResponse>} IApiFunction
26
+ */
27
+ export const apiFunctionSchema = z.function()
28
+ .args(apiFunctionParamsSchema)
29
+ .returns(z.promise(eventResponseSchema));
30
+
31
+ /**
32
+ * @template Params
33
+ * @template Response
34
+ * @typedef {IApiFunction<Params, Response>} IQueryApiFunction
35
+ */
36
+ export const queryApiFunctionSchema = apiFunctionSchema;
37
+
38
+ /**
39
+ * @template Params
40
+ * @template Response
41
+ * @typedef {IApiFunction<Params, Response>} GetApiFunction
42
+ */
43
+ export const getApiFunctionSchema = apiFunctionSchema;
44
+
45
+ /**
46
+ * @template Params
47
+ * @template RequestBody
48
+ * @template Response
49
+ * @typedef {function(IApiFunctionParams & {body: Partial<RequestBody>}): Promise<EventResponse<Response>>} IPostApiFunction
50
+ */
51
+ export const postApiFunctionSchema = (requestBodySchema) => z.function()
52
+ .args(apiFunctionParamsSchema.extend({
53
+ body: requestBodySchema.partial()
54
+ }))
55
+ .returns(z.promise(eventResponseSchema));
56
+
57
+ /**
58
+ * @template Params
59
+ * @template RequestBody
60
+ * @template Response
61
+ * @typedef {function(IApiFunctionParams & {body: Partial<RequestBody>}): Promise<EventResponse<Response>>} IPutApiFunction
62
+ */
63
+ export const putApiFunctionSchema = (requestBodySchema) => z.function()
64
+ .args(apiFunctionParamsSchema.extend({
65
+ body: requestBodySchema.partial()
66
+ }))
67
+ .returns(z.promise(eventResponseSchema));
68
+
69
+ /**
70
+ * @template Params
71
+ * @template RequestBody
72
+ * @template Response
73
+ * @typedef {function(IApiFunctionParams & {body: Partial<RequestBody>}): Promise<EventResponse<Response>>} IPatchApiFunction
74
+ */
75
+ export const patchApiFunctionSchema = (requestBodySchema) => z.function()
76
+ .args(apiFunctionParamsSchema.extend({
77
+ body: requestBodySchema.partial()
78
+ }))
79
+ .returns(z.promise(eventResponseSchema));
80
+
81
+ /**
82
+ * @template Params
83
+ * @template Response
84
+ * @typedef {IApiFunction<Params, Response>} IDeleteApiFunction
85
+ */
86
+ export const deleteApiFunctionSchema = apiFunctionSchema;
@@ -2,8 +2,14 @@ import { z } from 'zod';
2
2
  import { zId } from './utils.js';
3
3
  import { MessageSchema } from './message.js';
4
4
 
5
+ /**
6
+ * @typedef {import('zod').infer<typeof customerValueSchema>} ICustomerValue
7
+ */
5
8
  export const customerValueSchema = z.union([z.boolean(), z.number(), z.string()]);
6
9
 
10
+ /**
11
+ * @typedef {import('zod').infer<typeof customerSchema>} ICustomer
12
+ */
7
13
  export const customerSchema = z.object({
8
14
  firstName: z.string().optional(),
9
15
  lastName: z.string().optional(),
@@ -24,13 +30,16 @@ export const customerSchema = z.object({
24
30
  stripeDev: z.string().nullable().optional()
25
31
  }).catchall(customerValueSchema);
26
32
 
27
-
33
+ /**
34
+ * @typedef {import('zod').infer<typeof agentBaseConfigurationSchema>} IAgentBase
35
+ */
28
36
  export const agentBaseConfigurationSchema = z.object({
29
37
  deployed: z.object({
30
38
  web: z.string({description: 'Web URL for agent'}).optional(),
31
39
  phone: z.string({description: 'Phone number for agent'}).optional(),
32
40
  email: z.string({description: 'Email address for agent'}).optional()
33
41
  }).optional(),
42
+ img: z.string().nullable().optional(),
34
43
  firstName: z.string({description: 'Agent first name'}).optional(),
35
44
  lastName: z.string({description: 'Agent last name'}).optional(),
36
45
  inactive: z.boolean({description: 'Agent is inactive'}).optional(),
@@ -46,11 +55,23 @@ export const agentBaseConfigurationSchema = z.object({
46
55
  model: z.enum(['Scout9', 'bard', 'openai']).optional().default('openai'),
47
56
  transcripts: z.array(z.array(MessageSchema)).optional(),
48
57
  audios: z.array(z.any()).optional()
49
-
50
58
  });
59
+
60
+ /**
61
+ * @typedef {import('zod').infer<typeof agentBaseConfigurationSchema>} IAgent
62
+ * @typedef {import('zod').infer<typeof agentBaseConfigurationSchema>} IPersona
63
+ */
51
64
  export const agentConfigurationSchema = agentBaseConfigurationSchema.extend({
52
- id: zId('Agent ID', z.string({description: 'Unique ID for agent'})),
53
- })
65
+ id: zId('Agent ID', {description: 'Unique ID for agent'}),
66
+ });
67
+
68
+ /**
69
+ * @typedef {import('zod').infer<typeof agentsConfigurationSchema>} IAgentsConfiguration
70
+ */
54
71
  export const agentsConfigurationSchema = z.array(agentConfigurationSchema);
55
72
 
73
+ /**
74
+ * @typedef {import('zod').infer<typeof agentsBaseConfigurationSchema>} IAgentsBaseConfiguration
75
+ */
56
76
  export const agentsBaseConfigurationSchema = z.array(agentBaseConfigurationSchema);
77
+
@@ -1,12 +1,12 @@
1
1
  import { z } from 'zod';
2
2
 
3
3
  /**
4
- *
5
4
  * @param {string} name
6
- * @returns {ZodString}
5
+ * @param {Object} [props]
6
+ * @returns {import('zod').ZodString}
7
7
  */
8
- export function zId(name) {
9
- return z.string().regex(/^[A-Za-z0-9\-_\[\]]+$/, {
8
+ export function zId(name, props = {}) {
9
+ return z.string(props).regex(/^[A-Za-z0-9\-_\[\]]+$/, {
10
10
  message: `Invalid ${name} ID: ID must not contain spaces and should only contain alphanumeric characters, dashes, or underscores.`
11
11
  });
12
12
  }