spiderly 19.11.7 → 19.11.8

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.
@@ -28,6 +28,7 @@
28
28
  | `[MaxFileSize]` | Property | Specifies the maximum allowed file size (in bytes) for a blob property. When not applied, the file upload defaults to 20 MB (20,000,000 bytes). Use this attribute alongside any StorageAttribute subclass for file uploads. |
29
29
  | `[Output]` | All | Specifies the output configuration for the Source Generator. Note: This is a temporary solution and may be replaced in future versions. |
30
30
  | `[ReadOnly]` | Property | Marks a property as server-owned: the client may read it, but can never write it (mirrors OpenAPI readOnly). The property stays in the read {Entity}DTO — so it's still returned by GET endpoints and shown in the list table — but the generator closes the write path for it: no inbound FluentValidation rule is emitted, and the generated DTO→entity Mapster config .Ignore()s it, so a crafted payload can't tamper with it. It also gets no editable control in the generated details form. Use for values only backend code assigns — usage counters, denormalized aggregates, computed timestamps. Combine with [Required] to document the non-null DB column without generating an unsatisfiable inbound rule (the form never sends it). This differs from [UIDoNotGenerate] (hidden from the form but still writable and validated) and [ExcludeFromDTO] (dropped from every DTO, unreadable). |
31
+ | `[RetainReplacedBlobs]` | Property | Opt-out of save-time blob cleanup for a storage property. By default, saving an entity deletes every stored blob under the property's key prefix except the active one — correct when the entity is the only holder of the URL. Put this attribute on the property when copies of its URL outlive the entity's current value (order-line snapshots, emails, exports, third-party feeds): replacing the blob then keeps the old bytes, so historical references keep rendering. An orphaned blob costs fractions of a cent and is invisible; a deleted-but-referenced blob breaks a customer-facing record — when one side of the trade is cents and the other is broken history, don't optimise the cents. |
31
32
  | `[S3PrivateStorage]` | Property | Routes upload/delete operations for the decorated string property through S3PrivateStorageService. The column stores an opaque S3 key; access is expected to be mediated via signed URLs or a backend proxy rather than direct CDN retrieval. Intended for files that contain personal or compliance-sensitive data (warranty receipts, ID documents, customer-uploaded invoices). |
32
33
  | `[S3PublicStorage]` | Property | Routes upload/delete operations for the decorated string property through S3PublicStorageService. The bucket is configured for public access and the column stores a fully-qualified CDN URL; objects are uploaded with Cache-Control: public, max-age=31536000, immutable. |
33
34
  | `[SetNull]` | Property | Specifies that the property should be set to null when the parent entity is deleted. Apply this attribute to a many-to-one relationship property. |
@@ -3080,19 +3080,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImpo
3080
3080
  type: Input
3081
3081
  }] } });
3082
3082
 
