Skip to content

Commit

Permalink
Allow to name the constants of a string union by configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
Vampire committed Sep 17, 2024
1 parent 61ad4e6 commit 7a937ac
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 1 deletion.
10 changes: 10 additions & 0 deletions schema/karakum-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,16 @@
],
"title": "plugins"
},
"unionNameMapper": {
"additionalProperties": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"title": "unionNameMapper",
"type": "object"
},
"varianceModifiers": {
"anyOf": [
{
Expand Down
7 changes: 7 additions & 0 deletions src/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ export interface SchemaConfiguration {
* */
packageNameMapper?: Record<string, string>

/**
* @TJS-type object
* @additionalProperties { "type": "object", "additionalProperties": { "type": "string" } }
* */
unionNameMapper?: Record<string, Record<string, string>>

/**
* @TJS-type object
* @additionalProperties { "type": "array", "items": { "type": "string" } }
Expand Down Expand Up @@ -117,6 +123,7 @@ export interface Configuration extends PartialConfiguration {

moduleNameMapper: Record<string, string>
packageNameMapper: Record<string, string>
unionNameMapper: Record<string, Record<string, string>>

importInjector: Record<string, string[]>
importMapper: Record<string, string | Record<string, string>>
Expand Down
1 change: 1 addition & 0 deletions src/configuration/defaultizeConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export async function defaultizeConfiguration(configuration: PartialConfiguratio

moduleNameMapper: configuration.moduleNameMapper ?? {},
packageNameMapper: configuration.packageNameMapper ?? {},
unionNameMapper: configuration.unionNameMapper ?? {},

importInjector: configuration.importInjector ?? {},
importMapper: configuration.importMapper ?? {},
Expand Down
21 changes: 21 additions & 0 deletions src/converter/plugins/StringUnionTypePlugin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ts, {LiteralTypeNode, StringLiteral, UnionTypeNode} from "typescript";
import {escapeIdentifier, notEscapedIdentifier} from "../../utils/strings.js";
import {CheckCoverageService, checkCoverageServiceKey} from "./CheckCoveragePlugin.js";
import {ConfigurationService, configurationServiceKey} from "./ConfigurationPlugin.js";
import {ConverterContext} from "../context.js";
import {createAnonymousDeclarationPlugin} from "./AnonymousDeclarationPlugin.js";
import {flatUnionTypes, isNullableType} from "./NullableUnionTypePlugin.js";
Expand Down Expand Up @@ -48,6 +49,8 @@ export function convertStringUnionType(
const checkCoverageService = context.lookupService<CheckCoverageService>(checkCoverageServiceKey)
checkCoverageService?.cover(node)

const configurationService = context.lookupService<ConfigurationService>(configurationServiceKey)
if (configurationService === undefined) throw new Error("ConfigurationService required")
const typeScriptService = context.lookupService<TypeScriptService>(typeScriptServiceKey)
const namespaceInfoService = context.lookupService<NamespaceInfoService>(namespaceInfoServiceKey)
const injectionService = context.lookupService<InjectionService>(injectionServiceKey)
Expand All @@ -57,6 +60,8 @@ export function convertStringUnionType(
const nonNullableTypes = types.filter(type => !isNullableType(type))
const nullableTypes = types.filter(type => isNullableType(type))

const {unionNameMapper} = configurationService.configuration

const entries = nonNullableTypes
.filter((type): type is LiteralTypeNode => ts.isLiteralTypeNode(type))
.map(type => {
Expand All @@ -69,6 +74,22 @@ export function convertStringUnionType(
checkCoverageService?.cover(literal)

const value = literal.text

for (const [namePattern, valueMapping] of Object.entries(unionNameMapper)) {
const nameRegexp = new RegExp(namePattern)
if (nameRegexp.test(name)) {
for (const [valuePattern, key] of Object.entries(valueMapping)) {
const valueRegexp = new RegExp(valuePattern)
if (valueRegexp.test(value)) {
if (!key) {
throw new Error("Configured key in unionNameMapper must not be empty")
}
return [key, value] as const
}
}
}
}

const valueAsIdentifier = notEscapedIdentifier(value)
const key = (value === "") || (valueAsIdentifier === "")
? "_"
Expand Down
15 changes: 15 additions & 0 deletions test/functional/base/base.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,20 @@ testGeneration("base", import.meta.url, output => ({
input: "lib/**",
output,
libraryName: "sandbox-base",
unionNameMapper: {
"^Operator2$": {
"^$": "EMPTY",
"^=$": "EQUAL",
"^<$": "LT",
"^>$": "GT",
"^<=$": "LTE"
},
"^Operator3$": {
"": "OPERATOR"
},
"^Operator": {
"^>=$": "GTE"
}
},
verbose: true,
}))
36 changes: 35 additions & 1 deletion test/functional/base/generated/union/stringEnum.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,41 @@ val __4: Operator
@seskar.js.JsValue("<=")
val __5: Operator
@seskar.js.JsValue(">=")
val __6: Operator
val GTE: Operator
}
}

sealed external interface Operator2 {
companion object {
@seskar.js.JsValue("")
val EMPTY: Operator2
@seskar.js.JsValue("=")
val EQUAL: Operator2
@seskar.js.JsValue("<")
val LT: Operator2
@seskar.js.JsValue(">")
val GT: Operator2
@seskar.js.JsValue("<=")
val LTE: Operator2
@seskar.js.JsValue(">=")
val GTE: Operator2
}
}

sealed external interface Operator3 {
companion object {
@seskar.js.JsValue("")
val OPERATOR: Operator3
@seskar.js.JsValue("=")
val OPERATOR_2: Operator3
@seskar.js.JsValue("<")
val OPERATOR_3: Operator3
@seskar.js.JsValue(">")
val OPERATOR_4: Operator3
@seskar.js.JsValue("<=")
val OPERATOR_5: Operator3
@seskar.js.JsValue(">=")
val OPERATOR_6: Operator3
}
}
sealed external interface SwitcherResult {
Expand Down
4 changes: 4 additions & 0 deletions test/functional/base/lib/union/stringEnum.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ export declare type FormEncType = "application/x-www-form-urlencoded" | "multipa
export declare function switcher(): "on" | "off"

export declare type Operator = "" | "=" | "<" | ">" | "<=" | ">=";

export declare type Operator2 = "" | "=" | "<" | ">" | "<=" | ">=";

export declare type Operator3 = "" | "=" | "<" | ">" | "<=" | ">=";

0 comments on commit 7a937ac

Please sign in to comment.