@famgia/omnify-core 0.0.113 → 0.0.115
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/index.cjs +113 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +113 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -605,6 +605,8 @@ function parseJsonSchema(content, filePath) {
|
|
|
605
605
|
}
|
|
606
606
|
var VALID_SCHEMA_FIELDS = /* @__PURE__ */ new Set([
|
|
607
607
|
"kind",
|
|
608
|
+
"target",
|
|
609
|
+
// For partial schemas
|
|
608
610
|
"displayName",
|
|
609
611
|
"titleIndex",
|
|
610
612
|
"group",
|
|
@@ -641,6 +643,9 @@ function buildSchemaDefinition(data) {
|
|
|
641
643
|
if (data.kind !== void 0) {
|
|
642
644
|
schema.kind = data.kind;
|
|
643
645
|
}
|
|
646
|
+
if (data.target !== void 0 && typeof data.target === "string") {
|
|
647
|
+
schema.target = data.target;
|
|
648
|
+
}
|
|
644
649
|
if (data.displayName !== void 0 && (0, import_omnify_types.isLocalizedString)(data.displayName)) {
|
|
645
650
|
schema.displayName = data.displayName;
|
|
646
651
|
}
|
|
@@ -966,9 +971,14 @@ async function loadSchemas(directoryPath, options = {}) {
|
|
|
966
971
|
}
|
|
967
972
|
const schemaFiles = await findSchemaFiles(absoluteDir, extensions, recursive);
|
|
968
973
|
const schemas = {};
|
|
974
|
+
const partialSchemas = [];
|
|
969
975
|
const schemaLocations = {};
|
|
970
976
|
for (const filePath of schemaFiles) {
|
|
971
977
|
const schema = await loadSchema(filePath, { baseDir: absoluteDir });
|
|
978
|
+
if (schema.kind === "partial") {
|
|
979
|
+
partialSchemas.push(schema);
|
|
980
|
+
continue;
|
|
981
|
+
}
|
|
972
982
|
const existingLocation = schemaLocations[schema.name];
|
|
973
983
|
if (existingLocation !== void 0) {
|
|
974
984
|
throw duplicateSchemaError(
|
|
@@ -980,6 +990,26 @@ async function loadSchemas(directoryPath, options = {}) {
|
|
|
980
990
|
schemas[schema.name] = schema;
|
|
981
991
|
schemaLocations[schema.name] = filePath;
|
|
982
992
|
}
|
|
993
|
+
for (const partial of partialSchemas) {
|
|
994
|
+
const targetName = partial.target;
|
|
995
|
+
if (!targetName) {
|
|
996
|
+
console.warn(`Partial schema '${partial.name}' has no target, skipping`);
|
|
997
|
+
continue;
|
|
998
|
+
}
|
|
999
|
+
const target = schemas[targetName];
|
|
1000
|
+
if (!target) {
|
|
1001
|
+
console.warn(`Partial schema '${partial.name}' targets unknown schema '${targetName}', skipping`);
|
|
1002
|
+
continue;
|
|
1003
|
+
}
|
|
1004
|
+
const mergedProperties = {
|
|
1005
|
+
...partial.properties ?? {},
|
|
1006
|
+
...target.properties ?? {}
|
|
1007
|
+
};
|
|
1008
|
+
schemas[targetName] = {
|
|
1009
|
+
...target,
|
|
1010
|
+
properties: mergedProperties
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
983
1013
|
return schemas;
|
|
984
1014
|
}
|
|
985
1015
|
var FILE_SCHEMA_NAME = "File";
|
|
@@ -2831,6 +2861,62 @@ function validateEnumSchema(schema, filePath) {
|
|
|
2831
2861
|
}
|
|
2832
2862
|
return errors;
|
|
2833
2863
|
}
|
|
2864
|
+
function validatePartialSchema(schema, filePath) {
|
|
2865
|
+
const errors = [];
|
|
2866
|
+
if (schema.kind !== "partial") {
|
|
2867
|
+
return errors;
|
|
2868
|
+
}
|
|
2869
|
+
if (!schema.target) {
|
|
2870
|
+
errors.push(
|
|
2871
|
+
validationError(
|
|
2872
|
+
"Partial schema requires a target schema name",
|
|
2873
|
+
buildLocation7(filePath),
|
|
2874
|
+
"Add target: SchemaName to specify which schema to extend"
|
|
2875
|
+
)
|
|
2876
|
+
);
|
|
2877
|
+
} else if (typeof schema.target !== "string") {
|
|
2878
|
+
errors.push(
|
|
2879
|
+
validationError(
|
|
2880
|
+
"Partial schema target must be a string",
|
|
2881
|
+
buildLocation7(filePath),
|
|
2882
|
+
"Example: target: User"
|
|
2883
|
+
)
|
|
2884
|
+
);
|
|
2885
|
+
}
|
|
2886
|
+
if (!schema.properties || Object.keys(schema.properties).length === 0) {
|
|
2887
|
+
errors.push(
|
|
2888
|
+
validationError(
|
|
2889
|
+
"Partial schema requires at least one property to extend the target",
|
|
2890
|
+
buildLocation7(filePath),
|
|
2891
|
+
"Add properties to extend the target schema"
|
|
2892
|
+
)
|
|
2893
|
+
);
|
|
2894
|
+
}
|
|
2895
|
+
if (schema.values && schema.values.length > 0) {
|
|
2896
|
+
errors.push(
|
|
2897
|
+
validationError(
|
|
2898
|
+
"Partial schema cannot have values (values are for enum schemas)",
|
|
2899
|
+
buildLocation7(filePath),
|
|
2900
|
+
"Remove values or change kind to enum"
|
|
2901
|
+
)
|
|
2902
|
+
);
|
|
2903
|
+
}
|
|
2904
|
+
if (schema.options) {
|
|
2905
|
+
const invalidOptions = ["id", "timestamps", "softDelete", "tableName"];
|
|
2906
|
+
for (const opt of invalidOptions) {
|
|
2907
|
+
if (schema.options[opt] !== void 0) {
|
|
2908
|
+
errors.push(
|
|
2909
|
+
validationError(
|
|
2910
|
+
`Partial schema cannot have option '${opt}' (table options belong to the target schema)`,
|
|
2911
|
+
buildLocation7(filePath),
|
|
2912
|
+
`Remove options.${opt} - table-level options should be in the target schema`
|
|
2913
|
+
)
|
|
2914
|
+
);
|
|
2915
|
+
}
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2918
|
+
return errors;
|
|
2919
|
+
}
|
|
2834
2920
|
function validateLocalizedString(fieldName, value, filePath, localeConfig, context) {
|
|
2835
2921
|
const warnings = [];
|
|
2836
2922
|
if (value === void 0 || !(0, import_omnify_types2.isLocaleMap)(value)) {
|
|
@@ -2905,6 +2991,10 @@ function validateSchema(schema, options = {}) {
|
|
|
2905
2991
|
const enumErrors = validateEnumSchema(schema, schema.filePath);
|
|
2906
2992
|
errors.push(...enumErrors);
|
|
2907
2993
|
}
|
|
2994
|
+
if (schema.kind === "partial") {
|
|
2995
|
+
const partialErrors = validatePartialSchema(schema, schema.filePath);
|
|
2996
|
+
errors.push(...partialErrors);
|
|
2997
|
+
}
|
|
2908
2998
|
if (schema.titleIndex && schema.properties) {
|
|
2909
2999
|
if (!schema.properties[schema.titleIndex]) {
|
|
2910
3000
|
errors.push(
|
|
@@ -2981,6 +3071,29 @@ function validateSchemas(schemas, options = {}) {
|
|
|
2981
3071
|
}
|
|
2982
3072
|
}
|
|
2983
3073
|
}
|
|
3074
|
+
for (const schema of Object.values(schemas)) {
|
|
3075
|
+
if (schema.kind === "partial" && schema.target) {
|
|
3076
|
+
const targetExists = schemas[schema.target] !== void 0;
|
|
3077
|
+
if (!targetExists) {
|
|
3078
|
+
const error = validationError(
|
|
3079
|
+
`Partial schema '${schema.name}' targets non-existent schema '${schema.target}'`,
|
|
3080
|
+
buildLocation7(schema.filePath),
|
|
3081
|
+
`Available schemas: ${Object.keys(schemas).filter((n) => n !== schema.name).join(", ")}`
|
|
3082
|
+
);
|
|
3083
|
+
allErrors.push(error);
|
|
3084
|
+
const existingResult = schemaResults.find((r) => r.schemaName === schema.name);
|
|
3085
|
+
if (existingResult) {
|
|
3086
|
+
const updatedResult = {
|
|
3087
|
+
...existingResult,
|
|
3088
|
+
valid: false,
|
|
3089
|
+
errors: [...existingResult.errors, error]
|
|
3090
|
+
};
|
|
3091
|
+
const index = schemaResults.indexOf(existingResult);
|
|
3092
|
+
schemaResults[index] = updatedResult;
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
2984
3097
|
return {
|
|
2985
3098
|
valid: allErrors.length === 0,
|
|
2986
3099
|
errorCount: allErrors.length,
|