@kizunajs/kotlin 2.0.0-beta.17 → 2.0.0-beta.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs
CHANGED
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as generateKotlinClient } from "./generator-
|
|
2
|
+
import { t as generateKotlinClient } from "./generator-DT7c2Vo3.mjs";
|
|
3
3
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { dirname, resolve } from "node:path";
|
|
5
5
|
import { parseArgs } from "node:util";
|
|
@@ -142,6 +142,7 @@ const objectFields = (schema, registry, hint, shape = (0, kizunajs_generator.rea
|
|
|
142
142
|
wireName: key,
|
|
143
143
|
type: result.expression,
|
|
144
144
|
optional: result.optional,
|
|
145
|
+
requiredNullable: result.requiredNullable,
|
|
145
146
|
description: (0, kizunajs_generator.readMetaDescription)(value),
|
|
146
147
|
isFile: result.isFile,
|
|
147
148
|
deprecated: deprecation !== void 0,
|
|
@@ -264,6 +265,7 @@ const mapUnbrandedType = (schema, registry, hint) => {
|
|
|
264
265
|
return {
|
|
265
266
|
expression: innerResult.expression.endsWith("?") ? innerResult.expression : `${innerResult.expression}?`,
|
|
266
267
|
optional: true,
|
|
268
|
+
requiredNullable: nullable && !optional,
|
|
267
269
|
isFile: innerResult.isFile
|
|
268
270
|
};
|
|
269
271
|
}
|
|
@@ -448,6 +450,7 @@ const sanitizeCaseName = (literal) => {
|
|
|
448
450
|
const collectObjectFields = (schema, registry, hint) => {
|
|
449
451
|
return objectFields(schema, registry, hint);
|
|
450
452
|
};
|
|
453
|
+
const hasDefault = (field) => field.optional && field.requiredNullable !== true;
|
|
451
454
|
const objectFieldCount = (schema) => {
|
|
452
455
|
return Object.keys((0, kizunajs_generator.readObjectShape)(schema) ?? {}).length;
|
|
453
456
|
};
|
|
@@ -678,6 +681,10 @@ const KOTLIN_KEYWORDS = new Set([
|
|
|
678
681
|
const escapeKeyword = (name) => {
|
|
679
682
|
return KOTLIN_KEYWORDS.has(name) ? `\`${name}\`` : name;
|
|
680
683
|
};
|
|
684
|
+
const defaultArgument = (field) => {
|
|
685
|
+
if (!hasDefault(field)) return "";
|
|
686
|
+
return " = null";
|
|
687
|
+
};
|
|
681
688
|
const optionalize = (type, optional) => {
|
|
682
689
|
if (!optional) return type;
|
|
683
690
|
return type.endsWith("?") ? type : `${type}?`;
|
|
@@ -838,7 +845,7 @@ const emitDataClass = (writer, type, ownedTypeMap, ownedTypeLookup, registryName
|
|
|
838
845
|
if (!hasFile) writer.line("@Serializable");
|
|
839
846
|
const params = adjustedFields.map((field) => {
|
|
840
847
|
const typeExpression = optionalize(field.type, field.optional);
|
|
841
|
-
const defaultPart = field
|
|
848
|
+
const defaultPart = defaultArgument(field);
|
|
842
849
|
const serialNameAnnotation = needsSerialName && (field.name !== field.wireName || KOTLIN_KEYWORDS.has(field.name)) ? `@SerialName(${stringLiteral(field.wireName)}) ` : "";
|
|
843
850
|
return `${field.deprecated ? `${deprecatedAnnotation(field.deprecationMessage)} ` : ""}${serialNameAnnotation}val ${escapeKeyword(field.name)}: ${typeExpression}${defaultPart}`;
|
|
844
851
|
});
|
|
@@ -931,7 +938,7 @@ const emitSealedClass = (writer, type, registry, ownedTypeMap, ownedTypeLookup)
|
|
|
931
938
|
const params = fields.map((field) => {
|
|
932
939
|
const variantPath = registry.sealedVariantPath(variant.payloadType) ?? variant.payloadType;
|
|
933
940
|
const typeExpression = optionalize(relativeOwnedPath(field.type, ownedTypeMap, variantPath, registry) ?? ownedTypePath(field.type, ownedTypeMap, registry), field.optional);
|
|
934
|
-
const defaultPart = field
|
|
941
|
+
const defaultPart = defaultArgument(field);
|
|
935
942
|
return `val ${escapeKeyword(field.name)}: ${typeExpression}${defaultPart}`;
|
|
936
943
|
});
|
|
937
944
|
if (params.length === 1) writer.line(`data class ${variant.caseName}(${params[0]}) : ${type.name}`);
|
|
@@ -1130,7 +1137,7 @@ const groupTypeRef = (operationName, className, context) => `${context.clientNam
|
|
|
1130
1137
|
const groupMemberAccessor = (groupLabel, field) => `${groupLabel}.${escapeKeyword(field.name)}`;
|
|
1131
1138
|
const groupClassField = (field) => {
|
|
1132
1139
|
const typeExpression = optionalize(field.type, field.optional);
|
|
1133
|
-
const defaultPart = field
|
|
1140
|
+
const defaultPart = defaultArgument(field);
|
|
1134
1141
|
return `val ${escapeKeyword(field.name)}: ${typeExpression}${defaultPart}`;
|
|
1135
1142
|
};
|
|
1136
1143
|
const emitGroupClass = (writer, className, fields, method, context) => {
|
|
@@ -1189,13 +1196,13 @@ const methodChannels = (method) => {
|
|
|
1189
1196
|
if (method.query.length > 0) channels.push({
|
|
1190
1197
|
varName: "query",
|
|
1191
1198
|
className: "Query",
|
|
1192
|
-
required: method.query.some((field) => !field
|
|
1199
|
+
required: method.query.some((field) => !hasDefault(field)),
|
|
1193
1200
|
fields: method.query
|
|
1194
1201
|
});
|
|
1195
1202
|
if (method.headers.length > 0) channels.push({
|
|
1196
1203
|
varName: "headers",
|
|
1197
1204
|
className: "Headers",
|
|
1198
|
-
required: method.headers.some((field) => !field
|
|
1205
|
+
required: method.headers.some((field) => !hasDefault(field)),
|
|
1199
1206
|
fields: method.headers
|
|
1200
1207
|
});
|
|
1201
1208
|
if (hasBodyGroup(method)) {
|
|
@@ -1244,7 +1251,7 @@ const emitArgsScaffolding = (writer, method, context) => {
|
|
|
1244
1251
|
};
|
|
1245
1252
|
const factorySignature = (channel) => channel.fields.map((field) => {
|
|
1246
1253
|
const typeExpression = optionalize(field.type, field.optional);
|
|
1247
|
-
const defaultPart = field
|
|
1254
|
+
const defaultPart = defaultArgument(field);
|
|
1248
1255
|
return `${escapeKeyword(field.name)}: ${typeExpression}${defaultPart}`;
|
|
1249
1256
|
}).join(", ");
|
|
1250
1257
|
const factoryConstruction = (channel) => {
|
|
@@ -1301,10 +1308,16 @@ const emitBodyEncoding = (writer, method, context) => {
|
|
|
1301
1308
|
if (body.kind === "multipart") {
|
|
1302
1309
|
writer.line("val multipartBuilder = MultipartBody.Builder().setType(MultipartBody.FORM)");
|
|
1303
1310
|
for (const field of body.multipartFields) {
|
|
1304
|
-
const
|
|
1305
|
-
const
|
|
1306
|
-
|
|
1307
|
-
|
|
1311
|
+
const flattenedField = body.flattened.find((flatField) => flatField.name === field.name);
|
|
1312
|
+
const isFile = field.isFile || flattenedField?.isFile === true;
|
|
1313
|
+
const append = (accessor) => {
|
|
1314
|
+
if (isFile) writer.line(`multipartBuilder.addFormDataPart(${stringLiteral(field.wireName)}, ${accessor}.filename, ${accessor}.data.toRequestBody(${accessor}.mimeType.toMediaType()))`);
|
|
1315
|
+
else writer.line(`multipartBuilder.addFormDataPart(${stringLiteral(field.wireName)}, ${accessor}.toString())`);
|
|
1316
|
+
};
|
|
1317
|
+
if (flattenedField?.optional === true) writer.block(`if (${groupMemberAccessor("body", field)} != null)`, () => {
|
|
1318
|
+
append(groupMemberAccessor("body", field));
|
|
1319
|
+
});
|
|
1320
|
+
else append(groupMemberAccessor("body", field));
|
|
1308
1321
|
}
|
|
1309
1322
|
writer.line("requestBody = multipartBuilder.build()");
|
|
1310
1323
|
return;
|
|
@@ -1664,14 +1677,14 @@ const emitClient = (writer, config, partition, context, typesByOperation, regist
|
|
|
1664
1677
|
const allMethods = [...flatMethods, ...groups.flatMap((group) => group.methods)];
|
|
1665
1678
|
const usesMultipart = allMethods.some((method) => method.body?.kind === "multipart");
|
|
1666
1679
|
const contextFields = context.requestContextFields;
|
|
1667
|
-
const contextRequired = contextFields.some((field) => !field
|
|
1680
|
+
const contextRequired = contextFields.some((field) => !hasDefault(field));
|
|
1668
1681
|
const contextParam = contextFields.length > 0 ? `requestContext: RequestContext${contextRequired ? "" : " = RequestContext()"}, ` : "";
|
|
1669
1682
|
writer.blank();
|
|
1670
1683
|
writer.block(`class ${clientName}(private val baseUrl: String, ${contextParam}private val client: OkHttpClient = OkHttpClient(), private val json: Json = Json { ignoreUnknownKeys = true }, private val requestInterceptor: (suspend (Request.Builder) -> Unit)? = null, private val responseInterceptor: (suspend (Request, Response) -> Unit)? = null)`, () => {
|
|
1671
1684
|
if (contextFields.length > 0) {
|
|
1672
1685
|
writer.blank();
|
|
1673
1686
|
writer.line("/** Values sent as headers on every request, from the api's request context. */");
|
|
1674
|
-
emitConstructorClass(writer, "data class RequestContext", contextFields.map((field) => `val ${escapeKeyword(field.name)}: ${field.type}${field
|
|
1687
|
+
emitConstructorClass(writer, "data class RequestContext", contextFields.map((field) => `val ${escapeKeyword(field.name)}: ${field.type}${defaultArgument(field)}`));
|
|
1675
1688
|
writer.blank();
|
|
1676
1689
|
writer.block("private val requestContextHeaders: Map<String, String> = buildMap", () => {
|
|
1677
1690
|
for (const field of contextFields) if (field.optional) writer.line(`if (requestContext.${escapeKeyword(field.name)} != null) put(${stringLiteral(field.wireName)}, requestContext.${escapeKeyword(field.name)}!!)`);
|
|
@@ -142,6 +142,7 @@ const objectFields = (schema, registry, hint, shape = readObjectShape(schema) ??
|
|
|
142
142
|
wireName: key,
|
|
143
143
|
type: result.expression,
|
|
144
144
|
optional: result.optional,
|
|
145
|
+
requiredNullable: result.requiredNullable,
|
|
145
146
|
description: readMetaDescription(value),
|
|
146
147
|
isFile: result.isFile,
|
|
147
148
|
deprecated: deprecation !== void 0,
|
|
@@ -264,6 +265,7 @@ const mapUnbrandedType = (schema, registry, hint) => {
|
|
|
264
265
|
return {
|
|
265
266
|
expression: innerResult.expression.endsWith("?") ? innerResult.expression : `${innerResult.expression}?`,
|
|
266
267
|
optional: true,
|
|
268
|
+
requiredNullable: nullable && !optional,
|
|
267
269
|
isFile: innerResult.isFile
|
|
268
270
|
};
|
|
269
271
|
}
|
|
@@ -448,6 +450,7 @@ const sanitizeCaseName = (literal) => {
|
|
|
448
450
|
const collectObjectFields = (schema, registry, hint) => {
|
|
449
451
|
return objectFields(schema, registry, hint);
|
|
450
452
|
};
|
|
453
|
+
const hasDefault = (field) => field.optional && field.requiredNullable !== true;
|
|
451
454
|
const objectFieldCount = (schema) => {
|
|
452
455
|
return Object.keys(readObjectShape(schema) ?? {}).length;
|
|
453
456
|
};
|
|
@@ -678,6 +681,10 @@ const KOTLIN_KEYWORDS = new Set([
|
|
|
678
681
|
const escapeKeyword = (name) => {
|
|
679
682
|
return KOTLIN_KEYWORDS.has(name) ? `\`${name}\`` : name;
|
|
680
683
|
};
|
|
684
|
+
const defaultArgument = (field) => {
|
|
685
|
+
if (!hasDefault(field)) return "";
|
|
686
|
+
return " = null";
|
|
687
|
+
};
|
|
681
688
|
const optionalize = (type, optional) => {
|
|
682
689
|
if (!optional) return type;
|
|
683
690
|
return type.endsWith("?") ? type : `${type}?`;
|
|
@@ -838,7 +845,7 @@ const emitDataClass = (writer, type, ownedTypeMap, ownedTypeLookup, registryName
|
|
|
838
845
|
if (!hasFile) writer.line("@Serializable");
|
|
839
846
|
const params = adjustedFields.map((field) => {
|
|
840
847
|
const typeExpression = optionalize(field.type, field.optional);
|
|
841
|
-
const defaultPart = field
|
|
848
|
+
const defaultPart = defaultArgument(field);
|
|
842
849
|
const serialNameAnnotation = needsSerialName && (field.name !== field.wireName || KOTLIN_KEYWORDS.has(field.name)) ? `@SerialName(${stringLiteral(field.wireName)}) ` : "";
|
|
843
850
|
return `${field.deprecated ? `${deprecatedAnnotation(field.deprecationMessage)} ` : ""}${serialNameAnnotation}val ${escapeKeyword(field.name)}: ${typeExpression}${defaultPart}`;
|
|
844
851
|
});
|
|
@@ -931,7 +938,7 @@ const emitSealedClass = (writer, type, registry, ownedTypeMap, ownedTypeLookup)
|
|
|
931
938
|
const params = fields.map((field) => {
|
|
932
939
|
const variantPath = registry.sealedVariantPath(variant.payloadType) ?? variant.payloadType;
|
|
933
940
|
const typeExpression = optionalize(relativeOwnedPath(field.type, ownedTypeMap, variantPath, registry) ?? ownedTypePath(field.type, ownedTypeMap, registry), field.optional);
|
|
934
|
-
const defaultPart = field
|
|
941
|
+
const defaultPart = defaultArgument(field);
|
|
935
942
|
return `val ${escapeKeyword(field.name)}: ${typeExpression}${defaultPart}`;
|
|
936
943
|
});
|
|
937
944
|
if (params.length === 1) writer.line(`data class ${variant.caseName}(${params[0]}) : ${type.name}`);
|
|
@@ -1130,7 +1137,7 @@ const groupTypeRef = (operationName, className, context) => `${context.clientNam
|
|
|
1130
1137
|
const groupMemberAccessor = (groupLabel, field) => `${groupLabel}.${escapeKeyword(field.name)}`;
|
|
1131
1138
|
const groupClassField = (field) => {
|
|
1132
1139
|
const typeExpression = optionalize(field.type, field.optional);
|
|
1133
|
-
const defaultPart = field
|
|
1140
|
+
const defaultPart = defaultArgument(field);
|
|
1134
1141
|
return `val ${escapeKeyword(field.name)}: ${typeExpression}${defaultPart}`;
|
|
1135
1142
|
};
|
|
1136
1143
|
const emitGroupClass = (writer, className, fields, method, context) => {
|
|
@@ -1189,13 +1196,13 @@ const methodChannels = (method) => {
|
|
|
1189
1196
|
if (method.query.length > 0) channels.push({
|
|
1190
1197
|
varName: "query",
|
|
1191
1198
|
className: "Query",
|
|
1192
|
-
required: method.query.some((field) => !field
|
|
1199
|
+
required: method.query.some((field) => !hasDefault(field)),
|
|
1193
1200
|
fields: method.query
|
|
1194
1201
|
});
|
|
1195
1202
|
if (method.headers.length > 0) channels.push({
|
|
1196
1203
|
varName: "headers",
|
|
1197
1204
|
className: "Headers",
|
|
1198
|
-
required: method.headers.some((field) => !field
|
|
1205
|
+
required: method.headers.some((field) => !hasDefault(field)),
|
|
1199
1206
|
fields: method.headers
|
|
1200
1207
|
});
|
|
1201
1208
|
if (hasBodyGroup(method)) {
|
|
@@ -1244,7 +1251,7 @@ const emitArgsScaffolding = (writer, method, context) => {
|
|
|
1244
1251
|
};
|
|
1245
1252
|
const factorySignature = (channel) => channel.fields.map((field) => {
|
|
1246
1253
|
const typeExpression = optionalize(field.type, field.optional);
|
|
1247
|
-
const defaultPart = field
|
|
1254
|
+
const defaultPart = defaultArgument(field);
|
|
1248
1255
|
return `${escapeKeyword(field.name)}: ${typeExpression}${defaultPart}`;
|
|
1249
1256
|
}).join(", ");
|
|
1250
1257
|
const factoryConstruction = (channel) => {
|
|
@@ -1301,10 +1308,16 @@ const emitBodyEncoding = (writer, method, context) => {
|
|
|
1301
1308
|
if (body.kind === "multipart") {
|
|
1302
1309
|
writer.line("val multipartBuilder = MultipartBody.Builder().setType(MultipartBody.FORM)");
|
|
1303
1310
|
for (const field of body.multipartFields) {
|
|
1304
|
-
const
|
|
1305
|
-
const
|
|
1306
|
-
|
|
1307
|
-
|
|
1311
|
+
const flattenedField = body.flattened.find((flatField) => flatField.name === field.name);
|
|
1312
|
+
const isFile = field.isFile || flattenedField?.isFile === true;
|
|
1313
|
+
const append = (accessor) => {
|
|
1314
|
+
if (isFile) writer.line(`multipartBuilder.addFormDataPart(${stringLiteral(field.wireName)}, ${accessor}.filename, ${accessor}.data.toRequestBody(${accessor}.mimeType.toMediaType()))`);
|
|
1315
|
+
else writer.line(`multipartBuilder.addFormDataPart(${stringLiteral(field.wireName)}, ${accessor}.toString())`);
|
|
1316
|
+
};
|
|
1317
|
+
if (flattenedField?.optional === true) writer.block(`if (${groupMemberAccessor("body", field)} != null)`, () => {
|
|
1318
|
+
append(groupMemberAccessor("body", field));
|
|
1319
|
+
});
|
|
1320
|
+
else append(groupMemberAccessor("body", field));
|
|
1308
1321
|
}
|
|
1309
1322
|
writer.line("requestBody = multipartBuilder.build()");
|
|
1310
1323
|
return;
|
|
@@ -1664,14 +1677,14 @@ const emitClient = (writer, config, partition, context, typesByOperation, regist
|
|
|
1664
1677
|
const allMethods = [...flatMethods, ...groups.flatMap((group) => group.methods)];
|
|
1665
1678
|
const usesMultipart = allMethods.some((method) => method.body?.kind === "multipart");
|
|
1666
1679
|
const contextFields = context.requestContextFields;
|
|
1667
|
-
const contextRequired = contextFields.some((field) => !field
|
|
1680
|
+
const contextRequired = contextFields.some((field) => !hasDefault(field));
|
|
1668
1681
|
const contextParam = contextFields.length > 0 ? `requestContext: RequestContext${contextRequired ? "" : " = RequestContext()"}, ` : "";
|
|
1669
1682
|
writer.blank();
|
|
1670
1683
|
writer.block(`class ${clientName}(private val baseUrl: String, ${contextParam}private val client: OkHttpClient = OkHttpClient(), private val json: Json = Json { ignoreUnknownKeys = true }, private val requestInterceptor: (suspend (Request.Builder) -> Unit)? = null, private val responseInterceptor: (suspend (Request, Response) -> Unit)? = null)`, () => {
|
|
1671
1684
|
if (contextFields.length > 0) {
|
|
1672
1685
|
writer.blank();
|
|
1673
1686
|
writer.line("/** Values sent as headers on every request, from the api's request context. */");
|
|
1674
|
-
emitConstructorClass(writer, "data class RequestContext", contextFields.map((field) => `val ${escapeKeyword(field.name)}: ${field.type}${field
|
|
1687
|
+
emitConstructorClass(writer, "data class RequestContext", contextFields.map((field) => `val ${escapeKeyword(field.name)}: ${field.type}${defaultArgument(field)}`));
|
|
1675
1688
|
writer.blank();
|
|
1676
1689
|
writer.block("private val requestContextHeaders: Map<String, String> = buildMap", () => {
|
|
1677
1690
|
for (const field of contextFields) if (field.optional) writer.line(`if (requestContext.${escapeKeyword(field.name)} != null) put(${stringLiteral(field.wireName)}, requestContext.${escapeKeyword(field.name)}!!)`);
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_generator = require("./generator-
|
|
2
|
+
const require_generator = require("./generator-D4SnsG2Q.cjs");
|
|
3
3
|
let kizunajs_generator = require("kizunajs/generator");
|
|
4
4
|
let zod = require("zod");
|
|
5
5
|
//#region src/client-target.ts
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as kotlinClientWalk, t as generateKotlinClient } from "./generator-
|
|
1
|
+
import { n as kotlinClientWalk, t as generateKotlinClient } from "./generator-DT7c2Vo3.mjs";
|
|
2
2
|
import { defineClient } from "kizunajs/generator";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kizunajs/kotlin",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.19",
|
|
4
4
|
"description": "Kotlin client generation for Kizuna.js APIs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"kizunajs",
|
|
@@ -60,14 +60,14 @@
|
|
|
60
60
|
"access": "public"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@kizunajs/cli": "2.0.0-beta.
|
|
63
|
+
"@kizunajs/cli": "2.0.0-beta.19"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
|
-
"kizunajs": "2.0.0-beta.
|
|
66
|
+
"kizunajs": "2.0.0-beta.19",
|
|
67
67
|
"zod": "^4.0.0"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
-
"kizunajs": "2.0.0-beta.
|
|
70
|
+
"kizunajs": "2.0.0-beta.19",
|
|
71
71
|
"@types/node": "^22.9.0",
|
|
72
72
|
"tsdown": "^0.21.0",
|
|
73
73
|
"typescript": "^6.0.3",
|