3083
- class FooterComponent {
3084
- constructor(config) {
3085
- this.config = config;
3086
- this.companyName = this.config.companyName;
3087
- }
3088
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: FooterComponent, deps: [{ token: ConfigServiceBase }], target: i0.ɵɵFactoryTarget.Component }); }
3089
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.13", type: FooterComponent, isStandalone: true, selector: "footer", ngImport: i0, template: "<div class=\"layout-footer\">\n <span class=\"font-medium ml-2\">{{ companyName }}</span>\n</div>\n" }); }
3090
- }
3091
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: FooterComponent, decorators: [{
3092
- type: Component,
3093
- args: [{ selector: 'footer', standalone: true, template: "<div class=\"layout-footer\">\n <span class=\"font-medium ml-2\">{{ companyName }}</span>\n</div>\n" }]
3094
- }], ctorParameters: () => [{ type: ConfigServiceBase }] });
3095
-
3096
3083
  class IndexCardComponent {
3097
3084
  constructor(formBuilder) {
3098
3085
  this.formBuilder = formBuilder;
@@ -3829,7 +3816,7 @@ class SpiderlyLayoutComponent {
3829
3816
  this.onAfterNgDestroy();
3830
3817
  }
3831
3818
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: SpiderlyLayoutComponent, deps: [{ token: LayoutServiceBase }, { token: i0.Renderer2 }, { token: i3$2.Router }], target: i0.ɵɵFactoryTarget.Component }); }
3832
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.13", type: SpiderlyLayoutComponent, isStandalone: true, selector: "spiderly-layout", inputs: { menu: "menu", isSideMenuLayout: "isSideMenuLayout", showHoverBgOnRootTopMenuItems: "showHoverBgOnRootTopMenuItems", maxWidth: "maxWidth" }, viewQueries: [{ propertyName: "appSidebar", first: true, predicate: AppSidebarComponent, descendants: true }, { propertyName: "sidemenuTopbar", first: true, predicate: SideMenuTopBarComponent, descendants: true }, { propertyName: "topbarmenu", first: true, predicate: ["topbarmenu"], descendants: true }], ngImport: i0, template: "<div *ngIf=\"isSideMenuLayout\" class=\"layout-wrapper\" [ngClass]=\"containerClass\">\n <spiderly-sidemenu-topbar></spiderly-sidemenu-topbar>\n <div class=\"layout-sidebar\">\n <sidebar [menu]=\"sideMenu\"></sidebar>\n </div>\n <div class=\"layout-main-container\">\n <div class=\"layout-main\">\n <router-outlet></router-outlet>\n </div>\n <footer></footer>\n </div>\n <div class=\"layout-mask\"></div>\n</div>\n\n<div *ngIf=\"isSideMenuLayout === false\">\n <spiderly-topbar\n [menu]=\"topMenu\"\n [showHoverBgOnRootItems]=\"showHoverBgOnRootTopMenuItems\"\n >\n <ng-content ACTIONS select=\"[ACTIONS]\"></ng-content>\n </spiderly-topbar>\n <main [style.max-width]=\"maxWidth\" style=\"margin: auto; padding: 18px\">\n <router-outlet></router-outlet>\n </main>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i3$2.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: AppSidebarComponent, selector: "sidebar", inputs: ["menu"] }, { kind: "component", type: FooterComponent, selector: "footer" }, { kind: "component", type: SideMenuTopBarComponent, selector: "spiderly-sidemenu-topbar" }, { kind: "component", type: TopBarComponent, selector: "spiderly-topbar", inputs: ["menu", "showHoverBgOnRootItems"] }] }); }
3819
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.13", type: SpiderlyLayoutComponent, isStandalone: true, selector: "spiderly-layout", inputs: { menu: "menu", isSideMenuLayout: "isSideMenuLayout", showHoverBgOnRootTopMenuItems: "showHoverBgOnRootTopMenuItems", maxWidth: "maxWidth" }, viewQueries: [{ propertyName: "appSidebar", first: true, predicate: AppSidebarComponent, descendants: true }, { propertyName: "sidemenuTopbar", first: true, predicate: SideMenuTopBarComponent, descendants: true }, { propertyName: "topbarmenu", first: true, predicate: ["topbarmenu"], descendants: true }], ngImport: i0, template: "<div *ngIf=\"isSideMenuLayout\" class=\"layout-wrapper\" [ngClass]=\"containerClass\">\n <spiderly-sidemenu-topbar></spiderly-sidemenu-topbar>\n <div class=\"layout-sidebar\">\n <sidebar [menu]=\"sideMenu\"></sidebar>\n </div>\n <div class=\"layout-main-container\">\n <div class=\"layout-main\">\n <router-outlet></router-outlet>\n </div>\n </div>\n <div class=\"layout-mask\"></div>\n</div>\n\n<div *ngIf=\"isSideMenuLayout === false\">\n <spiderly-topbar\n [menu]=\"topMenu\"\n [showHoverBgOnRootItems]=\"showHoverBgOnRootTopMenuItems\"\n >\n <ng-content ACTIONS select=\"[ACTIONS]\"></ng-content>\n </spiderly-topbar>\n <main [style.max-width]=\"maxWidth\" style=\"margin: auto; padding: 18px\">\n <router-outlet></router-outlet>\n </main>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i3$2.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: AppSidebarComponent, selector: "sidebar", inputs: ["menu"] }, { kind: "component", type: SideMenuTopBarComponent, selector: "spiderly-sidemenu-topbar" }, { kind: "component", type: TopBarComponent, selector: "spiderly-topbar", inputs: ["menu", "showHoverBgOnRootItems"] }] }); }
3833
3820
  }
