@azlib/cms 0.2.0 → 0.4.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.cts CHANGED
@@ -1,195 +1,3 @@
1
- //#region src/core/types.d.ts
2
- /**
3
- * @azlib/cms - Universal Domain Types & Interfaces
4
- */
5
- type ContentStatus = "draft" | "pending_review" | "scheduled" | "published" | "private" | "trash";
6
- type FieldType = "text" | "slug" | "richText" | "number" | "boolean" | "select" | "image" | "taxonomy" | "relationship" | "date" | "json" | "repeater";
7
- interface SelectOption {
8
- readonly label: string;
9
- readonly value: string | number;
10
- }
11
- interface FieldDefinition<TValue = any> {
12
- readonly name: string;
13
- readonly type: FieldType;
14
- readonly label?: string;
15
- readonly description?: string;
16
- readonly required?: boolean;
17
- readonly defaultValue?: TValue;
18
- readonly unique?: boolean;
19
- readonly options?: readonly (string | SelectOption)[];
20
- readonly taxonomy?: string;
21
- readonly targetCollection?: string;
22
- readonly fromField?: string;
23
- readonly fields?: readonly FieldDefinition[];
24
- readonly min?: number;
25
- readonly max?: number;
26
- readonly pattern?: string;
27
- readonly validate?: (value: any, data: Record<string, unknown>) => string | null | boolean;
28
- }
29
- interface CollectionConfig {
30
- readonly slug: string;
31
- readonly label: string;
32
- readonly singularLabel?: string;
33
- readonly description?: string;
34
- readonly hierarchical?: boolean;
35
- readonly timestamps?: boolean;
36
- readonly revisions?: boolean;
37
- readonly draftable?: boolean;
38
- readonly fields: readonly FieldDefinition[];
39
- readonly taxonomies?: readonly string[];
40
- readonly defaultSort?: {
41
- readonly field: string;
42
- readonly direction: "asc" | "desc";
43
- };
44
- }
45
- interface ContentItem<TData extends Record<string, unknown> = Record<string, unknown>> {
46
- id: string;
47
- collection: string;
48
- slug: string;
49
- status: ContentStatus;
50
- title?: string;
51
- parentId?: string | null;
52
- authorId?: string | null;
53
- publishedAt?: string | null;
54
- scheduledAt?: string | null;
55
- createdAt: string;
56
- updatedAt: string;
57
- version: number;
58
- data: TData;
59
- terms?: Record<string, string[]>;
60
- }
61
- interface ContentQueryOptions {
62
- status?: ContentStatus | ContentStatus[];
63
- authorId?: string;
64
- parentId?: string | null;
65
- termIds?: string[];
66
- search?: string;
67
- where?: Record<string, unknown>;
68
- orderBy?: string;
69
- orderDirection?: "asc" | "desc";
70
- limit?: number;
71
- offset?: number;
72
- includeRevisions?: boolean;
73
- includeTerms?: boolean;
74
- }
75
- interface PaginatedResult<T> {
76
- items: T[];
77
- total: number;
78
- limit: number;
79
- offset: number;
80
- hasMore: boolean;
81
- }
82
- interface RevisionRecord {
83
- id: string;
84
- contentId: string;
85
- collection: string;
86
- version: number;
87
- snapshot: ContentItem;
88
- authorId?: string | null;
89
- note?: string;
90
- createdAt: string;
91
- }
92
- interface RevisionDiffField {
93
- field: string;
94
- oldValue: unknown;
95
- newValue: unknown;
96
- }
97
- interface RevisionDiff {
98
- contentId: string;
99
- fromVersion: number;
100
- toVersion: number;
101
- changes: RevisionDiffField[];
102
- }
103
- interface TaxonomyConfig {
104
- readonly slug: string;
105
- readonly label: string;
106
- readonly singularLabel?: string;
107
- readonly hierarchical?: boolean;
108
- readonly postTypes?: readonly string[];
109
- readonly description?: string;
110
- }
111
- interface TermItem {
112
- id: string;
113
- taxonomy: string;
114
- name: string;
115
- slug: string;
116
- description?: string;
117
- parentId?: string | null;
118
- count: number;
119
- meta?: Record<string, unknown>;
120
- createdAt: string;
121
- updatedAt: string;
122
- }
123
- interface TermTreeItem extends TermItem {
124
- children: TermTreeItem[];
125
- }
126
- interface MediaItem {
127
- id: string;
128
- filename: string;
129
- originalName: string;
130
- mimeType: string;
131
- sizeBytes: number;
132
- url: string;
133
- path?: string;
134
- width?: number;
135
- height?: number;
136
- altText?: string;
137
- caption?: string;
138
- authorId?: string | null;
139
- variants?: Record<string, string>;
140
- createdAt: string;
141
- updatedAt: string;
142
- }
143
- interface OptionItem<T = unknown> {
144
- key: string;
145
- value: T;
146
- autoload: boolean;
147
- namespace?: string;
148
- updatedAt: string;
149
- }
150
- type UserRole = "admin" | "editor" | "author" | "contributor" | "subscriber" | (string & {});
151
- type CMSCapability = "manage_options" | "manage_taxonomies" | "upload_files" | "delete_files" | "edit_posts" | "edit_others_posts" | "publish_posts" | "delete_posts" | "delete_others_posts" | "read_private_posts" | (string & {});
152
- interface CMSUser {
153
- id: string;
154
- username: string;
155
- email: string;
156
- displayName: string;
157
- role: UserRole;
158
- capabilities?: string[];
159
- active?: boolean;
160
- }
161
- interface SiteConfig {
162
- name: string;
163
- description?: string;
164
- url?: string;
165
- logo?: string;
166
- locale?: string;
167
- timezone?: string;
168
- }
169
- interface CMSConfig {
170
- site?: SiteConfig;
171
- collections: readonly CollectionConfig[];
172
- taxonomies?: readonly TaxonomyConfig[];
173
- admin?: {
174
- route?: string;
175
- enableRegistration?: boolean;
176
- };
177
- }
178
- //#endregion
179
- //#region src/core/config.d.ts
180
- /**
181
- * Default standard collections provided when not explicitly specified.
182
- */
183
- declare const DEFAULT_COLLECTIONS: CollectionConfig[];
184
- /**
185
- * Type-safe configuration helper function for azlib.config.ts.
186
- */
187
- declare function defineConfig(config: CMSConfig): CMSConfig;
188
- /**
189
- * Normalize and merge user config with CMS defaults.
190
- */
191
- declare function normalizeConfig(config: Partial<CMSConfig>): CMSConfig;
192
- //#endregion
193
1
  //#region src/core/hooks.d.ts
