skedyul 1.0.4 → 1.0.6

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/.build-stamp CHANGED
@@ -1 +1 @@
1
- 1772054420261
1
+ 1772514228755
@@ -0,0 +1 @@
1
+ export declare function deployCommand(args: string[]): Promise<void>;
@@ -0,0 +1,344 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.deployCommand = deployCommand;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const readline = __importStar(require("readline"));
40
+ const utils_1 = require("../utils");
41
+ const auth_1 = require("../utils/auth");
42
+ const config_1 = require("../../config");
43
+ function printHelp() {
44
+ console.log(`
45
+ skedyul dev deploy - Deploy your app to Skedyul
46
+
47
+ Usage:
48
+ skedyul dev deploy [options]
49
+
50
+ Options:
51
+ --config, -c Path to config file (default: auto-detect skedyul.config.ts)
52
+ --workplace, -w Workplace subdomain to deploy to
53
+ --yes, -y Auto-approve all prompts (skip interactive approval)
54
+ --dry-run Show what would be deployed without making changes
55
+ --json Output as JSON
56
+ --help, -h Show this help message
57
+
58
+ Description:
59
+ Deploys your app configuration to Skedyul. If the deployment includes
60
+ destructive CRM schema changes (deleting models, fields, or relationships
61
+ with existing data), you will be prompted to approve before proceeding.
62
+
63
+ Examples:
64
+ # Deploy to linked workplace
65
+ skedyul dev deploy --workplace demo-clinic
66
+
67
+ # Deploy with auto-approval (use with caution)
68
+ skedyul dev deploy --workplace demo-clinic --yes
69
+
70
+ # Preview deployment without making changes
71
+ skedyul dev deploy --workplace demo-clinic --dry-run
72
+ `);
73
+ }
74
+ function findConfigFile(startDir) {
75
+ for (const fileName of config_1.CONFIG_FILE_NAMES) {
76
+ const filePath = path.join(startDir, fileName);
77
+ if (fs.existsSync(filePath)) {
78
+ return filePath;
79
+ }
80
+ }
81
+ return null;
82
+ }
83
+ async function promptForApproval(impacts) {
84
+ const rl = readline.createInterface({
85
+ input: process.stdin,
86
+ output: process.stdout,
87
+ });
88
+ console.log('');
89
+ console.log('⚠️ This deployment includes destructive operations:');
90
+ console.log('');
91
+ const destructiveImpacts = impacts.filter((i) => i.isDestructive);
92
+ for (const impact of destructiveImpacts) {
93
+ const recordInfo = impact.affectedRecords
94
+ ? ` (${impact.affectedRecords.toLocaleString()} records affected)`
95
+ : '';
96
+ console.log(` • ${impact.operationType.replace(/_/g, ' ')}: ${impact.resourceHandle || impact.resourceType}${recordInfo}`);
97
+ if (impact.message) {
98
+ console.log(` ${impact.message}`);
99
+ }
100
+ }
101
+ console.log('');
102
+ console.log('These changes cannot be undone. Data will be permanently deleted.');
103
+ console.log('');
104
+ return new Promise((resolve) => {
105
+ rl.question('Do you want to proceed? (yes/no): ', (answer) => {
106
+ rl.close();
107
+ const normalized = answer.toLowerCase().trim();
108
+ resolve(normalized === 'yes' || normalized === 'y');
109
+ });
110
+ });
111
+ }
112
+ async function waitForMigrationApproval(serverUrl, token, migrationId, timeoutMs = 30 * 60 * 1000) {
113
+ const startTime = Date.now();
114
+ const pollInterval = 5000;
115
+ console.log('');
116
+ console.log('⏳ Waiting for migration approval in the Skedyul UI...');
117
+ console.log(` Migration ID: ${migrationId}`);
118
+ console.log(' (Press Ctrl+C to cancel)');
119
+ console.log('');
120
+ while (Date.now() - startTime < timeoutMs) {
121
+ try {
122
+ const response = await fetch(`${serverUrl}/api/cli/migration-status`, {
123
+ method: 'POST',
124
+ headers: {
125
+ 'Content-Type': 'application/json',
126
+ Authorization: `Bearer ${token}`,
127
+ },
128
+ body: JSON.stringify({ migrationId }),
129
+ });
130
+ if (!response.ok) {
131
+ throw new Error(`Failed to check migration status: ${response.statusText}`);
132
+ }
133
+ const data = await response.json();
134
+ if (data.status === 'APPROVED' || data.status === 'COMPLETED') {
135
+ return { approved: true, timedOut: false };
136
+ }
137
+ if (data.status === 'DENIED' || data.status === 'CANCELLED') {
138
+ return { approved: false, timedOut: false };
139
+ }
140
+ // Still pending, wait and poll again
141
+ const remaining = Math.ceil((timeoutMs - (Date.now() - startTime)) / 60000);
142
+ process.stdout.write(`\r Status: ${data.status} | Time remaining: ${remaining} minutes `);
143
+ }
144
+ catch {
145
+ // Ignore polling errors, continue waiting
146
+ }
147
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
148
+ }
149
+ return { approved: false, timedOut: true };
150
+ }
151
+ async function deployCommand(args) {
152
+ const { flags } = (0, utils_1.parseArgs)(args);
153
+ if (flags.help || flags.h) {
154
+ printHelp();
155
+ return;
156
+ }
157
+ const jsonOutput = Boolean(flags.json);
158
+ const dryRun = Boolean(flags['dry-run']);
159
+ const autoApprove = Boolean(flags.yes || flags.y);
160
+ const workplace = (flags.workplace || flags.w);
161
+ if (!workplace) {
162
+ if (jsonOutput) {
163
+ console.log(JSON.stringify({ error: 'Workplace is required' }));
164
+ }
165
+ else {
166
+ console.error('❌ Workplace is required');
167
+ console.error(' Use --workplace <subdomain> to specify the target workplace');
168
+ }
169
+ process.exit(1);
170
+ }
171
+ // Get auth token
172
+ const credentials = (0, auth_1.getCredentials)();
173
+ if (!credentials?.token) {
174
+ if (jsonOutput) {
175
+ console.log(JSON.stringify({ error: 'Not authenticated' }));
176
+ }
177
+ else {
178
+ console.error('❌ Not authenticated');
179
+ console.error(' Run: skedyul auth login');
180
+ }
181
+ process.exit(1);
182
+ }
183
+ const token = credentials.token;
184
+ const serverUrl = (0, auth_1.getServerUrl)();
185
+ // Find config file
186
+ let configPath = (flags.config || flags.c);
187
+ if (!configPath) {
188
+ const foundConfig = findConfigFile(process.cwd());
189
+ if (!foundConfig) {
190
+ if (jsonOutput) {
191
+ console.log(JSON.stringify({ error: 'No config file found' }));
192
+ }
193
+ else {
194
+ console.error('❌ No config file found');
195
+ console.error(` Create one of: ${config_1.CONFIG_FILE_NAMES.join(', ')}`);
196
+ }
197
+ process.exit(1);
198
+ }
199
+ configPath = foundConfig;
200
+ }
201
+ else {
202
+ configPath = path.resolve(process.cwd(), configPath);
203
+ }
204
+ if (!fs.existsSync(configPath)) {
205
+ if (jsonOutput) {
206
+ console.log(JSON.stringify({ error: `Config file not found: ${configPath}` }));
207
+ }
208
+ else {
209
+ console.error(`❌ Config file not found: ${configPath}`);
210
+ }
211
+ process.exit(1);
212
+ }
213
+ // Load config
214
+ let config;
215
+ try {
216
+ config = await (0, config_1.loadConfig)(configPath);
217
+ }
218
+ catch (error) {
219
+ if (jsonOutput) {
220
+ console.log(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
221
+ }
222
+ else {
223
+ console.error(`❌ Failed to load config: ${error instanceof Error ? error.message : String(error)}`);
224
+ }
225
+ process.exit(1);
226
+ }
227
+ // Validate config
228
+ const validation = (0, config_1.validateConfig)(config);
229
+ if (!validation.valid) {
230
+ if (jsonOutput) {
231
+ console.log(JSON.stringify({ error: 'Invalid config', errors: validation.errors }));
232
+ }
233
+ else {
234
+ console.error('❌ Config validation failed:');
235
+ for (const err of validation.errors) {
236
+ console.error(` • ${err}`);
237
+ }
238
+ }
239
+ process.exit(1);
240
+ }
241
+ if (!jsonOutput) {
242
+ console.log('');
243
+ console.log(`📦 Deploying ${config.name}${config.version ? ` v${config.version}` : ''}`);
244
+ console.log(` to ${workplace}`);
245
+ console.log('');
246
+ }
247
+ // Send deployment request
248
+ try {
249
+ const response = await fetch(`${serverUrl}/api/cli/deploy`, {
250
+ method: 'POST',
251
+ headers: {
252
+ 'Content-Type': 'application/json',
253
+ Authorization: `Bearer ${token}`,
254
+ },
255
+ body: JSON.stringify({
256
+ workplace,
257
+ config,
258
+ dryRun,
259
+ }),
260
+ });
261
+ if (!response.ok) {
262
+ const errorData = await response.json().catch(() => ({}));
263
+ throw new Error(errorData.error || `Deployment failed: ${response.statusText}`);
264
+ }
265
+ const result = await response.json();
266
+ if (jsonOutput) {
267
+ console.log(JSON.stringify(result, null, 2));
268
+ return;
269
+ }
270
+ if (dryRun) {
271
+ console.log('🔍 Dry run - no changes made');
272
+ console.log('');
273
+ if (result.impacts.length === 0) {
274
+ console.log('✅ No schema changes detected');
275
+ }
276
+ else {
277
+ console.log('Schema changes that would be applied:');
278
+ for (const impact of result.impacts) {
279
+ const prefix = impact.isDestructive ? '⚠️ ' : ' ';
280
+ const recordInfo = impact.affectedRecords
281
+ ? ` (${impact.affectedRecords.toLocaleString()} records)`
282
+ : '';
283
+ console.log(`${prefix}${impact.operationType.replace(/_/g, ' ')}: ${impact.resourceHandle || impact.resourceType}${recordInfo}`);
284
+ }
285
+ }
286
+ return;
287
+ }
288
+ // Handle approval flow
289
+ if (result.requiresApproval) {
290
+ if (autoApprove) {
291
+ // Auto-approve via CLI
292
+ const approved = await promptForApproval(result.impacts);
293
+ if (!approved) {
294
+ console.log('');
295
+ console.log('❌ Deployment cancelled');
296
+ process.exit(1);
297
+ }
298
+ // Send approval
299
+ const approvalResponse = await fetch(`${serverUrl}/api/cli/approve-migration`, {
300
+ method: 'POST',
301
+ headers: {
302
+ 'Content-Type': 'application/json',
303
+ Authorization: `Bearer ${token}`,
304
+ },
305
+ body: JSON.stringify({ migrationId: result.migrationId }),
306
+ });
307
+ if (!approvalResponse.ok) {
308
+ throw new Error('Failed to approve migration');
309
+ }
310
+ console.log('');
311
+ console.log('✅ Migration approved');
312
+ }
313
+ else {
314
+ // Wait for UI approval
315
+ const { approved, timedOut } = await waitForMigrationApproval(serverUrl, token, result.migrationId);
316
+ console.log('');
317
+ if (timedOut) {
318
+ console.log('⏰ Migration approval timed out');
319
+ console.log(' The migration has been automatically denied.');
320
+ process.exit(1);
321
+ }
322
+ if (!approved) {
323
+ console.log('❌ Migration was denied');
324
+ process.exit(1);
325
+ }
326
+ console.log('✅ Migration approved');
327
+ }
328
+ }
329
+ console.log('');
330
+ console.log('✅ Deployment successful!');
331
+ if (result.migrationId) {
332
+ console.log(` Migration ID: ${result.migrationId}`);
333
+ }
334
+ }
335
+ catch (error) {
336
+ if (jsonOutput) {
337
+ console.log(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
338
+ }
339
+ else {
340
+ console.error(`❌ Deployment failed: ${error instanceof Error ? error.message : String(error)}`);
341
+ }
342
+ process.exit(1);
343
+ }
344
+ }
package/dist/cli/index.js CHANGED
@@ -7,6 +7,7 @@ const tools_1 = require("./commands/tools");
7
7
  const serve_1 = require("./commands/serve");
8
8
  const validate_1 = require("./commands/validate");
9
9
  const diff_1 = require("./commands/diff");
10
+ const deploy_1 = require("./commands/deploy");
10
11
  const auth_1 = require("./commands/auth");
11
12
  const config_1 = require("./commands/config");
12
13
  const link_1 = require("./commands/link");
@@ -100,6 +101,7 @@ COMMANDS
100
101
  Deployment
101
102
  ──────────
102
103
  diff Show what would change on deploy
104
+ deploy Deploy your app to Skedyul
103
105
 
104
106
  STANDALONE MODE
105
107
  Test tools locally without connecting to Skedyul:
@@ -199,6 +201,9 @@ async function main() {
199
201
  case 'diff':
200
202
  await (0, diff_1.diffCommand)(subArgs);
201
203
  break;
204
+ case 'deploy':
205
+ await (0, deploy_1.deployCommand)(subArgs);
206
+ break;
202
207
  case 'link':
203
208
  await (0, link_1.linkCommand)(subArgs);
204
209
  break;
@@ -32,6 +32,7 @@ export type FieldType = 'string' | 'long_string' | 'text' | 'number' | 'boolean'
32
32
  export type OnDelete = 'none' | 'cascade' | 'restrict';
33
33
  /**
34
34
  * Inline field definition for constraints and options.
35
+ * @deprecated Use InlineFieldDefinition instead
35
36
  */
36
37
  export interface FieldConstraints {
37
38
  /** Limit number of selections for select fields */
@@ -51,6 +52,11 @@ export interface FieldConstraints {
51
52
  /** Regex pattern for validation */
52
53
  pattern?: string;
53
54
  }
55
+ /**
56
+ * Inline field definition for options and validation constraints.
57
+ * This is the preferred name - aligns with Zod schema and skedyul-core.
58
+ */
59
+ export type InlineFieldDefinition = FieldConstraints;
54
60
  /**
55
61
  * Field visibility settings in the UI.
56
62
  */
@@ -74,7 +80,9 @@ export interface FieldDefinition {
74
80
  type?: FieldType;
75
81
  /** Reference to a shared field definition by handle */
76
82
  definitionHandle?: string;
77
- /** Inline constraints and options */
83
+ /** Inline definition with options and constraints (preferred name) */
84
+ definition?: InlineFieldDefinition;
85
+ /** @deprecated Use 'definition' instead. Inline constraints and options */
78
86
  constraints?: FieldConstraints;
79
87
  /** Whether this field is required */
80
88
  required?: boolean;
@@ -107,6 +115,10 @@ export interface ModelDefinition extends BaseDefinition {
107
115
  fields: FieldDefinition[];
108
116
  /** Resource dependencies that must exist before this model can be used */
109
117
  requires?: ResourceDependency[];
118
+ /** Whether to create default LIST and INSTANCE pages for this model (default: false for provisioning) */
119
+ addDefaultPages?: boolean;
120
+ /** Whether to create a navigation item for this model (default: false for provisioning) */
121
+ addNavigation?: boolean;
110
122
  }
111
123
  /**
112
124
  * One side of a relationship link.
package/dist/schemas.d.ts CHANGED
@@ -123,6 +123,20 @@ export declare const ModelFieldDefinitionSchema: z.ZodObject<{
123
123
  relatedModel: z.ZodOptional<z.ZodString>;
124
124
  pattern: z.ZodOptional<z.ZodString>;
125
125
  }, z.core.$strip>>;
126
+ constraints: z.ZodOptional<z.ZodObject<{
127
+ limitChoices: z.ZodOptional<z.ZodNumber>;
128
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
129
+ label: z.ZodString;
130
+ value: z.ZodString;
131
+ color: z.ZodOptional<z.ZodString>;
132
+ }, z.core.$strip>>>;
133
+ minLength: z.ZodOptional<z.ZodNumber>;
134
+ maxLength: z.ZodOptional<z.ZodNumber>;
135
+ min: z.ZodOptional<z.ZodNumber>;
136
+ max: z.ZodOptional<z.ZodNumber>;
137
+ relatedModel: z.ZodOptional<z.ZodString>;
138
+ pattern: z.ZodOptional<z.ZodString>;
139
+ }, z.core.$strip>>;
126
140
  required: z.ZodOptional<z.ZodBoolean>;
127
141
  unique: z.ZodOptional<z.ZodBoolean>;
128
142
  system: z.ZodOptional<z.ZodBoolean>;
@@ -179,6 +193,20 @@ export declare const ModelDefinitionSchema: z.ZodObject<{
179
193
  relatedModel: z.ZodOptional<z.ZodString>;
180
194
  pattern: z.ZodOptional<z.ZodString>;
181
195
  }, z.core.$strip>>;
196
+ constraints: z.ZodOptional<z.ZodObject<{
197
+ limitChoices: z.ZodOptional<z.ZodNumber>;
198
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
199
+ label: z.ZodString;
200
+ value: z.ZodString;
201
+ color: z.ZodOptional<z.ZodString>;
202
+ }, z.core.$strip>>>;
203
+ minLength: z.ZodOptional<z.ZodNumber>;
204
+ maxLength: z.ZodOptional<z.ZodNumber>;
205
+ min: z.ZodOptional<z.ZodNumber>;
206
+ max: z.ZodOptional<z.ZodNumber>;
207
+ relatedModel: z.ZodOptional<z.ZodString>;
208
+ pattern: z.ZodOptional<z.ZodString>;
209
+ }, z.core.$strip>>;
182
210
  required: z.ZodOptional<z.ZodBoolean>;
183
211
  unique: z.ZodOptional<z.ZodBoolean>;
184
212
  system: z.ZodOptional<z.ZodBoolean>;
@@ -207,6 +235,8 @@ export declare const ModelDefinitionSchema: z.ZodObject<{
207
235
  }, z.core.$strip>, z.ZodObject<{
208
236
  workflow: z.ZodString;
209
237
  }, z.core.$strip>]>>>;
238
+ addDefaultPages: z.ZodOptional<z.ZodBoolean>;
239
+ addNavigation: z.ZodOptional<z.ZodBoolean>;
210
240
  }, z.core.$strip>;
211
241
  export declare const RelationshipCardinalitySchema: z.ZodEnum<{
212
242
  ONE_TO_ONE: "ONE_TO_ONE";
@@ -2821,6 +2851,20 @@ export declare const InstallConfigSchema: z.ZodObject<{
2821
2851
  relatedModel: z.ZodOptional<z.ZodString>;
2822
2852
  pattern: z.ZodOptional<z.ZodString>;
2823
2853
  }, z.core.$strip>>;
2854
+ constraints: z.ZodOptional<z.ZodObject<{
2855
+ limitChoices: z.ZodOptional<z.ZodNumber>;
2856
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
2857
+ label: z.ZodString;
2858
+ value: z.ZodString;
2859
+ color: z.ZodOptional<z.ZodString>;
2860
+ }, z.core.$strip>>>;
2861
+ minLength: z.ZodOptional<z.ZodNumber>;
2862
+ maxLength: z.ZodOptional<z.ZodNumber>;
2863
+ min: z.ZodOptional<z.ZodNumber>;
2864
+ max: z.ZodOptional<z.ZodNumber>;
2865
+ relatedModel: z.ZodOptional<z.ZodString>;
2866
+ pattern: z.ZodOptional<z.ZodString>;
2867
+ }, z.core.$strip>>;
2824
2868
  required: z.ZodOptional<z.ZodBoolean>;
2825
2869
  unique: z.ZodOptional<z.ZodBoolean>;
2826
2870
  system: z.ZodOptional<z.ZodBoolean>;
@@ -2849,6 +2893,8 @@ export declare const InstallConfigSchema: z.ZodObject<{
2849
2893
  }, z.core.$strip>, z.ZodObject<{
2850
2894
  workflow: z.ZodString;
2851
2895
  }, z.core.$strip>]>>>;
2896
+ addDefaultPages: z.ZodOptional<z.ZodBoolean>;
2897
+ addNavigation: z.ZodOptional<z.ZodBoolean>;
2852
2898
  }, z.core.$strip>>>;
2853
2899
  relationships: z.ZodOptional<z.ZodArray<z.ZodObject<{
2854
2900
  source: z.ZodObject<{
@@ -2921,6 +2967,20 @@ export declare const ProvisionConfigSchema: z.ZodObject<{
2921
2967
  relatedModel: z.ZodOptional<z.ZodString>;
2922
2968
  pattern: z.ZodOptional<z.ZodString>;
2923
2969
  }, z.core.$strip>>;
2970
+ constraints: z.ZodOptional<z.ZodObject<{
2971
+ limitChoices: z.ZodOptional<z.ZodNumber>;
2972
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
2973
+ label: z.ZodString;
2974
+ value: z.ZodString;
2975
+ color: z.ZodOptional<z.ZodString>;
2976
+ }, z.core.$strip>>>;
2977
+ minLength: z.ZodOptional<z.ZodNumber>;
2978
+ maxLength: z.ZodOptional<z.ZodNumber>;
2979
+ min: z.ZodOptional<z.ZodNumber>;
2980
+ max: z.ZodOptional<z.ZodNumber>;
2981
+ relatedModel: z.ZodOptional<z.ZodString>;
2982
+ pattern: z.ZodOptional<z.ZodString>;
2983
+ }, z.core.$strip>>;
2924
2984
  required: z.ZodOptional<z.ZodBoolean>;
2925
2985
  unique: z.ZodOptional<z.ZodBoolean>;
2926
2986
  system: z.ZodOptional<z.ZodBoolean>;
@@ -2949,6 +3009,8 @@ export declare const ProvisionConfigSchema: z.ZodObject<{
2949
3009
  }, z.core.$strip>, z.ZodObject<{
2950
3010
  workflow: z.ZodString;
2951
3011
  }, z.core.$strip>]>>>;
3012
+ addDefaultPages: z.ZodOptional<z.ZodBoolean>;
3013
+ addNavigation: z.ZodOptional<z.ZodBoolean>;
2952
3014
  }, z.core.$strip>>>;
2953
3015
  relationships: z.ZodOptional<z.ZodArray<z.ZodObject<{
2954
3016
  source: z.ZodObject<{
@@ -3546,6 +3608,20 @@ export declare const SkedyulConfigSchema: z.ZodObject<{
3546
3608
  relatedModel: z.ZodOptional<z.ZodString>;
3547
3609
  pattern: z.ZodOptional<z.ZodString>;
3548
3610
  }, z.core.$strip>>;
3611
+ constraints: z.ZodOptional<z.ZodObject<{
3612
+ limitChoices: z.ZodOptional<z.ZodNumber>;
3613
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
3614
+ label: z.ZodString;
3615
+ value: z.ZodString;
3616
+ color: z.ZodOptional<z.ZodString>;
3617
+ }, z.core.$strip>>>;
3618
+ minLength: z.ZodOptional<z.ZodNumber>;
3619
+ maxLength: z.ZodOptional<z.ZodNumber>;
3620
+ min: z.ZodOptional<z.ZodNumber>;
3621
+ max: z.ZodOptional<z.ZodNumber>;
3622
+ relatedModel: z.ZodOptional<z.ZodString>;
3623
+ pattern: z.ZodOptional<z.ZodString>;
3624
+ }, z.core.$strip>>;
3549
3625
  required: z.ZodOptional<z.ZodBoolean>;
3550
3626
  unique: z.ZodOptional<z.ZodBoolean>;
3551
3627
  system: z.ZodOptional<z.ZodBoolean>;
@@ -3574,6 +3650,8 @@ export declare const SkedyulConfigSchema: z.ZodObject<{
3574
3650
  }, z.core.$strip>, z.ZodObject<{
3575
3651
  workflow: z.ZodString;
3576
3652
  }, z.core.$strip>]>>>;
3653
+ addDefaultPages: z.ZodOptional<z.ZodBoolean>;
3654
+ addNavigation: z.ZodOptional<z.ZodBoolean>;
3577
3655
  }, z.core.$strip>>>;
3578
3656
  relationships: z.ZodOptional<z.ZodArray<z.ZodObject<{
3579
3657
  source: z.ZodObject<{
package/dist/schemas.js CHANGED
@@ -88,6 +88,7 @@ exports.ModelFieldDefinitionSchema = v4_1.z.object({
88
88
  type: exports.FieldDataTypeSchema.optional(),
89
89
  definitionHandle: v4_1.z.string().optional(),
90
90
  definition: exports.InlineFieldDefinitionSchema.optional(),
91
+ constraints: exports.InlineFieldDefinitionSchema.optional(), // Legacy alias for definition
91
92
  required: v4_1.z.boolean().optional(),
92
93
  unique: v4_1.z.boolean().optional(),
93
94
  system: v4_1.z.boolean().optional(),
@@ -105,6 +106,8 @@ exports.ModelDefinitionSchema = v4_1.z.object({
105
106
  description: v4_1.z.string().optional(),
106
107
  fields: v4_1.z.array(exports.ModelFieldDefinitionSchema),
107
108
  requires: v4_1.z.array(exports.ResourceDependencySchema).optional(),
109
+ addDefaultPages: v4_1.z.boolean().optional(),
110
+ addNavigation: v4_1.z.boolean().optional(),
108
111
  });
109
112
  // ─────────────────────────────────────────────────────────────────────────────
110
113
  // Relationship Schemas
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skedyul",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "The Skedyul SDK for Node.js",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",