3834
3821
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: SpiderlyLayoutComponent, decorators: [{
3835
3822
  type: Component,
@@ -3837,10 +3824,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImpo
3837
3824
  CommonModule,
3838
3825
  RouterModule,
3839
3826
  AppSidebarComponent,
3840
- FooterComponent,
3841
3827
  SideMenuTopBarComponent,
3842
3828
  TopBarComponent,
3843
- ], template: "<div *ngIf=\"isSideMenuLayout\" class=\"layout-wrapper\" [ngClass]=\"containerClass\">\n <spiderly-sidemenu-topbar></spiderly-sidemenu-topbar>\n <div class=\"layout-sidebar\">\n <sidebar [menu]=\"sideMenu\"></sidebar>\n </div>\n <div class=\"layout-main-container\">\n <div class=\"layout-main\">\n <router-outlet></router-outlet>\n </div>\n <footer></footer>\n </div>\n <div class=\"layout-mask\"></div>\n</div>\n\n<div *ngIf=\"isSideMenuLayout === false\">\n <spiderly-topbar\n [menu]=\"topMenu\"\n [showHoverBgOnRootItems]=\"showHoverBgOnRootTopMenuItems\"\n >\n <ng-content ACTIONS select=\"[ACTIONS]\"></ng-content>\n </spiderly-topbar>\n <main [style.max-width]=\"maxWidth\" style=\"margin: auto; padding: 18px\">\n <router-outlet></router-outlet>\n </main>\n</div>\n" }]
3829
+ ], template: "<div *ngIf=\"isSideMenuLayout\" class=\"layout-wrapper\" [ngClass]=\"containerClass\">\n <spiderly-sidemenu-topbar></spiderly-sidemenu-topbar>\n <div class=\"layout-sidebar\">\n <sidebar [menu]=\"sideMenu\"></sidebar>\n </div>\n <div class=\"layout-main-container\">\n <div class=\"layout-main\">\n <router-outlet></router-outlet>\n </div>\n </div>\n <div class=\"layout-mask\"></div>\n</div>\n\n<div *ngIf=\"isSideMenuLayout === false\">\n <spiderly-topbar\n [menu]=\"topMenu\"\n [showHoverBgOnRootItems]=\"showHoverBgOnRootTopMenuItems\"\n >\n <ng-content ACTIONS select=\"[ACTIONS]\"></ng-content>\n </spiderly-topbar>\n <main [style.max-width]=\"maxWidth\" style=\"margin: auto; padding: 18px\">\n <router-outlet></router-outlet>\n </main>\n</div>\n" }]
3844
3830
  }], ctorParameters: () => [{ type: LayoutServiceBase }, { type: i0.Renderer2 }, { type: i3$2.Router }], propDecorators: { menu: [{
3845
3831
  type: Input
3846
3832
  }], isSideMenuLayout: [{
@@ -5779,5 +5765,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImpo
5779
5765
  * Generated bundle index. Do not edit.
5780
5766
  */
5781
5767
 
5782
- export { Action, AllClickEvent, ApiErrorCodes, ApiSecurityService, AppSidebarComponent, AuthCardComponent, AuthGuard, AuthResult, AuthResultWithCookies, AuthServiceBase, BaseAutocompleteControl, BaseControl, BaseDropdownControl, BaseEntity, BaseFormComponent, BaseFormService, CardSkeletonComponent, Codebook, Column, ConfigServiceBase, DEFAULT_EXTERNAL_PROVIDER_ICONS, ExternalLoginComponent, ExternalProvider, ExternalProviderPublic, Filter, FilterRule, FilterSortMeta, FooterComponent, IndexCardComponent, InfoCardComponent, InitCompanyAuthDialogDetails, InitTopBarData, IsAuthorizedForSaveEvent, LastMenuIconIndexClicked, LayoutServiceBase, LazyLoadSelectedIdsResult, Login, LoginVerificationComponent, LoginVerificationToken, MatchModeCodes, MenuChangeEvent, MenuitemComponent, Namebook, NotAuthGuard, NotFoundComponent, PROPS_KEY, PaginatedResult, PanelBodyComponent, PanelFooterComponent, PanelHeaderComponent, PrimengOption, ProfileAvatarComponent, ReflectProp, RefreshTokenRequest, RequiredComponent, RowClickEvent, SecurityPermissionCodes, SendLoginVerificationEmailResult, SideMenuTopBarComponent, SidebarMenuComponent, SimpleSaveResult, SpiderlyAutocompleteComponent, SpiderlyButtonBaseComponent, SpiderlyButtonComponent, SpiderlyCalendarComponent, SpiderlyCardComponent, SpiderlyCellTemplateDirective, SpiderlyCheckboxComponent, SpiderlyColorPickerComponent, SpiderlyControlsModule, SpiderlyDataTableActionsDirective, SpiderlyDataTableComponent, SpiderlyDataViewComponent, SpiderlyDeleteConfirmationComponent, SpiderlyDropdownComponent, SpiderlyEditorComponent, SpiderlyErrorHandler, SpiderlyFileComponent, SpiderlyFileSelectEvent, SpiderlyFormArray, SpiderlyFormControl, SpiderlyFormGroup, SpiderlyLayoutComponent, SpiderlyLoginComponent, SpiderlyMarkdownComponent, SpiderlyMessageService, SpiderlyMultiAutocompleteComponent, SpiderlyMultiSelectComponent, SpiderlyNumberComponent, SpiderlyPanelComponent, SpiderlyPanelsModule, SpiderlyPasswordComponent, SpiderlyReturnButtonComponent, SpiderlySplitButtonComponent, SpiderlyTab, SpiderlyTemplateTypeDirective, SpiderlyTextareaComponent, SpiderlyTextboxComponent, SpiderlyTranslocoLoader, TopBarComponent, UserBase, UserRole, ValidatorAbstractService, VerificationTokenRequest, VerificationTypeCodes, VerificationWrapperComponent, adjustColor, authInitializer, capitalizeFirstChar, deleteAction, exportListToExcel, firstCharToUpper, getFileNameFromContentDisposition, getHtmlImgDisplayString64, getImageDimensions, getMimeTypeForFileName, getMonth, getParentUrl, getPrimengAutocompleteCodebookOptions, getPrimengAutocompleteNamebookOptions, getPrimengDropdownCodebookOptions, getPrimengDropdownNamebookOptions, getPrimengNamebookOptions, httpLoadingInterceptor, isExcelFileType, isFileImageType, isNullOrEmpty, jsonHttpInterceptor, jwtInterceptor, kebabToTitleCase, nameOf, nameof, parseDateOnlyLocal, pushAction, saveResponseAsFile, selectedTab, singleOrDefault, splitPascalCase, toCommaSeparatedString, unauthorizedInterceptor, validatePrecisionScale };
5768
+ export { Action, AllClickEvent, ApiErrorCodes, ApiSecurityService, AppSidebarComponent, AuthCardComponent, AuthGuard, AuthResult, AuthResultWithCookies, AuthServiceBase, BaseAutocompleteControl, BaseControl, BaseDropdownControl, BaseEntity, BaseFormComponent, BaseFormService, CardSkeletonComponent, Codebook, Column, ConfigServiceBase, DEFAULT_EXTERNAL_PROVIDER_ICONS, ExternalLoginComponent, ExternalProvider, ExternalProviderPublic, Filter, FilterRule, FilterSortMeta, IndexCardComponent, InfoCardComponent, InitCompanyAuthDialogDetails, InitTopBarData, IsAuthorizedForSaveEvent, LastMenuIconIndexClicked, LayoutServiceBase, LazyLoadSelectedIdsResult, Login, LoginVerificationComponent, LoginVerificationToken, MatchModeCodes, MenuChangeEvent, MenuitemComponent, Namebook, NotAuthGuard, NotFoundComponent, PROPS_KEY, PaginatedResult, PanelBodyComponent, PanelFooterComponent, PanelHeaderComponent, PrimengOption, ProfileAvatarComponent, ReflectProp, RefreshTokenRequest, RequiredComponent, RowClickEvent, SecurityPermissionCodes, SendLoginVerificationEmailResult, SideMenuTopBarComponent, SidebarMenuComponent, SimpleSaveResult, SpiderlyAutocompleteComponent, SpiderlyButtonBaseComponent, SpiderlyButtonComponent, SpiderlyCalendarComponent, SpiderlyCardComponent, SpiderlyCellTemplateDirective, SpiderlyCheckboxComponent, SpiderlyColorPickerComponent, SpiderlyControlsModule, SpiderlyDataTableActionsDirective, SpiderlyDataTableComponent, SpiderlyDataViewComponent, SpiderlyDeleteConfirmationComponent, SpiderlyDropdownComponent, SpiderlyEditorComponent, SpiderlyErrorHandler, SpiderlyFileComponent, SpiderlyFileSelectEvent, SpiderlyFormArray, SpiderlyFormControl, SpiderlyFormGroup, SpiderlyLayoutComponent, SpiderlyLoginComponent, SpiderlyMarkdownComponent, SpiderlyMessageService, SpiderlyMultiAutocompleteComponent, SpiderlyMultiSelectComponent, SpiderlyNumberComponent, SpiderlyPanelComponent, SpiderlyPanelsModule, SpiderlyPasswordComponent, SpiderlyReturnButtonComponent, SpiderlySplitButtonComponent, SpiderlyTab, SpiderlyTemplateTypeDirective, SpiderlyTextareaComponent, SpiderlyTextboxComponent, SpiderlyTranslocoLoader, TopBarComponent, UserBase, UserRole, ValidatorAbstractService, VerificationTokenRequest, VerificationTypeCodes, VerificationWrapperComponent, adjustColor, authInitializer, capitalizeFirstChar, deleteAction, exportListToExcel, firstCharToUpper, getFileNameFromContentDisposition, getHtmlImgDisplayString64, getImageDimensions, getMimeTypeForFileName, getMonth, getParentUrl, getPrimengAutocompleteCodebookOptions, getPrimengAutocompleteNamebookOptions, getPrimengDropdownCodebookOptions, getPrimengDropdownNamebookOptions, getPrimengNamebookOptions, httpLoadingInterceptor, isExcelFileType, isFileImageType, isNullOrEmpty, jsonHttpInterceptor, jwtInterceptor, kebabToTitleCase, nameOf, nameof, parseDateOnlyLocal, pushAction, saveResponseAsFile, selectedTab, singleOrDefault, splitPascalCase, toCommaSeparatedString, unauthorizedInterceptor, validatePrecisionScale };
5783
5769
  //# sourceMappingURL=spiderly.mjs.map