194
2
  /**
195
3
  * @azlib/cms - WordPress-style Action and Filter Hook System
@@ -565,13 +373,48 @@ declare class CMSEngine {
565
373
  readonly revisions: RevisionManager;
566
374
  readonly lifecycle: ContentLifecycle;
567
375
  private collections;
376
+ private plugins;
377
+ private customRoutes;
378
+ private pendingPluginSetups;
568
379
  constructor(config?: Partial<CMSConfig>, storage?: CMSStorageAdapter, hooks?: HooksManager);
380
+ /**
381
+ * Register a plugin with the CMS engine.
382
+ */
383
+ use(plugin: CMSPlugin): this;
384
+ /**
385
+ * Get all registered plugins.
386
+ */
387
+ getPlugins(): readonly CMSPlugin[];
388
+ /**
389
+ * Get a registered plugin by name.
390
+ */
391
+ getPlugin(name: string): CMSPlugin | undefined;
392
+ /**
393
+ * Check if a plugin is registered.
394
+ */
395
+ hasPlugin(name: string): boolean;
396
+ /**
397
+ * Register a collection dynamically.
398
+ */
399
+ registerCollection(coll: CollectionConfig): void;
400
+ /**
401
+ * Inject additional field definitions into an existing collection.
402
+ */
403
+ extendCollection(slug: string, newFields: readonly FieldDefinition[]): void;
404
+ /**
405
+ * Register a custom Web Standard HTTP route on the engine.
406
+ */
407
+ registerRoute(method: string, path: string, handler: CustomRouteHandler): void;
408
+ /**
409
+ * Get all custom routes registered across all HTTP methods.
410
+ */
411
+ getCustomRoutes(): Map<string, Map<string, CustomRouteHandler>>;
569
412
  /**
570
413
  * Initialize storage and trigger bootstrap hooks.
571
414
  */
572
415
  init(): Promise<void>;
573
416
  /**
574
- * Close storage connections.
417
+ * Close storage connections and run plugin teardown hooks.
575
418
  */
576
419
  close(): Promise<void>;
577
420
  /**
@@ -596,40 +439,309 @@ declare class CMSEngine {
596
439
  */
597
440
  declare function createCMSEngine(config?: Partial<CMSConfig>, storage?: CMSStorageAdapter, hooks?: HooksManager): CMSEngine;
598
441
  //#endregion
