diff --git a/.classpath b/.classpath
index c84a787..948a0ab 100644
--- a/.classpath
+++ b/.classpath
@@ -25,7 +25,7 @@
-
+
diff --git a/.project b/.project
index 1e3f1c4..ccbb290 100644
--- a/.project
+++ b/.project
@@ -11,12 +11,12 @@
- org.eclipse.m2e.core.maven2Builder
+ edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder
- edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder
+ org.eclipse.m2e.core.maven2Builder
diff --git a/src/org/kar/archidata/annotation/AnnotationTools.java b/src/org/kar/archidata/annotation/AnnotationTools.java
index af5d4ef..454c383 100644
--- a/src/org/kar/archidata/annotation/AnnotationTools.java
+++ b/src/org/kar/archidata/annotation/AnnotationTools.java
@@ -80,6 +80,14 @@ public class AnnotationTools {
return ((Schema) annotation[0]).example();
}
+ public static boolean getNoWriteSpecificMode(final Class> element) {
+ final Annotation[] annotation = element.getDeclaredAnnotationsByType(NoWriteSpecificMode.class);
+ if (annotation.length == 0) {
+ return false;
+ }
+ return true;
+ }
+
public static String getSchemaDescription(final Class> element) throws DataAccessException {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
if (annotation.length == 0) {
diff --git a/src/org/kar/archidata/annotation/NoWriteSpecificMode.java b/src/org/kar/archidata/annotation/NoWriteSpecificMode.java
new file mode 100644
index 0000000..4d6a2e8
--- /dev/null
+++ b/src/org/kar/archidata/annotation/NoWriteSpecificMode.java
@@ -0,0 +1,13 @@
+package org.kar.archidata.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** When we wend to have only One type for read and write mode (Wrapping API). */
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface NoWriteSpecificMode {
+
+}
diff --git a/src/org/kar/archidata/catcher/RestErrorResponse.java b/src/org/kar/archidata/catcher/RestErrorResponse.java
index 246a794..d9c540a 100644
--- a/src/org/kar/archidata/catcher/RestErrorResponse.java
+++ b/src/org/kar/archidata/catcher/RestErrorResponse.java
@@ -3,12 +3,14 @@ package org.kar.archidata.catcher;
import java.time.Instant;
import java.util.UUID;
+import org.kar.archidata.annotation.NoWriteSpecificMode;
import org.kar.archidata.tools.UuidUtils;
import jakarta.persistence.Column;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.core.Response;
+@NoWriteSpecificMode
public class RestErrorResponse {
public UUID uuid = UuidUtils.nextUUID();
@NotNull
diff --git a/src/org/kar/archidata/externalRestApi/model/ClassEnumModel.java b/src/org/kar/archidata/externalRestApi/model/ClassEnumModel.java
index 1791f6d..665a35f 100644
--- a/src/org/kar/archidata/externalRestApi/model/ClassEnumModel.java
+++ b/src/org/kar/archidata/externalRestApi/model/ClassEnumModel.java
@@ -10,6 +10,7 @@ public class ClassEnumModel extends ClassModel {
protected ClassEnumModel(final Class> clazz) {
this.originClasses = clazz;
+ this.noWriteSpecificMode = true;
}
@Override
diff --git a/src/org/kar/archidata/externalRestApi/model/ClassModel.java b/src/org/kar/archidata/externalRestApi/model/ClassModel.java
index 1e81c4b..27ab71d 100644
--- a/src/org/kar/archidata/externalRestApi/model/ClassModel.java
+++ b/src/org/kar/archidata/externalRestApi/model/ClassModel.java
@@ -11,12 +11,17 @@ import java.util.Set;
public abstract class ClassModel {
protected boolean analyzeDone = false;
protected Class> originClasses = null;
+ protected boolean noWriteSpecificMode = false;
protected List dependencyModels = new ArrayList<>();
public Class> getOriginClasses() {
return this.originClasses;
}
+ public boolean isNoWriteSpecificMode() {
+ return this.noWriteSpecificMode;
+ }
+
protected boolean isCompatible(final Class> clazz) {
return this.originClasses == clazz;
}
diff --git a/src/org/kar/archidata/externalRestApi/model/ClassObjectModel.java b/src/org/kar/archidata/externalRestApi/model/ClassObjectModel.java
index 3f1ddd6..1d97f02 100644
--- a/src/org/kar/archidata/externalRestApi/model/ClassObjectModel.java
+++ b/src/org/kar/archidata/externalRestApi/model/ClassObjectModel.java
@@ -123,6 +123,7 @@ public class ClassObjectModel extends ClassModel {
}
this.analyzeDone = true;
final Class> clazz = this.originClasses;
+ this.noWriteSpecificMode = AnnotationTools.getNoWriteSpecificMode(clazz);
this.isPrimitive = clazz.isPrimitive();
if (this.isPrimitive) {
return;
diff --git a/src/org/kar/archidata/externalRestApi/typescript/TsClassElement.java b/src/org/kar/archidata/externalRestApi/typescript/TsClassElement.java
index fdd626c..9c3cc2e 100644
--- a/src/org/kar/archidata/externalRestApi/typescript/TsClassElement.java
+++ b/src/org/kar/archidata/externalRestApi/typescript/TsClassElement.java
@@ -181,12 +181,18 @@ public class TsClassElement {
if (tsModel.nativeType != DefinedPosition.NATIVE) {
out.append("import {");
out.append(tsModel.zodName);
+ if (tsModel.nativeType == DefinedPosition.NORMAL && !(tsModel.models.get(0).isNoWriteSpecificMode())) {
+ out.append(", ");
+ out.append(tsModel.zodName);
+ out.append("Write ");
+ }
out.append("} from \"./");
out.append(tsModel.fileName);
out.append("\";\n");
}
}
return out.toString();
+
}
private Object generateComment(final ClassObjectModel model) {
@@ -215,22 +221,38 @@ public class TsClassElement {
return out.toString();
}
- public String optionalTypeZod(final FieldProperty field) {
+ public boolean isOptionalTypeZod(final FieldProperty field) {
// Common checking element (apply to List, Map, ...)
if (field.nullable()) {
- return ".optional()";
+ return true;
}
if (field.notNull()) {
- return "";
+ return false;
}
// Other object:
if (field.model().getOriginClasses() == null || field.model().getOriginClasses().isPrimitive()) {
- return "";
+ return false;
}
if (field.columnNotNull()) {
- return "";
+ return false;
}
- return ".optional()";
+ return true;
+ }
+
+ public String optionalTypeZod(final FieldProperty field) {
+ // Common checking element (apply to List, Map, ...)
+ if (isOptionalTypeZod(field)) {
+ return ".optional()";
+ }
+ return "";
+ }
+
+ public String optionalWriteTypeZod(final FieldProperty field) {
+ // Common checking element (apply to List, Map, ...)
+ if (isOptionalTypeZod(field)) {
+ return ".nullable()";
+ }
+ return "";
}
public String maxSizeZod(final FieldProperty field) {
@@ -270,7 +292,9 @@ public class TsClassElement {
out.append(getBaseHeader());
out.append(generateImports(model.getDependencyModels(), tsGroup));
out.append("\n");
-
+ // ------------------------------------------------------------------------
+ // -- Generate read mode
+ // ------------------------------------------------------------------------
out.append(generateComment(model));
out.append("export const ");
out.append(this.zodName);
@@ -315,27 +339,85 @@ public class TsClassElement {
out.append("\n});\n");
out.append(generateZodInfer(this.tsTypeName, this.zodName));
out.append(generateExportCheckFunctionWrite(""));
+ // check if we need to generate write mode :
+ if (!model.isNoWriteSpecificMode()) {
+ // ------------------------------------------------------------------------
+ // -- Generate write mode
+ // ------------------------------------------------------------------------
+ //out.append(generateComment(model));
+ out.append("export const ");
+ out.append(this.zodName);
+ out.append("Write = ");
- // Generate the Write Type associated.
- out.append("\nexport const ");
- out.append(this.zodName);
- out.append("Write = ");
- out.append(this.zodName);
- if (omitField.size() != 0) {
- out.append(".omit({\n");
- for (final String elem : omitField) {
- out.append("\t");
- out.append(elem);
- out.append(": true,\n");
+ if (model.getExtendsClass() != null) {
+ final ClassModel parentClass = model.getExtendsClass();
+ final TsClassElement tsParentModel = tsGroup.find(parentClass);
+ out.append(tsParentModel.zodName);
+ out.append("Write");
+ out.append(".extend({");
+ } else {
+ out.append("zod.object({");
}
- out.append("\n})");
+ out.append("\n");
+ for (final FieldProperty field : model.getFields()) {
+ // remove all readOnly field
+ if (field.readOnly()) {
+ continue;
+ }
+ final ClassModel fieldModel = field.model();
+ if (field.comment() != null) {
+ out.append("\t/**\n");
+ out.append("\t * ");
+ out.append(field.comment());
+ out.append("\n\t */\n");
+ }
+ out.append("\t");
+ out.append(field.name());
+ out.append(": ");
+ if (fieldModel instanceof ClassEnumModel || fieldModel instanceof ClassObjectModel) {
+ final TsClassElement tsFieldModel = tsGroup.find(fieldModel);
+ out.append(tsFieldModel.zodName);
+ } else if (fieldModel instanceof final ClassListModel fieldListModel) {
+ final String data = generateTsList(fieldListModel, tsGroup);
+ out.append(data);
+ } else if (fieldModel instanceof final ClassMapModel fieldMapModel) {
+ final String data = generateTsMap(fieldMapModel, tsGroup);
+ out.append(data);
+ }
+ out.append(maxSizeZod(field));
+ out.append(optionalWriteTypeZod(field));
+ // all write field are optional
+ if (field.model() instanceof final ClassObjectModel plop) {
+ if (!plop.isPrimitive()) {
+ out.append(".optional()");
+ }
+ } else {
+ out.append(".optional()");
+ }
+ out.append(",\n");
+ }
+ out.append("\n});\n");
+ out.append(generateZodInfer(this.tsTypeName + "Write", this.zodName + "Write"));
+ // Check only the input value ==> no need of the output
+ out.append(generateExportCheckFunctionWrite("Write"));
+ // Generate the Write Type associated.
+ /*
+ out.append("\nexport const ");
+ out.append(this.zodName);
+ out.append("Write = ");
+ out.append(this.zodName);
+ if (omitField.size() != 0) {
+ out.append(".omit({\n");
+ for (final String elem : omitField) {
+ out.append("\t");
+ out.append(elem);
+ out.append(": true,\n");
+ }
+ out.append("\n})");
+ }
+ out.append(".partial();\n");
+ */
}
- out.append(".partial();\n");
- out.append(generateZodInfer(this.tsTypeName + "Write", this.zodName + "Write"));
-
- // Check only the input value ==> no need of the output
- out.append(generateExportCheckFunctionWrite("Write"));
-
return out.toString();
}