diff --git a/npm-publish-gradle-plugin/src/main/kotlin/extension/domain/json/Exports.kt b/npm-publish-gradle-plugin/src/main/kotlin/extension/domain/json/Exports.kt new file mode 100644 index 00000000..6e25d70c --- /dev/null +++ b/npm-publish-gradle-plugin/src/main/kotlin/extension/domain/json/Exports.kt @@ -0,0 +1,69 @@ +package dev.petuska.npm.publish.extension.domain.json + +import org.gradle.api.provider.MapProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Optional + +/** + * [exports field](https://nodejs.org/api/packages.html#main-entry-point-export) + */ +public abstract class Exports : GenericJsonObject() { + + internal abstract val paths: MapProperty + + override fun finalise(): MutableMap = super.finalise().apply { + paths.get().forEach { (path, info) -> + put(path, info.finalise()) + } + } +} + +/** + * A path that will be exported in [Exports] + */ +public abstract class ExportedPath : GenericJsonObject() { + + /** + * If set, this path will be set in "default" + */ + @get:Input + @get:Optional + public abstract val default: Property + + /** + * If set, this path will be set in "types" + */ + @get:Input + @get:Optional + public abstract val types: Property + + /** + * If set, this path will be set in "import" + */ + @get:Input + @get:Optional + public abstract val import: Property + + /** + * If set, this path will be set in "require" + */ + @get:Input + @get:Optional + public abstract val require: Property + + override fun finalise(): MutableMap = super.finalise().apply { + types.finalOrNull?.let { + put("types", it) + } + default.finalOrNull?.let { + put("default", it) + } + require.finalOrNull?.let { + put("require", it) + } + import.finalOrNull?.let { + put("import", it) + } + } +} diff --git a/npm-publish-gradle-plugin/src/main/kotlin/extension/domain/json/PackageJson.kt b/npm-publish-gradle-plugin/src/main/kotlin/extension/domain/json/PackageJson.kt index 693e2fc8..e59cf31c 100644 --- a/npm-publish-gradle-plugin/src/main/kotlin/extension/domain/json/PackageJson.kt +++ b/npm-publish-gradle-plugin/src/main/kotlin/extension/domain/json/PackageJson.kt @@ -1,5 +1,6 @@ package dev.petuska.npm.publish.extension.domain.json +import dev.petuska.npm.publish.util.configure import org.gradle.api.Action import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property @@ -163,6 +164,13 @@ public abstract class PackageJson : GenericJsonObject() { @get:Optional public abstract val bundledDependencies: SetProperty + /** + * [exports](https://docs.npmjs.com/files/package.json#bundleddependencies) + */ + @get:Input + @get:Optional + public abstract val exports: Property + // region DSL /** @@ -286,6 +294,45 @@ public abstract class PackageJson : GenericJsonObject() { optionalDependencies.configure(action) } + /** + * Set exports to a single path that will map "." + * @see [exports] + */ + public infix fun Property.by(path: String) { + configure({ exports -> + exports.paths.configure { paths -> + paths["."] = instance(ExportedPath::class).apply { + default.set(path) + } + } + }) + } + + /** + * Set exports to a single path that will map ".", this path may have several export + * @see [exports] + */ + public infix fun Property.by(pathAction: Action) { + this by mapOf("." to pathAction) + } + + /** + * Configure exports to a map of configurable paths + * @see [exports] + */ + public infix fun Property.by(paths: Map>) { + exports.set( + instance(Exports::class).also { + it.paths.putAll( + paths.mapValues { (_, action) -> ExportedPath(action) } + ) + } + ) + } + + private fun ExportedPath(action: Action): ExportedPath = + instance(ExportedPath::class).apply(action::execute) + // endregion @Suppress("ComplexMethod") @@ -319,5 +366,6 @@ public abstract class PackageJson : GenericJsonObject() { peerDependencies.finalOrNull?.let { put("peerDependencies", it.finalise()) } optionalDependencies.finalOrNull?.let { put("optionalDependencies", it.finalise()) } bundledDependencies.final?.let { put("bundledDependencies", it) } + exports.finalOrNull?.let { put("exports", it) } } } diff --git a/samples/local-ts-consumer/kt/build.gradle.kts b/samples/local-ts-consumer/kt/build.gradle.kts index 4eba73cd..2e323375 100644 --- a/samples/local-ts-consumer/kt/build.gradle.kts +++ b/samples/local-ts-consumer/kt/build.gradle.kts @@ -1,3 +1,5 @@ +import dev.petuska.npm.publish.extension.domain.json.ExportedPath + plugins { kotlin("multiplatform") id("dev.petuska.npm.publish") @@ -20,4 +22,11 @@ kotlin { npmPublish { organization.set("mpetuska") + packages { + named("js") { + packageJson { + exports by "index.mjs" + } + } + } } \ No newline at end of file