599
- //#region src/content/schema.d.ts
600
- interface TextFieldOptions {
601
- name: string;
602
- label?: string;
603
- description?: string;
604
- required?: boolean;
605
- defaultValue?: string;
606
- unique?: boolean;
607
- min?: number;
608
- max?: number;
609
- pattern?: string;
610
- validate?: (value: string, data: Record<string, unknown>) => string | null | boolean;
611
- }
612
- interface SlugFieldOptions {
613
- name?: string;
614
- label?: string;
615
- from?: string;
616
- required?: boolean;
617
- unique?: boolean;
442
+ //#region src/core/plugin.d.ts
443
+ interface RouteContext {
444
+ readonly params: Record<string, string>;
445
+ readonly url: URL;
446
+ readonly engine: CMSEngine;
618
447
  }
619
- interface RichTextFieldOptions {
620
- name: string;
621
- label?: string;
622
- description?: string;
623
- required?: boolean;
624
- defaultValue?: string;
448
+ type CustomRouteHandler = (request: Request, context: RouteContext) => Promise<Response> | Response;
449
+ interface CMSPluginContext {
450
+ readonly engine: CMSEngine;
451
+ readonly hooks: HooksManager;
452
+ readonly storage: CMSStorageAdapter;
453
+ readonly options: OptionsManager;
454
+ readonly taxonomies: TaxonomyManager;
455
+ readonly media: MediaManager;
456
+ readonly rbac: RBACManager;
457
+ readonly revisions: RevisionManager;
458
+ readonly lifecycle: ContentLifecycle;
459
+ /**
460
+ * Register a new collection dynamically.
461
+ */
462
+ registerCollection(config: CollectionConfig): void;
463
+ /**
464
+ * Extend an existing collection with additional field definitions.
465
+ */
466
+ extendCollection(collectionSlug: string, fields: readonly FieldDefinition[]): void;
467
+ /**
468
+ * Register a new taxonomy dynamically.
469
+ */
470
+ registerTaxonomy(config: TaxonomyConfig): void;
471
+ /**
472
+ * Register a custom Web Standard HTTP route on the CMS router.
473
+ */
474
+ registerRoute(method: string, path: string, handler: CustomRouteHandler): void;
625
475
  }
626
- interface NumberFieldOptions {
627
- name: string;
628
- label?: string;
629
- description?: string;
630
- required?: boolean;
631
- defaultValue?: number;
632
- min?: number;
476
+ interface CMSPlugin {
477
+ /**
478
+ * Unique name of the plugin (e.g. "@azlib/cms-plugin-seo", "audit-log").
479
+ */
480
+ readonly name: string;
481
+ /**
482
+ * Optional semantic version string.
483
+ */
484
+ readonly version?: string;
485
+ /**
486
+ * Optional human-readable description.
487
+ */
488
+ readonly description?: string;
489
+ /**
490
+ * Declarative new collections provided by this plugin.
491
+ */
492
+ readonly collections?: readonly CollectionConfig[];
493
+ /**
494
+ * Declarative new taxonomies provided by this plugin.
495
+ */
496
+ readonly taxonomies?: readonly TaxonomyConfig[];
497
+ /**
498
+ * Declarative field extensions to inject into existing collections.
499
+ * Maps collection slug -> array of field definitions.
500
+ */
501
+ readonly extendCollections?: Record<string, readonly FieldDefinition[]>;
502
+ /**
503
+ * Setup hook called when the plugin is registered with the engine.
504
+ * Allows programmatic registration of hooks, routes, services, and schema extensions.
505
+ */
506
+ setup?: (context: CMSPluginContext) => void | Promise<void>;
507
+ /**
508
+ * Lifecycle hook executed during cms.init().
509
+ */
510
+ onInit?: (engine: CMSEngine) => void | Promise<void>;
511
+ /**
512
+ * Lifecycle hook executed during cms.close().
513
+ */
514
+ onClose?: (engine: CMSEngine) => void | Promise<void>;
515
+ }
516
+ /**
517
+ * Type-safe helper for authoring reusable CMS plugins and plugin factories.
518
+ */
519
+ declare function definePlugin<TOptions = void>(factory: (options: TOptions) => CMSPlugin): void extends TOptions ? (options?: TOptions) => CMSPlugin : undefined extends TOptions ? (options?: TOptions) => CMSPlugin : (options: TOptions) => CMSPlugin;
520
+ //#endregion
521
+ //#region src/core/types.d.ts
522
+ type ContentStatus = "draft" | "pending_review" | "scheduled" | "published" | "private" | "trash";
523
+ type FieldType = "text" | "slug" | "richText" | "number" | "boolean" | "select" | "image" | "taxonomy" | "relationship" | "date" | "json" | "repeater";
524
+ interface SelectOption {
525
+ readonly label: string;
526
+ readonly value: string | number;
527
+ }
528
+ interface FieldDefinition<TValue = any> {
529
+ readonly name: string;
530
+ readonly type: FieldType;
531
+ readonly label?: string;
532
+ readonly description?: string;
533
+ readonly required?: boolean;
534
+ readonly defaultValue?: TValue;
535
+ readonly unique?: boolean;
536
+ readonly options?: readonly (string | SelectOption)[];
537
+ readonly taxonomy?: string;
538
+ readonly targetCollection?: string;
539
+ readonly fromField?: string;
540
+ readonly fields?: readonly FieldDefinition[];
541
+ readonly min?: number;
542
+ readonly max?: number;
543
+ readonly pattern?: string;
544
+ readonly validate?: (value: any, data: Record<string, unknown>) => string | null | boolean;
545
+ }
546
+ interface CollectionConfig {
547
+ readonly slug: string;
548
+ readonly label: string;
549
+ readonly singularLabel?: string;
550
+ readonly description?: string;
551
+ readonly hierarchical?: boolean;
552
+ readonly timestamps?: boolean;
553
+ readonly revisions?: boolean;
554
+ readonly draftable?: boolean;
555
+ readonly fields: readonly FieldDefinition[];
556
+ readonly taxonomies?: readonly string[];
557
+ readonly defaultSort?: {
558
+ readonly field: string;
559
+ readonly direction: "asc" | "desc";
560
+ };
561
+ }
562
+ interface ContentItem<TData extends Record<string, unknown> = Record<string, unknown>> {
563
+ id: string;
564
+ collection: string;
565
+ slug: string;
566
+ status: ContentStatus;
567
+ title?: string;
568
+ parentId?: string | null;
569
+ authorId?: string | null;
570
+ publishedAt?: string | null;
571
+ scheduledAt?: string | null;
572
+ createdAt: string;
573
+ updatedAt: string;
574
+ version: number;
575
+ data: TData;
576
+ terms?: Record<string, string[]>;
577
+ }
578
+ interface ContentQueryOptions {
579
+ status?: ContentStatus | ContentStatus[];
580
+ authorId?: string;
581
+ parentId?: string | null;
582
+ termIds?: string[];
583
+ search?: string;
584
+ where?: Record<string, unknown>;
585
+ orderBy?: string;
586
+ orderDirection?: "asc" | "desc";
587
+ limit?: number;
588
+ offset?: number;
589
+ includeRevisions?: boolean;
590
+ includeTerms?: boolean;
591
+ }
592
+ interface PaginatedResult<T> {
593
+ items: T[];
594
+ total: number;
595
+ limit: number;
596
+ offset: number;
597
+ hasMore: boolean;
598
+ }
599
+ interface RevisionRecord {
600
+ id: string;
601
+ contentId: string;
602
+ collection: string;
603
+ version: number;
604
+ snapshot: ContentItem;
605
+ authorId?: string | null;
606
+ note?: string;
607
+ createdAt: string;
608
+ }
609
+ interface RevisionDiffField {
610
+ field: string;
611
+ oldValue: unknown;
612
+ newValue: unknown;
613
+ }
614
+ interface RevisionDiff {
615
+ contentId: string;
616
+ fromVersion: number;
617
+ toVersion: number;
618
+ changes: RevisionDiffField[];
619
+ }
620
+ interface TaxonomyConfig {
621
+ readonly slug: string;
622
+ readonly label: string;
623
+ readonly singularLabel?: string;
624
+ readonly hierarchical?: boolean;
625
+ readonly postTypes?: readonly string[];
626
+ readonly description?: string;
627
+ }
628
+ interface TermItem {
629
+ id: string;
630
+ taxonomy: string;
631
+ name: string;
632
+ slug: string;
633
+ description?: string;
634
+ parentId?: string | null;
635
+ count: number;
636
+ meta?: Record<string, unknown>;
637
+ createdAt: string;
638
+ updatedAt: string;
639
+ }
640
+ interface TermTreeItem extends TermItem {
641
+ children: TermTreeItem[];
642
+ }
643
+ interface MediaItem {
644
+ id: string;
645
+ filename: string;
646
+ originalName: string;
647
+ mimeType: string;
648
+ sizeBytes: number;
649
+ url: string;
650
+ path?: string;
651
+ width?: number;
652
+ height?: number;
653
+ altText?: string;
654
+ caption?: string;
655
+ authorId?: string | null;
656
+ variants?: Record<string, string>;
657
+ createdAt: string;
658
+ updatedAt: string;
659
+ }
660
+ interface OptionItem<T = unknown> {
661
+ key: string;
662
+ value: T;
663
+ autoload: boolean;
664
+ namespace?: string;
665
+ updatedAt: string;
666
+ }
667
+ type UserRole = "admin" | "editor" | "author" | "contributor" | "subscriber" | (string & {});
668
+ type CMSCapability = "manage_options" | "manage_taxonomies" | "upload_files" | "delete_files" | "edit_posts" | "edit_others_posts" | "publish_posts" | "delete_posts" | "delete_others_posts" | "read_private_posts" | (string & {});
669
+ interface CMSUser {
670
+ id: string;
671
+ username: string;
672
+ email: string;
673
+ displayName: string;
674
+ role: UserRole;
675
+ capabilities?: string[];
676
+ active?: boolean;
677
+ }
678
+ interface SiteConfig {
679
+ name: string;
680
+ description?: string;
681
+ url?: string;
682
+ logo?: string;
683
+ locale?: string;
684
+ timezone?: string;
685
+ }
686
+ interface CMSConfig {
687
+ site?: SiteConfig;
688
+ collections: readonly CollectionConfig[];
689
+ taxonomies?: readonly TaxonomyConfig[];
690
+ plugins?: readonly CMSPlugin[];
691
+ admin?: {
692
+ route?: string;
693
+ enableRegistration?: boolean;
694
+ };
695
+ }
696
+ //#endregion
697
+ //#region src/core/config.d.ts
698
+ /**
699
+ * Default standard collections provided when not explicitly specified.
700
+ */
701
+ declare const DEFAULT_COLLECTIONS: CollectionConfig[];
702
+ /**
703
+ * Type-safe configuration helper function for azlib.config.ts.
704
+ */
705
+ declare function defineConfig(config: CMSConfig): CMSConfig;
706
+ /**
707
+ * Normalize and merge user config with CMS defaults.
708
+ */
709
+ declare function normalizeConfig(config: Partial<CMSConfig>): CMSConfig;
710
+ //#endregion
711
+ //#region src/content/schema.d.ts
712
+ interface TextFieldOptions {
713
+ name: string;
714
+ label?: string;
715
+ description?: string;
716
+ required?: boolean;
717
+ defaultValue?: string;
718
+ unique?: boolean;
719
+ min?: number;
720
+ max?: number;
721
+ pattern?: string;
722
+ validate?: (value: string, data: Record<string, unknown>) => string | null | boolean;
723
+ }
724
+ interface SlugFieldOptions {
725
+ name?: string;
726
+ label?: string;
727
+ from?: string;
728
+ required?: boolean;
729
+ unique?: boolean;
730
+ }
731
+ interface RichTextFieldOptions {
732
+ name: string;
733
+ label?: string;
734
+ description?: string;
735
+ required?: boolean;
736
+ defaultValue?: string;
737
+ }
738
+ interface NumberFieldOptions {
739
+ name: string;
740
+ label?: string;
741
+ description?: string;
742
+ required?: boolean;
743
+ defaultValue?: number;
744
+ min?: number;
633
745
  max?: number;
634
746
  }
635
747
  interface BooleanFieldOptions {
@@ -795,11 +907,17 @@ declare class MemoryStorageAdapter implements CMSStorageAdapter {
795
907
  //#region src/api/router.d.ts
796
908
  declare class CMSRouter {
797
909
  private engine;
910
+ private localRoutes;
798
911
  constructor(engine: CMSEngine);
912
+ /**
913
+ * Register a custom Web Standard route on the router.
914
+ */
915
+ registerRoute(method: string, path: string, handler: CustomRouteHandler): this;
799
916
  /**
800
917
  * Universal Web Standards request handler.
801
918
  */
802
919
  handle(request: Request): Promise<Response>;
920
+ private handleCustomRoute;
803
921
  private handleContent;
804
922
  private handleTaxonomies;
805
923
  private handleMedia;
@@ -828,6 +946,10 @@ declare class CMSClient {
828
946
  private fetchFn;
829
947
  private headers;
830
948
  constructor(options: CMSClientOptions);
949
+ /**
950
+ * Access underlying CMSEngine instance when in in-process mode.
951
+ */
952
+ getEngine(): CMSEngine | undefined;
831
953
  collection<TData extends Record<string, unknown> = Record<string, unknown>>(slug: string): ClientCollectionApi<TData>;
832
954
  readonly taxonomies: {
833
955
  getTerms: (taxonomy: string) => Promise<TermItem[]>;
@@ -843,9 +965,489 @@ declare class CMSClient {
843
965
  readonly options: {
844
966
  get: <T = unknown>(key: string, defaultValue?: T) => Promise<T | undefined>;
845
967
  };
846
- private request;
968
+ /**
969
+ * Perform an HTTP request against the CMS API (available in remote mode).
970
+ */
971
+ request<T>(endpoint: string, init?: RequestInit): Promise<T>;
847
972
  }
848
973
  declare function createCmsClient(options: CMSClientOptions): CMSClient;
849
974
  //#endregion
850
- export { type ActionCallback, type BooleanFieldOptions, CMSCapability, CMSClient, type CMSClientOptions, CMSConfig, CMSEngine, CMSRouter, type CMSStorageAdapter, CMSUser, type ClientCollectionApi, CollectionConfig, type CollectionOptions, type CollectionService, ContentItem, ContentLifecycle, ContentQueryOptions, ContentStatus, type CreateContentInput, DEFAULT_COLLECTIONS, DEFAULT_ROLE_CAPABILITIES, type DateFieldOptions, FieldDefinition, FieldType, type FilterCallback, type HookEntry, HooksManager, type ImageFieldOptions, type JsonFieldOptions, MediaItem, MediaManager, type MediaUploadInput, MemoryStorageAdapter, type NumberFieldOptions, OptionItem, OptionsManager, PaginatedResult, RBACManager, type RelationshipFieldOptions, type RepeaterFieldOptions, RevisionDiff, RevisionDiffField, RevisionManager, RevisionRecord, type RichTextFieldOptions, type SelectFieldOptions, SelectOption, SiteConfig, type SlugFieldOptions, type SyncFilterCallback, TaxonomyConfig, type TaxonomyFieldOptions, TaxonomyManager, TermItem, TermTreeItem, type TextFieldOptions, type UpdateContentInput, UserRole, VALID_STATUS_TRANSITIONS, collection, createCMSEngine, createCMSRouter, createCmsClient, defaultHooks, defineConfig, fields, normalizeConfig, resolveUniqueSlug, slugify, validateAndNormalizeData };
975
+ //#region src/plugins/ecommerce/types.d.ts
976
+ type ProductStatus = "draft" | "published" | "out_of_stock" | "archived";
977
+ interface ProductVariant {
978
+ readonly id: string;
979
+ readonly title: string;
980
+ readonly sku?: string;
981
+ readonly price?: number;
982
+ readonly compareAtPrice?: number;
983
+ readonly stock?: number;
984
+ readonly attributes?: Record<string, string>;
985
+ readonly image?: string;
986
+ }
987
+ interface ProductImage {
988
+ readonly id?: string;
989
+ readonly url: string;
990
+ readonly altText?: string;
991
+ readonly caption?: string;
992
+ readonly width?: number;
993
+ readonly height?: number;
994
+ }
995
+ interface ProductData extends Record<string, unknown> {
996
+ sku?: string;
997
+ price: number;
998
+ compareAtPrice?: number;
999
+ costPrice?: number;
1000
+ currency?: string;
1001
+ stock: number;
1002
+ trackInventory?: boolean;
1003
+ status: ProductStatus;
1004
+ description?: string;
1005
+ shortDescription?: string;
1006
+ featuredImage?: string;
1007
+ gallery?: ProductImage[];
1008
+ variants?: ProductVariant[];
1009
+ attributes?: Record<string, unknown>;
1010
+ weight?: number;
1011
+ }
1012
+ type ProductItem = ContentItem<ProductData>;
1013
+ type DiscountType = "percentage" | "fixed_amount" | "free_shipping";
1014
+ type DiscountStatus = "active" | "disabled" | "expired";
1015
+ interface DiscountData extends Record<string, unknown> {
1016
+ code: string;
1017
+ discountType: DiscountType;
1018
+ value: number;
1019
+ minOrderAmount?: number;
1020
+ maxDiscountAmount?: number;
1021
+ maxUses?: number;
1022
+ usedCount: number;
1023
+ startDate?: string;
1024
+ endDate?: string;
1025
+ status: DiscountStatus;
1026
+ appliesToProductIds?: string[];
1027
+ appliesToCategoryIds?: string[];
1028
+ }
1029
+ type DiscountItem = ContentItem<DiscountData>;
1030
+ type OrderStatus = "pending" | "paid" | "processing" | "shipped" | "delivered" | "cancelled" | "refunded";
1031
+ interface OrderLineItem {
1032
+ productId: string;
1033
+ variantId?: string;
1034
+ title: string;
1035
+ sku?: string;
1036
+ price: number;
1037
+ quantity: number;
1038
+ subtotal: number;
1039
+ image?: string;
1040
+ }
1041
+ interface OrderAddress {
1042
+ firstName?: string;
1043
+ lastName?: string;
1044
+ company?: string;
1045
+ address1: string;
1046
+ address2?: string;
1047
+ city: string;
1048
+ province?: string;
1049
+ country: string;
1050
+ postalCode: string;
1051
+ phone?: string;
1052
+ }
1053
+ interface OrderData extends Record<string, unknown> {
1054
+ orderNumber: string;
1055
+ customerEmail: string;
1056
+ customerName?: string;
1057
+ status: OrderStatus;
1058
+ currency: string;
1059
+ items: OrderLineItem[];
1060
+ subtotal: number;
1061
+ discountTotal: number;
1062
+ discountCode?: string;
1063
+ shippingTotal: number;
1064
+ taxTotal: number;
1065
+ total: number;
1066
+ shippingAddress?: OrderAddress;
1067
+ billingAddress?: OrderAddress;
1068
+ paymentMethod?: string;
1069
+ notes?: string;
1070
+ }
1071
+ type OrderItem = ContentItem<OrderData>;
1072
+ interface EcommercePluginOptions {
1073
+ /**
1074
+ * Slug for the products collection. Default: "products"
1075
+ */
1076
+ readonly productCollectionSlug?: string;
1077
+ /**
1078
+ * Slug for the discounts collection. Default: "discounts"
1079
+ */
1080
+ readonly discountCollectionSlug?: string;
1081
+ /**
1082
+ * Slug for the orders collection. Default: "orders"
1083
+ */
1084
+ readonly orderCollectionSlug?: string;
1085
+ /**
1086
+ * Slug for the categories taxonomy. Default: "product_categories"
1087
+ */
1088
+ readonly categoriesTaxonomySlug?: string;
1089
+ /**
1090
+ * Slug for the tags taxonomy. Default: "product_tags"
1091
+ */
1092
+ readonly tagsTaxonomySlug?: string;
1093
+ /**
1094
+ * Slug for the brands taxonomy. Default: "product_brands"
1095
+ */
1096
+ readonly brandsTaxonomySlug?: string;
1097
+ /**
1098
+ * Default currency code. Default: "USD"
1099
+ */
1100
+ readonly defaultCurrency?: string;
1101
+ /**
1102
+ * REST API route prefix. Default: "/api/ecommerce"
1103
+ */
1104
+ readonly apiPrefix?: string;
1105
+ /**
1106
+ * Enable inventory management (decrement stock on orders, check availability). Default: true
1107
+ */
1108
+ readonly inventoryManagement?: boolean;
1109
+ /**
1110
+ * Enable orders collection and order routes. Default: true
1111
+ */
1112
+ readonly enableOrders?: boolean;
1113
+ /**
1114
+ * Enable discounts collection and discount calculation. Default: true
1115
+ */
1116
+ readonly enableDiscounts?: boolean;
1117
+ /**
1118
+ * Default flat tax rate multiplier (e.g. 0.08 for 8%). Default: 0
1119
+ */
1120
+ readonly defaultTaxRate?: number;
1121
+ /**
1122
+ * Default flat shipping cost. Default: 0
1123
+ */
1124
+ readonly defaultShippingCost?: number;
1125
+ }
1126
+ interface CreateProductInput {
1127
+ title: string;
1128
+ slug?: string;
1129
+ price: number;
1130
+ compareAtPrice?: number;
1131
+ costPrice?: number;
1132
+ sku?: string;
1133
+ currency?: string;
1134
+ stock?: number;
1135
+ trackInventory?: boolean;
1136
+ status?: ProductStatus;
1137
+ description?: string;
1138
+ shortDescription?: string;
1139
+ featuredImage?: string;
1140
+ gallery?: ProductImage[];
1141
+ variants?: ProductVariant[];
1142
+ attributes?: Record<string, unknown>;
1143
+ weight?: number;
1144
+ categoryIds?: string[];
1145
+ tagIds?: string[];
1146
+ brandIds?: string[];
1147
+ }
1148
+ interface UpdateProductInput {
1149
+ title?: string;
1150
+ slug?: string;
1151
+ price?: number;
1152
+ compareAtPrice?: number;
1153
+ costPrice?: number;
1154
+ sku?: string;
1155
+ currency?: string;
1156
+ stock?: number;
1157
+ trackInventory?: boolean;
1158
+ status?: ProductStatus;
1159
+ description?: string;
1160
+ shortDescription?: string;
1161
+ featuredImage?: string;
1162
+ gallery?: ProductImage[];
1163
+ variants?: ProductVariant[];
1164
+ attributes?: Record<string, unknown>;
1165
+ weight?: number;
1166
+ categoryIds?: string[];
1167
+ tagIds?: string[];
1168
+ brandIds?: string[];
1169
+ }
1170
+ interface CreateDiscountInput {
1171
+ title: string;
1172
+ code: string;
1173
+ discountType: DiscountType;
1174
+ value: number;
1175
+ minOrderAmount?: number;
1176
+ maxDiscountAmount?: number;
1177
+ maxUses?: number;
1178
+ startDate?: string;
1179
+ endDate?: string;
1180
+ status?: DiscountStatus;
1181
+ appliesToProductIds?: string[];
1182
+ appliesToCategoryIds?: string[];
1183
+ }
1184
+ interface CartItemInput {
1185
+ productId: string;
1186
+ variantId?: string;
1187
+ quantity: number;
1188
+ }
1189
+ interface CartCalculationInput {
1190
+ items: CartItemInput[];
1191
+ discountCode?: string;
1192
+ shippingCost?: number;
1193
+ taxRate?: number;
1194
+ }
1195
+ interface CartCalculationResult {
1196
+ items: OrderLineItem[];
1197
+ subtotal: number;
1198
+ discountTotal: number;
1199
+ discountCode?: string;
1200
+ shippingTotal: number;
1201
+ taxTotal: number;
1202
+ total: number;
1203
+ currency: string;
1204
+ }
1205
+ interface DiscountValidationResult {
1206
+ valid: boolean;
1207
+ code: string;
1208
+ message?: string;
1209
+ discountAmount: number;
1210
+ discountType?: DiscountType;
1211
+ discount?: DiscountItem;
1212
+ }
1213
+ interface CreateOrderInput {
1214
+ customerEmail: string;
1215
+ customerName?: string;
1216
+ items: CartItemInput[];
1217
+ discountCode?: string;
1218
+ shippingCost?: number;
1219
+ taxRate?: number;
1220
+ shippingAddress?: OrderAddress;
1221
+ billingAddress?: OrderAddress;
1222
+ paymentMethod?: string;
1223
+ notes?: string;
1224
+ }
1225
+ interface EcommerceProductQuery {
1226
+ categorySlug?: string;
1227
+ categoryId?: string;
1228
+ tagSlug?: string;
1229
+ brandSlug?: string;
1230
+ minPrice?: number;
1231
+ maxPrice?: number;
1232
+ inStock?: boolean;
1233
+ status?: ProductStatus | ProductStatus[];
1234
+ search?: string;
1235
+ orderBy?: "price" | "createdAt" | "title" | "stock";
1236
+ orderDirection?: "asc" | "desc";
1237
+ limit?: number;
1238
+ offset?: number;
1239
+ }
1240
+ //#endregion
1241
+ //#region src/plugins/ecommerce/service.d.ts
1242
+ declare class EcommerceService {
1243
+ readonly engine: CMSEngine;
1244
+ readonly options: EcommercePluginOptions;
1245
+ readonly productSlug: string;
1246
+ readonly discountSlug: string;
1247
+ readonly orderSlug: string;
1248
+ readonly categoriesTaxonomy: string;
1249
+ readonly tagsTaxonomy: string;
1250
+ readonly brandsTaxonomy: string;
1251
+ readonly defaultCurrency: string;
1252
+ readonly inventoryManagement: boolean;
1253
+ constructor(engine: CMSEngine, options?: EcommercePluginOptions);
1254
+ private get productsCollection();
1255
+ private get discountsCollection();
1256
+ private get ordersCollection();
1257
+ /**
1258
+ * Create a new product in the catalog.
1259
+ */
1260
+ createProduct(input: CreateProductInput, authorId?: string | null): Promise<ProductItem>;
1261
+ /**
1262
+ * Update an existing product.
1263
+ */
1264
+ updateProduct(id: string, input: UpdateProductInput, authorId?: string | null): Promise<ProductItem | null>;
1265
+ /**
1266
+ * Get a product by ID.
1267
+ */
1268
+ getProduct(id: string): Promise<ProductItem | null>;
1269
+ /**
1270
+ * Get a product by its URL slug.
1271
+ */
1272
+ getProductBySlug(slug: string): Promise<ProductItem | null>;
1273
+ /**
1274
+ * Delete a product by ID.
1275
+ */
1276
+ deleteProduct(id: string): Promise<boolean>;
1277
+ /**
1278
+ * List and filter catalog products.
1279
+ */
1280
+ listProducts(query?: EcommerceProductQuery): Promise<PaginatedResult<ProductItem>>;
1281
+ /**
1282
+ * Upload and link a product image to its gallery and featured slot.
1283
+ */
1284
+ uploadProductImage(productId: string, file: {
1285
+ filename: string;
1286
+ mimeType: string;
1287
+ sizeBytes: number;
1288
+ url?: string;
1289
+ altText?: string;
1290
+ caption?: string;
1291
+ width?: number;
1292
+ height?: number;
1293
+ isFeatured?: boolean;
1294
+ }, authorId?: string | null): Promise<{
1295
+ media: MediaItem;
1296
+ product: ProductItem;
1297
+ }>;
1298
+ /**
1299
+ * Adjust inventory stock for a product or variant.
1300
+ */
1301
+ adjustStock(productId: string, delta: number, variantId?: string): Promise<ProductItem | null>;
1302
+ /**
1303
+ * Create a catalog category in the hierarchical category taxonomy.
1304
+ */
1305
+ createCategory(input: {
1306
+ name: string;
1307
+ slug?: string;
1308
+ parentId?: string | null;
1309
+ description?: string;
1310
+ meta?: Record<string, unknown>;
1311
+ }): Promise<TermItem>;
1312
+ /**
1313
+ * Get all catalog categories.
1314
+ */
1315
+ getCategories(options?: {
1316
+ parentId?: string | null;
1317
+ }): Promise<TermItem[]>;
1318
+ /**
1319
+ * Get full hierarchical catalog category tree.
1320
+ */
1321
+ getCategoryTree(): Promise<TermTreeItem[]>;
1322
+ /**
1323
+ * Assign category IDs to a product.
1324
+ */
1325
+ assignProductCategory(productId: string, categoryIds: string | string[]): Promise<void>;
1326
+ /**
1327
+ * Get assigned categories for a product.
1328
+ */
1329
+ getProductCategories(productId: string): Promise<TermItem[]>;
1330
+ /**
1331
+ * Create a promotional coupon / discount code.
1332
+ */
1333
+ createDiscount(input: CreateDiscountInput, authorId?: string | null): Promise<DiscountItem>;
1334
+ /**
1335
+ * Find a discount code.
1336
+ */
1337
+ getDiscountByCode(code: string): Promise<DiscountItem | null>;
1338
+ /**
1339
+ * Validate a discount coupon against cart items and order subtotal.
1340
+ */
1341
+ validateDiscount(code: string, cartSubtotal: number, productIds?: string[]): Promise<DiscountValidationResult>;
1342
+ /**
1343
+ * Calculate cart subtotals, apply discounts, shipping, and taxes.
1344
+ */
1345
+ calculateCart(input: CartCalculationInput): Promise<CartCalculationResult>;
1346
+ /**
1347
+ * Place a new order with cart validation, inventory deduction, and coupon counter updates.
1348
+ */
1349
+ createOrder(input: CreateOrderInput, authorId?: string | null): Promise<OrderItem>;
1350
+ /**
1351
+ * Get order by ID.
1352
+ */
1353
+ getOrder(id: string): Promise<OrderItem | null>;
1354
+ /**
1355
+ * Get order by order number.
1356
+ */
1357
+ getOrderByNumber(orderNumber: string): Promise<OrderItem | null>;
1358
+ /**
1359
+ * Update the status of an order (e.g. pending -> paid -> shipped).
1360
+ */
1361
+ updateOrderStatus(id: string, status: OrderStatus, note?: string): Promise<OrderItem | null>;
1362
+ }
1363
+ //#endregion
1364
+ //#region src/plugins/ecommerce/schemas.d.ts
1365
+ /**
1366
+ * Creates the collection configuration for Products.
1367
+ */
1368
+ declare function createProductCollection(options?: EcommercePluginOptions): CollectionConfig;
1369
+ /**
1370
+ * Creates the collection configuration for Discounts / Coupons.
1371
+ */
1372
+ declare function createDiscountCollection(options?: EcommercePluginOptions): CollectionConfig;
1373
+ /**
1374
+ * Creates the collection configuration for Orders.
1375
+ */
1376
+ declare function createOrderCollection(options?: EcommercePluginOptions): CollectionConfig;
1377
+ /**
1378
+ * Creates the standard e-commerce taxonomies: product categories, tags, and brands.
1379
+ */
1380
+ declare function createEcommerceTaxonomies(options?: EcommercePluginOptions): TaxonomyConfig[];
1381
+ //#endregion
1382
+ //#region src/plugins/ecommerce/client.d.ts
1383
+ declare class EcommerceClient {
1384
+ private client;
1385
+ private options;
1386
+ private service?;
1387
+ private prefix;
1388
+ constructor(client: CMSClient, options?: EcommercePluginOptions);
1389
+ readonly products: {
1390
+ find: (query?: EcommerceProductQuery) => Promise<PaginatedResult<ProductItem>>;
1391
+ get: (idOrSlug: string, by?: "id" | "slug") => Promise<ProductItem | null>;
1392
+ create: (data: CreateProductInput) => Promise<ProductItem>;
1393
+ update: (id: string, data: UpdateProductInput) => Promise<ProductItem | null>;
1394
+ delete: (id: string) => Promise<boolean>;
1395
+ uploadImage: (productId: string, file: {
1396
+ filename: string;
1397
+ mimeType: string;
1398
+ sizeBytes: number;
1399
+ url?: string;
1400
+ altText?: string;
1401
+ caption?: string;
1402
+ width?: number;
1403
+ height?: number;
1404
+ isFeatured?: boolean;
1405
+ }) => Promise<{
1406
+ media: MediaItem;
1407
+ product: ProductItem;
1408
+ }>;
1409
+ };
1410
+ readonly categories: {
1411
+ list: (options?: {
1412
+ parentId?: string | null;
1413
+ }) => Promise<TermItem[]>;
1414
+ tree: () => Promise<TermTreeItem[]>;
1415
+ create: (input: {
1416
+ name: string;
1417
+ slug?: string;
1418
+ parentId?: string | null;
1419
+ description?: string;
1420
+ }) => Promise<TermItem>;
1421
+ };
1422
+ readonly discounts: {
1423
+ validate: (code: string, subtotal: number, productIds?: string[]) => Promise<DiscountValidationResult>;
1424
+ create: (input: CreateDiscountInput) => Promise<DiscountItem>;
1425
+ };
1426
+ readonly cart: {
1427
+ calculate: (input: CartCalculationInput) => Promise<CartCalculationResult>;
1428
+ };
1429
+ readonly orders: {
1430
+ create: (input: CreateOrderInput) => Promise<OrderItem>;
1431
+ get: (idOrNumber: string, by?: "id" | "number") => Promise<OrderItem | null>;
1432
+ updateStatus: (id: string, status: OrderStatus, note?: string) => Promise<OrderItem | null>;
1433
+ };
1434
+ }
1435
+ /**
1436
+ * Get or create an EcommerceClient adapter for a CMSClient.
1437
+ */
1438
+ declare function getEcommerceClient(client: CMSClient, options?: EcommercePluginOptions): EcommerceClient;
1439
+ //#endregion
1440
+ //#region src/plugins/ecommerce/index.d.ts
1441
+ /**
1442
+ * Built-in E-commerce plugin factory for @azlib/cms.
1443
+ * Equips the CMS engine with product catalogs, hierarchical categories,
1444
+ * image uploading, discount coupons, cart calculation, and order tracking.
1445
+ */
1446
+ declare const ecommercePlugin: (options?: void | EcommercePluginOptions | undefined) => CMSPlugin;
1447
+ /**
1448
+ * Retrieve the active EcommerceService instance associated with a CMSEngine.
1449
+ */
1450
+ declare function getEcommerceService(engine: CMSEngine, options?: EcommercePluginOptions): EcommerceService;
1451
+ //#endregion
1452
+ export { type ActionCallback, type BooleanFieldOptions, CMSCapability, CMSClient, type CMSClientOptions, CMSConfig, CMSEngine, type CMSPlugin, type CMSPluginContext, CMSRouter, type CMSStorageAdapter, CMSUser, CartCalculationInput, CartCalculationResult, CartItemInput, type ClientCollectionApi, CollectionConfig, type CollectionOptions, type CollectionService, ContentItem, ContentLifecycle, ContentQueryOptions, ContentStatus, type CreateContentInput, CreateDiscountInput, CreateOrderInput, CreateProductInput, type CustomRouteHandler, DEFAULT_COLLECTIONS, DEFAULT_ROLE_CAPABILITIES, type DateFieldOptions, DiscountData, DiscountItem, DiscountStatus, DiscountType, DiscountValidationResult, EcommerceClient, EcommercePluginOptions, EcommerceProductQuery, EcommerceService, FieldDefinition, FieldType, type FilterCallback, type HookEntry, HooksManager, type ImageFieldOptions, type JsonFieldOptions, MediaItem, MediaManager, type MediaUploadInput, MemoryStorageAdapter, type NumberFieldOptions, OptionItem, OptionsManager, OrderAddress, OrderData, OrderItem, OrderLineItem, OrderStatus, PaginatedResult, ProductData, ProductImage, ProductItem, ProductStatus, ProductVariant, RBACManager, type RelationshipFieldOptions, type RepeaterFieldOptions, RevisionDiff, RevisionDiffField, RevisionManager, RevisionRecord, type RichTextFieldOptions, type RouteContext, type SelectFieldOptions, SelectOption, SiteConfig, type SlugFieldOptions, type SyncFilterCallback, TaxonomyConfig, type TaxonomyFieldOptions, TaxonomyManager, TermItem, TermTreeItem, type TextFieldOptions, type UpdateContentInput, UpdateProductInput, UserRole, VALID_STATUS_TRANSITIONS, collection, createCMSEngine, createCMSRouter, createCmsClient, createDiscountCollection, createEcommerceTaxonomies, createOrderCollection, createProductCollection, defaultHooks, defineConfig, definePlugin, ecommercePlugin, fields, getEcommerceClient, getEcommerceService, normalizeConfig, resolveUniqueSlug, slugify, validateAndNormalizeData };
851
1453
  //# sourceMappingURL=index.d.cts.map