Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* Minimum IDE version has been increased to 2024.3. This helps avert compatibility issues with future versions. ([#TODO](https://github.com/fwdekker/intellij-randomness/issues/TODO))

### Added
* Added support for Nano ID. ([#TODO](https://github.com/fwdekker/intellij-randomness/issues/TODO))

### Changed
* Regex patterns now ignore named capturing groups instead of giving an error. Achieved by updating [RgxGen](https://github.com/curious-odd-man/RgxGen) to v3.1. ([#TODO](https://github.com/fwdekker/intellij-randomness/issues/TODO))

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ Randomness can also be found in the main menu under <kbd>Tools</kbd> and under <
3. **Strings**, such as `"PaQDQqSBEH"`, with support for reverse regex.
4. **Words**, such as `"Bridge"`, with predefined or custom word lists.
5. **UUIDs**, such as `0caa7b28-fe58-4ba6-a25a-9e5beaaf8f4b`, with or without dashes.
6. **Date-times**, such as `2022-02-03 19:03`, or any other format you want.
6. **Nano IDs**, such as `V1StGXR8_Z5jdHi6B-myT`, with customisable alphabets and sizes.
7. **Date-times**, such as `2022-02-03 19:03`, or any other format you want.
* 🧬 **Templates**<br />
For complex kinds of data, you can use templates.
A template is a list of data types that should be concatenated to create random data.
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ dependencies {
}
implementation(libs.rgxgen)
implementation(libs.github)
implementation(libs.nanoid)
scrambler(libs.kotlin.reflect)

testImplementation(libs.assertj.swing)
Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ kotest = "5.9.1" # https://mvnrepository.com/artifact/io.kotest/kotest-assertio
kover = "0.9.1" # https://plugins.gradle.org/plugin/org.jetbrains.kotlinx.kover
rgxgen = "3.1" # https://mvnrepository.com/artifact/com.github.curious-odd-man/rgxgen
uuidGenerator = "5.1.0" # https://mvnrepository.com/artifact/com.fasterxml.uuid/java-uuid-generator
nanoid = "1.0.1" # https://mvnrepository.com/artifact/io.viascom.nanoid/nanoid

[plugins]
changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" }
Expand All @@ -46,6 +47,7 @@ kotest-runner-junit5 = { module = "io.kotest:kotest-runner-junit5", version.ref
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect" }
rgxgen = { module = "com.github.curious-odd-man:rgxgen", version.ref = "rgxgen" }
uuidGenerator = { module = "com.fasterxml.uuid:java-uuid-generator", version.ref = "uuidGenerator" }
nanoid = { module = "io.viascom.nanoid:nanoid", version.ref = "nanoid" }

[bundles]
kotest = ["kotest-assertions-core", "kotest-framework-dataset", "kotest-runner-junit5"]
92 changes: 92 additions & 0 deletions src/main/kotlin/com/fwdekker/randomness/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,105 @@ internal class PersistentSettings : PersistentStateComponent<Element> {
prop.setAttribute("value", max.value)
}
}
},
Version.parse("3.5.0") to
{ settings ->
// Migrate UuidScheme to UidScheme
settings.getSchemes()
.filter { it.name == "UuidScheme" }
.forEach { scheme ->
// Change scheme name from UuidScheme to UidScheme
scheme.name = "UidScheme"

// Add idTypeKey property set to "uuid"
scheme.addProperty("idTypeKey", "uuid")

// Wrap existing UUID properties into uuidConfig
val uuidConfigElement = Element("UuidConfig")

// Move UUID-specific properties to uuidConfig
listOf("version", "minDateTime", "maxDateTime", "isUppercase", "addDashes").forEach { propName ->
scheme.getMultiProperty(propName).forEach { prop ->
scheme.children.remove(prop)
uuidConfigElement.addContent(prop.clone())
}
}

// Add uuidConfig as a property
scheme.addContent(
Element("option")
.setAttribute("name", "uuidConfig")
.addContent(uuidConfigElement)
)

// Add default nanoIdConfig
val nanoIdConfigElement = Element("NanoIdConfig")
scheme.addContent(
Element("option")
.setAttribute("name", "nanoIdConfig")
.addContent(nanoIdConfigElement)
)
}

// Add default UUID and NanoID templates if they don't exist
val templatesElement = settings.getPropertyByPath("templateList", null, "templates", null)
if (templatesElement != null) {
val existingTemplateNames = settings.getTemplates()
.mapNotNull { it.getPropertyValue("name") }

// Add UUID template if not present
if ("UUID" !in existingTemplateNames) {
templatesElement.addContent(createUidTemplateElement("UUID", "uuid"))
}

// Add Nano ID template if not present
if ("Nano ID" !in existingTemplateNames) {
templatesElement.addContent(createUidTemplateElement("Nano ID", "nanoid"))
}
}
}
)

/**
* The settings format version of Randomness.
*/
val CURRENT_VERSION: Version = UPGRADES.keys.max()

/**
* Creates an XML Element representing a Template with a UidScheme.
*
* @param templateName The name of the template (e.g., "UUID" or "Nano ID")
* @param idTypeKey The ID type key (e.g., "uuid" or "nanoid")
*/
private fun createUidTemplateElement(templateName: String, idTypeKey: String): Element {
val uidScheme = Element("UidScheme")
.apply {
addProperty("idTypeKey", idTypeKey)
addContent(
Element("option")
.setAttribute("name", "uuidConfig")
.addContent(Element("UuidConfig"))
)
addContent(
Element("option")
.setAttribute("name", "nanoIdConfig")
.addContent(Element("NanoIdConfig"))
)
}

val schemesOption = Element("option")
.setAttribute("name", "schemes")
.addContent(
Element("list")
.addContent(uidScheme)
)

return Element("Template")
.apply {
addProperty("name", templateName)
addContent(schemesOption)
}
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/com/fwdekker/randomness/template/Template.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import com.fwdekker.randomness.decimal.DecimalScheme
import com.fwdekker.randomness.integer.IntegerScheme
import com.fwdekker.randomness.string.StringScheme
import com.fwdekker.randomness.ui.ValidatorDsl.Companion.validators
import com.fwdekker.randomness.uuid.UuidScheme
import com.fwdekker.randomness.uid.UidScheme
import com.fwdekker.randomness.word.WordScheme
import com.intellij.ui.Gray
import com.intellij.util.xmlb.annotations.OptionTag
Expand All @@ -36,7 +36,7 @@ data class Template(
IntegerScheme::class,
StringScheme::class,
TemplateReference::class,
UuidScheme::class,
UidScheme::class,
WordScheme::class,
]
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.fwdekker.randomness.datetime.DateTimeScheme
import com.fwdekker.randomness.decimal.DecimalScheme
import com.fwdekker.randomness.integer.IntegerScheme
import com.fwdekker.randomness.string.StringScheme
import com.fwdekker.randomness.uuid.UuidScheme
import com.fwdekker.randomness.uid.UidScheme
import com.fwdekker.randomness.word.WordScheme
import com.intellij.icons.AllIcons
import com.intellij.openapi.actionSystem.ActionToolbarPosition
Expand Down Expand Up @@ -710,7 +710,7 @@ class TemplateJTree(
DecimalScheme(),
StringScheme(),
WordScheme(),
UuidScheme(),
UidScheme(),
DateTimeScheme(),
TemplateReference(),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import com.fwdekker.randomness.decimal.DecimalScheme
import com.fwdekker.randomness.integer.IntegerScheme
import com.fwdekker.randomness.string.StringScheme
import com.fwdekker.randomness.ui.ValidatorDsl.Companion.validators
import com.fwdekker.randomness.uuid.UuidScheme
import com.fwdekker.randomness.uid.IdType
import com.fwdekker.randomness.uid.UidScheme
import com.fwdekker.randomness.word.DefaultWordList
import com.fwdekker.randomness.word.WordScheme
import com.intellij.util.xmlb.annotations.OptionTag
Expand Down Expand Up @@ -133,7 +134,8 @@ data class TemplateList(
)
)
),
Template("UUID", mutableListOf(UuidScheme())),
Template("UUID", mutableListOf(UidScheme(idTypeKey = IdType.Uuid.key))),
Template("Nano ID", mutableListOf(UidScheme(idTypeKey = IdType.NanoId.key))),
Template("Date-Time", mutableListOf(DateTimeScheme())),
Template(
"IP address",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import com.fwdekker.randomness.ui.PreviewPanel
import com.fwdekker.randomness.ui.ValidationInfo
import com.fwdekker.randomness.ui.addChangeListenerTo
import com.fwdekker.randomness.ui.focusLater
import com.fwdekker.randomness.uuid.UuidScheme
import com.fwdekker.randomness.uuid.UuidSchemeEditor
import com.fwdekker.randomness.uid.UidScheme
import com.fwdekker.randomness.uid.UidSchemeEditor
import com.fwdekker.randomness.word.WordScheme
import com.fwdekker.randomness.word.WordSchemeEditor
import com.intellij.openapi.Disposable
Expand Down Expand Up @@ -153,7 +153,7 @@ class TemplateListEditor(
is IntegerScheme -> IntegerSchemeEditor(scheme)
is DecimalScheme -> DecimalSchemeEditor(scheme)
is StringScheme -> StringSchemeEditor(scheme)
is UuidScheme -> UuidSchemeEditor(scheme)
is UidScheme -> UidSchemeEditor(scheme)
is WordScheme -> WordSchemeEditor(scheme)
is DateTimeScheme -> DateTimeSchemeEditor(scheme)
is TemplateReference -> TemplateReferenceEditor(scheme)
Expand Down
57 changes: 57 additions & 0 deletions src/main/kotlin/com/fwdekker/randomness/uid/IdType.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.fwdekker.randomness.uid

import com.fwdekker.randomness.Bundle


/**
* Represents the type of unique identifier to generate.
*
* This sealed class allows for type-safe selection of ID types and is designed
* to be extensible for adding new ID types in the future.
*/
sealed class IdType {
/**
* The display name shown in the UI dropdown.
*/
abstract val displayName: String

/**
* A unique key used for serialization and identification.
*/
abstract val key: String


/**
* UUID (Universally Unique Identifier) type.
*/
data object Uuid : IdType() {
override val displayName: String get() = Bundle("uid.type.uuid")
override val key: String = "uuid"
}

/**
* NanoID type - a tiny, secure, URL-friendly unique string ID generator.
*/
data object NanoId : IdType() {
override val displayName: String get() = Bundle("uid.type.nanoid")
override val key: String = "nanoid"
}


companion object {
/**
* All available ID types.
*/
val entries: List<IdType> get() = listOf(Uuid, NanoId)

/**
* The default ID type.
*/
val DEFAULT: IdType get() = Uuid

/**
* Returns the [IdType] with the given [key], or [DEFAULT] if not found.
*/
fun fromKey(key: String): IdType = entries.find { it.key == key } ?: DEFAULT
}
}
55 changes: 55 additions & 0 deletions src/main/kotlin/com/fwdekker/randomness/uid/NanoIdConfig.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.fwdekker.randomness.uid

import io.viascom.nanoid.NanoId
import kotlin.random.Random


/**
* Configuration for generating Nano IDs.
*
* @property size The length of the generated Nano ID.
* @property alphabet The alphabet to use when generating the Nano ID.
*/
data class NanoIdConfig(
var size: Int = DEFAULT_SIZE,
var alphabet: String = DEFAULT_ALPHABET,
) {
/**
* Generates [count] random Nano IDs using the given [random] instance.
*
* Note: The [random] parameter is currently unused as the NanoId library uses its own random source,
* but it's included for API consistency with other config classes.
*/
@Suppress("UNUSED_PARAMETER") // random parameter kept for API consistency
fun generate(count: Int, random: Random): List<String> =
List(count) { NanoId.generate(size, alphabet) }


/**
* Creates a deep copy of this configuration.
*/
fun deepCopy() = copy()


companion object {
/**
* The minimum allowed value of [size].
*/
const val MIN_SIZE = 1

/**
* The default value of [size].
*/
const val DEFAULT_SIZE = 21

/**
* The default value of [alphabet].
*/
const val DEFAULT_ALPHABET: String = "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

/**
* The preset values for affix decorators.
*/
val PRESET_AFFIX_DECORATOR_DESCRIPTORS = listOf("'", "\"", "`")
}
}
Loading