@constela/core 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.
package/dist/index.d.ts CHANGED
@@ -10,6 +10,14 @@ declare const UPDATE_OPERATIONS: readonly ["increment", "decrement", "push", "po
10
10
  type UpdateOperation = (typeof UPDATE_OPERATIONS)[number];
11
11
  declare const HTTP_METHODS: readonly ["GET", "POST", "PUT", "DELETE"];
12
12
  type HttpMethod = (typeof HTTP_METHODS)[number];
13
+ declare const STORAGE_OPERATIONS: readonly ["get", "set", "remove"];
14
+ type StorageOperation = (typeof STORAGE_OPERATIONS)[number];
15
+ declare const STORAGE_TYPES: readonly ["local", "session"];
16
+ type StorageType = (typeof STORAGE_TYPES)[number];
17
+ declare const CLIPBOARD_OPERATIONS: readonly ["write", "read"];
18
+ type ClipboardOperation = (typeof CLIPBOARD_OPERATIONS)[number];
19
+ declare const NAVIGATE_TARGETS: readonly ["_self", "_blank"];
20
+ type NavigateTarget = (typeof NAVIGATE_TARGETS)[number];
13
21
  declare const PARAM_TYPES: readonly ["string", "number", "boolean", "json"];
14
22
  type ParamType = (typeof PARAM_TYPES)[number];
15
23
  interface ParamDef {
@@ -79,7 +87,31 @@ interface GetExpr {
79
87
  base: Expression;
80
88
  path: string;
81
89
  }
82
- type Expression = LitExpr | StateExpr | VarExpr | BinExpr | NotExpr | ParamExpr | CondExpr | GetExpr;
90
+ /**
91
+ * Route expression - references route parameters
92
+ */
93
+ interface RouteExpr {
94
+ expr: 'route';
95
+ name: string;
96
+ source?: 'param' | 'query' | 'path';
97
+ }
98
+ /**
99
+ * Import expression - references imported external data
100
+ */
101
+ interface ImportExpr {
102
+ expr: 'import';
103
+ name: string;
104
+ path?: string;
105
+ }
106
+ /**
107
+ * Data expression - references loaded data from data sources
108
+ */
109
+ interface DataExpr {
110
+ expr: 'data';
111
+ name: string;
112
+ path?: string;
113
+ }
114
+ type Expression = LitExpr | StateExpr | VarExpr | BinExpr | NotExpr | ParamExpr | CondExpr | GetExpr | RouteExpr | ImportExpr | DataExpr;
83
115
  /**
84
116
  * Number state field
85
117
  */
@@ -164,7 +196,40 @@ interface FetchStep {
164
196
  onSuccess?: ActionStep[];
165
197
  onError?: ActionStep[];
166
198
  }
167
- type ActionStep = SetStep | UpdateStep | FetchStep;
199
+ /**
200
+ * Storage step - localStorage/sessionStorage operations
201
+ */
202
+ interface StorageStep {
203
+ do: 'storage';
204
+ operation: StorageOperation;
205
+ key: Expression;
206
+ value?: Expression;
207
+ storage: StorageType;
208
+ result?: string;
209
+ onSuccess?: ActionStep[];
210
+ onError?: ActionStep[];
211
+ }
212
+ /**
213
+ * Clipboard step - clipboard API operations
214
+ */
215
+ interface ClipboardStep {
216
+ do: 'clipboard';
217
+ operation: ClipboardOperation;
218
+ value?: Expression;
219
+ result?: string;
220
+ onSuccess?: ActionStep[];
221
+ onError?: ActionStep[];
222
+ }
223
+ /**
224
+ * Navigate step - page navigation
225
+ */
226
+ interface NavigateStep {
227
+ do: 'navigate';
228
+ url: Expression;
229
+ target?: NavigateTarget;
230
+ replace?: boolean;
231
+ }
232
+ type ActionStep = SetStep | UpdateStep | FetchStep | StorageStep | ClipboardStep | NavigateStep;
168
233
  /**
169
234
  * Event handler - binds an event to an action
170
235
  */
@@ -227,9 +292,11 @@ interface ComponentNode {
227
292
  }
228
293
  /**
229
294
  * Slot node - placeholder for children in component definition
295
+ * For layouts, can have an optional name for named slots
230
296
  */
231
297
  interface SlotNode {
232
298
  kind: 'slot';
299
+ name?: string;
233
300
  }
234
301
  /**
235
302
  * Markdown node - renders markdown content
@@ -251,17 +318,83 @@ interface ComponentDef {
251
318
  params?: Record<string, ParamDef>;
252
319
  view: ViewNode;
253
320
  }
321
+ /**
322
+ * Data transform types for build-time content loading
323
+ */
324
+ declare const DATA_TRANSFORMS: readonly ["mdx", "yaml", "csv"];
325
+ type DataTransform = (typeof DATA_TRANSFORMS)[number];
326
+ /**
327
+ * Data source types
328
+ */
329
+ declare const DATA_SOURCE_TYPES: readonly ["glob", "file", "api"];
330
+ type DataSourceType = (typeof DATA_SOURCE_TYPES)[number];
331
+ /**
332
+ * Data source for build-time content loading
333
+ */
334
+ interface DataSource {
335
+ type: DataSourceType;
336
+ pattern?: string;
337
+ path?: string;
338
+ url?: string;
339
+ transform?: DataTransform;
340
+ }
341
+ /**
342
+ * Static paths definition for SSG
343
+ */
344
+ interface StaticPathsDefinition {
345
+ source: string;
346
+ params: Record<string, Expression>;
347
+ }
348
+ /**
349
+ * Route definition for a page
350
+ */
351
+ interface RouteDefinition {
352
+ path: string;
353
+ title?: Expression;
354
+ layout?: string;
355
+ meta?: Record<string, Expression>;
356
+ getStaticPaths?: StaticPathsDefinition;
357
+ }
358
+ /**
359
+ * Lifecycle hooks for component/page lifecycle events
360
+ */
361
+ interface LifecycleHooks {
362
+ onMount?: string;
363
+ onUnmount?: string;
364
+ onRouteEnter?: string;
365
+ onRouteLeave?: string;
366
+ }
254
367
  /**
255
368
  * Program - the root of a Constela AST
256
369
  */
257
370
  interface Program {
258
371
  version: '1.0';
372
+ route?: RouteDefinition;
373
+ imports?: Record<string, string>;
374
+ data?: Record<string, DataSource>;
375
+ lifecycle?: LifecycleHooks;
259
376
  state: Record<string, StateField>;
260
377
  actions: ActionDefinition[];
261
378
  view: ViewNode;
262
379
  components?: Record<string, ComponentDef>;
263
380
  }
264
381
  type ConstelaAst = Program;
382
+ /**
383
+ * Layout program - a special type of program that wraps page content
384
+ * Must contain at least one SlotNode in the view tree
385
+ */
386
+ interface LayoutProgram {
387
+ version: '1.0';
388
+ type: 'layout';
389
+ state?: Record<string, StateField>;
390
+ actions?: ActionDefinition[];
391
+ view: ViewNode;
392
+ components?: Record<string, ComponentDef>;
393
+ }
394
+ /**
395
+ * Union type for both regular Program and LayoutProgram
396
+ */
397
+ type ConstelaProgram = Program | LayoutProgram;
265
398
 
266
399
  /**
267
400
  * Type Guards for Constela AST Types
@@ -325,6 +458,30 @@ declare function isCondExpr(value: unknown): value is CondExpr;
325
458
  * Use the AST validator for full recursive validation instead.
326
459
  */
327
460
  declare function isGetExpr(value: unknown): value is GetExpr;
461
+ /**
462
+ * Checks if value is a route expression
463
+ */
464
+ declare function isRouteExpr(value: unknown): value is RouteExpr;
465
+ /**
466
+ * Checks if value is an import expression
467
+ */
468
+ declare function isImportExpr(value: unknown): value is ImportExpr;
469
+ /**
470
+ * Checks if value is a data expression
471
+ */
472
+ declare function isDataExpr(value: unknown): value is DataExpr;
473
+ /**
474
+ * Checks if value is a data source
475
+ */
476
+ declare function isDataSource(value: unknown): value is DataSource;
477
+ /**
478
+ * Checks if value is a static paths definition
479
+ */
480
+ declare function isStaticPathsDefinition(value: unknown): value is StaticPathsDefinition;
481
+ /**
482
+ * Checks if value is a route definition
483
+ */
484
+ declare function isRouteDefinition(value: unknown): value is RouteDefinition;
328
485
  /**
329
486
  * Checks if value is any valid expression
330
487
  */
@@ -377,6 +534,18 @@ declare function isUpdateStep(value: unknown): value is UpdateStep;
377
534
  * Checks if value is a fetch step
378
535
  */
379
536
  declare function isFetchStep(value: unknown): value is FetchStep;
537
+ /**
538
+ * Checks if value is a storage step
539
+ */
540
+ declare function isStorageStep(value: unknown): value is StorageStep;
541
+ /**
542
+ * Checks if value is a clipboard step
543
+ */
544
+ declare function isClipboardStep(value: unknown): value is ClipboardStep;
545
+ /**
546
+ * Checks if value is a navigate step
547
+ */
548
+ declare function isNavigateStep(value: unknown): value is NavigateStep;
380
549
  /**
381
550
  * Checks if value is any valid action step
382
551
  */
@@ -409,6 +578,23 @@ declare function isStateField(value: unknown): value is StateField;
409
578
  * Checks if value is an event handler
410
579
  */
411
580
  declare function isEventHandler(value: unknown): value is EventHandler;
581
+ /**
582
+ * Checks if value is a layout program
583
+ */
584
+ declare function isLayoutProgram(value: unknown): value is LayoutProgram;
585
+ /**
586
+ * Checks if value is a named slot node (slot with a name property)
587
+ */
588
+ declare function isNamedSlotNode(value: unknown): value is SlotNode & {
589
+ name: string;
590
+ };
591
+ /**
592
+ * Checks if value is a lifecycle hooks object
593
+ *
594
+ * Lifecycle hooks are permissive - they allow unknown properties for extensibility.
595
+ * Only known properties are validated to be strings.
596
+ */
597
+ declare function isLifecycleHooks(value: unknown): value is LifecycleHooks;
412
598
 
413
599
  /**
414
600
  * Error Types for Constela
@@ -416,7 +602,7 @@ declare function isEventHandler(value: unknown): value is EventHandler;
416
602
  * This module defines error types, the ConstelaError class,
417
603
  * and factory functions for creating specific errors.
418
604
  */
419
- type ErrorCode = 'SCHEMA_INVALID' | 'UNDEFINED_STATE' | 'UNDEFINED_ACTION' | 'VAR_UNDEFINED' | 'DUPLICATE_ACTION' | 'UNSUPPORTED_VERSION' | 'COMPONENT_NOT_FOUND' | 'COMPONENT_PROP_MISSING' | 'COMPONENT_CYCLE' | 'COMPONENT_PROP_TYPE' | 'PARAM_UNDEFINED' | 'OPERATION_INVALID_FOR_TYPE' | 'OPERATION_MISSING_FIELD' | 'OPERATION_UNKNOWN' | 'EXPR_INVALID_BASE' | 'EXPR_INVALID_CONDITION' | 'EXPR_COND_ELSE_REQUIRED';
605
+ type ErrorCode = 'SCHEMA_INVALID' | 'UNDEFINED_STATE' | 'UNDEFINED_ACTION' | 'VAR_UNDEFINED' | 'DUPLICATE_ACTION' | 'UNSUPPORTED_VERSION' | 'COMPONENT_NOT_FOUND' | 'COMPONENT_PROP_MISSING' | 'COMPONENT_CYCLE' | 'COMPONENT_PROP_TYPE' | 'PARAM_UNDEFINED' | 'OPERATION_INVALID_FOR_TYPE' | 'OPERATION_MISSING_FIELD' | 'OPERATION_UNKNOWN' | 'EXPR_INVALID_BASE' | 'EXPR_INVALID_CONDITION' | 'EXPR_COND_ELSE_REQUIRED' | 'UNDEFINED_ROUTE_PARAM' | 'ROUTE_NOT_DEFINED' | 'UNDEFINED_IMPORT' | 'IMPORTS_NOT_DEFINED' | 'LAYOUT_MISSING_SLOT' | 'LAYOUT_NOT_FOUND' | 'INVALID_SLOT_NAME' | 'DUPLICATE_SLOT_NAME' | 'DUPLICATE_DEFAULT_SLOT' | 'SLOT_IN_LOOP' | 'INVALID_DATA_SOURCE' | 'UNDEFINED_DATA_SOURCE' | 'DATA_NOT_DEFINED' | 'UNDEFINED_DATA' | 'INVALID_STORAGE_OPERATION' | 'INVALID_STORAGE_TYPE' | 'STORAGE_SET_MISSING_VALUE' | 'INVALID_CLIPBOARD_OPERATION' | 'CLIPBOARD_WRITE_MISSING_VALUE' | 'INVALID_NAVIGATE_TARGET';
420
606
  /**
421
607
  * Custom error class for Constela validation errors
422
608
  */
@@ -497,6 +683,86 @@ declare function createOperationUnknownError(operation: string, path?: string):
497
683
  * Creates a cond else required error
498
684
  */
499
685
  declare function createCondElseRequiredError(path?: string): ConstelaError;
686
+ /**
687
+ * Creates an undefined route param error
688
+ */
689
+ declare function createUndefinedRouteParamError(paramName: string, path?: string): ConstelaError;
690
+ /**
691
+ * Creates a route not defined error
692
+ */
693
+ declare function createRouteNotDefinedError(path?: string): ConstelaError;
694
+ /**
695
+ * Creates an undefined import reference error
696
+ */
697
+ declare function createUndefinedImportError(importName: string, path?: string): ConstelaError;
698
+ /**
699
+ * Creates an imports not defined error
700
+ */
701
+ declare function createImportsNotDefinedError(path?: string): ConstelaError;
702
+ /**
703
+ * Creates a layout missing slot error
704
+ */
705
+ declare function createLayoutMissingSlotError(path?: string): ConstelaError;
706
+ /**
707
+ * Creates a layout not found error
708
+ */
709
+ declare function createLayoutNotFoundError(layoutName: string, path?: string): ConstelaError;
710
+ /**
711
+ * Creates an invalid slot name error
712
+ */
713
+ declare function createInvalidSlotNameError(slotName: string, layoutName: string, path?: string): ConstelaError;
714
+ /**
715
+ * Creates a duplicate slot name error
716
+ */
717
+ declare function createDuplicateSlotNameError(slotName: string, path?: string): ConstelaError;
718
+ /**
719
+ * Creates a duplicate default slot error
720
+ */
721
+ declare function createDuplicateDefaultSlotError(path?: string): ConstelaError;
722
+ /**
723
+ * Creates a slot in loop error
724
+ */
725
+ declare function createSlotInLoopError(path?: string): ConstelaError;
726
+ /**
727
+ * Creates an invalid data source error
728
+ */
729
+ declare function createInvalidDataSourceError(dataName: string, reason: string, path?: string): ConstelaError;
730
+ /**
731
+ * Creates an undefined data source error (for getStaticPaths)
732
+ */
733
+ declare function createUndefinedDataSourceError(sourceName: string, path?: string): ConstelaError;
734
+ /**
735
+ * Creates a data not defined error (for data or getStaticPaths used without data field)
736
+ */
737
+ declare function createDataNotDefinedError(path?: string): ConstelaError;
738
+ /**
739
+ * Creates an undefined data error (for DataExpr references)
740
+ */
741
+ declare function createUndefinedDataError(dataName: string, path?: string): ConstelaError;
742
+ /**
743
+ * Creates an invalid storage operation error
744
+ */
745
+ declare function createInvalidStorageOperationError(operation: string, path?: string): ConstelaError;
746
+ /**
747
+ * Creates an invalid storage type error
748
+ */
749
+ declare function createInvalidStorageTypeError(storageType: string, path?: string): ConstelaError;
750
+ /**
751
+ * Creates a storage set missing value error
752
+ */
753
+ declare function createStorageSetMissingValueError(path?: string): ConstelaError;
754
+ /**
755
+ * Creates an invalid clipboard operation error
756
+ */
757
+ declare function createInvalidClipboardOperationError(operation: string, path?: string): ConstelaError;
758
+ /**
759
+ * Creates a clipboard write missing value error
760
+ */
761
+ declare function createClipboardWriteMissingValueError(path?: string): ConstelaError;
762
+ /**
763
+ * Creates an invalid navigate target error
764
+ */
765
+ declare function createInvalidNavigateTargetError(target: string, path?: string): ConstelaError;
500
766
 
501
767
  /**
502
768
  * AST Validator for Constela
@@ -1141,4 +1407,4 @@ declare const astSchema: {
1141
1407
  };
1142
1408
  };
1143
1409
 
1144
- export { type ActionDefinition, type ActionStep, BINARY_OPERATORS, type BinExpr, type BinaryOperator, type BooleanField, type CodeNode, type ComponentDef, type ComponentNode, type CondExpr, type ConstelaAst, ConstelaError, type EachNode, type ElementNode, type ErrorCode, type EventHandler, type Expression, type FetchStep, type GetExpr, HTTP_METHODS, type HttpMethod, type IfNode, type ListField, type LitExpr, type MarkdownNode, type NotExpr, type NumberField, type ObjectField, PARAM_TYPES, type ParamDef, type ParamExpr, type ParamType, type Program, type SetStep, type SlotNode, type StateExpr, type StateField, type StringField, type TextNode, UPDATE_OPERATIONS, type UpdateOperation, type UpdateStep, type ValidationFailure, type ValidationResult, type ValidationSuccess, type VarExpr, type ViewNode, astSchema, createComponentCycleError, createComponentNotFoundError, createComponentPropMissingError, createComponentPropTypeError, createCondElseRequiredError, createDuplicateActionError, createOperationInvalidForTypeError, createOperationMissingFieldError, createOperationUnknownError, createSchemaError, createUndefinedActionError, createUndefinedParamError, createUndefinedStateError, createUndefinedVarError, createUnsupportedVersionError, isActionStep, isBinExpr, isBooleanField, isCodeNode, isComponentNode, isCondExpr, isConstelaError, isEachNode, isElementNode, isEventHandler, isExpression, isFetchStep, isGetExpr, isIfNode, isListField, isLitExpr, isMarkdownNode, isNotExpr, isNumberField, isObjectField, isParamExpr, isSetStep, isSlotNode, isStateExpr, isStateField, isStringField, isTextNode, isUpdateStep, isVarExpr, isViewNode, validateAst };
1410
+ export { type ActionDefinition, type ActionStep, BINARY_OPERATORS, type BinExpr, type BinaryOperator, type BooleanField, CLIPBOARD_OPERATIONS, type ClipboardOperation, type ClipboardStep, type CodeNode, type ComponentDef, type ComponentNode, type CondExpr, type ConstelaAst, ConstelaError, type ConstelaProgram, DATA_SOURCE_TYPES, DATA_TRANSFORMS, type DataExpr, type DataSource, type DataSourceType, type DataTransform, type EachNode, type ElementNode, type ErrorCode, type EventHandler, type Expression, type FetchStep, type GetExpr, HTTP_METHODS, type HttpMethod, type IfNode, type ImportExpr, type LayoutProgram, type LifecycleHooks, type ListField, type LitExpr, type MarkdownNode, NAVIGATE_TARGETS, type NavigateStep, type NavigateTarget, type NotExpr, type NumberField, type ObjectField, PARAM_TYPES, type ParamDef, type ParamExpr, type ParamType, type Program, type RouteDefinition, type RouteExpr, STORAGE_OPERATIONS, STORAGE_TYPES, type SetStep, type SlotNode, type StateExpr, type StateField, type StaticPathsDefinition, type StorageOperation, type StorageStep, type StorageType, type StringField, type TextNode, UPDATE_OPERATIONS, type UpdateOperation, type UpdateStep, type ValidationFailure, type ValidationResult, type ValidationSuccess, type VarExpr, type ViewNode, astSchema, createClipboardWriteMissingValueError, createComponentCycleError, createComponentNotFoundError, createComponentPropMissingError, createComponentPropTypeError, createCondElseRequiredError, createDataNotDefinedError, createDuplicateActionError, createDuplicateDefaultSlotError, createDuplicateSlotNameError, createImportsNotDefinedError, createInvalidClipboardOperationError, createInvalidDataSourceError, createInvalidNavigateTargetError, createInvalidSlotNameError, createInvalidStorageOperationError, createInvalidStorageTypeError, createLayoutMissingSlotError, createLayoutNotFoundError, createOperationInvalidForTypeError, createOperationMissingFieldError, createOperationUnknownError, createRouteNotDefinedError, createSchemaError, createSlotInLoopError, createStorageSetMissingValueError, createUndefinedActionError, createUndefinedDataError, createUndefinedDataSourceError, createUndefinedImportError, createUndefinedParamError, createUndefinedRouteParamError, createUndefinedStateError, createUndefinedVarError, createUnsupportedVersionError, isActionStep, isBinExpr, isBooleanField, isClipboardStep, isCodeNode, isComponentNode, isCondExpr, isConstelaError, isDataExpr, isDataSource, isEachNode, isElementNode, isEventHandler, isExpression, isFetchStep, isGetExpr, isIfNode, isImportExpr, isLayoutProgram, isLifecycleHooks, isListField, isLitExpr, isMarkdownNode, isNamedSlotNode, isNavigateStep, isNotExpr, isNumberField, isObjectField, isParamExpr, isRouteDefinition, isRouteExpr, isSetStep, isSlotNode, isStateExpr, isStateField, isStaticPathsDefinition, isStorageStep, isStringField, isTextNode, isUpdateStep, isVarExpr, isViewNode, validateAst };
package/dist/index.js CHANGED
@@ -26,7 +26,13 @@ var UPDATE_OPERATIONS = [
26
26
  "splice"
27
27
  ];
28
28
  var HTTP_METHODS = ["GET", "POST", "PUT", "DELETE"];
29
+ var STORAGE_OPERATIONS = ["get", "set", "remove"];
30
+ var STORAGE_TYPES = ["local", "session"];
31
+ var CLIPBOARD_OPERATIONS = ["write", "read"];
32
+ var NAVIGATE_TARGETS = ["_self", "_blank"];
29
33
  var PARAM_TYPES = ["string", "number", "boolean", "json"];
34
+ var DATA_TRANSFORMS = ["mdx", "yaml", "csv"];
35
+ var DATA_SOURCE_TYPES = ["glob", "file", "api"];
30
36
 
31
37
  // src/types/guards.ts
32
38
  function isObject(value) {
@@ -84,8 +90,71 @@ function isGetExpr(value) {
84
90
  if (typeof value["path"] !== "string") return false;
85
91
  return true;
86
92
  }
93
+ function isRouteExpr(value) {
94
+ if (!isObject(value)) return false;
95
+ if (value["expr"] !== "route") return false;
96
+ if (typeof value["name"] !== "string") return false;
97
+ if ("source" in value && value["source"] !== void 0) {
98
+ const validSources = ["param", "query", "path"];
99
+ if (!validSources.includes(value["source"])) return false;
100
+ }
101
+ return true;
102
+ }
103
+ function isImportExpr(value) {
104
+ if (!isObject(value)) return false;
105
+ if (value["expr"] !== "import") return false;
106
+ if (typeof value["name"] !== "string") return false;
107
+ if ("path" in value && value["path"] !== void 0) {
108
+ if (typeof value["path"] !== "string") return false;
109
+ }
110
+ return true;
111
+ }
112
+ function isDataExpr(value) {
113
+ if (!isObject(value)) return false;
114
+ if (value["expr"] !== "data") return false;
115
+ if (typeof value["name"] !== "string") return false;
116
+ if ("path" in value && value["path"] !== void 0) {
117
+ if (typeof value["path"] !== "string") return false;
118
+ }
119
+ return true;
120
+ }
121
+ function isDataSource(value) {
122
+ if (!isObject(value)) return false;
123
+ const type = value["type"];
124
+ if (!DATA_SOURCE_TYPES.includes(type)) {
125
+ return false;
126
+ }
127
+ if ("transform" in value && value["transform"] !== void 0) {
128
+ if (!DATA_TRANSFORMS.includes(value["transform"])) {
129
+ return false;
130
+ }
131
+ }
132
+ switch (type) {
133
+ case "glob":
134
+ if (typeof value["pattern"] !== "string") return false;
135
+ break;
136
+ case "file":
137
+ if (typeof value["path"] !== "string") return false;
138
+ break;
139
+ case "api":
140
+ if (typeof value["url"] !== "string") return false;
141
+ break;
142
+ }
143
+ return true;
144
+ }
145
+ function isStaticPathsDefinition(value) {
146
+ if (!isObject(value)) return false;
147
+ if (typeof value["source"] !== "string") return false;
148
+ if (!("params" in value) || !isObject(value["params"])) return false;
149
+ return true;
150
+ }
151
+ function isRouteDefinition(value) {
152
+ if (!isObject(value)) return false;
153
+ if (typeof value["path"] !== "string") return false;
154
+ return true;
155
+ }
87
156
  function isExpression(value) {
88
- return isLitExpr(value) || isStateExpr(value) || isVarExpr(value) || isBinExpr(value) || isNotExpr(value) || isParamExpr(value) || isCondExpr(value) || isGetExpr(value);
157
+ return isLitExpr(value) || isStateExpr(value) || isVarExpr(value) || isBinExpr(value) || isNotExpr(value) || isParamExpr(value) || isCondExpr(value) || isGetExpr(value) || isRouteExpr(value) || isImportExpr(value) || isDataExpr(value);
89
158
  }
90
159
  function isElementNode(value) {
91
160
  if (!isObject(value)) return false;
@@ -170,8 +239,39 @@ function isFetchStep(value) {
170
239
  }
171
240
  return true;
172
241
  }
242
+ function isStorageStep(value) {
243
+ if (!isObject(value)) return false;
244
+ if (value["do"] !== "storage") return false;
245
+ if (!STORAGE_OPERATIONS.includes(value["operation"])) {
246
+ return false;
247
+ }
248
+ if (!STORAGE_TYPES.includes(value["storage"])) {
249
+ return false;
250
+ }
251
+ if (!("key" in value)) return false;
252
+ return true;
253
+ }
254
+ function isClipboardStep(value) {
255
+ if (!isObject(value)) return false;
256
+ if (value["do"] !== "clipboard") return false;
257
+ if (!CLIPBOARD_OPERATIONS.includes(value["operation"])) {
258
+ return false;
259
+ }
260
+ return true;
261
+ }
262
+ function isNavigateStep(value) {
263
+ if (!isObject(value)) return false;
264
+ if (value["do"] !== "navigate") return false;
265
+ if (!("url" in value)) return false;
266
+ if ("target" in value && value["target"] !== void 0) {
267
+ if (!NAVIGATE_TARGETS.includes(value["target"])) {
268
+ return false;
269
+ }
270
+ }
271
+ return true;
272
+ }
173
273
  function isActionStep(value) {
174
- return isSetStep(value) || isUpdateStep(value) || isFetchStep(value);
274
+ return isSetStep(value) || isUpdateStep(value) || isFetchStep(value) || isStorageStep(value) || isClipboardStep(value) || isNavigateStep(value);
175
275
  }
176
276
  function isNumberField(value) {
177
277
  if (!isObject(value)) return false;
@@ -207,6 +307,37 @@ function isEventHandler(value) {
207
307
  if (!("action" in value) || typeof value["action"] !== "string") return false;
208
308
  return true;
209
309
  }
310
+ function isLayoutProgram(value) {
311
+ if (!isObject(value)) return false;
312
+ if (value["version"] !== "1.0") return false;
313
+ if (value["type"] !== "layout") return false;
314
+ if (!("view" in value)) return false;
315
+ return true;
316
+ }
317
+ function isNamedSlotNode(value) {
318
+ if (!isObject(value)) return false;
319
+ if (value["kind"] !== "slot") return false;
320
+ if (typeof value["name"] !== "string") return false;
321
+ return true;
322
+ }
323
+ function isLifecycleHooks(value) {
324
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
325
+ return false;
326
+ }
327
+ const obj = value;
328
+ const knownFields = ["onMount", "onUnmount", "onRouteEnter", "onRouteLeave"];
329
+ for (const key of knownFields) {
330
+ if (key in obj && obj[key] !== void 0) {
331
+ if (typeof obj[key] !== "string") return false;
332
+ }
333
+ }
334
+ for (const key of Object.keys(obj)) {
335
+ if (!knownFields.includes(key)) {
336
+ if (typeof obj[key] !== "string") return false;
337
+ }
338
+ }
339
+ return true;
340
+ }
210
341
 
211
342
  // src/types/error.ts
212
343
  var ConstelaError = class _ConstelaError extends Error {
@@ -334,6 +465,146 @@ function createCondElseRequiredError(path) {
334
465
  path
335
466
  );
336
467
  }
468
+ function createUndefinedRouteParamError(paramName, path) {
469
+ return new ConstelaError(
470
+ "UNDEFINED_ROUTE_PARAM",
471
+ `Undefined route param reference: '${paramName}' is not defined in route path`,
472
+ path
473
+ );
474
+ }
475
+ function createRouteNotDefinedError(path) {
476
+ return new ConstelaError(
477
+ "ROUTE_NOT_DEFINED",
478
+ `Route expression used but no route is defined in the program`,
479
+ path
480
+ );
481
+ }
482
+ function createUndefinedImportError(importName, path) {
483
+ return new ConstelaError(
484
+ "UNDEFINED_IMPORT",
485
+ `Undefined import reference: '${importName}' is not defined in imports`,
486
+ path
487
+ );
488
+ }
489
+ function createImportsNotDefinedError(path) {
490
+ return new ConstelaError(
491
+ "IMPORTS_NOT_DEFINED",
492
+ `Import expression used but no imports are defined in the program`,
493
+ path
494
+ );
495
+ }
496
+ function createLayoutMissingSlotError(path) {
497
+ return new ConstelaError(
498
+ "LAYOUT_MISSING_SLOT",
499
+ `Layout must contain at least one slot node for page content`,
500
+ path
501
+ );
502
+ }
503
+ function createLayoutNotFoundError(layoutName, path) {
504
+ return new ConstelaError(
505
+ "LAYOUT_NOT_FOUND",
506
+ `Layout '${layoutName}' is not found`,
507
+ path
508
+ );
509
+ }
510
+ function createInvalidSlotNameError(slotName, layoutName, path) {
511
+ return new ConstelaError(
512
+ "INVALID_SLOT_NAME",
513
+ `Named slot '${slotName}' does not exist in layout '${layoutName}'`,
514
+ path
515
+ );
516
+ }
517
+ function createDuplicateSlotNameError(slotName, path) {
518
+ return new ConstelaError(
519
+ "DUPLICATE_SLOT_NAME",
520
+ `Duplicate named slot '${slotName}' found in layout`,
521
+ path
522
+ );
523
+ }
524
+ function createDuplicateDefaultSlotError(path) {
525
+ return new ConstelaError(
526
+ "DUPLICATE_DEFAULT_SLOT",
527
+ `Layout contains multiple default (unnamed) slots`,
528
+ path
529
+ );
530
+ }
531
+ function createSlotInLoopError(path) {
532
+ return new ConstelaError(
533
+ "SLOT_IN_LOOP",
534
+ `Slot cannot be placed inside a loop (each node) as it would render multiple times`,
535
+ path
536
+ );
537
+ }
538
+ function createInvalidDataSourceError(dataName, reason, path) {
539
+ return new ConstelaError(
540
+ "INVALID_DATA_SOURCE",
541
+ `Invalid data source '${dataName}': ${reason}`,
542
+ path
543
+ );
544
+ }
545
+ function createUndefinedDataSourceError(sourceName, path) {
546
+ return new ConstelaError(
547
+ "UNDEFINED_DATA_SOURCE",
548
+ `Undefined data source reference: '${sourceName}' is not defined in data`,
549
+ path
550
+ );
551
+ }
552
+ function createDataNotDefinedError(path) {
553
+ return new ConstelaError(
554
+ "DATA_NOT_DEFINED",
555
+ `Data expression or getStaticPaths used but no data is defined in the program`,
556
+ path
557
+ );
558
+ }
559
+ function createUndefinedDataError(dataName, path) {
560
+ return new ConstelaError(
561
+ "UNDEFINED_DATA",
562
+ `Undefined data reference: '${dataName}' is not defined in data`,
563
+ path
564
+ );
565
+ }
566
+ function createInvalidStorageOperationError(operation, path) {
567
+ return new ConstelaError(
568
+ "INVALID_STORAGE_OPERATION",
569
+ `Invalid storage operation: '${operation}'. Valid operations are: get, set, remove`,
570
+ path
571
+ );
572
+ }
573
+ function createInvalidStorageTypeError(storageType, path) {
574
+ return new ConstelaError(
575
+ "INVALID_STORAGE_TYPE",
576
+ `Invalid storage type: '${storageType}'. Valid types are: local, session`,
577
+ path
578
+ );
579
+ }
580
+ function createStorageSetMissingValueError(path) {
581
+ return new ConstelaError(
582
+ "STORAGE_SET_MISSING_VALUE",
583
+ `Storage 'set' operation requires a 'value' field`,
584
+ path
585
+ );
586
+ }
587
+ function createInvalidClipboardOperationError(operation, path) {
588
+ return new ConstelaError(
589
+ "INVALID_CLIPBOARD_OPERATION",
590
+ `Invalid clipboard operation: '${operation}'. Valid operations are: write, read`,
591
+ path
592
+ );
593
+ }
594
+ function createClipboardWriteMissingValueError(path) {
595
+ return new ConstelaError(
596
+ "CLIPBOARD_WRITE_MISSING_VALUE",
597
+ `Clipboard 'write' operation requires a 'value' field`,
598
+ path
599
+ );
600
+ }
601
+ function createInvalidNavigateTargetError(target, path) {
602
+ return new ConstelaError(
603
+ "INVALID_NAVIGATE_TARGET",
604
+ `Invalid navigate target: '${target}'. Valid targets are: _self, _blank`,
605
+ path
606
+ );
607
+ }
337
608
 
338
609
  // src/schema/validator.ts
339
610
  function isObject2(value) {
@@ -1299,33 +1570,62 @@ var astSchema = {
1299
1570
  };
1300
1571
  export {
1301
1572
  BINARY_OPERATORS,
1573
+ CLIPBOARD_OPERATIONS,
1302
1574
  ConstelaError,
1575
+ DATA_SOURCE_TYPES,
1576
+ DATA_TRANSFORMS,
1303
1577
  HTTP_METHODS,
1578
+ NAVIGATE_TARGETS,
1304
1579
  PARAM_TYPES,
1580
+ STORAGE_OPERATIONS,
1581
+ STORAGE_TYPES,
1305
1582
  UPDATE_OPERATIONS,
1306
1583
  astSchema,
1584
+ createClipboardWriteMissingValueError,
1307
1585
  createComponentCycleError,
1308
1586
  createComponentNotFoundError,
1309
1587
  createComponentPropMissingError,
1310
1588
  createComponentPropTypeError,
1311
1589
  createCondElseRequiredError,
1590
+ createDataNotDefinedError,
1312
1591
  createDuplicateActionError,
1592
+ createDuplicateDefaultSlotError,
1593
+ createDuplicateSlotNameError,
1594
+ createImportsNotDefinedError,
1595
+ createInvalidClipboardOperationError,
1596
+ createInvalidDataSourceError,
1597
+ createInvalidNavigateTargetError,
1598
+ createInvalidSlotNameError,
1599
+ createInvalidStorageOperationError,
1600
+ createInvalidStorageTypeError,
1601
+ createLayoutMissingSlotError,
1602
+ createLayoutNotFoundError,
1313
1603
  createOperationInvalidForTypeError,
1314
1604
  createOperationMissingFieldError,
1315
1605
  createOperationUnknownError,
1606
+ createRouteNotDefinedError,
1316
1607
  createSchemaError,
1608
+ createSlotInLoopError,
1609
+ createStorageSetMissingValueError,
1317
1610
  createUndefinedActionError,
1611
+ createUndefinedDataError,
1612
+ createUndefinedDataSourceError,
1613
+ createUndefinedImportError,
1318
1614
  createUndefinedParamError,
1615
+ createUndefinedRouteParamError,
1319
1616
  createUndefinedStateError,
1320
1617
  createUndefinedVarError,
1321
1618
  createUnsupportedVersionError,
1322
1619
  isActionStep,
1323
1620
  isBinExpr,
1324
1621
  isBooleanField,
1622
+ isClipboardStep,
1325
1623
  isCodeNode,
1326
1624
  isComponentNode,
1327
1625
  isCondExpr,
1328
1626
  isConstelaError,
1627
+ isDataExpr,
1628
+ isDataSource,
1329
1629
  isEachNode,
1330
1630
  isElementNode,
1331
1631
  isEventHandler,
@@ -1333,17 +1633,26 @@ export {
1333
1633
  isFetchStep,
1334
1634
  isGetExpr,
1335
1635
  isIfNode,
1636
+ isImportExpr,
1637
+ isLayoutProgram,
1638
+ isLifecycleHooks,
1336
1639
  isListField,
1337
1640
  isLitExpr,
1338
1641
  isMarkdownNode,
1642
+ isNamedSlotNode,
1643
+ isNavigateStep,
1339
1644
  isNotExpr,
1340
1645
  isNumberField,
1341
1646
  isObjectField,
1342
1647
  isParamExpr,
1648
+ isRouteDefinition,
1649
+ isRouteExpr,
1343
1650
  isSetStep,
1344
1651
  isSlotNode,
1345
1652
  isStateExpr,
1346
1653
  isStateField,
1654
+ isStaticPathsDefinition,
1655
+ isStorageStep,
1347
1656
  isStringField,
1348
1657
  isTextNode,
1349
1658
  isUpdateStep,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constela/core",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Core types, schema, and validator for Constela UI framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",