diff --git a/LICENCE b/LICENCE index 49d1b85..86f3741 100644 --- a/LICENCE +++ b/LICENCE @@ -1,4 +1,4 @@ -MIT License +MIT Licence Copyright (c) 2026 OnixByte diff --git a/docs/en-gb/_nav.json b/docs/en-gb/_nav.json index 64b7c36..c810b93 100644 --- a/docs/en-gb/_nav.json +++ b/docs/en-gb/_nav.json @@ -1,14 +1,14 @@ [ - { - "text": "blogs", - "link": "/blogs/", - "activeMatch": "/blogs/" - }, { "text": "projects", "link": "/projects/", "activeMatch": "/projects/" }, + { + "text": "blogs", + "link": "/blogs/", + "activeMatch": "/blogs/" + }, { "text": "notifications", "link": "/notifications/", diff --git a/docs/en-gb/projects/calendar-toolbox/api.md b/docs/en-gb/projects/calendar-toolbox/api.md new file mode 100644 index 0000000..f1da780 --- /dev/null +++ b/docs/en-gb/projects/calendar-toolbox/api.md @@ -0,0 +1,390 @@ +--- +title: Calendar Toolbox API +--- + +## Package Overview + +The library is organised under the base package `com.onixbyte.calendar` with the following structure: + +| Package | Description | +|--------------------------------------------|--------------------------------------------| +| `com.onixbyte.calendar` | Root calendar object | +| `com.onixbyte.calendar.component` | iCalendar components (VEVENT, VTODO, etc.) | +| `com.onixbyte.calendar.component.property` | Component-level properties | +| `com.onixbyte.calendar.property` | Calendar-level properties | +| `com.onixbyte.calendar.parameter` | iCalendar property parameters | +| `com.onixbyte.calendar.recurrence` | Recurrence rule types | +| `com.onixbyte.calendar.value` | Value types | +| `com.onixbyte.calendar.util` | Formatting utilities | + +--- + +## Calendar + +The top-level object representing an iCalendar (RFC 5545) VCALENDAR container. + +```java +Calendar calendar = Calendar.builder() + .withCalendarScale(...) + .withMethod(...) + .withProductIdentifier(...) + .withVersion(...) + .withOwner(...) + .withPrimaryCalendar(...) + .withPublishedTTL(...) + .withCalendarDescription(...) + .withCalendarName(...) + .withCalendarId(...) + .withCustomProperties(...) + .withComponents(event, todo, ...) + .build(); + +String icsContent = calendar.formatted(); +``` + +### Calendar Properties + +All calendar-level properties live in `com.onixbyte.calendar.property` and implement `CalendarProperty`. + +| Class | iCalendar Property | Description | +|--------------------------|----------------------|-------------------------------------------| +| `CalendarScale` | `CALSCALE` | Calendar system (e.g., GREGORIAN) | +| `Method` | `METHOD` | iCalendar method (e.g., PUBLISH, REQUEST) | +| `ProductIdentifier` | `PRODID` | Product identifier of the calendar | +| `Version` | `VERSION` | iCalendar version (e.g., 2.0) | +| `Owner` | `X-OWNER` | Owner of the calendar | +| `PrimaryCalendar` | `X-PRIMARY-CALENDAR` | Whether this is a primary calendar | +| `PublishedTTL` | `X-PUBLISHED-TTL` | Time-to-live for published calendar | +| `CalendarDescription` | `X-CALENDAR-DESC` | Calendar description | +| `CalendarName` | `X-CALENDAR-NAME` | Calendar name | +| `CalendarId` | `X-CALENDAR-ID` | Calendar identifier | +| `CustomCalendarProperty` | `X-*` | Custom calendar properties | + +Custom properties are created using a builder: + +```java +var customProp = CustomCalendarProperty.builder() + .withParameters(...) + .build("X-MY-PROPERTY", "my-value"); +``` + +> Note: Custom property names **must** start with `X-`. + +--- + +## Components + +Components represent the core entities in an iCalendar object. Each component implements `CalendarComponent` and is rendered between `BEGIN:TYPE` and `END:TYPE` delimiters. + +### Event (VEVENT) + +Represents a scheduled event. + +```java +Event event = Event.builder() + .withDateTimeStamp(dtstamp) // required + .withUniqueIdentifier(uid) // required + .withDateTimeStart(dtstart) + .withDateTimeEnd(dtend) // mutually exclusive with duration + .withDuration(duration) // mutually exclusive with dtend + .withSummary(summary) + .withDescription(description) + .withClassification(classification) + .withDateTimeCreated(dateTimeCreated) + .withGeographicPosition(geoPos) + .withLastModified(lastModified) + .withLocation(location) + .withOrganiser(organiser) + .withPriority(priority) + .withSequenceNumber(seqNumber) + .withStatus(status) + .withTimeTransparency(transparency) + .withUniformResourceLocator(url) + .withRecurrenceId(recurrenceId) + .withRecurrenceRule(rrule) + .withAttachments(attachments) + .withAttendees(attendees) + .withCategories(categories) + .withComments(comments) + .withContacts(contacts) + .withExceptionDateTimes(exDates) + .withRequestStatuses(statuses) + .withRelated(related) + .withResources(resources) + .withRecurrenceDateTimes(rDates) + .build(); +``` + +### Todo (VTODO) + +Represents a to-do item or task. + +```java +Todo todo = Todo.builder() + .withDateTimeStamp(dtstamp) // required + .withUniqueIdentifier(uid) // required + .withSummary(summary) + .withDateTimeStart(dtstart) + .withDateTimeDue(due) // mutually exclusive with duration + .withDuration(duration) // mutually exclusive with due + .withDateTimeCompleted(completed) + .withPercentComplete(percent) + .withClassification(classification) + .withDateTimeCreated(created) + .withDescription(description) + .withGeographicPosition(geoPos) + .withLastModified(lastModified) + .withLocation(location) + .withOrganiser(organiser) + .withPriority(priority) + .withSequenceNumber(seq) + .withStatus(status) + .withRecurrenceId(recurId) + .withRecurrenceRule(rrule) + .withUniformResourceLocator(url) + .withAttachments(attachments) + .withAttendees(attendees) + .withCategories(categories) + .withComments(comments) + .withContacts(contacts) + .withExceptionDateTimes(exDates) + .withRequestStatuses(statuses) + .withRelatedToList(related) + .withResources(resources) + .withRecurrenceDateTimes(rDates) + .build(); +``` + +### Journal (VJOURNAL) + +Represents a journal entry or diary note. + +```java +Journal journal = Journal.builder() + .withDateTimeStamp(dtstamp) // required + .withUniqueIdentifier(uid) // required + .withSummary(summary) + .withClassification(classification) + .withDateTimeCreated(created) + .withDateTimeStart(dtstart) + .withLastModified(lastModified) + .withOrganiser(organiser) + .withRecurrenceId(recurId) + .withSequenceNumber(seq) + .withStatus(status) + .withUniformResourceLocator(url) + .withRecurrenceRule(rrule) + .withAttachments(attachments) + .withAttendees(attendees) + .withCategories(categories) + .withComments(comments) + .withContacts(contacts) + .withDescriptions(descriptions) + .withExceptionDateTimes(exDates) + .withRelatedToList(related) + .withRecurrenceDate(rDates) + .withRequestStatuses(statuses) + .build(); +``` + +### FreeBusy (VFREEBUSY) + +Represents free/busy time information. + +```java +FreeBusy freeBusy = FreeBusy.builder() + .withDateTimeStamp(dtstamp) // required + .withUniqueIdentifier(uid) // required + .withContact(contact) + .withDateTimeStart(dtstart) + .withDateTimeEnd(dtend) + .withOrganiser(organiser) + .withUniformResourceLocator(url) + .withAttendees(attendees) + .withComments(comments) + .withFreeBusyTimes(freeBusyTimes) + .withRequestStatuses(statuses) + .build(); +``` + +### TimeZone (VTIMEZONE) + +Defines time zone rules including standard and daylight saving time transitions. + +```java +TimeZone timezone = TimeZone.builder() + .withTimeZoneIdentifier(tzId) + .withLastModified(lastModified) + .withTimeZoneUrl(tzUrl) + .withTimeZoneProperties(standardProp, daylightProp) + .build(); +``` + +Time zone properties define the actual transition rules: + +```java +TimeZoneProperty standard = TimeZoneProperty.builder() + .withDateTimeStart(dtstart) + .withTimeZoneOffsetTo(offsetTo) + .withTimeZoneOffsetFrom(offsetFrom) + .withRecurrenceRule(rrule) + .withTimeZoneNames(tzName) + .buildStandard(); // or buildDaylight() + +TimeZoneProperty daylight = TimeZoneProperty.builder() + .withDateTimeStart(dtstart) + .withTimeZoneOffsetTo(offsetTo) + .withTimeZoneOffsetFrom(offsetFrom) + .buildDaylight(); +``` + +### Alarm (VALARM) + +Defines alarm/reminder notifications. Three alarm types are supported: + +```java +// Audio alarm +Alarm audioAlarm = Alarm.builder() + .withTrigger(trigger) + .withDuration(duration) + .withRepeatCount(repeatCount) + .withAttachments(audioAttachment) + .buildAudio(); + +// Display alarm +Alarm displayAlarm = Alarm.builder() + .withTrigger(trigger) + .withDescription(description) // required + .withDuration(duration) + .withRepeatCount(repeatCount) + .buildDisplay(); + +// Email alarm +Alarm emailAlarm = Alarm.builder() + .withTrigger(trigger) + .withDescription(description) // required + .withSummary(summary) // required + .withAttendees(attendees) // required + .withDuration(duration) + .withRepeatCount(repeatCount) + .buildEmail(); +``` + +--- + +## Component Properties + +Component properties live in `com.onixbyte.calendar.component.property` and implement `ComponentProperty`. + +| Class | iCalendar Property | Description | +|---------------------------|--------------------|----------------------------------------------------------| +| `Action` | `ACTION` | Alarm action type (AUDIO, DISPLAY, EMAIL) | +| `Attachment` | `ATTACH` | Document attachment | +| `Attendee` | `ATTENDEE` | Event/task attendee | +| `Categories` | `CATEGORIES` | Categories or tags | +| `Classification` | `CLASS` | Access classification (PUBLIC, PRIVATE, CONFIDENTIAL) | +| `Comment` | `COMMENT` | Comment | +| `Contact` | `CONTACT` | Contact information | +| `DateTimeCompleted` | `COMPLETED` | Completion date-time | +| `DateTimeCreated` | `CREATED` | Creation date-time | +| `DateTimeDue` | `DUE` | Due date-time | +| `DateTimeEnd` | `DTEND` | End date-time | +| `DateTimeStamp` | `DTSTAMP` | Date-time stamp | +| `DateTimeStart` | `DTSTART` | Start date-time | +| `Description` | `DESCRIPTION` | Description | +| `ExceptionDateTimes` | `EXDATE` | Exception date-times | +| `FreeBusyTime` | `FREEBUSY` | Free/busy time periods | +| `GeographicPosition` | `GEO` | Geographic position (lat/long) | +| `LastModified` | `LAST-MODIFIED` | Last modified date-time | +| `Location` | `LOCATION` | Location | +| `Organiser` | `ORGANIZER` | Event organiser | +| `PercentComplete` | `PERCENT-COMPLETE` | Completion percentage | +| `Priority` | `PRIORITY` | Priority level | +| `RecurrenceDateTimes` | `RDATE` | Recurrence date-times | +| `RecurrenceId` | `RECURRENCE-ID` | Recurrence instance identifier | +| `RecurrenceRule` | `RRULE` | Recurrence rule | +| `RelatedTo` | `RELATED-TO` | Related component reference | +| `RepeatCount` | `REPEAT` | Alarm repeat count | +| `RequestStatus` | `REQUEST-STATUS` | Request status | +| `Resources` | `RESOURCES` | Resources | +| `SequenceNumber` | `SEQUENCE` | Sequence number (revision) | +| `Status` | `STATUS` | Component status (TENTATIVE, CONFIRMED, CANCELLED, etc.) | +| `Summary` | `SUMMARY` | Title or summary | +| `TimeTransparency` | `TRANSP` | Time transparency (OPAQUE, TRANSPARENT) | +| `TimeZoneIdentifier` | `TZID` | Time zone identifier | +| `TimeZoneName` | `TZNAME` | Time zone name | +| `TimeZoneOffsetFrom` | `TZOFFSETFROM` | Time zone offset from UTC | +| `TimeZoneOffsetTo` | `TZOFFSETTO` | Time zone offset to UTC | +| `TimeZoneUrl` | `TZURL` | Time zone URL | +| `Trigger` | `TRIGGER` | Alarm trigger | +| `UniformResourceLocator` | `URL` | Associated URL | +| `UniqueIdentifier` | `UID` | Unique identifier | +| `CustomComponentProperty` | `X-*` | Custom component properties | + +--- + +## Parameters + +Parameters in `com.onixbyte.calendar.parameter` provide additional qualifiers on component properties. + +| Class | iCalendar Parameter | Description | +|-------------------------------|---------------------|--------------------------------------------------------| +| `AlarmTriggerRelationship` | `RELATED` | Trigger relationship (START, END) | +| `AlternateTextRepresentation` | `ALTREP` | Alternate text URI | +| `CalendarUserType` | `CUTYPE` | Calendar user type (INDIVIDUAL, GROUP, RESOURCE, etc.) | +| `CommonName` | `CN` | Common name | +| `Delegatees` | `DELEGATED-TO` | Delegatees | +| `Delegators` | `DELEGATED-FROM` | Delegators | +| `DirectoryEntryReference` | `DIR` | Directory entry URI | +| `FormatType` | `FMTTYPE` | Format type (MIME type) | +| `FreeBusyTimeType` | `FBTYPE` | Free/busy time type | +| `InlineEncoding` | `ENCODING` | Inline encoding (BASE64) | +| `Language` | `LANGUAGE` | Language | +| `Membership` | `MEMBER` | Group membership | +| `ParticipationRole` | `ROLE` | Participation role (CHAIR, REQ-PARTICIPANT, etc.) | +| `ParticipationStatus` | `PARTSTAT` | Participation status (ACCEPTED, DECLINED, etc.) | +| `RecurrenceIdentifierRange` | `RANGE` | Recurrence range (THISANDPRIOR, THISANDFUTURE) | +| `RelationshipType` | `RELTYPE` | Relationship type (PARENT, CHILD, SIBLING) | +| `RsvpExpectation` | `RSVP` | RSVP expectation (TRUE, FALSE) | +| `SentBy` | `SENT-BY` | Sent by | +| `TimeZoneIdentifier` | `TZID` | Time zone identifier | +| `ValueDataType` | `VALUE` | Value data type (DATE, DATE-TIME, etc.) | + +--- + +## Recurrence Types + +Located in `com.onixbyte.calendar.recurrence`. + +| Class | Description | +|--------------|---------------------------------------------------------------------------| +| `Frequency` | Frequency constants (DAILY, WEEKLY, MONTHLY, YEARLY) for recurrence rules | +| `WeekdayNum` | Weekday number for recurrence rules (e.g., 2nd Monday) | + +--- + +## Value Types + +Located in `com.onixbyte.calendar.value`. + +| Class | Description | +|---------------------|------------------------------------------------| +| `FreeBusyTimeValue` | Represents free/busy time value | +| `PeriodOfTime` | Represents a period of time with start and end | +| `PropertyValue` | Base value type for properties | +| `UtcOffset` | UTC offset value (e.g., `-05:00`, `+01:00`) | + +--- + +## Formatted Output + +All components and properties provide a `formatted()` method that returns an iCalendar-compliant string representation. The `Calendar.formatted()` method produces a complete `.ics` output wrapped in `BEGIN:VCALENDAR`/`END:VCALENDAR`. + +```java +String ics = calendar.formatted(); +// BEGIN:VCALENDAR +// CALSCALE:GREGORIAN +// METHOD:PUBLISH +// ... +// END:VCALENDAR +``` diff --git a/docs/en-gb/projects/calendar-toolbox/index.mdx b/docs/en-gb/projects/calendar-toolbox/index.mdx new file mode 100644 index 0000000..0b3799e --- /dev/null +++ b/docs/en-gb/projects/calendar-toolbox/index.mdx @@ -0,0 +1,102 @@ +--- +title: Calendar Toolbox +--- + +import { Tabs, Tab } from "@rspress/core/theme" + +## Introduction + +Calendar Toolbox is a Java library designed to simplify the creation of `.ics` files, adhering to the iCalendar specification (RFC 5545). This library provides developers with a straightforward API to generate calendar events that can be imported into popular calendar applications such as Microsoft Outlook, Google Calendar, and Apple Calendar. + +With Calendar Toolbox, you can effortlessly create, customise, and export calendar event files programmatically, enabling integration of calendar functionalities into your Java applications with minimal effort. + +## Features + +- **Full RFC 5545 Compliance** — Supports standard iCalendar components including VEVENT, VTODO, VJOURNAL, VFREEBUSY, VTIMEZONE, and VALARM. +- **Fluent Builder Pattern** — All components and properties use builder pattern for readable and intuitive construction. +- **Type-Safe Properties** — Strongly typed properties and parameters ensure correctness at compile time. +- **Custom Extensions** — Support for custom `X-` properties at both calendar and component level. +- **Lightweight** — Zero external dependencies for core functionality. + +## Installation + + + + ```kotlin title="build.gradle.kts" + dependencies { + implementation("com.onixbyte:calendar-toolbox:1.1.0") + } + ``` + + + ```xml title="pom.xml" + + + com.onixbyte + calendar-toolbox + 1.1.0 + + + ``` + + + +## Quick Start + +```java +import com.onixbyte.calendar.Calendar; +import com.onixbyte.calendar.component.Event; +import com.onixbyte.calendar.component.property.*; +import com.onixbyte.calendar.property.*; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +public class CalendarExample { + + public static void main(String[] args) { + // Create required date-time properties + var now = ZonedDateTime.now(ZoneOffset.UTC); + var dtstamp = DateTimeStamp.of(now); + var uid = UniqueIdentifier.of("meeting-001@example.com"); + var dtstart = DateTimeStart.of( + LocalDateTime.of(2025, 8, 15, 9, 0), + "America/New_York" + ); + var dtend = DateTimeEnd.of( + LocalDateTime.of(2025, 8, 15, 10, 0), + "America/New_York" + ); + var summary = Summary.of("Team Standup"); + var description = Description.of("Daily team standup meeting."); + + // Build the event + var event = Event.builder() + .withDateTimeStamp(dtstamp) + .withUniqueIdentifier(uid) + .withDateTimeStart(dtstart) + .withDateTimeEnd(dtend) + .withSummary(summary) + .withDescription(description) + .build(); + + // Build the calendar and output .ics content + var calendar = Calendar.builder() + .withCalendarScale(CalendarScale.of("GREGORIAN")) + .withMethod(Method.of("PUBLISH")) + .withProductIdentifier(ProductIdentifier.of("-//OnixByte//Calendar Toolbox//EN")) + .withVersion(Version.of("2.0")) + .withComponents(event) + .build(); + + System.out.println(calendar.formatted()); + } +} +``` + +This produces an `.ics` string that can be saved to a file or sent via email. + +## License + +Calendar Toolbox is open-source software released under the MIT License. diff --git a/docs/en-gb/projects/captcha/api.md b/docs/en-gb/projects/captcha/api.md new file mode 100644 index 0000000..40498f5 --- /dev/null +++ b/docs/en-gb/projects/captcha/api.md @@ -0,0 +1,248 @@ +--- +title: Captcha API +--- + +## Package Overview + +The library is organised under the base package `com.onixbyte.captcha` with the following structure: + +| Package | Description | +|---------------------------------------------|---------------------------------------| +| `com.onixbyte.captcha` | Core interfaces | +| `com.onixbyte.captcha.impl` | Default implementations | +| `com.onixbyte.captcha.text` | Text producer and renderer interfaces | +| `com.onixbyte.captcha.text.impl` | Text producer and renderer impls | +| `com.onixbyte.captcha.text.enums` | Text-related enums | +| `com.onixbyte.captcha.background` | Background producer interface | +| `com.onixbyte.captcha.background.impl` | Background producer implementations | +| `com.onixbyte.captcha.noise` | Noise producer interface | +| `com.onixbyte.captcha.noise.impl` | Noise producer implementations | +| `com.onixbyte.captcha.gimpy` | Distortion engine interface | +| `com.onixbyte.captcha.gimpy.impl` | Distortion engine implementations | + +--- + +## Producer + +The top-level interface responsible for creating CAPTCHA images with text drawn on them. + +```java +Producer captcha = DefaultCaptchaProducer.builder() + .textProducer(textProducer) + .wordRenderer(wordRenderer) + .gimpyEngine(gimpyEngine) + .backgroundProducer(backgroundProducer) + .width(200) + .height(50) + .borderDrawn(true) + .borderColour(Color.BLACK) + .borderThickness(1) + .build(); + +String text = captcha.createText(); +BufferedImage image = captcha.createImage(text); +``` + +### DefaultCaptchaProducer Builder + +| Method | Default Value | Description | +|---------------------|---------------------------------------------|---------------------------------------| +| `textProducer` | `DefaultTextProducer.builder().build()` | The text producer to use | +| `wordRenderer` | `DefaultWordRenderer.builder().build()` | The word renderer to use | +| `gimpyEngine` | `WaterRipple.builder().build()` | The distortion engine to use | +| `backgroundProducer`| `DefaultBackgroundProducer.builder().build()`| The background producer to use | +| `width` | `200` | Width of the CAPTCHA image | +| `height` | `50` | Height of the CAPTCHA image | +| `borderDrawn` | `true` | Whether a border is drawn | +| `borderColour` | `Color.BLACK` | The colour of the border | +| `borderThickness` | `1` | The thickness of the border | + +--- + +## Text + +### TextProducer + +Interface for creating CAPTCHA text strings. + +```java +public interface TextProducer { + String getText(); +} +``` + +#### DefaultTextProducer + +Generates random text with configurable length and character set. + +```java +DefaultTextProducer textProducer = DefaultTextProducer.builder() + .length(6) // default: 6 + .chars("ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray()) // default: a-z, A-Z, 0-9 + .build(); +``` + +| Method | Default Value | Description | +|----------|-----------------------------------------------------------|--------------------------------| +| `length` | `6` | Length of generated text | +| `chars` | `a-z`, `A-Z`, `0-9` (62 characters) | Characters used for generation | + +### WordRenderer + +Interface for rendering text onto an image. + +```java +public interface WordRenderer { + BufferedImage renderWord(String word, int width, int height); +} +``` + +#### DefaultWordRenderer + +Renders text with configurable font, colour, and spacing. + +```java +DefaultWordRenderer wordRenderer = DefaultWordRenderer.builder() + .fontSize(40) // default: 40 + .fonts("Arial", "Courier") // default: Arial, Courier + .fontColour(Color.BLACK) // default: Color.BLACK + .charSpace(2) // default: 2 + .fontStyle(FontStyle.BOLD) // default: FontStyle.BOLD + .build(); +``` + +| Method | Default Value | Description | +|-------------|-----------------------------------|-----------------------------------------| +| `fontSize` | `40` | Font size in pixels | +| `fonts` | `["Arial", "Courier"]` | Font families to use (randomly chosen) | +| `fontColour`| `Color.BLACK` | Font colour | +| `charSpace` | `2` | Space between characters in pixels | +| `fontStyle` | `FontStyle.BOLD` | Font style to apply | + +### FontStyle + +Defines the supported font styles for rendering CAPTCHA text. + +| Value | Corresponding AWT Constant | Description | +|---------------|-------------------------------------|------------------------------| +| `PLAIN` | `java.awt.Font.PLAIN` | Plain style | +| `BOLD` | `java.awt.Font.BOLD` | Bold style | +| `ITALIC` | `java.awt.Font.ITALIC` | Italic style | +| `BOLD_ITALIC` | `java.awt.Font.BOLD | Font.ITALIC` | Bold and italic combined | + +--- + +## GimpyEngine + +Interface for applying image distortion effects. + +```java +public interface GimpyEngine { + BufferedImage getDistortedImage(BufferedImage baseImage); +} +``` + +### WaterRipple + +Applies a water ripple distortion effect. Extends `AbstractGimpyEngine` and adds noise automatically. + +```java +WaterRipple gimpy = WaterRipple.builder() + .noiseProducer(DefaultNoiseProducer.builder().build()) // default: DefaultNoiseProducer + .build(); +``` + +| Method | Default Value | Description | +|-----------------|---------------------------------------------|------------------------------| +| `noiseProducer` | `DefaultNoiseProducer.builder().build()` | The noise producer to use | + +### FishEyeGimpy + +Applies a fish-eye distortion effect with horizontal and vertical lines over the image. + +```java +FishEyeGimpy gimpy = FishEyeGimpy.builder() + .build(); +``` + +### ShadowGimpy + +Applies a shadow and ripple effect. Extends `AbstractGimpyEngine` and adds noise automatically. + +```java +ShadowGimpy gimpy = ShadowGimpy.builder() + .noiseProducer(DefaultNoiseProducer.builder().build()) // default: DefaultNoiseProducer + .build(); +``` + +| Method | Default Value | Description | +|-----------------|---------------------------------------------|------------------------------| +| `noiseProducer` | `DefaultNoiseProducer.builder().build()` | The noise producer to use | + +--- + +## Noise + +### NoiseProducer + +Interface for adding noise to an image. + +```java +public interface NoiseProducer { + void makeNoise(BufferedImage image, float factorOne, float factorTwo, + float factorThree, float factorFour); +} +``` + +#### DefaultNoiseProducer + +Adds noise curves with configurable colour. + +```java +DefaultNoiseProducer noise = DefaultNoiseProducer.builder() + .noiseColour(Color.BLACK) // default: Color.BLACK + .build(); +``` + +| Method | Default Value | Description | +|---------------|---------------|---------------------| +| `noiseColour` | `Color.BLACK` | The noise colour | + +#### NoNoiseProducer + +A no-op implementation that does not add any noise to the image. + +```java +NoiseProducer noise = NoNoiseProducer.builder() + .build(); +``` + +--- + +## Background + +### BackgroundProducer + +Interface for adding background to an image. + +```java +public interface BackgroundProducer { + BufferedImage addBackground(BufferedImage image); +} +``` + +#### DefaultBackgroundProducer + +Creates a gradient background with configurable start and end colours. + +```java +DefaultBackgroundProducer background = DefaultBackgroundProducer.builder() + .colourFrom(Color.WHITE) // default: Color.LIGHT_GRAY + .colourTo(Color.LIGHT_GRAY) // default: Color.WHITE + .build(); +``` + +| Method | Default Value | Description | +|--------------|--------------------|---------------------------------| +| `colourFrom` | `Color.LIGHT_GRAY` | The starting colour of gradient | +| `colourTo` | `Color.WHITE` | The ending colour of gradient | diff --git a/docs/en-gb/projects/captcha/index.mdx b/docs/en-gb/projects/captcha/index.mdx new file mode 100644 index 0000000..b2d29b0 --- /dev/null +++ b/docs/en-gb/projects/captcha/index.mdx @@ -0,0 +1,89 @@ +--- +title: Captcha +--- + +import { Tabs, Tab } from "@rspress/core/theme" + +## Introduction + +Captcha is a Java library for generating CAPTCHA images. This project is a spiritual successor to Google's Kaptcha, modernised for contemporary development practices. + +With Captcha, you can easily generate customisable CAPTCHA images with various distortion effects, noise, and background options to integrate into your Java applications. + +## Features + +- **Easy Integration** — Simple builder-based API for quick setup and configuration. +- **Customisable CAPTCHA Generation** — Configure text length, character sets, font styles, and colours. +- **Multiple Distortion Effects** — Choose from Water Ripple, Fish Eye, and Shadow effects. +- **Configurable Noise** — Add noise lines with custom colours, or disable noise entirely. +- **Gradient Backgrounds** — Customisable gradient background colours. +- **Clean, Modern Codebase** — Well-documented, type-safe, and easy to extend. + +## Installation + + + + ```kotlin title="build.gradle.kts" + dependencies { + implementation("com.onixbyte:captcha:1.0.0") + } + ``` + + + ```xml title="pom.xml" + + + com.onixbyte + captcha + 1.0.0 + + + ``` + + + +## Quick Start + +```java +import com.onixbyte.captcha.Producer; +import com.onixbyte.captcha.background.BackgroundProducer; +import com.onixbyte.captcha.background.impl.DefaultBackgroundProducer; +import com.onixbyte.captcha.gimpy.GimpyEngine; +import com.onixbyte.captcha.gimpy.impl.WaterRipple; +import com.onixbyte.captcha.impl.DefaultCaptchaProducer; +import com.onixbyte.captcha.noise.NoiseProducer; +import com.onixbyte.captcha.noise.impl.DefaultNoiseProducer; +import com.onixbyte.captcha.text.TextProducer; +import com.onixbyte.captcha.text.WordRenderer; +import com.onixbyte.captcha.text.impl.DefaultTextProducer; +import com.onixbyte.captcha.text.impl.DefaultWordRenderer; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +public class CaptchaExample { + + public static void main(String[] args) throws IOException { + // Create a CAPTCHA producer with default configurations + Producer captcha = DefaultCaptchaProducer.builder().build(); + + // Generate text and create the image + String captchaText = captcha.createText(); + BufferedImage captchaImage = captcha.createImage(captchaText); + + // Save the image to a file + ImageIO.write(captchaImage, "png", new File("captcha.png")); + + System.out.println("CAPTCHA text: " + captchaText); + } +} +``` + +This generates a CAPTCHA image with a 6-character random text and saves it as a PNG file. + +## License + +Captcha is open-source software released under the MIT License. diff --git a/docs/en-gb/projects/delta-force-guide/api.md b/docs/en-gb/projects/delta-force-guide/api.md new file mode 100644 index 0000000..13eb5b6 --- /dev/null +++ b/docs/en-gb/projects/delta-force-guide/api.md @@ -0,0 +1,91 @@ +--- +title: Delta Force Guide API +--- + +## Backend API Overview + +The backend is a Spring Boot 3 application organised under the base package `com.onixbyte.deltaforceguide`: + +| Package | Description | +|---------------------------------------------|-----------------------------------| +| `controller` | REST API endpoint controllers | +| `service` | Business logic layer | +| `repository` | MyBatis data access layer | +| `domain` | JPA entity and domain objects | +| `config` | Spring configuration (security, cache, etc.) | +| `properties` | Configuration property classes | +| `enumeration` | Enumerated types | +| `shared` | Shared utilities | + +## API Endpoints + +### Authentication + +| Method | Path | Description | Auth | +|--------|-----------------------|--------------------------|------| +| `POST` | `/api/auth/login` | Log in with credentials | No | +| `POST` | `/api/auth/refresh` | Refresh access token | No | +| `GET` | `/api/auth/profile` | Get current user profile | Yes | + +### Firearms + +| Method | Path | Description | +|----------|-----------------------|--------------------------| +| `GET` | `/api/firearms` | List firearms (paginated, filterable by type) | +| `GET` | `/api/firearms/:id` | Get firearm by ID | +| `POST` | `/api/firearms` | Create a new firearm | +| `PUT` | `/api/firearms/:id` | Update an existing firearm | +| `DELETE` | `/api/firearms/:id` | Remove a firearm | + +### Modifications + +| Method | Path | Description | +|----------|-----------------------------------|--------------------------------| +| `GET` | `/api/modifications` | List modifications (paginated, filterable by firearm and tags) | +| `GET` | `/api/modifications/:id` | Get modification by ID | +| `POST` | `/api/modifications` | Create a modification | +| `POST` | `/api/modifications/batch` | Batch create modifications | +| `PUT` | `/api/modifications/:id` | Update a modification | +| `DELETE` | `/api/modifications/:id` | Remove a modification | +| `DELETE` | `/api/modifications/batch-delete` | Batch remove modifications | + +### Tags + +| Method | Path | Description | +|--------|-----------------------|-----------------------| +| `GET` | `/api/tags` | List all tags | + +## Frontend Routes + +| Path | Layout | Page | Description | +|---------------|-------------|-------------------|---------------------------------| +| `/` | Hero Layout | Firearms Browser | Home page — firearm list | +| `/firearms` | Hero Layout | Firearms Browser | Firearm detail and search | +| `/mod-codes` | Hero Layout | Modification Codes| Modification code library | +| `/legal` | Hero Layout | Legal | Legal and privacy information | +| `/login` | Empty Layout| Login | User authentication page | + +## Frontend State Management + +Redux Toolkit with Redux Persist manages: + +- **Auth state** — Access tokens, refresh tokens, user profile +- **Settings state** — User preferences persisted to local storage + +## API Client + +The frontend uses a shared `WebClient` wrapper around Axios that handles: + +- Base URL configuration (pointing to the backend API) +- JWT access token injection via request interceptors +- Automatic token refresh on 401 responses + +## Infrastructure + +| Component | Technology | +|---------------|-----------------------------| +| Database | PostgreSQL (with Flyway migrations) | +| Cache | Redis (session/token storage) | +| File Storage | AWS S3 (firearm images) | +| Containerisation | Docker | +| Deployment | Docker Compose behind Nginx | diff --git a/docs/en-gb/projects/delta-force-guide/index.mdx b/docs/en-gb/projects/delta-force-guide/index.mdx new file mode 100644 index 0000000..c5e9e11 --- /dev/null +++ b/docs/en-gb/projects/delta-force-guide/index.mdx @@ -0,0 +1,46 @@ +--- +title: Delta Force Guide +--- + +## Introduction + +Delta Force Guide is a full-stack web application providing a searchable library of firearm modification codes for the game Delta Force. It consists of two components: + +- **Web Frontend** — A React-based SPA for browsing, filtering, and copying modification codes. +- **Backend Server** — A Spring Boot REST API handling data persistence, authentication, and content management. + +The live site is available at **[dfguide.onixbyte.cn](https://dfguide.onixbyte.cn)**. + +## Features + +- **Firearm Browser** — Browse a curated list of in-game firearms with detailed stats. +- **Modification Code Library** — Search and filter modification codes by weapon, mode, and tags. +- **One-Click Copy** — Copy modification codes directly from the interface. +- **Efficient Rendering** — Large lists rendered smoothly with window virtualisation. +- **Authentication** — User login with JWT-based auth and CAPTCHA verification. +- **Admin Panel** — Full CRUD operations for firearms and modification data. +- **Static-Friendly** — Frontend deployed as a static site with API proxy. + +## Architecture + +| Component | Tech Stack | +|---------------|---------------------------------------------------------------| +| **Frontend** | React 19, TypeScript, Tailwind CSS 4, Ant Design 6, React Router 7, Redux Toolkit, TanStack Virtual | +| **Backend** | Spring Boot 3, Java 21, PostgreSQL, MyBatis, Flyway, Redis | +| **Auth** | JWT (access + refresh tokens), CAPTCHA integration | +| **Storage** | AWS S3 for image uploads | + +The frontend is a static site served by Vite, communicating with the Spring Boot REST API backend. Authentication uses JWT access and refresh tokens with Redis-backed refresh token management. + +## Repositories + +- [delta-force-guide-server](https://github.com/onixbyte/delta-force-guide-server) — Spring Boot backend +- [delta-force-guide-web](https://github.com/onixbyte/delta-force-guide-web) — React frontend + +## Quick Links + +- **Live Site:** [dfguide.onixbyte.cn](https://dfguide.onixbyte.cn) + +## License + +Delta Force Guide is open-source software released under the MIT Licence. diff --git a/docs/en-gb/projects/helix/index.mdx b/docs/en-gb/projects/helix/index.mdx new file mode 100644 index 0000000..d3c4c51 --- /dev/null +++ b/docs/en-gb/projects/helix/index.mdx @@ -0,0 +1,71 @@ +--- +title: Helix +--- + +## Introduction + +Helix is a full-stack enterprise application template designed to accelerate the development of production-grade business applications. It provides a pre-built foundation with all the essential features an enterprise application needs, allowing teams to focus on business logic rather than infrastructure. + +The project consists of two components: + +- **Helix Server** — A Spring Boot backend providing REST APIs, authentication, authorisation, and data management. +- **Helix Web** — A React-based SPA frontend with a modern UI, role-based routing, and enterprise identity integration. + +Helix is intended to be used as a starting point. Fork or clone it and begin building your own domain-specific features on top of the ready-made foundation. + +## Features + +### Backend (Helix Server) + +- **Authentication & Authorisation** — JWT-based access and refresh token flow with Spring Security. Supports Microsoft Entra ID (Azure AD) integration. +- **Role-Based Access Control** — Fine-grained permissions via roles, authorities, and menu-level access control. +- **User & Organisation Management** — Full CRUD for users, departments, positions, and roles. +- **Menu Management** — Hierarchical menu tree with configurable visibility per role. +- **Asset Management** — File uploads to AWS S3 with CDN-ready prefix handling. +- **Settings Management** — Typed application settings persisted to database. +- **Captcha Integration** — Image CAPTCHA verification for login and registration flows. +- **Redis Caching** — High-performance caching with configurable TTL and custom serialisers. +- **Data Access** — Hybrid persistence with Spring Data JPA and MyBatis. +- **Validation** — Bean Validation groups with custom validation constraints. + +### Frontend (Helix Web) + +- **Enterprise Identity** — Microsoft Entra ID login via MSAL. Extensible social login provider architecture (Microsoft, Google, GitLab, Slack, Discord, DingTalk, Lark, WeCom, email/password). +- **Dashboard Layout** — Responsive admin dashboard with collapsible sidebar and role-based menu rendering. +- **User Management** — Data table with search, pagination, add/edit dialogues, role assignment, and phone number validation. +- **Role & Menu Management** — Role CRUD with authority assignment. Tree-based menu configuration. +- **Department & Position** — Organisation hierarchy management interfaces. +- **Protected Routing** — Route guards checking authentication and authorisation before page load. +- **State Management** — Redux Toolkit with Redux Persist for auth token persistence. +- **HTTP Client** — Axios wrapper with automatic JWT token injection and 401 refresh handling. + +## Architecture + +| Layer | Technology | +|--------------|---------------------------------------------------------------| +| **Frontend** | React 19, TypeScript, Tailwind CSS 4, Ant Design 6, React Router 7, Redux Toolkit, Axios, MSAL | +| **Backend** | Spring Boot 3.5, Java 17, Spring Security, MyBatis, Spring Data JPA | +| **Database** | PostgreSQL (with Flyway migrations) | +| **Cache** | Redis (session/token storage) | +| **Storage** | AWS S3 (asset uploads) | + +The frontend communicates with the backend via a RESTful JSON API. Authentication flow uses JWT access tokens (short-lived) with refresh tokens stored in Redis. Microsoft Entra ID integration is handled client-side via MSAL and validated server-side. + +## Repositories + +- [helix-server](https://git.onixbyte.cn/helix/helix-server) — Spring Boot backend +- [helix-web](https://git.onixbyte.cn/helix/helix-web) — React frontend + +## Getting Started + +Helix is designed as a template project. To start a new project: + +1. Fork or clone both `helix-server` and `helix-web` repositories. +2. Configure your database, Redis, and S3 settings in the backend. +3. Configure your authentication providers and API base URL in the frontend. +4. Run the backend: `./gradlew bootRun` +5. Run the frontend: `pnpm install && pnpm dev` + +## License + +Helix is open-source software released under the MIT License. diff --git a/docs/en-gb/projects/index.md b/docs/en-gb/projects/index.md new file mode 100644 index 0000000..8becd7e --- /dev/null +++ b/docs/en-gb/projects/index.md @@ -0,0 +1,21 @@ +--- +title: Projects +--- + +Explore open-source projects developed by OnixByte. + +## Libraries & Toolkits + +- **[OnixByte Toolbox](/projects/onixbyte-toolbox)** — A development kit for Java applications: AES, hashing, Base64, collection utilities, crypto key loaders, statistical calculators, identity generators, and generic tuples. +- **[regions4j](/projects/regions4j)** — Type-safe ISO 3166-1 regional metadata as a Java enum with O(1) lookups, E.164 dialling codes, and locale tags. +- **[Captcha](/projects/captcha)** — A modern Java CAPTCHA generation library with water ripple, fish-eye, and shadow distortion effects. +- **[Calendar Toolbox](/projects/calendar-toolbox)** — A Java library for creating `.ics` files conforming to the iCalendar specification (RFC 5545). + +## Full-Stack Applications + +- **[Helix](/projects/helix)** — An enterprise application template with Spring Boot backend and React frontend, featuring JWT auth, RBAC, user and organisation management, and Microsoft Entra ID integration. +- **[Delta Force Guide](/projects/delta-force-guide)** — A web app providing a searchable library of firearm modification codes for the game _Delta Force: Havvk Ops_, with a React SPA and Spring Boot REST API. + +## Vite Plugins + +- **[Port Checker](/projects/vite-plugins/port-checker)** — Warns when the Vite dev server listens on a browser-restricted port, preventing silent connection failures. diff --git a/docs/en-gb/projects/onixbyte-toolbox/api.md b/docs/en-gb/projects/onixbyte-toolbox/api.md new file mode 100644 index 0000000..c097076 --- /dev/null +++ b/docs/en-gb/projects/onixbyte-toolbox/api.md @@ -0,0 +1,209 @@ +--- +title: OnixByte Toolbox API +--- + +## Package Overview + +All modules are published under the `com.onixbyte` group ID. Each module has its own base package: + +| Module | Maven Artifact | Base Package | +|----------------------|------------------------|---------------------------------------| +| Common Toolbox | `common-toolbox` | `com.onixbyte.common` | +| Crypto Toolbox | `crypto-toolbox` | `com.onixbyte.crypto` | +| Math Toolbox | `math-toolbox` | `com.onixbyte.math` | +| Tuple | `tuple` | `com.onixbyte.tuple` | +| Identity Generator | `identity-generator` | `com.onixbyte.identitygenerator` | + +--- + +## Common Toolbox + +### Adapter + +`ObjectMapAdapter` — Converts between objects and maps. Useful for serialisation or data transformation scenarios where key-value representations are preferred. + +```java +import com.onixbyte.common.adapter.ObjectMapAdapter; +``` + +### Utility Classes + +| Class | Description | +|--------------------|----------------------------------------------------------| +| `AesUtil` | AES symmetric encryption/decryption with key generation | +| `Base64Util` | Base64 encoding and decoding with multiple charset support| +| `BoolUtil` | Boolean parsing and conversion utilities | +| `BranchUtil` | Conditional branching helpers with functional-style chains| +| `CollectionUtil` | Collection manipulation — grouping, partitioning, merging | +| `HashUtil` | Hashing utilities supporting MD5, SHA-1, SHA-256, SHA-512 | +| `MapUtil` | Map builder, merge, and transformation helpers | +| `RangeUtil` | Numeric range operations with boundary handling | + +**AesUtil Example:** + +```java +var key = AesUtil.generateKey(); +var encrypted = AesUtil.encrypt("hello world", key); +var decrypted = AesUtil.decrypt(encrypted, key); +``` + +**HashUtil Example:** + +```java +var md5 = HashUtil.md5("hello world"); +var sha256 = HashUtil.sha256("hello world"); +var fileSha = HashUtil.sha256(new File("data.bin")); +``` + +**CollectionUtil Example:** + +```java +var partitioned = CollectionUtil.partition(list, 100); +var grouped = CollectionUtil.groupBy(users, User::getDepartment); +``` + +--- + +## Crypto Toolbox + +Provides a clean abstraction for loading cryptographic keys in PEM format. Supports both RSA and ECDSA algorithms. + +### Key Loaders + +| Class | Description | +|---------------------------|--------------------------------------------| +| `RSAPrivateKeyLoader` | Load RSA private keys from PEM strings | +| `RSAPublicKeyLoader` | Load RSA public keys from PEM strings | +| `ECPrivateKeyLoader` | Load ECDSA private keys from PEM strings | +| `ECPublicKeyLoader` | Load ECDSA public keys from PEM strings | + +All key loaders implement either `PrivateKeyLoader` or `PublicKeyLoader` interfaces. + +**RSA Example:** + +```java +var privateKey = new RSAPrivateKeyLoader().load(pemString); +var publicKey = new RSAPublicKeyLoader().load(pemString); +``` + +**ECDSA Example:** + +```java +var ecPrivateKey = new ECPrivateKeyLoader().load(pemString); +var ecPublicKey = new ECPublicKeyLoader().load(pemString); +``` + +### Utility + +`CryptoUtil` — Provides convenient methods for digital signature creation and verification, as well as general-purpose cryptographic helpers. + +### Exceptions + +| Class | Description | +|------------------------|---------------------------------------------------| +| `KeyLoadingException` | Thrown when a PEM-formatted key fails to parse | + +--- + +## Math Toolbox + +Statistical computation utilities for working with numeric datasets. + +### Core Classes + +| Class | Description | +|-------------------------|----------------------------------------------------------| +| `Calculator` | Statistical calculator for mean, median, variance, standard deviation, sum, min, max | +| `PercentileCalculator` | Percentile computation with configurable interpolation strategies | + +**Calculator Example:** + +```java +var stats = new Calculator(Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0)); +double mean = stats.getMean(); +double median = stats.getMedian(); +double stdDev = stats.getStandardDeviation(); +``` + +**PercentileCalculator Example:** + +```java +var calculator = new PercentileCalculator(data); +double p95 = calculator.calculate(95); +double p99 = calculator.calculate(99); +``` + +### Model + +| Class | Description | +|-------------------|----------------------------------------------------------------| +| `QuartileBounds` | Holds Q1, median (Q2), Q3 values along with IQR and whisker bounds | + +--- + +## Tuple + +Lightweight generic tuple types for when you need to return multiple values without defining a dedicated class. + +### Classes + +| Class | Type Parameters | Mutability | +|--------------------|-----------------|------------| +| `Tuple` | Two elements | Mutable | +| `ImmutableTuple` | Two elements | Immutable | +| `Triple` | Three elements | Mutable | +| `ImmutableTriple` | Three elements | Immutable | + +**Example:** + +```java +var pair = Tuple.of("key", 42); +var triple = Triple.of("id", "name", 100); +var immutable = ImmutableTuple.of("constant", true); + +// Accessors +String first = pair.getFirst(); +Integer second = pair.getSecond(); + +// Triple accessors +String a = triple.getFirst(); +String b = triple.getSecond(); +Integer c = triple.getThird(); +``` + +--- + +## Identity Generator + +Generates unique identifiers suitable for use as database primary keys or distributed IDs. + +### Interface + +`IdentityGenerator` — Generates identities of type `T`. + +### Implementations + +| Class | Description | +|------------------------------|-----------------------------------------------------------------| +| `SequentialUuidGenerator` | Generates time-ordered, sequential UUIDs (optimised for DB indexes) | +| `SnowflakeIdentityGenerator` | Snowflake-style distributed unique ID generation | + +**Sequential UUID:** + +```java +var generator = new SequentialUuidGenerator(); +UUID id = generator.nextId(); // time-ordered UUID, B-tree friendly +``` + +**Snowflake:** + +```java +var generator = new SnowflakeIdentityGenerator(workerId, datacenterId); +long id = generator.nextId(); // 64-bit snowflake ID +``` + +### Exceptions + +| Class | Description | +|-------------------|----------------------------------------------------------------| +| `TimingException` | Thrown when the system clock moves backwards, compromising ID uniqueness | diff --git a/docs/en-gb/projects/onixbyte-toolbox/index.mdx b/docs/en-gb/projects/onixbyte-toolbox/index.mdx new file mode 100644 index 0000000..b392ea8 --- /dev/null +++ b/docs/en-gb/projects/onixbyte-toolbox/index.mdx @@ -0,0 +1,54 @@ +--- +title: OnixByte Toolbox +--- + +import { Tabs, Tab } from "@rspress/core/theme" + +## Introduction + +OnixByte Toolbox is a Development Kit for Java applications that provides a set of convenient, reusable tools for writing code efficiently. It is designed and maintained by OnixByte as a monorepo containing multiple purpose-built libraries, each addressing a specific development need — from common utilities and cryptography to mathematical computation and identity generation. + +The toolkit is available on Maven Central under the `com.onixbyte` group ID. Each module is independently versioned and can be included in any Java 17+ project. + +## Modules + +| Module | Artifact ID | Description | +|--------------------|----------------------|---------------------------------------------------------------------------| +| Common Toolbox | `common-toolbox` | Everyday utilities — AES, hashing, Base64, collections, branching, ranges | +| Crypto Toolbox | `crypto-toolbox` | Public/private key loading for RSA and ECDSA algorithms | +| Math Toolbox | `math-toolbox` | Statistical calculation, percentile analysis, quartile computation | +| Tuple | `tuple` | Generic 2-tuple and 3-tuple with immutable variants | +| Identity Generator | `identity-generator` | Snowflake-style and sequential UUID identity generation | +| Version Catalogue | `version-catalogue` | Centralised Gradle version catalogue for OnixByte projects | + +## Installation + +Add the desired module as a dependency in your build config: + + + + ```kotlin title="build.gradle.kts" + dependencies { + implementation("com.onixbyte:$artefactId:$version") + } + ``` + + + + ```xml title="pom.xml" + + com.onixbyte + ${artefactId} + ${version} + + ``` + + + +## Requirements + +- Java 17 or later + +## License + +OnixByte Toolbox is open-source software released under the MIT Licence. diff --git a/docs/en-gb/projects/regions4j/index.mdx b/docs/en-gb/projects/regions4j/index.mdx new file mode 100644 index 0000000..340b511 --- /dev/null +++ b/docs/en-gb/projects/regions4j/index.mdx @@ -0,0 +1,98 @@ +--- +title: Regions for Java +--- + +## Introduction + +**regions4j** is a lightweight, type-safe Java library that provides comprehensive metadata for world regions based on the ISO 3166-1 standard. It is designed to simplify internationalisation (i18n), telecommunication routing, and regional data management in Java-based enterprise applications. + +The library models every ISO 3166-1 country and territory as an enum constant, giving you compile-time safety and IDE autocompletion when referencing regions. With built-in O(1) lookups, zero external dependencies, and Java 8 compatibility, it is suitable for projects of any size — from microservices to monolithic enterprise systems. + +## Features + +- **ISO 3166-1 Compliant** — Full support for Alpha-2 (`abbreviation`) and Alpha-3 (`code`) formats across all assigned countries and territories. +- **Telecommunication Metadata** — Includes E.164 international dialling prefixes for every region. +- **Locality Support** — Default locale tags (`zh_HK`, `en_US`, `en_GB`, etc.) for each region to assist with i18n workflows. +- **High Performance** — Thread-safe, immutable internal hash maps provide constant-time lookups by abbreviation or code. +- **Zero Dependencies** — A pure Java library with no external overhead. +- **Calendar Versioning** — Versions follow a `YYYY.MM` scheme (e.g. `2025.12`) to transparently indicate the freshness of the underlying ISO data, rather than semantic versioning. + +## Core Schema + +Each region exposes four attributes: + +| Attribute | Type | Description | Example | +|----------------|--------|---------------------------------|------------------------------------| +| `abbreviation` | String | ISO 3166-1 alpha-2 abbreviation | `HK`, `US`, `GB`, `RU` | +| `code` | String | ISO 3166-1 alpha-3 code | `HKG`, `USA`, `GBR`, `RUS` | +| `callingCode` | String | E.164 international dialling prefix | `852`, `1`, `44`, `7` | +| `locale` | String | Default language and region tag | `zh_HK`, `en_US`, `en_GB`, `ru_RU` | + +## Installation + +**Maven:** + +```xml + + com.onixbyte + regions4j + 2025.12 + +``` + +**Gradle (Kotlin DSL):** + +```kotlin +implementation("com.onixbyte:regions4j:2025.12") +``` + +> **Versioning note:** This library uses Calendar Versioning (`YYYY.MM`) rather than Semantic Versioning. A version string like `2025.12` tells you immediately that the regional data reflects the ISO 3166-1 state as of December 2025. + +## Usage + +### Direct Access + +Reference any region directly via its enum constant: + +```java +Region uk = Region.UNITED_KINGDOM; + +uk.getAbbreviation(); // "GB" +uk.getCode(); // "GBR" +uk.getDialCode(); // "44" +uk.getLocale(); // "en_GB" +``` + +### Efficient Lookups + +Look up regions from string inputs — ideal for processing web requests, API payloads, or database records: + +```java +// By Alpha-2 abbreviation (case-sensitive) +Region region = Region.fromAbbreviation("HK"); + +// By Alpha-3 code (case-insensitive) +Region region = Region.fromCode("HKG"); +``` + +### Java Locale Integration + +Convert a region's locale string to a `java.util.Locale` for use with standard Java i18n APIs: + +```java +Region region = Region.CHINA; +Locale javaLocale = Locale.forLanguageTag(region.getLocale().replace("_", "-")); +javaLocale.getDisplayCountry(Locale.UK); // "China" +``` + +## Performance + +On first access, the library initialises all regions into immutable `HashMap` structures. Subsequent lookups via `fromAbbreviation()` and `fromCode()` are thread-safe and run in constant time — suitable for high-throughput request paths. + +## Requirements + +- Java 8 or later + +## License + +regions4j is open-source software released under the MIT License. diff --git a/docs/en-gb/projects/vite-plugins/index.mdx b/docs/en-gb/projects/vite-plugins/index.mdx new file mode 100644 index 0000000..88e44ed --- /dev/null +++ b/docs/en-gb/projects/vite-plugins/index.mdx @@ -0,0 +1,11 @@ +--- +title: Vite Plugins +--- + +## Overview + +A collection of Vite plugins developed and maintained by OnixByte. Each plugin is designed to solve a specific problem in the Vite development workflow — lightweight, zero-dependency, and plug-and-play. + +## Available Plugins + +- **[Port Checker](/projects/vite-plugins/port-checker)** — Warns when the dev server listens on a browser-restricted port (per the Fetch specification), helping you avoid silent connection failures. diff --git a/docs/en-gb/projects/vite-plugins/port-checker/index.mdx b/docs/en-gb/projects/vite-plugins/port-checker/index.mdx new file mode 100644 index 0000000..7327d2d --- /dev/null +++ b/docs/en-gb/projects/vite-plugins/port-checker/index.mdx @@ -0,0 +1,68 @@ +--- +title: Port Checker +--- + +import { Tabs, Tab } from "@rspress/core/theme" + +## Introduction + +**vite-plugin-port-checker** is a lightweight Vite plugin that warns you when the dev server is listening on a port blocked by common browsers. Browsers such as Chrome and Firefox maintain a [list of restricted ports](https://fetch.spec.whatwg.org/#port-blocking) — typically those associated with well-known protocols like SMTP, SSH, and DNS — and refuse to connect to them. Accidentally running your dev server on one of these ports leads to a confusing "connection refused" or "blocked" error with no clear explanation. + +This plugin detects the situation at startup and prints a clear, colour-coded warning to the console, advising you to change the `server.port` setting in your Vite configuration. + +## Features + +- **Automatic Detection** — Checks the dev server port against the complete Fetch spec port-blocking list (68 restricted ports). +- **Clear Warnings** — Yellow-highlighted console output with actionable guidance. +- **Zero Configuration** — Works out of the box with no options to set. +- **Lightweight** — Single-file plugin with no dependencies beyond Vite itself. + +## Installation + + + + ```bash + npm install vite-plugin-port-checker -D + ``` + + + ```bash + pnpm add vite-plugin-port-checker -D + ``` + + + +## Usage + +Add the plugin to your `vite.config.ts`: + +```ts +// vite.config.ts +import { defineConfig } from "vite" +import checkRestrictedPort from "vite-plugin-port-checker" + +export default defineConfig({ + plugins: [checkRestrictedPort()], +}) +``` + +When the dev server starts on a restricted port (e.g. port 25, 22, or 53), you will see: + +``` +[Warning] The current listening port 25 is categorised as a restricted port +by most browsers. This may prevent you from accessing the application. +Please consider changing the port in your 'vite.config.ts' or 'vite.config.js' +via 'server.port'. +``` + +## How It Works + +The plugin hooks into Vite's `configureServer` lifecycle. Once the HTTP server emits the `listening` event, the plugin inspects the bound port and checks it against the hardcoded set of 68 restricted ports defined in the [Fetch specification](https://fetch.spec.whatwg.org/#port-blocking). If there is a match, a yellow `console.warn` message alerts the developer. + +## Requirements + +- Vite 3.0.0 or later + +## License + +vite-plugin-port-checker is open-source software released under the MIT License. diff --git a/docs/zh-hans/_nav.json b/docs/zh-hans/_nav.json index 64b7c36..c810b93 100644 --- a/docs/zh-hans/_nav.json +++ b/docs/zh-hans/_nav.json @@ -1,14 +1,14 @@ [ - { - "text": "blogs", - "link": "/blogs/", - "activeMatch": "/blogs/" - }, { "text": "projects", "link": "/projects/", "activeMatch": "/projects/" }, + { + "text": "blogs", + "link": "/blogs/", + "activeMatch": "/blogs/" + }, { "text": "notifications", "link": "/notifications/", diff --git a/docs/zh-hans/index.md b/docs/zh-hans/index.md index 56f11e7..5c4183a 100644 --- a/docs/zh-hans/index.md +++ b/docs/zh-hans/index.md @@ -8,9 +8,6 @@ hero: - theme: brand text: 探索项目 link: https://github.com/onixbyte - - theme: alt - text: 体验 Dev Lab - link: https://dev-lab.onixbyte.dev features: - title: OnixByte Toolbox details: 一个多功能 Java 类库,为现代 Java 开发提供通用工具,无缝集成 Spring 生态。已上架 Maven Central。 diff --git a/docs/zh-hans/projects/calendar-toolbox/api.md b/docs/zh-hans/projects/calendar-toolbox/api.md new file mode 100644 index 0000000..76184d0 --- /dev/null +++ b/docs/zh-hans/projects/calendar-toolbox/api.md @@ -0,0 +1,390 @@ +--- +title: Calendar Toolbox API +--- + +## 包结构概览 + +库的代码组织在基础包 `com.onixbyte.calendar` 下,结构如下: + +| 包 | 描述 | +|---|---| +| `com.onixbyte.calendar` | 根日历对象 | +| `com.onixbyte.calendar.component` | iCalendar 组件(VEVENT、VTODO 等) | +| `com.onixbyte.calendar.component.property` | 组件级属性 | +| `com.onixbyte.calendar.property` | 日历级属性 | +| `com.onixbyte.calendar.parameter` | iCalendar 属性参数 | +| `com.onixbyte.calendar.recurrence` | 重复规则类型 | +| `com.onixbyte.calendar.value` | 值类型 | +| `com.onixbyte.calendar.util` | 格式化工具类 | + +--- + +## Calendar + +表示 iCalendar(RFC 5545)VCALENDAR 容器的顶层对象。 + +```java +Calendar calendar = Calendar.builder() + .withCalendarScale(...) + .withMethod(...) + .withProductIdentifier(...) + .withVersion(...) + .withOwner(...) + .withPrimaryCalendar(...) + .withPublishedTTL(...) + .withCalendarDescription(...) + .withCalendarName(...) + .withCalendarId(...) + .withCustomProperties(...) + .withComponents(event, todo, ...) + .build(); + +String icsContent = calendar.formatted(); +``` + +### 日历属性 + +所有日历级属性位于 `com.onixbyte.calendar.property`,实现 `CalendarProperty` 接口。 + +| 类 | iCalendar 属性 | 描述 | +|---|---|---| +| `CalendarScale` | `CALSCALE` | 日历系统(例如 GREGORIAN) | +| `Method` | `METHOD` | iCalendar 方法(例如 PUBLISH、REQUEST) | +| `ProductIdentifier` | `PRODID` | 日历的产品标识符 | +| `Version` | `VERSION` | iCalendar 版本(例如 2.0) | +| `Owner` | `X-OWNER` | 日历所有者 | +| `PrimaryCalendar` | `X-PRIMARY-CALENDAR` | 是否为主日历 | +| `PublishedTTL` | `X-PUBLISHED-TTL` | 已发布日历的生存时间 | +| `CalendarDescription` | `X-CALENDAR-DESC` | 日历描述 | +| `CalendarName` | `X-CALENDAR-NAME` | 日历名称 | +| `CalendarId` | `X-CALENDAR-ID` | 日历标识符 | +| `CustomCalendarProperty` | `X-*` | 自定义日历属性 | + +自定义属性使用 Builder 创建: + +```java +var customProp = CustomCalendarProperty.builder() + .withParameters(...) + .build("X-MY-PROPERTY", "my-value"); +``` + +> 注意:自定义属性名称**必须**以 `X-` 开头。 + +--- + +## 组件 + +组件是 iCalendar 对象的核心实体。每个组件实现 `CalendarComponent` 接口,并在 `BEGIN:TYPE` 和 `END:TYPE` 定界符之间渲染。 + +### Event(VEVENT) + +表示一个预定的活动/事件。 + +```java +Event event = Event.builder() + .withDateTimeStamp(dtstamp) // 必需 + .withUniqueIdentifier(uid) // 必需 + .withDateTimeStart(dtstart) + .withDateTimeEnd(dtend) // 与 duration 互斥 + .withDuration(duration) // 与 dtend 互斥 + .withSummary(summary) + .withDescription(description) + .withClassification(classification) + .withDateTimeCreated(dateTimeCreated) + .withGeographicPosition(geoPos) + .withLastModified(lastModified) + .withLocation(location) + .withOrganiser(organiser) + .withPriority(priority) + .withSequenceNumber(seqNumber) + .withStatus(status) + .withTimeTransparency(transparency) + .withUniformResourceLocator(url) + .withRecurrenceId(recurrenceId) + .withRecurrenceRule(rrule) + .withAttachments(attachments) + .withAttendees(attendees) + .withCategories(categories) + .withComments(comments) + .withContacts(contacts) + .withExceptionDateTimes(exDates) + .withRequestStatuses(statuses) + .withRelated(related) + .withResources(resources) + .withRecurrenceDateTimes(rDates) + .build(); +``` + +### Todo(VTODO) + +表示待办事项或任务。 + +```java +Todo todo = Todo.builder() + .withDateTimeStamp(dtstamp) // 必需 + .withUniqueIdentifier(uid) // 必需 + .withSummary(summary) + .withDateTimeStart(dtstart) + .withDateTimeDue(due) // 与 duration 互斥 + .withDuration(duration) // 与 due 互斥 + .withDateTimeCompleted(completed) + .withPercentComplete(percent) + .withClassification(classification) + .withDateTimeCreated(created) + .withDescription(description) + .withGeographicPosition(geoPos) + .withLastModified(lastModified) + .withLocation(location) + .withOrganiser(organiser) + .withPriority(priority) + .withSequenceNumber(seq) + .withStatus(status) + .withRecurrenceId(recurId) + .withRecurrenceRule(rrule) + .withUniformResourceLocator(url) + .withAttachments(attachments) + .withAttendees(attendees) + .withCategories(categories) + .withComments(comments) + .withContacts(contacts) + .withExceptionDateTimes(exDates) + .withRequestStatuses(statuses) + .withRelatedToList(related) + .withResources(resources) + .withRecurrenceDateTimes(rDates) + .build(); +``` + +### Journal(VJOURNAL) + +表示日记条目或笔记。 + +```java +Journal journal = Journal.builder() + .withDateTimeStamp(dtstamp) // 必需 + .withUniqueIdentifier(uid) // 必需 + .withSummary(summary) + .withClassification(classification) + .withDateTimeCreated(created) + .withDateTimeStart(dtstart) + .withLastModified(lastModified) + .withOrganiser(organiser) + .withRecurrenceId(recurId) + .withSequenceNumber(seq) + .withStatus(status) + .withUniformResourceLocator(url) + .withRecurrenceRule(rrule) + .withAttachments(attachments) + .withAttendees(attendees) + .withCategories(categories) + .withComments(comments) + .withContacts(contacts) + .withDescriptions(descriptions) + .withExceptionDateTimes(exDates) + .withRelatedToList(related) + .withRecurrenceDate(rDates) + .withRequestStatuses(statuses) + .build(); +``` + +### FreeBusy(VFREEBUSY) + +表示空闲/忙碌时间信息。 + +```java +FreeBusy freeBusy = FreeBusy.builder() + .withDateTimeStamp(dtstamp) // 必需 + .withUniqueIdentifier(uid) // 必需 + .withContact(contact) + .withDateTimeStart(dtstart) + .withDateTimeEnd(dtend) + .withOrganiser(organiser) + .withUniformResourceLocator(url) + .withAttendees(attendees) + .withComments(comments) + .withFreeBusyTimes(freeBusyTimes) + .withRequestStatuses(statuses) + .build(); +``` + +### TimeZone(VTIMEZONE) + +定义时区规则,包括标准时间和夏令时转换。 + +```java +TimeZone timezone = TimeZone.builder() + .withTimeZoneIdentifier(tzId) + .withLastModified(lastModified) + .withTimeZoneUrl(tzUrl) + .withTimeZoneProperties(standardProp, daylightProp) + .build(); +``` + +时区属性定义实际的转换规则: + +```java +TimeZoneProperty standard = TimeZoneProperty.builder() + .withDateTimeStart(dtstart) + .withTimeZoneOffsetTo(offsetTo) + .withTimeZoneOffsetFrom(offsetFrom) + .withRecurrenceRule(rrule) + .withTimeZoneNames(tzName) + .buildStandard(); // 或 buildDaylight() + +TimeZoneProperty daylight = TimeZoneProperty.builder() + .withDateTimeStart(dtstart) + .withTimeZoneOffsetTo(offsetTo) + .withTimeZoneOffsetFrom(offsetFrom) + .buildDaylight(); +``` + +### Alarm(VALARM) + +定义闹钟/提醒通知。支持三种闹钟类型: + +```java +// 音频闹钟 +Alarm audioAlarm = Alarm.builder() + .withTrigger(trigger) + .withDuration(duration) + .withRepeatCount(repeatCount) + .withAttachments(audioAttachment) + .buildAudio(); + +// 显示闹钟 +Alarm displayAlarm = Alarm.builder() + .withTrigger(trigger) + .withDescription(description) // 必需 + .withDuration(duration) + .withRepeatCount(repeatCount) + .buildDisplay(); + +// 邮件闹钟 +Alarm emailAlarm = Alarm.builder() + .withTrigger(trigger) + .withDescription(description) // 必需 + .withSummary(summary) // 必需 + .withAttendees(attendees) // 必需 + .withDuration(duration) + .withRepeatCount(repeatCount) + .buildEmail(); +``` + +--- + +## 组件属性 + +组件属性位于 `com.onixbyte.calendar.component.property`,实现 `ComponentProperty` 接口。 + +| 类 | iCalendar 属性 | 描述 | +|---|---|---| +| `Action` | `ACTION` | 闹钟操作类型(AUDIO、DISPLAY、EMAIL) | +| `Attachment` | `ATTACH` | 文档附件 | +| `Attendee` | `ATTENDEE` | 事件/任务参与者 | +| `Categories` | `CATEGORIES` | 类别或标签 | +| `Classification` | `CLASS` | 访问分类(PUBLIC、PRIVATE、CONFIDENTIAL) | +| `Comment` | `COMMENT` | 评论 | +| `Contact` | `CONTACT` | 联系信息 | +| `DateTimeCompleted` | `COMPLETED` | 完成日期时间 | +| `DateTimeCreated` | `CREATED` | 创建日期时间 | +| `DateTimeDue` | `DUE` | 截止日期时间 | +| `DateTimeEnd` | `DTEND` | 结束日期时间 | +| `DateTimeStamp` | `DTSTAMP` | 日期时间戳 | +| `DateTimeStart` | `DTSTART` | 开始日期时间 | +| `Description` | `DESCRIPTION` | 描述 | +| `ExceptionDateTimes` | `EXDATE` | 例外日期时间 | +| `FreeBusyTime` | `FREEBUSY` | 空闲/忙碌时间段 | +| `GeographicPosition` | `GEO` | 地理位置(纬度/经度) | +| `LastModified` | `LAST-MODIFIED` | 最后修改日期时间 | +| `Location` | `LOCATION` | 地点 | +| `Organiser` | `ORGANIZER` | 组织者 | +| `PercentComplete` | `PERCENT-COMPLETE` | 完成百分比 | +| `Priority` | `PRIORITY` | 优先级 | +| `RecurrenceDateTimes` | `RDATE` | 重复日期时间 | +| `RecurrenceId` | `RECURRENCE-ID` | 重复实例标识符 | +| `RecurrenceRule` | `RRULE` | 重复规则 | +| `RelatedTo` | `RELATED-TO` | 相关组件引用 | +| `RepeatCount` | `REPEAT` | 闹钟重复次数 | +| `RequestStatus` | `REQUEST-STATUS` | 请求状态 | +| `Resources` | `RESOURCES` | 资源 | +| `SequenceNumber` | `SEQUENCE` | 序列号(修订版本) | +| `Status` | `STATUS` | 组件状态(TENTATIVE、CONFIRMED、CANCELLED 等) | +| `Summary` | `SUMMARY` | 标题或摘要 | +| `TimeTransparency` | `TRANSP` | 时间透明度(OPAQUE、TRANSPARENT) | +| `TimeZoneIdentifier` | `TZID` | 时区标识符 | +| `TimeZoneName` | `TZNAME` | 时区名称 | +| `TimeZoneOffsetFrom` | `TZOFFSETFROM` | 相对于 UTC 的时区偏移(原) | +| `TimeZoneOffsetTo` | `TZOFFSETTO` | 相对于 UTC 的时区偏移(目标) | +| `TimeZoneUrl` | `TZURL` | 时区 URL | +| `Trigger` | `TRIGGER` | 闹钟触发器 | +| `UniformResourceLocator` | `URL` | 关联 URL | +| `UniqueIdentifier` | `UID` | 唯一标识符 | +| `CustomComponentProperty` | `X-*` | 自定义组件属性 | + +--- + +## 参数 + +参数位于 `com.onixbyte.calendar.parameter`,为组件属性提供额外限定。 + +| 类 | iCalendar 参数 | 描述 | +|---|---|---| +| `AlarmTriggerRelationship` | `RELATED` | 触发器关联(START、END) | +| `AlternateTextRepresentation` | `ALTREP` | 替代文本 URI | +| `CalendarUserType` | `CUTYPE` | 日历用户类型(INDIVIDUAL、GROUP、RESOURCE 等) | +| `CommonName` | `CN` | 通用名称 | +| `Delegatees` | `DELEGATED-TO` | 受托人 | +| `Delegators` | `DELEGATED-FROM` | 委托人 | +| `DirectoryEntryReference` | `DIR` | 目录条目 URI | +| `FormatType` | `FMTTYPE` | 格式类型(MIME 类型) | +| `FreeBusyTimeType` | `FBTYPE` | 空闲/忙碌时间类型 | +| `InlineEncoding` | `ENCODING` | 内联编码(BASE64) | +| `Language` | `LANGUAGE` | 语言 | +| `Membership` | `MEMBER` | 组成员 | +| `ParticipationRole` | `ROLE` | 参与角色(CHAIR、REQ-PARTICIPANT 等) | +| `ParticipationStatus` | `PARTSTAT` | 参与状态(ACCEPTED、DECLINED 等) | +| `RecurrenceIdentifierRange` | `RANGE` | 重复范围(THISANDPRIOR、THISANDFUTURE) | +| `RelationshipType` | `RELTYPE` | 关系类型(PARENT、CHILD、SIBLING) | +| `RsvpExpectation` | `RSVP` | RSVP 期望(TRUE、FALSE) | +| `SentBy` | `SENT-BY` | 发送者 | +| `TimeZoneIdentifier` | `TZID` | 时区标识符 | +| `ValueDataType` | `VALUE` | 值数据类型(DATE、DATE-TIME 等) | + +--- + +## 递归类型 + +位于 `com.onixbyte.calendar.recurrence`。 + +| 类 | 描述 | +|---|---| +| `Frequency` | 重复频率常量(DAILY、WEEKLY、MONTHLY、YEARLY),用于重复规则 | +| `WeekdayNum` | 重复规则的星期序号(例如第 2 个星期一) | + +--- + +## 值类型 + +位于 `com.onixbyte.calendar.value`。 + +| 类 | 描述 | +|---|---| +| `FreeBusyTimeValue` | 表示空闲/忙碌时间值 | +| `PeriodOfTime` | 表示一个时间段,包含开始和结束 | +| `PropertyValue` | 属性的基础值类型 | +| `UtcOffset` | UTC 偏移值(例如 `-05:00`、`+01:00`) | + +--- + +## 格式化输出 + +所有组件和属性都提供 `formatted()` 方法,返回符合 iCalendar 规范的字符串。`Calendar.formatted()` 方法生成完整的 `.ics` 输出,包含 `BEGIN:VCALENDAR`/`END:VCALENDAR`。 + +```java +String ics = calendar.formatted(); +// BEGIN:VCALENDAR +// CALSCALE:GREGORIAN +// METHOD:PUBLISH +// ... +// END:VCALENDAR +``` diff --git a/docs/zh-hans/projects/calendar-toolbox/index.mdx b/docs/zh-hans/projects/calendar-toolbox/index.mdx new file mode 100644 index 0000000..fb7f995 --- /dev/null +++ b/docs/zh-hans/projects/calendar-toolbox/index.mdx @@ -0,0 +1,102 @@ +--- +title: Calendar Toolbox +--- + +import { Tabs, Tab } from "@rspress/core/theme" + +## 介绍 + +Calendar Toolbox 是一个 Java 库,旨在简化遵循 iCalendar 规范(RFC 5545)的 `.ics` 文件的创建。该库为开发者提供了简洁的 API,可生成能够导入到 Microsoft Outlook、Google Calendar 和 Apple Calendar 等主流日历应用程序中的日历事件。 + +通过 Calendar Toolbox,您可以以编程方式轻松创建、定制和导出日历事件文件,从而以最少的代价将日历功能集成到您的 Java 应用中。 + +## 特性 + +- **完整 RFC 5545 兼容** — 支持 VEVENT、VTODO、VJOURNAL、VFREEBUSY、VTIMEZONE 和 VALARM 等标准 iCalendar 组件。 +- **流式 Builder 模式** — 所有组件和属性均使用 Builder 模式,构建过程可读性强且直观。 +- **类型安全属性** — 强类型的属性和参数确保编译期正确性。 +- **自定义扩展** — 支持日历级和组件级的自定义 `X-` 属性。 +- **轻量级** — 核心功能零外部依赖。 + +## 安装 + + + + ```kotlin title="build.gradle.kts" + dependencies { + implementation("com.onixbyte:calendar-toolbox:1.1.0") + } + ``` + + + ```xml title="pom.xml" + + + com.onixbyte + calendar-toolbox + 1.1.0 + + + ``` + + + +## 快速开始 + +```java +import com.onixbyte.calendar.Calendar; +import com.onixbyte.calendar.component.Event; +import com.onixbyte.calendar.component.property.*; +import com.onixbyte.calendar.property.*; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +public class CalendarExample { + + public static void main(String[] args) { + // 创建所需的日期时间属性 + var now = ZonedDateTime.now(ZoneOffset.UTC); + var dtstamp = DateTimeStamp.of(now); + var uid = UniqueIdentifier.of("meeting-001@example.com"); + var dtstart = DateTimeStart.of( + LocalDateTime.of(2025, 8, 15, 9, 0), + "America/New_York" + ); + var dtend = DateTimeEnd.of( + LocalDateTime.of(2025, 8, 15, 10, 0), + "America/New_York" + ); + var summary = Summary.of("Team Standup"); + var description = Description.of("Daily team standup meeting."); + + // 构建事件 + var event = Event.builder() + .withDateTimeStamp(dtstamp) + .withUniqueIdentifier(uid) + .withDateTimeStart(dtstart) + .withDateTimeEnd(dtend) + .withSummary(summary) + .withDescription(description) + .build(); + + // 构建日历并输出 .ics 内容 + var calendar = Calendar.builder() + .withCalendarScale(CalendarScale.of("GREGORIAN")) + .withMethod(Method.of("PUBLISH")) + .withProductIdentifier(ProductIdentifier.of("-//OnixByte//Calendar Toolbox//EN")) + .withVersion(Version.of("2.0")) + .withComponents(event) + .build(); + + System.out.println(calendar.formatted()); + } +} +``` + +上述代码会生成一个 `.ics` 格式的字符串,可以保存为文件或通过邮件发送。 + +## 许可证 + +Calendar Toolbox 是采用 MIT 许可证发布的开源软件。 diff --git a/docs/zh-hans/projects/captcha/api.md b/docs/zh-hans/projects/captcha/api.md new file mode 100644 index 0000000..60370ad --- /dev/null +++ b/docs/zh-hans/projects/captcha/api.md @@ -0,0 +1,248 @@ +--- +title: Captcha API +--- + +## 包结构概览 + +库的代码组织在基础包 `com.onixbyte.captcha` 下,结构如下: + +| 包 | 描述 | +|---|---| +| `com.onixbyte.captcha` | 核心接口 | +| `com.onixbyte.captcha.impl` | 默认实现 | +| `com.onixbyte.captcha.text` | 文本生成器和渲染器接口 | +| `com.onixbyte.captcha.text.impl` | 文本生成器和渲染器实现 | +| `com.onixbyte.captcha.text.enums` | 文本相关枚举 | +| `com.onixbyte.captcha.background` | 背景生成器接口 | +| `com.onixbyte.captcha.background.impl` | 背景生成器实现 | +| `com.onixbyte.captcha.noise` | 噪点生成器接口 | +| `com.onixbyte.captcha.noise.impl` | 噪点生成器实现 | +| `com.onixbyte.captcha.gimpy` | 扭曲引擎接口 | +| `com.onixbyte.captcha.gimpy.impl` | 扭曲引擎实现 | + +--- + +## Producer + +负责创建 CAPTCHA 图片并在其上绘制文字的顶层接口。 + +```java +Producer captcha = DefaultCaptchaProducer.builder() + .textProducer(textProducer) + .wordRenderer(wordRenderer) + .gimpyEngine(gimpyEngine) + .backgroundProducer(backgroundProducer) + .width(200) + .height(50) + .borderDrawn(true) + .borderColour(Color.BLACK) + .borderThickness(1) + .build(); + +String text = captcha.createText(); +BufferedImage image = captcha.createImage(text); +``` + +### DefaultCaptchaProducer Builder + +| 方法 | 默认值 | 描述 | +|---|---|---| +| `textProducer` | `DefaultTextProducer.builder().build()` | 文本生成器 | +| `wordRenderer` | `DefaultWordRenderer.builder().build()` | 文字渲染器 | +| `gimpyEngine` | `WaterRipple.builder().build()` | 扭曲引擎 | +| `backgroundProducer` | `DefaultBackgroundProducer.builder().build()` | 背景生成器 | +| `width` | `200` | 验证码图片宽度 | +| `height` | `50` | 验证码图片高度 | +| `borderDrawn` | `true` | 是否绘制边框 | +| `borderColour` | `Color.BLACK` | 边框颜色 | +| `borderThickness` | `1` | 边框厚度 | + +--- + +## Text + +### TextProducer + +用于创建 CAPTCHA 文本字符串的接口。 + +```java +public interface TextProducer { + String getText(); +} +``` + +#### DefaultTextProducer + +生成可配置长度和字符集的随机文本。 + +```java +DefaultTextProducer textProducer = DefaultTextProducer.builder() + .length(6) // 默认: 6 + .chars("ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray()) // 默认: a-z, A-Z, 0-9 + .build(); +``` + +| 方法 | 默认值 | 描述 | +|---|---|---| +| `length` | `6` | 生成文本的长度 | +| `chars` | `a-z`、`A-Z`、`0-9`(共 62 个字符) | 生成文本使用的字符集 | + +### WordRenderer + +将文字渲染到图片上的接口。 + +```java +public interface WordRenderer { + BufferedImage renderWord(String word, int width, int height); +} +``` + +#### DefaultWordRenderer + +使用可配置的字体、颜色和间距渲染文字。 + +```java +DefaultWordRenderer wordRenderer = DefaultWordRenderer.builder() + .fontSize(40) // 默认: 40 + .fonts("Arial", "Courier") // 默认: Arial, Courier + .fontColour(Color.BLACK) // 默认: Color.BLACK + .charSpace(2) // 默认: 2 + .fontStyle(FontStyle.BOLD) // 默认: FontStyle.BOLD + .build(); +``` + +| 方法 | 默认值 | 描述 | +|---|---|---| +| `fontSize` | `40` | 字号(像素) | +| `fonts` | `["Arial", "Courier"]` | 字体族(随机选择) | +| `fontColour` | `Color.BLACK` | 字体颜色 | +| `charSpace` | `2` | 字符间距(像素) | +| `fontStyle` | `FontStyle.BOLD` | 字体样式 | + +### FontStyle + +定义 CAPTCHA 文字渲染支持的字体样式。 + +| 值 | 对应的 AWT 常量 | 描述 | +|---|---|---| +| `PLAIN` | `java.awt.Font.PLAIN` | 普通样式 | +| `BOLD` | `java.awt.Font.BOLD` | 粗体 | +| `ITALIC` | `java.awt.Font.ITALIC` | 斜体 | +| `BOLD_ITALIC` | `java.awt.Font.BOLD | Font.ITALIC` | 粗斜体 | + +--- + +## GimpyEngine + +用于对图片应用扭曲效果的接口。 + +```java +public interface GimpyEngine { + BufferedImage getDistortedImage(BufferedImage baseImage); +} +``` + +### WaterRipple + +应用水波纹扭曲效果。继承 `AbstractGimpyEngine`,自动添加噪点。 + +```java +WaterRipple gimpy = WaterRipple.builder() + .noiseProducer(DefaultNoiseProducer.builder().build()) // 默认: DefaultNoiseProducer + .build(); +``` + +| 方法 | 默认值 | 描述 | +|---|---|---| +| `noiseProducer` | `DefaultNoiseProducer.builder().build()` | 噪点生成器 | + +### FishEyeGimpy + +应用鱼眼扭曲效果,在图片上绘制水平和垂直线条。 + +```java +FishEyeGimpy gimpy = FishEyeGimpy.builder() + .build(); +``` + +### ShadowGimpy + +应用阴影和波纹效果。继承 `AbstractGimpyEngine`,自动添加噪点。 + +```java +ShadowGimpy gimpy = ShadowGimpy.builder() + .noiseProducer(DefaultNoiseProducer.builder().build()) // 默认: DefaultNoiseProducer + .build(); +``` + +| 方法 | 默认值 | 描述 | +|---|---|---| +| `noiseProducer` | `DefaultNoiseProducer.builder().build()` | 噪点生成器 | + +--- + +## Noise + +### NoiseProducer + +向图片添加噪点的接口。 + +```java +public interface NoiseProducer { + void makeNoise(BufferedImage image, float factorOne, float factorTwo, + float factorThree, float factorFour); +} +``` + +#### DefaultNoiseProducer + +使用可配置的颜色添加噪点曲线。 + +```java +DefaultNoiseProducer noise = DefaultNoiseProducer.builder() + .noiseColour(Color.BLACK) // 默认: Color.BLACK + .build(); +``` + +| 方法 | 默认值 | 描述 | +|---|---|---| +| `noiseColour` | `Color.BLACK` | 噪点颜色 | + +#### NoNoiseProducer + +不向图片添加任何噪点的空实现。 + +```java +NoiseProducer noise = NoNoiseProducer.builder() + .build(); +``` + +--- + +## Background + +### BackgroundProducer + +向图片添加背景的接口。 + +```java +public interface BackgroundProducer { + BufferedImage addBackground(BufferedImage image); +} +``` + +#### DefaultBackgroundProducer + +创建具有可配置起始和结束颜色的渐变背景。 + +```java +DefaultBackgroundProducer background = DefaultBackgroundProducer.builder() + .colourFrom(Color.WHITE) // 默认: Color.LIGHT_GRAY + .colourTo(Color.LIGHT_GRAY) // 默认: Color.WHITE + .build(); +``` + +| 方法 | 默认值 | 描述 | +|---|---|---| +| `colourFrom` | `Color.LIGHT_GRAY` | 渐变起始颜色 | +| `colourTo` | `Color.WHITE` | 渐变结束颜色 | diff --git a/docs/zh-hans/projects/captcha/index.mdx b/docs/zh-hans/projects/captcha/index.mdx new file mode 100644 index 0000000..68dd663 --- /dev/null +++ b/docs/zh-hans/projects/captcha/index.mdx @@ -0,0 +1,89 @@ +--- +title: Captcha +--- + +import { Tabs, Tab } from "@rspress/core/theme" + +## 介绍 + +Captcha 是一个用于生成 CAPTCHA 验证码图片的 Java 库。本项目是 Google Kaptcha 的精神继承者,按照现代开发实践进行了现代化改造。 + +通过 Captcha,您可以轻松生成可定制的 CAPTCHA 图片,支持多种扭曲效果、噪点和背景选项,轻松集成到您的 Java 应用中。 + +## 特性 + +- **易于集成** — 基于 Builder 的简洁 API,快速完成配置和集成。 +- **可定制的验证码生成** — 配置文本长度、字符集、字体样式和颜色。 +- **多种扭曲效果** — 支持水波纹、鱼眼和阴影效果。 +- **可配置噪点** — 使用自定义颜色添加噪点线条,或完全禁用噪点。 +- **渐变背景** — 可自定义的渐变背景颜色。 +- **简洁现代的代码** — 文档完善、类型安全且易于扩展。 + +## 安装 + + + + ```kotlin title="build.gradle.kts" + dependencies { + implementation("com.onixbyte:captcha:1.0.0") + } + ``` + + + ```xml title="pom.xml" + + + com.onixbyte + captcha + 1.0.0 + + + ``` + + + +## 快速开始 + +```java +import com.onixbyte.captcha.Producer; +import com.onixbyte.captcha.background.BackgroundProducer; +import com.onixbyte.captcha.background.impl.DefaultBackgroundProducer; +import com.onixbyte.captcha.gimpy.GimpyEngine; +import com.onixbyte.captcha.gimpy.impl.WaterRipple; +import com.onixbyte.captcha.impl.DefaultCaptchaProducer; +import com.onixbyte.captcha.noise.NoiseProducer; +import com.onixbyte.captcha.noise.impl.DefaultNoiseProducer; +import com.onixbyte.captcha.text.TextProducer; +import com.onixbyte.captcha.text.WordRenderer; +import com.onixbyte.captcha.text.impl.DefaultTextProducer; +import com.onixbyte.captcha.text.impl.DefaultWordRenderer; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +public class CaptchaExample { + + public static void main(String[] args) throws IOException { + // 使用默认配置创建 CAPTCHA 生产者 + Producer captcha = DefaultCaptchaProducer.builder().build(); + + // 生成文本并创建图片 + String captchaText = captcha.createText(); + BufferedImage captchaImage = captcha.createImage(captchaText); + + // 保存图片到文件 + ImageIO.write(captchaImage, "png", new File("captcha.png")); + + System.out.println("CAPTCHA 文本: " + captchaText); + } +} +``` + +以上代码生成一张包含 6 位随机字符的 CAPTCHA 图片,并将其保存为 PNG 文件。 + +## 许可证 + +Captcha 是采用 MIT 许可证发布的开源软件。 diff --git a/docs/zh-hans/projects/delta-force-guide/api.md b/docs/zh-hans/projects/delta-force-guide/api.md new file mode 100644 index 0000000..47ebe05 --- /dev/null +++ b/docs/zh-hans/projects/delta-force-guide/api.md @@ -0,0 +1,91 @@ +--- +title: Delta Force Guide API +--- + +## 后端 API 概览 + +后端是基于 Spring Boot 3 的应用程序,代码组织在基础包 `com.onixbyte.deltaforceguide` 下: + +| 包 | 描述 | +|---|---| +| `controller` | REST API 端点控制器 | +| `service` | 业务逻辑层 | +| `repository` | MyBatis 数据访问层 | +| `domain` | JPA 实体与领域对象 | +| `config` | Spring 配置(安全、缓存等) | +| `properties` | 配置属性类 | +| `enumeration` | 枚举类型 | +| `shared` | 共享工具类 | + +## API 端点 + +### 认证 + +| 方法 | 路径 | 描述 | 认证 | +|---|---|---|---| +| `POST` | `/api/auth/login` | 使用凭证登录 | 否 | +| `POST` | `/api/auth/refresh` | 刷新 access token | 否 | +| `GET` | `/api/auth/profile` | 获取当前用户信息 | 是 | + +### 枪械 + +| 方法 | 路径 | 描述 | +|---|---|---| +| `GET` | `/api/firearms` | 枪械列表(分页,可按类型筛选) | +| `GET` | `/api/firearms/:id` | 按 ID 获取枪械详情 | +| `POST` | `/api/firearms` | 创建新枪械 | +| `PUT` | `/api/firearms/:id` | 更新枪械信息 | +| `DELETE` | `/api/firearms/:id` | 删除枪械 | + +### 改装 + +| 方法 | 路径 | 描述 | +|---|---|---| +| `GET` | `/api/modifications` | 改装列表(分页,可按枪械和标签筛选) | +| `GET` | `/api/modifications/:id` | 按 ID 获取改装详情 | +| `POST` | `/api/modifications` | 创建改装 | +| `POST` | `/api/modifications/batch` | 批量创建改装 | +| `PUT` | `/api/modifications/:id` | 更新改装 | +| `DELETE` | `/api/modifications/:id` | 删除改装 | +| `DELETE` | `/api/modifications/batch-delete` | 批量删除改装 | + +### 标签 + +| 方法 | 路径 | 描述 | +|---|---|---| +| `GET` | `/api/tags` | 获取所有标签 | + +## 前端路由 + +| 路径 | 布局 | 页面 | 描述 | +|---|---|---|---| +| `/` | 主布局 | 枪械浏览 | 首页 — 枪械列表 | +| `/firearms` | 主布局 | 枪械浏览 | 枪械详情与搜索 | +| `/mod-codes` | 主布局 | 改装代码 | 改装代码库 | +| `/legal` | 主布局 | 法律信息 | 法律与隐私信息 | +| `/login` | 空白布局 | 登录 | 用户认证页面 | + +## 前端状态管理 + +Redux Toolkit 结合 Redux Persist 管理以下状态: + +- **认证状态** — Access token、refresh token、用户信息 +- **设置状态** — 用户偏好,持久化至本地存储 + +## API 客户端 + +前端使用基于 Axios 封装的共享 `WebClient`,提供以下能力: + +- 基础 URL 配置(指向后端 API) +- 通过请求拦截器自动注入 JWT access token +- 在收到 401 响应时自动刷新 token + +## 基础设施 + +| 组件 | 技术 | +|---|---| +| 数据库 | PostgreSQL(使用 Flyway 进行数据库迁移) | +| 缓存 | Redis(会话和 token 存储) | +| 文件存储 | AWS S3(枪械图片) | +| 容器化 | Docker | +| 部署 | Docker Compose + Nginx | diff --git a/docs/zh-hans/projects/delta-force-guide/index.mdx b/docs/zh-hans/projects/delta-force-guide/index.mdx new file mode 100644 index 0000000..26bd9c6 --- /dev/null +++ b/docs/zh-hans/projects/delta-force-guide/index.mdx @@ -0,0 +1,48 @@ +--- +title: Delta Force Guide +--- + +import { Tabs, Tab } from "@rspress/core/theme" + +## 介绍 + +Delta Force Guide 是一个全栈 Web 应用,为游戏 Delta Force(三角洲部队)提供可搜索的枪械改装代码库。项目包含两个组件: + +- **Web 前端** — 基于 React 的单页应用,用于浏览、筛选和复制改装代码。 +- **后端服务** — 基于 Spring Boot 的 REST API,处理数据持久化、身份认证和内容管理。 + +线上站点位于 **[dfguide.onixbyte.cn](https://dfguide.onixbyte.cn)**。 + +## 特性 + +- **枪械浏览** — 浏览精选的游戏内枪械列表及详细属性。 +- **改装代码库** — 按武器、模式和标签搜索筛选改装代码。 +- **一键复制** — 直接从界面复制改装代码。 +- **高效渲染** — 通过窗口虚拟化实现大列表的流畅渲染。 +- **身份认证** — 支持用户登录,采用 JWT 认证和验证码校验。 +- **后台管理** — 枪械与改装数据完整的增删改查功能。 +- **静态友好** — 前端以静态站点部署,通过 API 代理与后端通信。 + +## 架构 + +| 组件 | 技术栈 | +|---|---| +| **前端** | React 19、TypeScript、Tailwind CSS 4、Ant Design 6、React Router 7、Redux Toolkit、TanStack Virtual | +| **后端** | Spring Boot 3、Java 21、PostgreSQL、MyBatis、Flyway、Redis | +| **认证** | JWT(access 和 refresh token)、验证码集成 | +| **存储** | AWS S3(图片上传) | + +前端是由 Vite 构建的静态站点,通过 API 与 Spring Boot 后端通信。认证采用 JWT access 和 refresh token 机制,refresh token 通过 Redis 管理。 + +## 代码仓库 + +- [delta-force-guide-server](https://github.com/onixbyte/delta-force-guide-server) — Spring Boot 后端 +- [delta-force-guide-web](https://github.com/onixbyte/delta-force-guide-web) — React 前端 + +## 快速链接 + +- **线上站点:** [dfguide.onixbyte.cn](https://dfguide.onixbyte.cn) + +## 许可证 + +Delta Force Guide 是采用 MIT 许可证发布的开源软件。 diff --git a/docs/zh-hans/projects/helix/index.mdx b/docs/zh-hans/projects/helix/index.mdx new file mode 100644 index 0000000..d8b2261 --- /dev/null +++ b/docs/zh-hans/projects/helix/index.mdx @@ -0,0 +1,71 @@ +--- +title: Helix +--- + +## 介绍 + +Helix 是一个全栈企业级应用模板,旨在加速生产级业务应用的开发。它提供了预构建的基础,包含企业应用所需的全部基本功能,使团队能够专注于业务逻辑而非基础设施。 + +项目由两个组件构成: + +- **Helix Server** — 基于 Spring Boot 的后端,提供 REST API、身份认证、权限管理和数据管理。 +- **Helix Web** — 基于 React 的单页应用前端,具备现代化的 UI、基于角色的路由和企业级身份集成。 + +Helix 旨在作为项目的起点使用。Fork 或克隆它,然后在现成的基础上开始构建您自己的业务功能。 + +## 特性 + +### 后端(Helix Server) + +- **身份认证与授权** — 基于 JWT 的 access token 和 refresh token 流程,配合 Spring Security。支持 Microsoft Entra ID(Azure AD)集成。 +- **基于角色的访问控制** — 通过角色、权限和菜单级访问控制实现细粒度权限管理。 +- **用户与组织管理** — 用户、部门、职位和角色的完整增删改查。 +- **菜单管理** — 层级菜单树,支持按角色配置可见性。 +- **资产管理** — 文件上传至 AWS S3,支持 CDN 前缀处理。 +- **设置管理** — 类型化的应用配置项持久化至数据库。 +- **验证码集成** — 登录和注册流程中的图形验证码校验。 +- **Redis 缓存** — 高性能缓存,支持可配置 TTL 和自定义序列化器。 +- **数据访问** — Spring Data JPA 与 MyBatis 混合持久化方案。 +- **校验** — Bean Validation 分组校验与自定义校验约束。 + +### 前端(Helix Web) + +- **企业级身份认证** — 通过 MSAL 实现 Microsoft Entra ID 登录。可扩展的社交登录提供商架构(Microsoft、Google、GitLab、Slack、Discord、钉钉、飞书、企业微信、邮箱/密码)。 +- **仪表盘布局** — 响应式管理后台,可折叠侧边栏,基于角色的菜单渲染。 +- **用户管理** — 数据表格支持搜索、分页,添加/编辑对话框,角色分配和手机号校验。 +- **角色与菜单管理** — 角色增删改查与权限分配。基于树形的菜单配置。 +- **部门与职位** — 组织层级管理界面。 +- **路由保护** — 在页面加载前检查认证和授权状态。 +- **状态管理** — Redux Toolkit 配合 Redux Persist 实现认证 token 的持久化。 +- **HTTP 客户端** — 基于 Axios 封装的请求客户端,自动注入 JWT token 并在 401 时自动刷新。 + +## 架构 + +| 层 | 技术栈 | +|---|---| +| **前端** | React 19、TypeScript、Tailwind CSS 4、Ant Design 6、React Router 7、Redux Toolkit、Axios、MSAL | +| **后端** | Spring Boot 3.5、Java 17、Spring Security、MyBatis、Spring Data JPA | +| **数据库** | PostgreSQL(使用 Flyway 迁移) | +| **缓存** | Redis(会话和 token 存储) | +| **存储** | AWS S3(资源上传) | + +前端通过 RESTful JSON API 与后端通信。认证流程使用短有效期的 JWT access token,refresh token 存储在 Redis 中。Microsoft Entra ID 集成在前端通过 MSAL 处理,并在后端进行校验。 + +## 代码仓库 + +- [helix-server](https://git.onixbyte.cn/helix/helix-server) — Spring Boot 后端 +- [helix-web](https://git.onixbyte.cn/helix/helix-web) — React 前端 + +## 快速开始 + +Helix 是一个模板项目。启动新项目的步骤: + +1. Fork 或克隆 `helix-server` 和 `helix-web` 两个仓库。 +2. 在后端配置您的数据库、Redis 和 S3 设置。 +3. 在前端配置您的认证提供商和 API 基础地址。 +4. 启动后端:`./gradlew bootRun` +5. 启动前端:`pnpm install && pnpm dev` + +## 许可证 + +Helix 是采用 MIT 许可证发布的开源软件。 diff --git a/docs/zh-hans/projects/index.md b/docs/zh-hans/projects/index.md new file mode 100644 index 0000000..97e0907 --- /dev/null +++ b/docs/zh-hans/projects/index.md @@ -0,0 +1,21 @@ +--- +title: 项目 +--- + +探索由 OnixByte 开发的开源项目。 + +## 库和工具包 + +- **[OnixByte Toolbox](/projects/onixbyte-toolbox)** — 面向 Java 应用的开发工具包:AES、哈希、Base64、集合工具、密钥加载器、统计计算器、标识符生成器和泛型元组。 +- **[regions4j](/projects/regions4j)** — 基于 ISO 3166-1 的类型安全 Java 枚举地区元数据,支持 O(1) 查找、E.164 拨号前缀和区域标签。 +- **[Captcha](/projects/captcha)** — 现代化的 Java 验证码生成库,支持水波纹、鱼眼和阴影扭曲效果。 +- **[Calendar Toolbox](/projects/calendar-toolbox)** — 遵循 iCalendar 规范(RFC 5545)创建 `.ics` 文件的 Java 库。 + +## 全栈应用 + +- **[Helix](/projects/helix)** — 企业级应用模板,后端使用 Spring Boot,前端使用 React,集成 JWT 认证、RBAC 权限管理、用户与组织管理以及 Microsoft Entra ID 集成。 +- **[Delta Force Guide](/projects/delta-force-guide)** — 为游戏《三角洲行动》提供可搜索枪械改装代码库的 Web 应用,包含 React 单页应用和 Spring Boot REST API。 + +## Vite 插件 + +- **[Port Checker](/projects/vite-plugins/port-checker)** — 当 Vite 开发服务器监听浏览器限制的端口时发出警告,避免无响应的连接失败。 diff --git a/docs/zh-hans/projects/onixbyte-toolbox/api.md b/docs/zh-hans/projects/onixbyte-toolbox/api.md new file mode 100644 index 0000000..ca82acf --- /dev/null +++ b/docs/zh-hans/projects/onixbyte-toolbox/api.md @@ -0,0 +1,209 @@ +--- +title: OnixByte Toolbox API +--- + +## 包结构概览 + +所有模块均在 `com.onixbyte` group ID 下发布。每个模块有自己独立的基础包: + +| 模块 | Maven Artifact | 基础包 | +|---|---|---| +| Common Toolbox | `common-toolbox` | `com.onixbyte.common` | +| Crypto Toolbox | `crypto-toolbox` | `com.onixbyte.crypto` | +| Math Toolbox | `math-toolbox` | `com.onixbyte.math` | +| Tuple | `tuple` | `com.onixbyte.tuple` | +| Identity Generator | `identity-generator` | `com.onixbyte.identitygenerator` | + +--- + +## Common Toolbox + +### 适配器 + +`ObjectMapAdapter` — 对象与 Map 之间的转换器。适用于需要键值表示的场景,如序列化或数据转换。 + +```java +import com.onixbyte.common.adapter.ObjectMapAdapter; +``` + +### 工具类 + +| 类 | 描述 | +|---|---| +| `AesUtil` | AES 对称加密/解密,支持密钥生成 | +| `Base64Util` | Base64 编解码,支持多种字符集 | +| `BoolUtil` | 布尔值解析与转换工具 | +| `BranchUtil` | 条件分支辅助,支持函数式链式调用 | +| `CollectionUtil` | 集合操作 — 分组、分区、合并 | +| `HashUtil` | 哈希工具,支持 MD5、SHA-1、SHA-256、SHA-512 | +| `MapUtil` | Map 构建、合并和转换辅助 | +| `RangeUtil` | 数值范围操作,支持边界处理 | + +**AesUtil 示例:** + +```java +var key = AesUtil.generateKey(); +var encrypted = AesUtil.encrypt("hello world", key); +var decrypted = AesUtil.decrypt(encrypted, key); +``` + +**HashUtil 示例:** + +```java +var md5 = HashUtil.md5("hello world"); +var sha256 = HashUtil.sha256("hello world"); +var fileSha = HashUtil.sha256(new File("data.bin")); +``` + +**CollectionUtil 示例:** + +```java +var partitioned = CollectionUtil.partition(list, 100); +var grouped = CollectionUtil.groupBy(users, User::getDepartment); +``` + +--- + +## Crypto Toolbox + +提供了加载 PEM 格式密钥的简洁抽象。支持 RSA 和 ECDSA 算法。 + +### 密钥加载器 + +| 类 | 描述 | +|---|---| +| `RSAPrivateKeyLoader` | 从 PEM 字符串加载 RSA 私钥 | +| `RSAPublicKeyLoader` | 从 PEM 字符串加载 RSA 公钥 | +| `ECPrivateKeyLoader` | 从 PEM 字符串加载 ECDSA 私钥 | +| `ECPublicKeyLoader` | 从 PEM 字符串加载 ECDSA 公钥 | + +所有密钥加载器实现 `PrivateKeyLoader` 或 `PublicKeyLoader` 接口。 + +**RSA 示例:** + +```java +var privateKey = new RSAPrivateKeyLoader().load(pemString); +var publicKey = new RSAPublicKeyLoader().load(pemString); +``` + +**ECDSA 示例:** + +```java +var ecPrivateKey = new ECPrivateKeyLoader().load(pemString); +var ecPublicKey = new ECPublicKeyLoader().load(pemString); +``` + +### 工具类 + +`CryptoUtil` — 提供便捷的数字签名生成和验证方法,以及通用密码学辅助功能。 + +### 异常 + +| 类 | 描述 | +|---|---| +| `KeyLoadingException` | PEM 格式密钥解析失败时抛出 | + +--- + +## Math Toolbox + +用于处理数值数据集的统计计算工具。 + +### 核心类 + +| 类 | 描述 | +|---|---| +| `Calculator` | 统计计算器 — 均值、中位数、方差、标准差、总和、最小值、最大值 | +| `PercentileCalculator` | 百分位数计算器,支持可配置的插值策略 | + +**Calculator 示例:** + +```java +var stats = new Calculator(Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0)); +double mean = stats.getMean(); +double median = stats.getMedian(); +double stdDev = stats.getStandardDeviation(); +``` + +**PercentileCalculator 示例:** + +```java +var calculator = new PercentileCalculator(data); +double p95 = calculator.calculate(95); +double p99 = calculator.calculate(99); +``` + +### 数据模型 + +| 类 | 描述 | +|---|---| +| `QuartileBounds` | 包含 Q1、中位数(Q2)、Q3 值及 IQR 和须线边界 | + +--- + +## Tuple + +轻量级泛型元组类型,适用于需要返回多个值但无需定义专用类的场景。 + +### 类 + +| 类 | 类型参数 | 可变性 | +|---|---|---| +| `Tuple` | 两个元素 | 可变 | +| `ImmutableTuple` | 两个元素 | 不可变 | +| `Triple` | 三个元素 | 可变 | +| `ImmutableTriple` | 三个元素 | 不可变 | + +**示例:** + +```java +var pair = Tuple.of("key", 42); +var triple = Triple.of("id", "name", 100); +var immutable = ImmutableTuple.of("constant", true); + +// 访问器 +String first = pair.getFirst(); +Integer second = pair.getSecond(); + +// 三元组访问器 +String a = triple.getFirst(); +String b = triple.getSecond(); +Integer c = triple.getThird(); +``` + +--- + +## Identity Generator + +生成适用于数据库主键或分布式 ID 的唯一标识符。 + +### 接口 + +`IdentityGenerator` — 生成类型为 `T` 的标识符。 + +### 实现 + +| 类 | 描述 | +|---|---| +| `SequentialUuidGenerator` | 生成时间排序的顺序 UUID(优化数据库索引性能) | +| `SnowflakeIdentityGenerator` | 雪花算法分布式唯一 ID 生成 | + +**顺序 UUID:** + +```java +var generator = new SequentialUuidGenerator(); +UUID id = generator.nextId(); // 时间排序 UUID,对 B-tree 友好 +``` + +**雪花:** + +```java +var generator = new SnowflakeIdentityGenerator(workerId, datacenterId); +long id = generator.nextId(); // 64 位雪花 ID +``` + +### 异常 + +| 类 | 描述 | +|---|---| +| `TimingException` | 系统时钟回拨时抛出,保证 ID 唯一性不受影响 | diff --git a/docs/zh-hans/projects/onixbyte-toolbox/index.mdx b/docs/zh-hans/projects/onixbyte-toolbox/index.mdx new file mode 100644 index 0000000..e42f450 --- /dev/null +++ b/docs/zh-hans/projects/onixbyte-toolbox/index.mdx @@ -0,0 +1,54 @@ +--- +title: OnixByte Toolbox +--- + +import { Tabs, Tab } from "@rspress/core/theme" + +## 介绍 + +OnixByte Toolbox 是一个面向 Java 应用的开发工具包,提供了一系列便捷、可复用的工具,帮助开发者高效编写代码。它由 OnixByte 设计和维护,采用 monorepo 架构,包含多个专用库,每个库解决一个特定的开发需求 — 从通用工具类和密码学,到数学计算和标识符生成。 + +该工具包已发布到 Maven Central,使用 `com.onixbyte` 作为 group ID。每个模块独立版本管理,可在任何 Java 17+ 项目中使用。 + +## 模块 + +| 模块 | Artifact ID | 描述 | +|--------------------|----------------------|-----------------------------------| +| Common Toolbox | `common-toolbox` | 日常工具类 — AES 加密、哈希、Base64、集合、分支、范围 | +| Crypto Toolbox | `crypto-toolbox` | RSA 和 ECDSA 算法的公私钥加载 | +| Math Toolbox | `math-toolbox` | 统计计算、百分位数分析、四分位数计算 | +| Tuple | `tuple` | 泛型二元组和三元组,含不可变版本 | +| Identity Generator | `identity-generator` | 雪花算法和顺序 UUID 唯一标识符生成 | +| Version Catalogue | `version-catalogue` | OnixByte 项目的集中式 Gradle 版本目录 | + +## 安装 + +在构建配置中添加所需模块的依赖: + + + + ```kotlin title="build.gradle.kts" + dependencies { + implementation("com.onixbyte:$artefactId:$version") + } + ``` + + + + ```xml title="pom.xml" + + com.onixbyte + ${artefactId} + ${version} + + ``` + + + +## 要求 + +- Java 17 或更高版本 + +## 许可证 + +OnixByte Toolbox 是采用 MIT 许可证发布的开源软件。 diff --git a/docs/zh-hans/projects/regions4j/index.mdx b/docs/zh-hans/projects/regions4j/index.mdx new file mode 100644 index 0000000..fdbd104 --- /dev/null +++ b/docs/zh-hans/projects/regions4j/index.mdx @@ -0,0 +1,104 @@ +--- +title: Regions for Java +--- + +import { Tabs, Tab } from "@rspress/core/theme" + +## 介绍 + +**regions4j** 是一个轻量级、类型安全的 Java 库,基于 ISO 3166-1 标准提供全面的世界地区元数据。它旨在简化 Java 企业应用中的国际化(i18n)、电信路由和地区数据管理工作。 + +该库将每个 ISO 3166-1 国家和地区建模为枚举常量,使您在引用地区时获得编译期安全性和 IDE 自动补全支持。凭借内置的 O(1) 查找、零外部依赖和 Java 8 兼容性,它适用于任何规模的项目 — 从微服务到整体式企业系统。 + +## 特性 + +- **ISO 3166-1 合规** — 完整支持所有已分配国家和地区的 Alpha-2(`abbreviation`)和 Alpha-3(`code`)格式。 +- **电信元数据** — 包含每个地区的 E.164 国际拨号前缀。 +- **区域支持** — 每个地区提供默认的区域标签(如 `zh_HK`、`en_US`、`en_GB` 等),辅助 i18n 工作流。 +- **高性能** — 线程安全、不可变的内部哈希映射提供常量时间的缩写或代码查找。 +- **零依赖** — 纯 Java 库,无任何外部依赖。 +- **日历化版本管理** — 版本号采用 `YYYY.MM` 格式(如 `2025.12`),以透明地反映底层 ISO 数据的新鲜度,而非语义化版本号。 + +## 核心数据模型 + +每个地区暴露四个属性: + +| 属性 | 类型 | 描述 | 示例 | +|---|---|---|---| +| `abbreviation` | String | ISO 3166-1 alpha-2 缩写 | `HK`、`US`、`GB`、`RU` | +| `code` | String | ISO 3166-1 alpha-3 代码 | `HKG`、`USA`、`GBR`、`RUS` | +| `callingCode` | String | E.164 国际拨号前缀 | `852`、`1`、`44`、`7` | +| `locale` | String | 默认语言和地区标签 | `zh_HK`、`en_US`、`en_GB`、`ru_RU` | + +## 安装 + + + + ```kotlin title="build.gradle.kts" + dependencies { + implementation("com.onixbyte:regions4j:$version") + } + ``` + + + + ```xml title="pom.xml" + + com.onixbyte + regions4j + ${version} + + ``` + + + +> **版本说明:** 该库使用日历化版本管理(`YYYY.MM`)而非语义化版本号。版本字符串如 `2025.12` 可以直观地告诉您地区数据反映的是 2025 年 12 月的 ISO 3166-1 状态。 + +## 使用 + +### 直接访问 + +通过枚举常量直接引用任何地区: + +```java +Region uk = Region.UNITED_KINGDOM; + +uk.getAbbreviation(); // "GB" +uk.getCode(); // "GBR" +uk.getDialCode(); // "44" +uk.getLocale(); // "en_GB" +``` + +### 高效查找 + +从字符串输入中查找地区 — 非常适合处理 Web 请求、API 负载或数据库记录: + +```java +// 按 Alpha-2 缩写查找(区分大小写) +Region region = Region.fromAbbreviation("HK"); + +// 按 Alpha-3 代码查找(不区分大小写) +Region region = Region.fromCode("HKG"); +``` + +### Java Locale 集成 + +将地区的 locale 字符串转换为 `java.util.Locale` 以配合标准 Java i18n API 使用: + +```java +Region region = Region.CHINA; +Locale javaLocale = Locale.forLanguageTag(region.getLocale().replace("_", "-")); +javaLocale.getDisplayCountry(Locale.UK); // "China" +``` + +## 性能 + +首次访问时,库会将所有地区初始化到不可变的 `HashMap` 结构中。后续通过 `fromAbbreviation()` 和 `fromCode()` 进行的查找均为线程安全且以常量时间运行 — 适用于高吞吐量的请求路径。 + +## 要求 + +- Java 8 或更高版本 + +## 许可证 + +regions4j 是采用 MIT 许可证发布的开源软件。 diff --git a/docs/zh-hans/projects/vite-plugins/index.mdx b/docs/zh-hans/projects/vite-plugins/index.mdx new file mode 100644 index 0000000..07bfebc --- /dev/null +++ b/docs/zh-hans/projects/vite-plugins/index.mdx @@ -0,0 +1,11 @@ +--- +title: Vite 插件 +--- + +## 概览 + +由 OnixByte 开发和维护的 Vite 插件合集。每个插件旨在解决 Vite 开发工作流中的特定问题 — 轻量级、零依赖、即插即用。 + +## 可用插件 + +- **[Port Checker](/projects/vite-plugins/port-checker)** — 当开发服务器监听浏览器限制的端口(依据 Fetch 规范)时发出警告,帮助您避免无响应的连接失败。 diff --git a/docs/zh-hans/projects/vite-plugins/port-checker/index.mdx b/docs/zh-hans/projects/vite-plugins/port-checker/index.mdx new file mode 100644 index 0000000..4af0052 --- /dev/null +++ b/docs/zh-hans/projects/vite-plugins/port-checker/index.mdx @@ -0,0 +1,67 @@ +--- +title: Port Checker +--- + +import { Tabs, Tab } from "@rspress/core/theme" + +## 介绍 + +**vite-plugin-port-checker** 是一个轻量级的 Vite 插件,可在开发服务器监听被常见浏览器屏蔽的端口时发出警告。Chrome 和 Firefox 等浏览器维护了一份[受限制端口列表](https://fetch.spec.whatwg.org/#port-blocking) — 这些端口通常与 SMTP、SSH 和 DNS 等知名协议关联 — 并拒绝连接这些端口。如果不小心将开发服务器运行在这些端口上,会导致令人困惑的"连接被拒绝"或"已被屏蔽"错误,且没有任何明确的解释。 + +该插件会在启动时检测到这种情况,并向控制台打印一条清晰且带有颜色标记的警告,建议您修改 Vite 配置中的 `server.port` 设置。 + +## 特性 + +- **自动检测** — 对照完整的 Fetch 规范端口屏蔽列表(68 个受限端口)检查开发服务器端口。 +- **清晰的警告** — 黄色高亮控制台输出,并提供可操作的指导。 +- **零配置** — 开箱即用,无需设置任何选项。 +- **轻量级** — 单文件插件,除 Vite 本身外无任何依赖。 + +## 安装 + + + + ```bash + npm install vite-plugin-port-checker -D + ``` + + + ```bash + pnpm add vite-plugin-port-checker -D + ``` + + + +## 使用 + +在 `vite.config.ts` 中添加插件: + +```ts title="vite.config.ts" +import { defineConfig } from "vite" +import checkRestrictedPort from "vite-plugin-port-checker" + +export default defineConfig({ + plugins: [checkRestrictedPort()], +}) +``` + +当开发服务器启动在受限端口(如 25、22 或 53 端口)时,您将看到: + +``` +[Warning] The current listening port 25 is categorised as a restricted port +by most browsers. This may prevent you from accessing the application. +Please consider changing the port in your 'vite.config.ts' or 'vite.config.js' +via 'server.port'. +``` + +## 工作原理 + +该插件通过钩入 Vite 的 `configureServer` 生命周期工作。当 HTTP 服务器触发 `listening` 事件后,插件检查绑定的端口号,并与 [Fetch 规范](https://fetch.spec.whatwg.org/#port-blocking)中定义的 68 个受限端口进行比对。如果匹配,则通过黄色的 `console.warn` 消息提醒开发者。 + +## 要求 + +- Vite 3.0.0 或更高版本 + +## 许可证 + +vite-plugin-port-checker 是采用 MIT 许可证发布的开源软件。 diff --git a/i18n.json b/i18n.json index 9fb0532..de46ba9 100644 --- a/i18n.json +++ b/i18n.json @@ -112,7 +112,7 @@ "zh-hans": "折叠" }, "blogs": { - "en-gb": "Blogs", + "en-gb": "Blog", "zh-hans": "博客" }, "notifications": {