@interactive-inc/docs-client 0.0.9 → 0.0.10
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/PRODUCT.md +108 -0
- package/build/index.d.ts +107 -32
- package/build/index.js +872 -588
- package/build/models.d.ts +18 -2
- package/build/models.js +8 -1
- package/package.json +2 -2
package/build/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// lib/models.ts
|
|
2
|
-
import { z } from "zod
|
|
2
|
+
import { z } from "zod";
|
|
3
3
|
var zDocFilePath = z.object({
|
|
4
4
|
name: z.string(),
|
|
5
5
|
path: z.string(),
|
|
@@ -150,6 +150,11 @@ var zDocFileMdFrontMatter = z.record(
|
|
|
150
150
|
])
|
|
151
151
|
);
|
|
152
152
|
var zDocSchema = z.record(z.string(), zDocSchemaField);
|
|
153
|
+
var zDocSchemaFieldMinimal = z.object({
|
|
154
|
+
type: zDocSchemaFieldType,
|
|
155
|
+
required: z.boolean()
|
|
156
|
+
});
|
|
157
|
+
var zDocSchemaMinimal = z.record(z.string(), zDocSchemaFieldMinimal);
|
|
153
158
|
var zDocFileIndexFrontMatter = z.object({
|
|
154
159
|
type: z.literal("index-frontmatter"),
|
|
155
160
|
icon: z.string(),
|
|
@@ -829,16 +834,16 @@ var DocSchemaFieldNumberSingleValue = class {
|
|
|
829
834
|
}
|
|
830
835
|
};
|
|
831
836
|
|
|
832
|
-
// lib/values/doc-schema-field-
|
|
833
|
-
var
|
|
837
|
+
// lib/values/doc-schema-field-text-multiple-value.ts
|
|
838
|
+
var DocSchemaFieldTextMultipleValue = class {
|
|
834
839
|
constructor(key, value) {
|
|
835
840
|
this.key = key;
|
|
836
841
|
this.value = value;
|
|
842
|
+
Object.freeze(this);
|
|
837
843
|
Object.freeze(this.value);
|
|
838
|
-
if (this.value.default
|
|
844
|
+
if (this.value.default) {
|
|
839
845
|
Object.freeze(this.value.default);
|
|
840
846
|
}
|
|
841
|
-
Object.freeze(this);
|
|
842
847
|
}
|
|
843
848
|
get type() {
|
|
844
849
|
return this.value.type;
|
|
@@ -855,25 +860,22 @@ var DocSchemaFieldRelationMultipleValue = class {
|
|
|
855
860
|
get default() {
|
|
856
861
|
return this.value.default;
|
|
857
862
|
}
|
|
858
|
-
get path() {
|
|
859
|
-
return this.value.path;
|
|
860
|
-
}
|
|
861
863
|
isArray = true;
|
|
862
864
|
isSingle = false;
|
|
863
|
-
|
|
865
|
+
isText = true;
|
|
866
|
+
toJson() {
|
|
867
|
+
return { ...this.value };
|
|
868
|
+
}
|
|
864
869
|
/**
|
|
865
|
-
*
|
|
870
|
+
* 値の型を検証する
|
|
866
871
|
*/
|
|
867
872
|
validate(value) {
|
|
868
873
|
return Array.isArray(value) && value.every((v) => typeof v === "string");
|
|
869
874
|
}
|
|
870
|
-
toJson() {
|
|
871
|
-
return { ...this.value };
|
|
872
|
-
}
|
|
873
875
|
};
|
|
874
876
|
|
|
875
|
-
// lib/values/doc-schema-field-
|
|
876
|
-
var
|
|
877
|
+
// lib/values/doc-schema-field-text-single-value.ts
|
|
878
|
+
var DocSchemaFieldTextSingleValue = class {
|
|
877
879
|
constructor(key, value) {
|
|
878
880
|
this.key = key;
|
|
879
881
|
this.value = value;
|
|
@@ -894,12 +896,9 @@ var DocSchemaFieldRelationSingleValue = class {
|
|
|
894
896
|
get default() {
|
|
895
897
|
return this.value.default;
|
|
896
898
|
}
|
|
897
|
-
get path() {
|
|
898
|
-
return this.value.path;
|
|
899
|
-
}
|
|
900
899
|
isArray = false;
|
|
901
900
|
isSingle = true;
|
|
902
|
-
|
|
901
|
+
isText = true;
|
|
903
902
|
toJson() {
|
|
904
903
|
return { ...this.value };
|
|
905
904
|
}
|
|
@@ -911,17 +910,142 @@ var DocSchemaFieldRelationSingleValue = class {
|
|
|
911
910
|
}
|
|
912
911
|
};
|
|
913
912
|
|
|
914
|
-
// lib/values/doc-schema-
|
|
915
|
-
|
|
913
|
+
// lib/values/doc-schema-builder.ts
|
|
914
|
+
import { z as z2 } from "zod";
|
|
915
|
+
var DocSchemaBuilder = class {
|
|
916
|
+
/**
|
|
917
|
+
* 動的にZodスキーマを生成
|
|
918
|
+
*/
|
|
919
|
+
createDynamicSchema(value) {
|
|
920
|
+
if (typeof value !== "object" || value === null) {
|
|
921
|
+
throw new Error("Schema must be an object");
|
|
922
|
+
}
|
|
923
|
+
const schemaObj = value;
|
|
924
|
+
const zodFields = {};
|
|
925
|
+
for (const [key, field] of Object.entries(schemaObj)) {
|
|
926
|
+
if (typeof field !== "object" || field === null) {
|
|
927
|
+
throw new Error(`Field "${key}" must be an object`);
|
|
928
|
+
}
|
|
929
|
+
const fieldObj = field;
|
|
930
|
+
if (!("type" in fieldObj) || !("required" in fieldObj)) {
|
|
931
|
+
throw new Error(
|
|
932
|
+
`Field "${key}" must have "type" and "required" properties`
|
|
933
|
+
);
|
|
934
|
+
}
|
|
935
|
+
try {
|
|
936
|
+
zDocSchemaFieldMinimal.parse(fieldObj);
|
|
937
|
+
} catch (error) {
|
|
938
|
+
if (error instanceof Error) {
|
|
939
|
+
throw new Error(`Field "${key}": ${error.message}`);
|
|
940
|
+
}
|
|
941
|
+
throw error;
|
|
942
|
+
}
|
|
943
|
+
zodFields[key] = this.createFieldSchema(fieldObj.type);
|
|
944
|
+
}
|
|
945
|
+
return z2.object(zodFields);
|
|
946
|
+
}
|
|
947
|
+
/**
|
|
948
|
+
* フィールドタイプに応じたZodスキーマを生成
|
|
949
|
+
*/
|
|
950
|
+
createFieldSchema(type) {
|
|
951
|
+
const baseSchema = {
|
|
952
|
+
type: z2.literal(type),
|
|
953
|
+
required: z2.boolean(),
|
|
954
|
+
title: z2.string().nullable().optional(),
|
|
955
|
+
description: z2.string().nullable().optional()
|
|
956
|
+
};
|
|
957
|
+
if (type === "text") {
|
|
958
|
+
return z2.object({
|
|
959
|
+
...baseSchema,
|
|
960
|
+
default: z2.string().nullable().default("")
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
if (type === "number") {
|
|
964
|
+
return z2.object({
|
|
965
|
+
...baseSchema,
|
|
966
|
+
default: z2.number().nullable().default(0)
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
if (type === "boolean") {
|
|
970
|
+
return z2.object({
|
|
971
|
+
...baseSchema,
|
|
972
|
+
default: z2.boolean().nullable().default(false)
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
if (type === "multi-text") {
|
|
976
|
+
return z2.object({
|
|
977
|
+
...baseSchema,
|
|
978
|
+
default: z2.array(z2.string()).default([])
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
if (type === "multi-number") {
|
|
982
|
+
return z2.object({
|
|
983
|
+
...baseSchema,
|
|
984
|
+
default: z2.array(z2.number()).default([])
|
|
985
|
+
});
|
|
986
|
+
}
|
|
987
|
+
if (type === "multi-boolean") {
|
|
988
|
+
return z2.object({
|
|
989
|
+
...baseSchema,
|
|
990
|
+
default: z2.array(z2.boolean()).default([])
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
if (type === "relation") {
|
|
994
|
+
return z2.object({
|
|
995
|
+
...baseSchema,
|
|
996
|
+
path: z2.string().min(1),
|
|
997
|
+
default: z2.string().nullable().default(null)
|
|
998
|
+
});
|
|
999
|
+
}
|
|
1000
|
+
if (type === "multi-relation") {
|
|
1001
|
+
return z2.object({
|
|
1002
|
+
...baseSchema,
|
|
1003
|
+
path: z2.string().min(1),
|
|
1004
|
+
default: z2.array(z2.string()).nullable().default(null)
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
1007
|
+
if (type === "select-text") {
|
|
1008
|
+
return z2.object({
|
|
1009
|
+
...baseSchema,
|
|
1010
|
+
options: z2.array(z2.string()),
|
|
1011
|
+
default: z2.string().nullable().default(null)
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
if (type === "select-number") {
|
|
1015
|
+
return z2.object({
|
|
1016
|
+
...baseSchema,
|
|
1017
|
+
options: z2.array(z2.number()),
|
|
1018
|
+
default: z2.number().nullable().default(null)
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
if (type === "multi-select-text") {
|
|
1022
|
+
return z2.object({
|
|
1023
|
+
...baseSchema,
|
|
1024
|
+
options: z2.array(z2.string()),
|
|
1025
|
+
default: z2.array(z2.string()).nullable().default(null)
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
if (type === "multi-select-number") {
|
|
1029
|
+
return z2.object({
|
|
1030
|
+
...baseSchema,
|
|
1031
|
+
options: z2.array(z2.number()),
|
|
1032
|
+
default: z2.array(z2.number()).nullable().default(null)
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
1035
|
+
throw new Error(`Unknown field type: ${type}`);
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
// lib/values/doc-schema-field-relation-multiple-value.ts
|
|
1040
|
+
var DocSchemaFieldRelationMultipleValue = class {
|
|
916
1041
|
constructor(key, value) {
|
|
917
1042
|
this.key = key;
|
|
918
1043
|
this.value = value;
|
|
919
|
-
Object.freeze(this);
|
|
920
1044
|
Object.freeze(this.value);
|
|
921
|
-
Object.freeze(this.value.options);
|
|
922
1045
|
if (this.value.default && Array.isArray(this.value.default)) {
|
|
923
1046
|
Object.freeze(this.value.default);
|
|
924
1047
|
}
|
|
1048
|
+
Object.freeze(this);
|
|
925
1049
|
}
|
|
926
1050
|
get type() {
|
|
927
1051
|
return this.value.type;
|
|
@@ -938,32 +1062,29 @@ var DocSchemaFieldSelectNumberMultipleValue = class {
|
|
|
938
1062
|
get default() {
|
|
939
1063
|
return this.value.default;
|
|
940
1064
|
}
|
|
941
|
-
get
|
|
942
|
-
return this.value.
|
|
1065
|
+
get path() {
|
|
1066
|
+
return this.value.path;
|
|
943
1067
|
}
|
|
944
1068
|
isArray = true;
|
|
945
1069
|
isSingle = false;
|
|
946
|
-
|
|
947
|
-
isNumberSelect = true;
|
|
1070
|
+
isRelation = true;
|
|
948
1071
|
/**
|
|
949
1072
|
* 値を検証する
|
|
950
1073
|
*/
|
|
951
1074
|
validate(value) {
|
|
952
|
-
return Array.isArray(value) && value.every((v) => typeof v === "
|
|
1075
|
+
return Array.isArray(value) && value.every((v) => typeof v === "string");
|
|
953
1076
|
}
|
|
954
1077
|
toJson() {
|
|
955
1078
|
return { ...this.value };
|
|
956
1079
|
}
|
|
957
1080
|
};
|
|
958
1081
|
|
|
959
|
-
// lib/values/doc-schema-field-
|
|
960
|
-
var
|
|
1082
|
+
// lib/values/doc-schema-field-relation-single-value.ts
|
|
1083
|
+
var DocSchemaFieldRelationSingleValue = class {
|
|
961
1084
|
constructor(key, value) {
|
|
962
1085
|
this.key = key;
|
|
963
1086
|
this.value = value;
|
|
964
1087
|
Object.freeze(this);
|
|
965
|
-
Object.freeze(this.value);
|
|
966
|
-
Object.freeze(this.value.options);
|
|
967
1088
|
}
|
|
968
1089
|
get type() {
|
|
969
1090
|
return this.value.type;
|
|
@@ -980,26 +1101,25 @@ var DocSchemaFieldSelectNumberSingleValue = class {
|
|
|
980
1101
|
get default() {
|
|
981
1102
|
return this.value.default;
|
|
982
1103
|
}
|
|
983
|
-
get
|
|
984
|
-
return this.value.
|
|
1104
|
+
get path() {
|
|
1105
|
+
return this.value.path;
|
|
985
1106
|
}
|
|
986
1107
|
isArray = false;
|
|
987
1108
|
isSingle = true;
|
|
988
|
-
|
|
989
|
-
|
|
1109
|
+
isRelation = true;
|
|
1110
|
+
toJson() {
|
|
1111
|
+
return { ...this.value };
|
|
1112
|
+
}
|
|
990
1113
|
/**
|
|
991
|
-
*
|
|
1114
|
+
* 値の型を検証する
|
|
992
1115
|
*/
|
|
993
1116
|
validate(value) {
|
|
994
|
-
return typeof value === "
|
|
995
|
-
}
|
|
996
|
-
toJson() {
|
|
997
|
-
return { ...this.value };
|
|
1117
|
+
return typeof value === "string";
|
|
998
1118
|
}
|
|
999
1119
|
};
|
|
1000
1120
|
|
|
1001
|
-
// lib/values/doc-schema-field-select-
|
|
1002
|
-
var
|
|
1121
|
+
// lib/values/doc-schema-field-select-number-multiple-value.ts
|
|
1122
|
+
var DocSchemaFieldSelectNumberMultipleValue = class {
|
|
1003
1123
|
constructor(key, value) {
|
|
1004
1124
|
this.key = key;
|
|
1005
1125
|
this.value = value;
|
|
@@ -1031,28 +1151,26 @@ var DocSchemaFieldSelectTextMultipleValue = class {
|
|
|
1031
1151
|
isArray = true;
|
|
1032
1152
|
isSingle = false;
|
|
1033
1153
|
isSelect = true;
|
|
1034
|
-
|
|
1154
|
+
isNumberSelect = true;
|
|
1035
1155
|
/**
|
|
1036
1156
|
* 値を検証する
|
|
1037
1157
|
*/
|
|
1038
1158
|
validate(value) {
|
|
1039
|
-
return Array.isArray(value) && value.every((v) => typeof v === "
|
|
1159
|
+
return Array.isArray(value) && value.every((v) => typeof v === "number");
|
|
1040
1160
|
}
|
|
1041
1161
|
toJson() {
|
|
1042
1162
|
return { ...this.value };
|
|
1043
1163
|
}
|
|
1044
1164
|
};
|
|
1045
1165
|
|
|
1046
|
-
// lib/values/doc-schema-field-select-
|
|
1047
|
-
var
|
|
1166
|
+
// lib/values/doc-schema-field-select-number-single-value.ts
|
|
1167
|
+
var DocSchemaFieldSelectNumberSingleValue = class {
|
|
1048
1168
|
constructor(key, value) {
|
|
1049
1169
|
this.key = key;
|
|
1050
1170
|
this.value = value;
|
|
1051
|
-
if (this.value.options) {
|
|
1052
|
-
Object.freeze(this.value.options);
|
|
1053
|
-
}
|
|
1054
|
-
Object.freeze(this.value);
|
|
1055
1171
|
Object.freeze(this);
|
|
1172
|
+
Object.freeze(this.value);
|
|
1173
|
+
Object.freeze(this.value.options);
|
|
1056
1174
|
}
|
|
1057
1175
|
get type() {
|
|
1058
1176
|
return this.value.type;
|
|
@@ -1075,26 +1193,27 @@ var DocSchemaFieldSelectTextSingleValue = class {
|
|
|
1075
1193
|
isArray = false;
|
|
1076
1194
|
isSingle = true;
|
|
1077
1195
|
isSelect = true;
|
|
1078
|
-
|
|
1079
|
-
toJson() {
|
|
1080
|
-
return { ...this.value };
|
|
1081
|
-
}
|
|
1196
|
+
isNumberSelect = true;
|
|
1082
1197
|
/**
|
|
1083
|
-
*
|
|
1198
|
+
* 値を検証する
|
|
1084
1199
|
*/
|
|
1085
1200
|
validate(value) {
|
|
1086
|
-
return typeof value === "
|
|
1201
|
+
return typeof value === "number";
|
|
1202
|
+
}
|
|
1203
|
+
toJson() {
|
|
1204
|
+
return { ...this.value };
|
|
1087
1205
|
}
|
|
1088
1206
|
};
|
|
1089
1207
|
|
|
1090
|
-
// lib/values/doc-schema-field-text-multiple-value.ts
|
|
1091
|
-
var
|
|
1208
|
+
// lib/values/doc-schema-field-select-text-multiple-value.ts
|
|
1209
|
+
var DocSchemaFieldSelectTextMultipleValue = class {
|
|
1092
1210
|
constructor(key, value) {
|
|
1093
1211
|
this.key = key;
|
|
1094
1212
|
this.value = value;
|
|
1095
1213
|
Object.freeze(this);
|
|
1096
1214
|
Object.freeze(this.value);
|
|
1097
|
-
|
|
1215
|
+
Object.freeze(this.value.options);
|
|
1216
|
+
if (this.value.default && Array.isArray(this.value.default)) {
|
|
1098
1217
|
Object.freeze(this.value.default);
|
|
1099
1218
|
}
|
|
1100
1219
|
}
|
|
@@ -1113,25 +1232,33 @@ var DocSchemaFieldTextMultipleValue = class {
|
|
|
1113
1232
|
get default() {
|
|
1114
1233
|
return this.value.default;
|
|
1115
1234
|
}
|
|
1235
|
+
get options() {
|
|
1236
|
+
return this.value.options;
|
|
1237
|
+
}
|
|
1116
1238
|
isArray = true;
|
|
1117
1239
|
isSingle = false;
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
return { ...this.value };
|
|
1121
|
-
}
|
|
1240
|
+
isSelect = true;
|
|
1241
|
+
isTextSelect = true;
|
|
1122
1242
|
/**
|
|
1123
|
-
*
|
|
1243
|
+
* 値を検証する
|
|
1124
1244
|
*/
|
|
1125
1245
|
validate(value) {
|
|
1126
1246
|
return Array.isArray(value) && value.every((v) => typeof v === "string");
|
|
1127
1247
|
}
|
|
1248
|
+
toJson() {
|
|
1249
|
+
return { ...this.value };
|
|
1250
|
+
}
|
|
1128
1251
|
};
|
|
1129
1252
|
|
|
1130
|
-
// lib/values/doc-schema-field-text-single-value.ts
|
|
1131
|
-
var
|
|
1253
|
+
// lib/values/doc-schema-field-select-text-single-value.ts
|
|
1254
|
+
var DocSchemaFieldSelectTextSingleValue = class {
|
|
1132
1255
|
constructor(key, value) {
|
|
1133
1256
|
this.key = key;
|
|
1134
1257
|
this.value = value;
|
|
1258
|
+
if (this.value.options) {
|
|
1259
|
+
Object.freeze(this.value.options);
|
|
1260
|
+
}
|
|
1261
|
+
Object.freeze(this.value);
|
|
1135
1262
|
Object.freeze(this);
|
|
1136
1263
|
}
|
|
1137
1264
|
get type() {
|
|
@@ -1149,9 +1276,13 @@ var DocSchemaFieldTextSingleValue = class {
|
|
|
1149
1276
|
get default() {
|
|
1150
1277
|
return this.value.default;
|
|
1151
1278
|
}
|
|
1279
|
+
get options() {
|
|
1280
|
+
return this.value.options;
|
|
1281
|
+
}
|
|
1152
1282
|
isArray = false;
|
|
1153
1283
|
isSingle = true;
|
|
1154
|
-
|
|
1284
|
+
isSelect = true;
|
|
1285
|
+
isTextSelect = true;
|
|
1155
1286
|
toJson() {
|
|
1156
1287
|
return { ...this.value };
|
|
1157
1288
|
}
|
|
@@ -1402,101 +1533,367 @@ var DocSchemaFieldFactory = class {
|
|
|
1402
1533
|
}
|
|
1403
1534
|
};
|
|
1404
1535
|
|
|
1405
|
-
// lib/values/doc-
|
|
1406
|
-
var
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1536
|
+
// lib/values/doc-schema-value.ts
|
|
1537
|
+
var DocSchemaValue = class _DocSchemaValue {
|
|
1538
|
+
value;
|
|
1539
|
+
zodSchema;
|
|
1540
|
+
constructor(value, zodSchema, schemaBuilder) {
|
|
1541
|
+
this.zodSchema = zodSchema || null;
|
|
1542
|
+
const builder = schemaBuilder || new DocSchemaBuilder();
|
|
1543
|
+
if (this.zodSchema) {
|
|
1544
|
+
const parsed = this.zodSchema.parse(value);
|
|
1545
|
+
this.value = _DocSchemaValue.normalizeSchema(parsed);
|
|
1546
|
+
} else {
|
|
1547
|
+
const dynamicSchema = builder.createDynamicSchema(value);
|
|
1548
|
+
const parsed = dynamicSchema.parse(value);
|
|
1549
|
+
this.value = _DocSchemaValue.normalizeSchema(parsed);
|
|
1550
|
+
}
|
|
1551
|
+
zDocSchema.parse(this.value);
|
|
1552
|
+
Object.freeze(this.value);
|
|
1410
1553
|
Object.freeze(this);
|
|
1411
1554
|
}
|
|
1412
|
-
toJson() {
|
|
1413
|
-
return this.value;
|
|
1414
|
-
}
|
|
1415
|
-
toYaml() {
|
|
1416
|
-
return stringify2(this.value).trim();
|
|
1417
|
-
}
|
|
1418
1555
|
/**
|
|
1419
|
-
*
|
|
1556
|
+
* フィールド名の一覧を取得
|
|
1557
|
+
* Zodスキーマを使用している場合は自動的に型安全
|
|
1420
1558
|
*/
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1559
|
+
get fieldNames() {
|
|
1560
|
+
return Object.keys(this.value);
|
|
1561
|
+
}
|
|
1562
|
+
field(name) {
|
|
1563
|
+
const fieldDef = this.value[name];
|
|
1564
|
+
if (fieldDef === void 0) {
|
|
1565
|
+
return null;
|
|
1566
|
+
}
|
|
1567
|
+
const factory = new DocSchemaFieldFactory();
|
|
1568
|
+
return factory.fromUnknown(name, fieldDef);
|
|
1426
1569
|
}
|
|
1427
1570
|
/**
|
|
1428
|
-
*
|
|
1571
|
+
* すべてのフィールドを取得
|
|
1572
|
+
* 注意: 型安全性のため、個別にfield()メソッドを使用することを推奨
|
|
1429
1573
|
*/
|
|
1430
|
-
|
|
1431
|
-
|
|
1574
|
+
get fields() {
|
|
1575
|
+
const factory = new DocSchemaFieldFactory();
|
|
1576
|
+
return this.fieldNames.map((name) => {
|
|
1577
|
+
const fieldValue = this.value[name];
|
|
1578
|
+
if (!fieldValue) {
|
|
1579
|
+
throw new Error(`Field ${name} not found in schema`);
|
|
1580
|
+
}
|
|
1581
|
+
return factory.fromUnknown(name, fieldValue);
|
|
1582
|
+
});
|
|
1583
|
+
}
|
|
1584
|
+
get relationFields() {
|
|
1585
|
+
return this.fields.filter((t) => {
|
|
1586
|
+
return t instanceof DocSchemaFieldRelationSingleValue || t instanceof DocSchemaFieldRelationMultipleValue;
|
|
1587
|
+
});
|
|
1432
1588
|
}
|
|
1433
1589
|
/**
|
|
1434
|
-
*
|
|
1590
|
+
* 空のスキーマエンティティを作成
|
|
1435
1591
|
*/
|
|
1436
|
-
static
|
|
1437
|
-
|
|
1438
|
-
return new _DocFrontMatterMdValue(validatedData);
|
|
1592
|
+
static empty(zodSchema, dynamicBuilder) {
|
|
1593
|
+
return new _DocSchemaValue({}, zodSchema, dynamicBuilder);
|
|
1439
1594
|
}
|
|
1440
1595
|
/**
|
|
1441
|
-
*
|
|
1596
|
+
* スキーマからリレーションパスを抽出
|
|
1442
1597
|
*/
|
|
1443
|
-
|
|
1444
|
-
if (
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
if (fieldDef.type === "number") {
|
|
1451
|
-
return fieldDef.default ?? 0;
|
|
1452
|
-
}
|
|
1453
|
-
if (fieldDef.type === "multi-text" || fieldDef.type === "multi-number" || fieldDef.type === "multi-boolean" || fieldDef.type === "multi-relation") {
|
|
1454
|
-
return fieldDef.default ?? [];
|
|
1455
|
-
}
|
|
1456
|
-
if (fieldDef.type === "relation") {
|
|
1457
|
-
return fieldDef.default ?? null;
|
|
1598
|
+
extractRelationPaths() {
|
|
1599
|
+
if (!this.value) return /* @__PURE__ */ new Set();
|
|
1600
|
+
const uniqueRelationPaths = /* @__PURE__ */ new Set();
|
|
1601
|
+
for (const field of Object.values(this.value)) {
|
|
1602
|
+
if (this.isRelationField(field) && "path" in field) {
|
|
1603
|
+
uniqueRelationPaths.add(field.path);
|
|
1604
|
+
}
|
|
1458
1605
|
}
|
|
1459
|
-
return
|
|
1606
|
+
return uniqueRelationPaths;
|
|
1460
1607
|
}
|
|
1461
1608
|
/**
|
|
1462
|
-
*
|
|
1463
|
-
* スキーマに基づいて型を検証し、スキーマのフィールドのみを含む新しいインスタンスを生成
|
|
1609
|
+
* フィールドがリレーション型かどうかを判定
|
|
1464
1610
|
*/
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1611
|
+
isRelationField(field) {
|
|
1612
|
+
return field.type === "relation" || field.type === "multi-relation";
|
|
1613
|
+
}
|
|
1614
|
+
/**
|
|
1615
|
+
* リレーションオプションを作成
|
|
1616
|
+
*/
|
|
1617
|
+
createRelationOption(filePath, title) {
|
|
1618
|
+
const fileName = this.extractFileName(filePath);
|
|
1619
|
+
return zDocRelationFile.parse({
|
|
1620
|
+
name: fileName,
|
|
1621
|
+
label: title || fileName,
|
|
1622
|
+
value: fileName,
|
|
1623
|
+
path: filePath
|
|
1624
|
+
});
|
|
1625
|
+
}
|
|
1626
|
+
/**
|
|
1627
|
+
* ファイルをスキップすべきかどうかを判定
|
|
1628
|
+
*/
|
|
1629
|
+
shouldSkipFile(filePath) {
|
|
1630
|
+
return filePath.endsWith("index.md") || filePath.endsWith("README.md");
|
|
1631
|
+
}
|
|
1632
|
+
/**
|
|
1633
|
+
* 値を指定された型に変換する(デフォルト値フォールバック付き)
|
|
1634
|
+
*/
|
|
1635
|
+
convertValue(value, targetType, defaultValue) {
|
|
1636
|
+
if (this.isNullOrUndefined(value)) {
|
|
1637
|
+
return defaultValue;
|
|
1470
1638
|
}
|
|
1471
|
-
|
|
1472
|
-
return this;
|
|
1639
|
+
try {
|
|
1640
|
+
return this.convertByType(value, targetType, defaultValue);
|
|
1641
|
+
} catch {
|
|
1642
|
+
return defaultValue;
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
/**
|
|
1646
|
+
* 型別の変換処理
|
|
1647
|
+
*/
|
|
1648
|
+
convertByType(value, targetType, defaultValue) {
|
|
1649
|
+
if (targetType === "text") {
|
|
1650
|
+
return this.convertToString(value, defaultValue);
|
|
1651
|
+
}
|
|
1652
|
+
if (targetType === "number") {
|
|
1653
|
+
return this.convertToNumber(value, defaultValue);
|
|
1654
|
+
}
|
|
1655
|
+
if (targetType === "boolean") {
|
|
1656
|
+
return this.convertToBoolean(value, defaultValue);
|
|
1657
|
+
}
|
|
1658
|
+
if (targetType === "multi-text" || targetType === "array") {
|
|
1659
|
+
return this.convertToArray(value, defaultValue);
|
|
1660
|
+
}
|
|
1661
|
+
if (targetType === "relation") {
|
|
1662
|
+
return this.convertToRelation(value, defaultValue);
|
|
1663
|
+
}
|
|
1664
|
+
if (targetType === "multi-relation") {
|
|
1665
|
+
return this.convertToMultiRelation(value, defaultValue);
|
|
1666
|
+
}
|
|
1667
|
+
return defaultValue;
|
|
1668
|
+
}
|
|
1669
|
+
/**
|
|
1670
|
+
* 文字列型への変換
|
|
1671
|
+
*/
|
|
1672
|
+
convertToString(value, defaultValue) {
|
|
1673
|
+
if (typeof value === "string") return value;
|
|
1674
|
+
if (typeof value === "number") return String(value);
|
|
1675
|
+
if (typeof value === "boolean") return String(value);
|
|
1676
|
+
return defaultValue;
|
|
1677
|
+
}
|
|
1678
|
+
/**
|
|
1679
|
+
* 数値型への変換
|
|
1680
|
+
*/
|
|
1681
|
+
convertToNumber(value, defaultValue) {
|
|
1682
|
+
if (typeof value === "number") return value;
|
|
1683
|
+
if (typeof value === "string") {
|
|
1684
|
+
const parsed = Number(value);
|
|
1685
|
+
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
1686
|
+
}
|
|
1687
|
+
if (typeof value === "boolean") return value ? 1 : 0;
|
|
1688
|
+
return defaultValue;
|
|
1689
|
+
}
|
|
1690
|
+
/**
|
|
1691
|
+
* ブール型への変換
|
|
1692
|
+
*/
|
|
1693
|
+
convertToBoolean(value, defaultValue) {
|
|
1694
|
+
if (typeof value === "boolean") return value;
|
|
1695
|
+
if (typeof value === "string") {
|
|
1696
|
+
const lower = value.toLowerCase();
|
|
1697
|
+
if (lower === "true" || lower === "1") return true;
|
|
1698
|
+
if (lower === "false" || lower === "0") return false;
|
|
1699
|
+
return defaultValue;
|
|
1700
|
+
}
|
|
1701
|
+
if (typeof value === "number") return value !== 0;
|
|
1702
|
+
return defaultValue;
|
|
1703
|
+
}
|
|
1704
|
+
/**
|
|
1705
|
+
* 配列型への変換
|
|
1706
|
+
*/
|
|
1707
|
+
convertToArray(value, defaultValue) {
|
|
1708
|
+
if (Array.isArray(value)) return value;
|
|
1709
|
+
if (typeof value === "string") {
|
|
1710
|
+
return value.split(",").map((item) => item.trim());
|
|
1711
|
+
}
|
|
1712
|
+
return defaultValue;
|
|
1713
|
+
}
|
|
1714
|
+
/**
|
|
1715
|
+
* リレーション型への変換
|
|
1716
|
+
*/
|
|
1717
|
+
convertToRelation(value, defaultValue) {
|
|
1718
|
+
if (typeof value === "string") {
|
|
1719
|
+
return this.extractFileNameFromPath(value);
|
|
1720
|
+
}
|
|
1721
|
+
return defaultValue;
|
|
1722
|
+
}
|
|
1723
|
+
/**
|
|
1724
|
+
* マルチリレーション型への変換
|
|
1725
|
+
*/
|
|
1726
|
+
convertToMultiRelation(value, defaultValue) {
|
|
1727
|
+
if (Array.isArray(value)) {
|
|
1728
|
+
return value.filter((item) => typeof item === "string").map((item) => this.extractFileNameFromPath(item));
|
|
1729
|
+
}
|
|
1730
|
+
if (typeof value === "string") {
|
|
1731
|
+
return value.split(",").map((item) => this.extractFileNameFromPath(item.trim()));
|
|
1732
|
+
}
|
|
1733
|
+
return defaultValue;
|
|
1734
|
+
}
|
|
1735
|
+
/**
|
|
1736
|
+
* パスからファイル名を抽出(拡張子除去)
|
|
1737
|
+
*/
|
|
1738
|
+
extractFileNameFromPath(path) {
|
|
1739
|
+
const fileName = path.split("/").pop() || path;
|
|
1740
|
+
return fileName.replace(/\.md$/, "");
|
|
1741
|
+
}
|
|
1742
|
+
/**
|
|
1743
|
+
* スキーマベースでFrontMatterを補完する
|
|
1744
|
+
*/
|
|
1745
|
+
getCompleteFrontMatter(rawFrontMatter) {
|
|
1746
|
+
const defaultFrontMatter = this.generateDefaultFrontMatter();
|
|
1747
|
+
return this.mergePreservingExistingValues(
|
|
1748
|
+
defaultFrontMatter,
|
|
1749
|
+
rawFrontMatter
|
|
1750
|
+
);
|
|
1751
|
+
}
|
|
1752
|
+
/**
|
|
1753
|
+
* 型安全にFrontMatterを補完する(Zodスキーマを使用している場合)
|
|
1754
|
+
*/
|
|
1755
|
+
getTypedCompleteFrontMatter(rawFrontMatter) {
|
|
1756
|
+
if (!this.zodSchema) {
|
|
1757
|
+
throw new Error("Typed method requires a Zod schema");
|
|
1758
|
+
}
|
|
1759
|
+
const defaultFrontMatter = this.generateDefaultFrontMatter();
|
|
1760
|
+
const merged = this.mergePreservingExistingValues(
|
|
1761
|
+
defaultFrontMatter,
|
|
1762
|
+
rawFrontMatter
|
|
1763
|
+
);
|
|
1764
|
+
return this.zodSchema.parse(merged);
|
|
1765
|
+
}
|
|
1766
|
+
/**
|
|
1767
|
+
* スキーマからデフォルトFrontMatterを生成
|
|
1768
|
+
*/
|
|
1769
|
+
generateDefaultFrontMatter() {
|
|
1770
|
+
if (!this.value) return {};
|
|
1771
|
+
const defaultFrontMatter = {};
|
|
1772
|
+
for (const [key, field] of Object.entries(this.value)) {
|
|
1773
|
+
defaultFrontMatter[key] = DocFrontMatterMdValue.generateDefaultValueFromSchemaField(field);
|
|
1473
1774
|
}
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1775
|
+
return zDocFileMdFrontMatter.parse(defaultFrontMatter);
|
|
1776
|
+
}
|
|
1777
|
+
/**
|
|
1778
|
+
* 既存の値を保持しながらマージ
|
|
1779
|
+
*/
|
|
1780
|
+
mergePreservingExistingValues(defaults, existing) {
|
|
1781
|
+
const result = { ...defaults };
|
|
1782
|
+
if (existing && typeof existing === "object") {
|
|
1783
|
+
const validatedData = zDocFileMdFrontMatter.parse(existing);
|
|
1784
|
+
for (const [key, value] of Object.entries(validatedData)) {
|
|
1785
|
+
if (value !== void 0 && value !== null) {
|
|
1786
|
+
result[key] = value;
|
|
1483
1787
|
}
|
|
1484
|
-
} else {
|
|
1485
|
-
draft[fieldKey] = field.toJson().default;
|
|
1486
1788
|
}
|
|
1487
1789
|
}
|
|
1488
|
-
return
|
|
1790
|
+
return result;
|
|
1791
|
+
}
|
|
1792
|
+
/**
|
|
1793
|
+
* ファイルパスからファイル名を抽出(拡張子なし)
|
|
1794
|
+
*/
|
|
1795
|
+
extractFileName(filePath) {
|
|
1796
|
+
return filePath.split("/").pop()?.replace(".md", "") || filePath;
|
|
1797
|
+
}
|
|
1798
|
+
/**
|
|
1799
|
+
* nullまundefinedのチェック
|
|
1800
|
+
*/
|
|
1801
|
+
isNullOrUndefined(value) {
|
|
1802
|
+
return value === null || value === void 0;
|
|
1803
|
+
}
|
|
1804
|
+
toJson() {
|
|
1805
|
+
return this.value;
|
|
1806
|
+
}
|
|
1807
|
+
/**
|
|
1808
|
+
* スキーマを正規化(エラーを出すように変更)
|
|
1809
|
+
*/
|
|
1810
|
+
static normalizeSchema(schema) {
|
|
1811
|
+
if (typeof schema !== "object" || schema === null) {
|
|
1812
|
+
throw new Error("Schema must be an object");
|
|
1813
|
+
}
|
|
1814
|
+
const normalized = {};
|
|
1815
|
+
const factory = new DocSchemaFieldFactory();
|
|
1816
|
+
for (const [key, field] of Object.entries(schema)) {
|
|
1817
|
+
const normalizedField = factory.fromUnknown(key, field);
|
|
1818
|
+
normalized[key] = normalizedField.toJson();
|
|
1819
|
+
}
|
|
1820
|
+
return normalized;
|
|
1821
|
+
}
|
|
1822
|
+
};
|
|
1823
|
+
|
|
1824
|
+
// lib/values/doc-front-matter-md-value.ts
|
|
1825
|
+
var DocFrontMatterMdValue = class _DocFrontMatterMdValue {
|
|
1826
|
+
zodSchema;
|
|
1827
|
+
constructor(value, zodSchema) {
|
|
1828
|
+
this.value = zodSchema.parse(value);
|
|
1829
|
+
this.zodSchema = zodSchema;
|
|
1830
|
+
Object.freeze(this.value);
|
|
1831
|
+
Object.freeze(this);
|
|
1832
|
+
}
|
|
1833
|
+
value;
|
|
1834
|
+
toJson() {
|
|
1835
|
+
return this.value;
|
|
1836
|
+
}
|
|
1837
|
+
toYaml() {
|
|
1838
|
+
return stringify2(this.value).trim();
|
|
1839
|
+
}
|
|
1840
|
+
schema(zodSchema) {
|
|
1841
|
+
return new DocSchemaValue(this.value.schema, zodSchema);
|
|
1842
|
+
}
|
|
1843
|
+
/**
|
|
1844
|
+
* Markdownテキストから生成
|
|
1845
|
+
*/
|
|
1846
|
+
static from(markdownText, zodSchema) {
|
|
1847
|
+
const openMarkdown = new DocContentMdValue(markdownText);
|
|
1848
|
+
const rawData = openMarkdown.frontMatter.data || {};
|
|
1849
|
+
return new _DocFrontMatterMdValue(rawData, zodSchema);
|
|
1850
|
+
}
|
|
1851
|
+
/**
|
|
1852
|
+
* 空のFrontMatterを生成
|
|
1853
|
+
*/
|
|
1854
|
+
static empty(zodSchema) {
|
|
1855
|
+
return new _DocFrontMatterMdValue({}, zodSchema);
|
|
1856
|
+
}
|
|
1857
|
+
/**
|
|
1858
|
+
* データから直接生成
|
|
1859
|
+
*/
|
|
1860
|
+
static fromData(data, zodSchema) {
|
|
1861
|
+
return new _DocFrontMatterMdValue(data, zodSchema);
|
|
1862
|
+
}
|
|
1863
|
+
/**
|
|
1864
|
+
* スキーマフィールドに基づいてデフォルト値を生成する
|
|
1865
|
+
*/
|
|
1866
|
+
static generateDefaultValueFromSchemaField(fieldDef) {
|
|
1867
|
+
if (fieldDef.type === "text") {
|
|
1868
|
+
return fieldDef.default ?? "";
|
|
1869
|
+
}
|
|
1870
|
+
if (fieldDef.type === "boolean") {
|
|
1871
|
+
return fieldDef.default ?? false;
|
|
1872
|
+
}
|
|
1873
|
+
if (fieldDef.type === "number") {
|
|
1874
|
+
return fieldDef.default ?? 0;
|
|
1875
|
+
}
|
|
1876
|
+
if (fieldDef.type === "multi-text" || fieldDef.type === "multi-number" || fieldDef.type === "multi-boolean" || fieldDef.type === "multi-relation") {
|
|
1877
|
+
return fieldDef.default ?? [];
|
|
1878
|
+
}
|
|
1879
|
+
if (fieldDef.type === "relation") {
|
|
1880
|
+
return fieldDef.default ?? null;
|
|
1881
|
+
}
|
|
1882
|
+
return null;
|
|
1489
1883
|
}
|
|
1490
1884
|
/**
|
|
1491
|
-
*
|
|
1885
|
+
* 単一のプロパティを更新した新しいインスタンスを返す
|
|
1492
1886
|
*/
|
|
1493
|
-
|
|
1887
|
+
withProperty(key, value) {
|
|
1888
|
+
const currentData = {
|
|
1889
|
+
...this.toJson(),
|
|
1890
|
+
[key]: value
|
|
1891
|
+
};
|
|
1494
1892
|
try {
|
|
1495
|
-
const
|
|
1496
|
-
|
|
1497
|
-
return schemaField.validate(value);
|
|
1893
|
+
const validated = this.zodSchema.parse(currentData);
|
|
1894
|
+
return new _DocFrontMatterMdValue(validated, this.zodSchema);
|
|
1498
1895
|
} catch {
|
|
1499
|
-
return
|
|
1896
|
+
return this;
|
|
1500
1897
|
}
|
|
1501
1898
|
}
|
|
1502
1899
|
/**
|
|
@@ -1615,7 +2012,7 @@ var DocFrontMatterMdValue = class _DocFrontMatterMdValue {
|
|
|
1615
2012
|
* プロパティが存在するかチェック
|
|
1616
2013
|
*/
|
|
1617
2014
|
has(key) {
|
|
1618
|
-
return key in this.value && this.value[key] !== void 0;
|
|
2015
|
+
return key in this.value && this.value[key] !== void 0 && this.value[key] !== null;
|
|
1619
2016
|
}
|
|
1620
2017
|
/**
|
|
1621
2018
|
* すべてのキーを取得
|
|
@@ -1623,15 +2020,35 @@ var DocFrontMatterMdValue = class _DocFrontMatterMdValue {
|
|
|
1623
2020
|
get keys() {
|
|
1624
2021
|
return Object.keys(this.value);
|
|
1625
2022
|
}
|
|
1626
|
-
|
|
1627
|
-
|
|
2023
|
+
field(key) {
|
|
2024
|
+
try {
|
|
2025
|
+
const parsed = this.zodSchema.parse(this.value);
|
|
2026
|
+
return parsed[key] ?? null;
|
|
2027
|
+
} catch {
|
|
2028
|
+
return this.value[key] ?? null;
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
/**
|
|
2032
|
+
* 型安全な値の取得
|
|
2033
|
+
*/
|
|
2034
|
+
get typedValue() {
|
|
2035
|
+
try {
|
|
2036
|
+
return this.zodSchema.parse(this.value);
|
|
2037
|
+
} catch {
|
|
2038
|
+
return null;
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
};
|
|
2042
|
+
|
|
1628
2043
|
// lib/values/doc-file-content-md-value.ts
|
|
1629
2044
|
var DocFileContentMdValue = class _DocFileContentMdValue {
|
|
1630
|
-
constructor(value) {
|
|
2045
|
+
constructor(value, zodSchema) {
|
|
1631
2046
|
this.value = value;
|
|
1632
2047
|
zDocFileContentMd.parse(value);
|
|
2048
|
+
this.zodSchema = zodSchema;
|
|
1633
2049
|
Object.freeze(this);
|
|
1634
2050
|
}
|
|
2051
|
+
zodSchema;
|
|
1635
2052
|
/**
|
|
1636
2053
|
* コンテンツ本文(frontMatterを含まない)
|
|
1637
2054
|
*/
|
|
@@ -1651,10 +2068,14 @@ var DocFileContentMdValue = class _DocFileContentMdValue {
|
|
|
1651
2068
|
return this.value.description;
|
|
1652
2069
|
}
|
|
1653
2070
|
/**
|
|
1654
|
-
* FrontMatter
|
|
2071
|
+
* FrontMatter(コンストラクタのZodスキーマまたは引数のスキーマを使用)
|
|
1655
2072
|
*/
|
|
1656
|
-
|
|
1657
|
-
|
|
2073
|
+
frontMatter(zodSchema) {
|
|
2074
|
+
const schema = zodSchema || this.zodSchema;
|
|
2075
|
+
return new DocFrontMatterMdValue(
|
|
2076
|
+
this.value.frontMatter,
|
|
2077
|
+
schema
|
|
2078
|
+
);
|
|
1658
2079
|
}
|
|
1659
2080
|
/**
|
|
1660
2081
|
* タイトルを更新
|
|
@@ -1664,13 +2085,16 @@ var DocFileContentMdValue = class _DocFileContentMdValue {
|
|
|
1664
2085
|
const engine = new DocMarkdownSystem();
|
|
1665
2086
|
const updatedText = engine.updateTitle(fullText, title);
|
|
1666
2087
|
const updatedBody = engine.extractBody(updatedText);
|
|
1667
|
-
return new _DocFileContentMdValue(
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
2088
|
+
return new _DocFileContentMdValue(
|
|
2089
|
+
{
|
|
2090
|
+
type: "markdown-content",
|
|
2091
|
+
body: updatedBody,
|
|
2092
|
+
title,
|
|
2093
|
+
description: this.description,
|
|
2094
|
+
frontMatter: this.value.frontMatter
|
|
2095
|
+
},
|
|
2096
|
+
this.zodSchema
|
|
2097
|
+
);
|
|
1674
2098
|
}
|
|
1675
2099
|
/**
|
|
1676
2100
|
* 説明を更新
|
|
@@ -1684,52 +2108,72 @@ var DocFileContentMdValue = class _DocFileContentMdValue {
|
|
|
1684
2108
|
defaultTitle || this.title
|
|
1685
2109
|
);
|
|
1686
2110
|
const updatedBody = engine.extractBody(updatedText);
|
|
1687
|
-
return new _DocFileContentMdValue(
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
2111
|
+
return new _DocFileContentMdValue(
|
|
2112
|
+
{
|
|
2113
|
+
type: "markdown-content",
|
|
2114
|
+
body: updatedBody,
|
|
2115
|
+
title: this.title,
|
|
2116
|
+
description,
|
|
2117
|
+
frontMatter: this.value.frontMatter
|
|
2118
|
+
},
|
|
2119
|
+
this.zodSchema
|
|
2120
|
+
);
|
|
1694
2121
|
}
|
|
1695
2122
|
/**
|
|
1696
2123
|
* コンテンツを更新
|
|
1697
2124
|
*/
|
|
1698
2125
|
withContent(content) {
|
|
1699
2126
|
const engine = new DocMarkdownSystem();
|
|
1700
|
-
return new _DocFileContentMdValue(
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
2127
|
+
return new _DocFileContentMdValue(
|
|
2128
|
+
{
|
|
2129
|
+
type: "markdown-content",
|
|
2130
|
+
body: content,
|
|
2131
|
+
title: engine.extractTitle(content) || "",
|
|
2132
|
+
description: engine.extractDescription(content) || "",
|
|
2133
|
+
frontMatter: this.value.frontMatter
|
|
2134
|
+
},
|
|
2135
|
+
this.zodSchema
|
|
2136
|
+
);
|
|
1707
2137
|
}
|
|
1708
2138
|
/**
|
|
1709
2139
|
* FrontMatterを更新
|
|
1710
2140
|
*/
|
|
1711
|
-
withFrontMatter(frontMatter) {
|
|
1712
|
-
return new _DocFileContentMdValue(
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
2141
|
+
withFrontMatter(frontMatter, zodSchema) {
|
|
2142
|
+
return new _DocFileContentMdValue(
|
|
2143
|
+
{
|
|
2144
|
+
type: "markdown-content",
|
|
2145
|
+
body: this.body,
|
|
2146
|
+
title: this.title,
|
|
2147
|
+
description: this.description,
|
|
2148
|
+
frontMatter: frontMatter.value
|
|
2149
|
+
},
|
|
2150
|
+
zodSchema
|
|
2151
|
+
);
|
|
2152
|
+
}
|
|
2153
|
+
/**
|
|
2154
|
+
* FrontMatterの特定のプロパティを更新
|
|
2155
|
+
*/
|
|
2156
|
+
withFrontMatterProperty(key, value) {
|
|
2157
|
+
const currentFrontMatter = this.frontMatter();
|
|
2158
|
+
const updatedFrontMatter = currentFrontMatter.withProperty(key, value);
|
|
2159
|
+
return this.withFrontMatter(updatedFrontMatter, this.zodSchema);
|
|
1719
2160
|
}
|
|
1720
2161
|
/**
|
|
1721
2162
|
* Markdownテキストから生成
|
|
1722
2163
|
*/
|
|
1723
|
-
static fromMarkdown(markdown) {
|
|
2164
|
+
static fromMarkdown(markdown, zodSchema = zDocFileMdFrontMatter) {
|
|
1724
2165
|
const engine = new DocMarkdownSystem();
|
|
1725
|
-
const frontMatter = DocFrontMatterMdValue.from(markdown);
|
|
1726
|
-
return new _DocFileContentMdValue(
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
2166
|
+
const frontMatter = DocFrontMatterMdValue.from(markdown, zodSchema);
|
|
2167
|
+
return new _DocFileContentMdValue(
|
|
2168
|
+
{
|
|
2169
|
+
type: "markdown-content",
|
|
2170
|
+
body: engine.extractBody(markdown),
|
|
2171
|
+
title: engine.extractTitle(markdown) || "",
|
|
2172
|
+
description: engine.extractDescription(markdown) || "",
|
|
2173
|
+
frontMatter: frontMatter.value
|
|
2174
|
+
},
|
|
2175
|
+
zodSchema
|
|
2176
|
+
);
|
|
1733
2177
|
}
|
|
1734
2178
|
/**
|
|
1735
2179
|
* 完全なMarkdownテキストを生成
|
|
@@ -1742,7 +2186,7 @@ var DocFileContentMdValue = class _DocFileContentMdValue {
|
|
|
1742
2186
|
*/
|
|
1743
2187
|
toText() {
|
|
1744
2188
|
return `---
|
|
1745
|
-
${this.frontMatter.toYaml()}
|
|
2189
|
+
${this.frontMatter().toYaml()}
|
|
1746
2190
|
---
|
|
1747
2191
|
|
|
1748
2192
|
${this.body}`;
|
|
@@ -1750,14 +2194,17 @@ ${this.body}`;
|
|
|
1750
2194
|
/**
|
|
1751
2195
|
* 空のコンテンツを生成
|
|
1752
2196
|
*/
|
|
1753
|
-
static empty(title) {
|
|
1754
|
-
return new _DocFileContentMdValue(
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
2197
|
+
static empty(title, zodSchema) {
|
|
2198
|
+
return new _DocFileContentMdValue(
|
|
2199
|
+
{
|
|
2200
|
+
type: "markdown-content",
|
|
2201
|
+
body: `# ${title}`,
|
|
2202
|
+
title,
|
|
2203
|
+
description: "",
|
|
2204
|
+
frontMatter: {}
|
|
2205
|
+
},
|
|
2206
|
+
zodSchema
|
|
2207
|
+
);
|
|
1761
2208
|
}
|
|
1762
2209
|
/**
|
|
1763
2210
|
* JSON形式で出力
|
|
@@ -1778,7 +2225,7 @@ var DocFileMdEntity = class _DocFileMdEntity {
|
|
|
1778
2225
|
* コンテンツ
|
|
1779
2226
|
*/
|
|
1780
2227
|
get content() {
|
|
1781
|
-
return new DocFileContentMdValue(this.value.content);
|
|
2228
|
+
return new DocFileContentMdValue(this.value.content, zDocFileMdFrontMatter);
|
|
1782
2229
|
}
|
|
1783
2230
|
/**
|
|
1784
2231
|
* パス情報
|
|
@@ -1952,424 +2399,160 @@ var DocRelationValue = class _DocRelationValue {
|
|
|
1952
2399
|
Object.freeze(this);
|
|
1953
2400
|
Object.freeze(this.value);
|
|
1954
2401
|
}
|
|
1955
|
-
/**
|
|
1956
|
-
* リレーションパス
|
|
1957
|
-
*/
|
|
1958
|
-
get path() {
|
|
1959
|
-
return this.value.path;
|
|
1960
|
-
}
|
|
1961
|
-
/**
|
|
1962
|
-
* リレーション対象ファイル一覧(値オブジェクト)
|
|
1963
|
-
*/
|
|
1964
|
-
get files() {
|
|
1965
|
-
return this.value.files.map((file) => new DocRelationFileValue(file));
|
|
1966
|
-
}
|
|
1967
|
-
/**
|
|
1968
|
-
* ファイル数を取得
|
|
1969
|
-
*/
|
|
1970
|
-
get fileCount() {
|
|
1971
|
-
return this.files.length;
|
|
1972
|
-
}
|
|
1973
|
-
/**
|
|
1974
|
-
* 空かどうか
|
|
1975
|
-
*/
|
|
1976
|
-
get isEmpty() {
|
|
1977
|
-
return this.files.length === 0;
|
|
1978
|
-
}
|
|
1979
|
-
/**
|
|
1980
|
-
* 空のリレーションエンティティを作成
|
|
1981
|
-
*/
|
|
1982
|
-
static empty(path) {
|
|
1983
|
-
return new _DocRelationValue({
|
|
1984
|
-
path,
|
|
1985
|
-
files: []
|
|
1986
|
-
});
|
|
1987
|
-
}
|
|
1988
|
-
/**
|
|
1989
|
-
* JSON形式で出力
|
|
1990
|
-
*/
|
|
1991
|
-
toJson() {
|
|
1992
|
-
return {
|
|
1993
|
-
path: this.path,
|
|
1994
|
-
files: this.files.map((file) => file.toJson())
|
|
1995
|
-
};
|
|
1996
|
-
}
|
|
1997
|
-
};
|
|
1998
|
-
|
|
1999
|
-
// lib/doc-file-relation-reference.ts
|
|
2000
|
-
var DocFileRelationReference = class {
|
|
2001
|
-
constructor(props) {
|
|
2002
|
-
this.props = props;
|
|
2003
|
-
this.pathSystem = props.pathSystem;
|
|
2004
|
-
Object.freeze(this);
|
|
2005
|
-
}
|
|
2006
|
-
pathSystem;
|
|
2007
|
-
get fileSystem() {
|
|
2008
|
-
return this.props.fileSystem;
|
|
2009
|
-
}
|
|
2010
|
-
get basePath() {
|
|
2011
|
-
return this.fileSystem.getBasePath();
|
|
2012
|
-
}
|
|
2013
|
-
/**
|
|
2014
|
-
* リレーションパス
|
|
2015
|
-
*/
|
|
2016
|
-
get path() {
|
|
2017
|
-
return this.props.filePath;
|
|
2018
|
-
}
|
|
2019
|
-
/**
|
|
2020
|
-
* フルパス
|
|
2021
|
-
*/
|
|
2022
|
-
get fullPath() {
|
|
2023
|
-
return this.pathSystem.join(
|
|
2024
|
-
this.fileSystem.getBasePath(),
|
|
2025
|
-
this.props.filePath
|
|
2026
|
-
);
|
|
2027
|
-
}
|
|
2028
|
-
async read() {
|
|
2029
|
-
const files = await this.readFiles();
|
|
2030
|
-
return new DocRelationValue({
|
|
2031
|
-
path: this.path,
|
|
2032
|
-
files: files.map((value) => value.toJson())
|
|
2033
|
-
});
|
|
2034
|
-
}
|
|
2035
|
-
/**
|
|
2036
|
-
* リレーションファイルの一覧を読み込む
|
|
2037
|
-
*/
|
|
2038
|
-
async readFiles() {
|
|
2039
|
-
const exists = await this.fileSystem.exists(this.path);
|
|
2040
|
-
if (!exists) {
|
|
2041
|
-
return [];
|
|
2042
|
-
}
|
|
2043
|
-
const filePaths = await this.fileSystem.readDirectoryFilePaths(this.path);
|
|
2044
|
-
const files = [];
|
|
2045
|
-
for (const filePath of filePaths) {
|
|
2046
|
-
const file = await this.readFile(filePath);
|
|
2047
|
-
if (file === null) continue;
|
|
2048
|
-
files.push(file);
|
|
2049
|
-
}
|
|
2050
|
-
return files;
|
|
2051
|
-
}
|
|
2052
|
-
/**
|
|
2053
|
-
* 単一のリレーションファイルを読み込む
|
|
2054
|
-
*/
|
|
2055
|
-
async readFile(filePath) {
|
|
2056
|
-
if (filePath.includes("index.md")) {
|
|
2057
|
-
return null;
|
|
2058
|
-
}
|
|
2059
|
-
const content = await this.fileSystem.readFile(filePath);
|
|
2060
|
-
if (content === null) {
|
|
2061
|
-
return null;
|
|
2062
|
-
}
|
|
2063
|
-
const contentValue = DocFileContentMdValue.fromMarkdown(content);
|
|
2064
|
-
const pathValue = DocFilePathValue.fromPathWithSystem(
|
|
2065
|
-
filePath,
|
|
2066
|
-
this.pathSystem,
|
|
2067
|
-
this.basePath
|
|
2068
|
-
);
|
|
2069
|
-
const fileEntity = new DocFileMdEntity({
|
|
2070
|
-
type: "markdown",
|
|
2071
|
-
content: contentValue.value,
|
|
2072
|
-
path: pathValue.value,
|
|
2073
|
-
isArchived: false
|
|
2074
|
-
});
|
|
2075
|
-
return DocRelationFileValue.from(filePath, fileEntity.value.content.title);
|
|
2076
|
-
}
|
|
2077
|
-
/**
|
|
2078
|
-
* ファイルの存在確認
|
|
2079
|
-
*/
|
|
2080
|
-
async exists(slug) {
|
|
2081
|
-
const filePath = `${this.path}/${slug}.md`;
|
|
2082
|
-
return this.fileSystem.exists(filePath);
|
|
2083
|
-
}
|
|
2084
|
-
/**
|
|
2085
|
-
* ファイル名の一覧を取得(拡張子なし)
|
|
2086
|
-
*/
|
|
2087
|
-
async readSlugs() {
|
|
2088
|
-
const files = await this.readFiles();
|
|
2089
|
-
return files.map((file) => file.id);
|
|
2090
|
-
}
|
|
2091
|
-
/**
|
|
2092
|
-
* ファイル数を取得
|
|
2093
|
-
*/
|
|
2094
|
-
async count() {
|
|
2095
|
-
const files = await this.readFiles();
|
|
2096
|
-
return files.length;
|
|
2097
|
-
}
|
|
2098
|
-
/**
|
|
2099
|
-
* 空かどうかを確認
|
|
2100
|
-
*/
|
|
2101
|
-
async isEmpty() {
|
|
2102
|
-
const count = await this.count();
|
|
2103
|
-
return count === 0;
|
|
2104
|
-
}
|
|
2105
|
-
};
|
|
2106
|
-
|
|
2107
|
-
// lib/values/doc-front-matter-index-value.ts
|
|
2108
|
-
import { parse as parse2, stringify as stringify3 } from "yaml";
|
|
2109
|
-
|
|
2110
|
-
// lib/values/doc-schema-value.ts
|
|
2111
|
-
var DocSchemaValue = class _DocSchemaValue {
|
|
2112
|
-
value;
|
|
2113
|
-
constructor(value) {
|
|
2114
|
-
this.value = _DocSchemaValue.normalizeSchema(value);
|
|
2115
|
-
zDocSchema.parse(this.value);
|
|
2116
|
-
Object.freeze(this.value);
|
|
2117
|
-
Object.freeze(this);
|
|
2118
|
-
}
|
|
2119
|
-
/**
|
|
2120
|
-
* フィールド名の一覧を取得
|
|
2121
|
-
*/
|
|
2122
|
-
get fieldNames() {
|
|
2123
|
-
return Object.keys(this.value);
|
|
2124
|
-
}
|
|
2125
|
-
/**
|
|
2126
|
-
* 指定されたフィールド名のフィールドを取得
|
|
2127
|
-
*/
|
|
2128
|
-
field(name) {
|
|
2129
|
-
const fieldDef = this.value[name];
|
|
2130
|
-
if (fieldDef === void 0) {
|
|
2131
|
-
return null;
|
|
2132
|
-
}
|
|
2133
|
-
const factory = new DocSchemaFieldFactory();
|
|
2134
|
-
return factory.fromUnknown(name, fieldDef);
|
|
2135
|
-
}
|
|
2136
|
-
get fields() {
|
|
2137
|
-
const factory = new DocSchemaFieldFactory();
|
|
2138
|
-
return this.fieldNames.map((name) => {
|
|
2139
|
-
const fieldValue = this.value[name];
|
|
2140
|
-
if (!fieldValue) {
|
|
2141
|
-
throw new Error(`Field ${name} not found in schema`);
|
|
2142
|
-
}
|
|
2143
|
-
return factory.fromUnknown(name, fieldValue);
|
|
2144
|
-
});
|
|
2145
|
-
}
|
|
2146
|
-
get relationFields() {
|
|
2147
|
-
return this.fields.filter((t) => {
|
|
2148
|
-
return t instanceof DocSchemaFieldRelationSingleValue || t instanceof DocSchemaFieldRelationMultipleValue;
|
|
2149
|
-
});
|
|
2150
|
-
}
|
|
2151
|
-
/**
|
|
2152
|
-
* 空のスキーマエンティティを作成
|
|
2153
|
-
*/
|
|
2154
|
-
static empty() {
|
|
2155
|
-
return new _DocSchemaValue({});
|
|
2156
|
-
}
|
|
2157
|
-
/**
|
|
2158
|
-
* スキーマからリレーションパスを抽出
|
|
2159
|
-
*/
|
|
2160
|
-
extractRelationPaths() {
|
|
2161
|
-
if (!this.value) return /* @__PURE__ */ new Set();
|
|
2162
|
-
const uniqueRelationPaths = /* @__PURE__ */ new Set();
|
|
2163
|
-
for (const field of Object.values(this.value)) {
|
|
2164
|
-
if (this.isRelationField(field) && "path" in field) {
|
|
2165
|
-
uniqueRelationPaths.add(field.path);
|
|
2166
|
-
}
|
|
2167
|
-
}
|
|
2168
|
-
return uniqueRelationPaths;
|
|
2169
|
-
}
|
|
2170
|
-
/**
|
|
2171
|
-
* フィールドがリレーション型かどうかを判定
|
|
2172
|
-
*/
|
|
2173
|
-
isRelationField(field) {
|
|
2174
|
-
return field.type === "relation" || field.type === "multi-relation";
|
|
2175
|
-
}
|
|
2176
|
-
/**
|
|
2177
|
-
* リレーションオプションを作成
|
|
2178
|
-
*/
|
|
2179
|
-
createRelationOption(filePath, title) {
|
|
2180
|
-
const fileName = this.extractFileName(filePath);
|
|
2181
|
-
return zDocRelationFile.parse({
|
|
2182
|
-
name: fileName,
|
|
2183
|
-
label: title || fileName,
|
|
2184
|
-
value: fileName,
|
|
2185
|
-
path: filePath
|
|
2186
|
-
});
|
|
2187
|
-
}
|
|
2188
|
-
/**
|
|
2189
|
-
* ファイルをスキップすべきかどうかを判定
|
|
2190
|
-
*/
|
|
2191
|
-
shouldSkipFile(filePath) {
|
|
2192
|
-
return filePath.endsWith("index.md") || filePath.endsWith("README.md");
|
|
2193
|
-
}
|
|
2194
|
-
/**
|
|
2195
|
-
* 値を指定された型に変換する(デフォルト値フォールバック付き)
|
|
2196
|
-
*/
|
|
2197
|
-
convertValue(value, targetType, defaultValue) {
|
|
2198
|
-
if (this.isNullOrUndefined(value)) {
|
|
2199
|
-
return defaultValue;
|
|
2200
|
-
}
|
|
2201
|
-
try {
|
|
2202
|
-
return this.convertByType(value, targetType, defaultValue);
|
|
2203
|
-
} catch {
|
|
2204
|
-
return defaultValue;
|
|
2205
|
-
}
|
|
2206
|
-
}
|
|
2207
|
-
/**
|
|
2208
|
-
* 型別の変換処理
|
|
2209
|
-
*/
|
|
2210
|
-
convertByType(value, targetType, defaultValue) {
|
|
2211
|
-
if (targetType === "text") {
|
|
2212
|
-
return this.convertToString(value, defaultValue);
|
|
2213
|
-
}
|
|
2214
|
-
if (targetType === "number") {
|
|
2215
|
-
return this.convertToNumber(value, defaultValue);
|
|
2216
|
-
}
|
|
2217
|
-
if (targetType === "boolean") {
|
|
2218
|
-
return this.convertToBoolean(value, defaultValue);
|
|
2219
|
-
}
|
|
2220
|
-
if (targetType === "multi-text" || targetType === "array") {
|
|
2221
|
-
return this.convertToArray(value, defaultValue);
|
|
2222
|
-
}
|
|
2223
|
-
if (targetType === "relation") {
|
|
2224
|
-
return this.convertToRelation(value, defaultValue);
|
|
2225
|
-
}
|
|
2226
|
-
if (targetType === "multi-relation") {
|
|
2227
|
-
return this.convertToMultiRelation(value, defaultValue);
|
|
2228
|
-
}
|
|
2229
|
-
return defaultValue;
|
|
2230
|
-
}
|
|
2231
|
-
/**
|
|
2232
|
-
* 文字列型への変換
|
|
2233
|
-
*/
|
|
2234
|
-
convertToString(value, defaultValue) {
|
|
2235
|
-
if (typeof value === "string") return value;
|
|
2236
|
-
if (typeof value === "number") return String(value);
|
|
2237
|
-
if (typeof value === "boolean") return String(value);
|
|
2238
|
-
return defaultValue;
|
|
2402
|
+
/**
|
|
2403
|
+
* リレーションパス
|
|
2404
|
+
*/
|
|
2405
|
+
get path() {
|
|
2406
|
+
return this.value.path;
|
|
2239
2407
|
}
|
|
2240
2408
|
/**
|
|
2241
|
-
*
|
|
2409
|
+
* リレーション対象ファイル一覧(値オブジェクト)
|
|
2242
2410
|
*/
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
if (typeof value === "string") {
|
|
2246
|
-
const parsed = Number(value);
|
|
2247
|
-
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
2248
|
-
}
|
|
2249
|
-
if (typeof value === "boolean") return value ? 1 : 0;
|
|
2250
|
-
return defaultValue;
|
|
2411
|
+
get files() {
|
|
2412
|
+
return this.value.files.map((file) => new DocRelationFileValue(file));
|
|
2251
2413
|
}
|
|
2252
2414
|
/**
|
|
2253
|
-
*
|
|
2415
|
+
* ファイル数を取得
|
|
2254
2416
|
*/
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
if (typeof value === "string") {
|
|
2258
|
-
const lower = value.toLowerCase();
|
|
2259
|
-
if (lower === "true" || lower === "1") return true;
|
|
2260
|
-
if (lower === "false" || lower === "0") return false;
|
|
2261
|
-
return defaultValue;
|
|
2262
|
-
}
|
|
2263
|
-
if (typeof value === "number") return value !== 0;
|
|
2264
|
-
return defaultValue;
|
|
2417
|
+
get fileCount() {
|
|
2418
|
+
return this.files.length;
|
|
2265
2419
|
}
|
|
2266
2420
|
/**
|
|
2267
|
-
*
|
|
2421
|
+
* 空かどうか
|
|
2268
2422
|
*/
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
if (typeof value === "string") {
|
|
2272
|
-
return value.split(",").map((item) => item.trim());
|
|
2273
|
-
}
|
|
2274
|
-
return defaultValue;
|
|
2423
|
+
get isEmpty() {
|
|
2424
|
+
return this.files.length === 0;
|
|
2275
2425
|
}
|
|
2276
2426
|
/**
|
|
2277
|
-
*
|
|
2427
|
+
* 空のリレーションエンティティを作成
|
|
2278
2428
|
*/
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2429
|
+
static empty(path) {
|
|
2430
|
+
return new _DocRelationValue({
|
|
2431
|
+
path,
|
|
2432
|
+
files: []
|
|
2433
|
+
});
|
|
2284
2434
|
}
|
|
2285
2435
|
/**
|
|
2286
|
-
*
|
|
2436
|
+
* JSON形式で出力
|
|
2287
2437
|
*/
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2438
|
+
toJson() {
|
|
2439
|
+
return {
|
|
2440
|
+
path: this.path,
|
|
2441
|
+
files: this.files.map((file) => file.toJson())
|
|
2442
|
+
};
|
|
2443
|
+
}
|
|
2444
|
+
};
|
|
2445
|
+
|
|
2446
|
+
// lib/doc-file-relation-reference.ts
|
|
2447
|
+
var DocFileRelationReference = class {
|
|
2448
|
+
constructor(props) {
|
|
2449
|
+
this.props = props;
|
|
2450
|
+
this.pathSystem = props.pathSystem;
|
|
2451
|
+
Object.freeze(this);
|
|
2452
|
+
}
|
|
2453
|
+
pathSystem;
|
|
2454
|
+
get fileSystem() {
|
|
2455
|
+
return this.props.fileSystem;
|
|
2456
|
+
}
|
|
2457
|
+
get basePath() {
|
|
2458
|
+
return this.fileSystem.getBasePath();
|
|
2296
2459
|
}
|
|
2297
2460
|
/**
|
|
2298
|
-
*
|
|
2461
|
+
* リレーションパス
|
|
2299
2462
|
*/
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
return fileName.replace(/\.md$/, "");
|
|
2463
|
+
get path() {
|
|
2464
|
+
return this.props.filePath;
|
|
2303
2465
|
}
|
|
2304
2466
|
/**
|
|
2305
|
-
*
|
|
2467
|
+
* フルパス
|
|
2306
2468
|
*/
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
rawFrontMatter
|
|
2469
|
+
get fullPath() {
|
|
2470
|
+
return this.pathSystem.join(
|
|
2471
|
+
this.fileSystem.getBasePath(),
|
|
2472
|
+
this.props.filePath
|
|
2312
2473
|
);
|
|
2313
2474
|
}
|
|
2475
|
+
async read() {
|
|
2476
|
+
const files = await this.readFiles();
|
|
2477
|
+
return new DocRelationValue({
|
|
2478
|
+
path: this.path,
|
|
2479
|
+
files: files.map((value) => value.toJson())
|
|
2480
|
+
});
|
|
2481
|
+
}
|
|
2314
2482
|
/**
|
|
2315
|
-
*
|
|
2483
|
+
* リレーションファイルの一覧を読み込む
|
|
2316
2484
|
*/
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
defaultFrontMatter[key] = DocFrontMatterMdValue.generateDefaultValueFromSchemaField(field);
|
|
2485
|
+
async readFiles() {
|
|
2486
|
+
const exists = await this.fileSystem.exists(this.path);
|
|
2487
|
+
if (!exists) {
|
|
2488
|
+
return [];
|
|
2322
2489
|
}
|
|
2323
|
-
|
|
2490
|
+
const filePaths = await this.fileSystem.readDirectoryFilePaths(this.path);
|
|
2491
|
+
const files = [];
|
|
2492
|
+
for (const filePath of filePaths) {
|
|
2493
|
+
const file = await this.readFile(filePath);
|
|
2494
|
+
if (file === null) continue;
|
|
2495
|
+
files.push(file);
|
|
2496
|
+
}
|
|
2497
|
+
return files;
|
|
2324
2498
|
}
|
|
2325
2499
|
/**
|
|
2326
|
-
*
|
|
2500
|
+
* 単一のリレーションファイルを読み込む
|
|
2327
2501
|
*/
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
const validatedData = zDocFileMdFrontMatter.parse(existing);
|
|
2332
|
-
for (const [key, value] of Object.entries(validatedData)) {
|
|
2333
|
-
if (value !== void 0 && value !== null) {
|
|
2334
|
-
result[key] = value;
|
|
2335
|
-
}
|
|
2336
|
-
}
|
|
2502
|
+
async readFile(filePath) {
|
|
2503
|
+
if (filePath.includes("index.md")) {
|
|
2504
|
+
return null;
|
|
2337
2505
|
}
|
|
2338
|
-
|
|
2506
|
+
const content = await this.fileSystem.readFile(filePath);
|
|
2507
|
+
if (content === null) {
|
|
2508
|
+
return null;
|
|
2509
|
+
}
|
|
2510
|
+
const contentValue = DocFileContentMdValue.fromMarkdown(content);
|
|
2511
|
+
const pathValue = DocFilePathValue.fromPathWithSystem(
|
|
2512
|
+
filePath,
|
|
2513
|
+
this.pathSystem,
|
|
2514
|
+
this.basePath
|
|
2515
|
+
);
|
|
2516
|
+
const fileEntity = new DocFileMdEntity({
|
|
2517
|
+
type: "markdown",
|
|
2518
|
+
content: contentValue.value,
|
|
2519
|
+
path: pathValue.value,
|
|
2520
|
+
isArchived: false
|
|
2521
|
+
});
|
|
2522
|
+
return DocRelationFileValue.from(filePath, fileEntity.value.content.title);
|
|
2339
2523
|
}
|
|
2340
2524
|
/**
|
|
2341
|
-
*
|
|
2525
|
+
* ファイルの存在確認
|
|
2342
2526
|
*/
|
|
2343
|
-
|
|
2344
|
-
|
|
2527
|
+
async exists(slug) {
|
|
2528
|
+
const filePath = `${this.path}/${slug}.md`;
|
|
2529
|
+
return this.fileSystem.exists(filePath);
|
|
2345
2530
|
}
|
|
2346
2531
|
/**
|
|
2347
|
-
*
|
|
2532
|
+
* ファイル名の一覧を取得(拡張子なし)
|
|
2348
2533
|
*/
|
|
2349
|
-
|
|
2350
|
-
|
|
2534
|
+
async readSlugs() {
|
|
2535
|
+
const files = await this.readFiles();
|
|
2536
|
+
return files.map((file) => file.id);
|
|
2351
2537
|
}
|
|
2352
|
-
|
|
2353
|
-
|
|
2538
|
+
/**
|
|
2539
|
+
* ファイル数を取得
|
|
2540
|
+
*/
|
|
2541
|
+
async count() {
|
|
2542
|
+
const files = await this.readFiles();
|
|
2543
|
+
return files.length;
|
|
2354
2544
|
}
|
|
2355
2545
|
/**
|
|
2356
|
-
*
|
|
2546
|
+
* 空かどうかを確認
|
|
2357
2547
|
*/
|
|
2358
|
-
|
|
2359
|
-
const
|
|
2360
|
-
|
|
2361
|
-
for (const [key, field] of Object.entries(schema)) {
|
|
2362
|
-
try {
|
|
2363
|
-
const normalizedField = factory.fromUnknown(key, field);
|
|
2364
|
-
normalized[key] = normalizedField.toJson();
|
|
2365
|
-
} catch {
|
|
2366
|
-
}
|
|
2367
|
-
}
|
|
2368
|
-
return normalized;
|
|
2548
|
+
async isEmpty() {
|
|
2549
|
+
const count = await this.count();
|
|
2550
|
+
return count === 0;
|
|
2369
2551
|
}
|
|
2370
2552
|
};
|
|
2371
2553
|
|
|
2372
2554
|
// lib/values/doc-front-matter-index-value.ts
|
|
2555
|
+
import { parse as parse2, stringify as stringify3 } from "yaml";
|
|
2373
2556
|
var DocFrontMatterIndexValue = class _DocFrontMatterIndexValue {
|
|
2374
2557
|
constructor(value) {
|
|
2375
2558
|
this.value = value;
|
|
@@ -2379,14 +2562,14 @@ var DocFrontMatterIndexValue = class _DocFrontMatterIndexValue {
|
|
|
2379
2562
|
/**
|
|
2380
2563
|
* アイコンを取得
|
|
2381
2564
|
*/
|
|
2382
|
-
|
|
2565
|
+
icon() {
|
|
2383
2566
|
return this.value.icon;
|
|
2384
2567
|
}
|
|
2385
2568
|
/**
|
|
2386
2569
|
* スキーマを取得
|
|
2387
2570
|
*/
|
|
2388
|
-
|
|
2389
|
-
return new DocSchemaValue(this.value.schema);
|
|
2571
|
+
schema(zodSchema) {
|
|
2572
|
+
return new DocSchemaValue(this.value.schema, zodSchema);
|
|
2390
2573
|
}
|
|
2391
2574
|
/**
|
|
2392
2575
|
* iconフィールドを更新
|
|
@@ -2760,7 +2943,8 @@ var DocFileIndexReference = class _DocFileIndexReference {
|
|
|
2760
2943
|
async read() {
|
|
2761
2944
|
const content = await this.fileSystem.readFile(this.filePath);
|
|
2762
2945
|
if (content === null) {
|
|
2763
|
-
const
|
|
2946
|
+
const dirPath = this.pathSystem.dirname(this.filePath);
|
|
2947
|
+
const dirName = this.pathSystem.basename(dirPath);
|
|
2764
2948
|
const pathValue2 = DocFilePathValue.fromPathWithSystem(
|
|
2765
2949
|
this.filePath,
|
|
2766
2950
|
this.pathSystem,
|
|
@@ -3139,12 +3323,16 @@ var DocFileMdReference = class _DocFileMdReference {
|
|
|
3139
3323
|
if (file instanceof Error) {
|
|
3140
3324
|
return file;
|
|
3141
3325
|
}
|
|
3142
|
-
const relationValue = file.content.frontMatter.relation(key);
|
|
3326
|
+
const relationValue = file.content.frontMatter().relation(key);
|
|
3143
3327
|
if (relationValue === null) {
|
|
3144
3328
|
return null;
|
|
3145
3329
|
}
|
|
3146
|
-
const
|
|
3147
|
-
if (!
|
|
3330
|
+
const indexRef = await this.getDirectoryIndex();
|
|
3331
|
+
if (!indexRef) {
|
|
3332
|
+
return null;
|
|
3333
|
+
}
|
|
3334
|
+
const indexFile = await indexRef.read();
|
|
3335
|
+
if (indexFile instanceof Error) {
|
|
3148
3336
|
return null;
|
|
3149
3337
|
}
|
|
3150
3338
|
const schemaData = indexFile.content.frontMatter.value.schema;
|
|
@@ -3156,7 +3344,12 @@ var DocFileMdReference = class _DocFileMdReference {
|
|
|
3156
3344
|
if (!field || !("path" in field) || !field.path) {
|
|
3157
3345
|
return null;
|
|
3158
3346
|
}
|
|
3159
|
-
|
|
3347
|
+
let resolvedPath = field.path;
|
|
3348
|
+
if (field.path.startsWith("..")) {
|
|
3349
|
+
resolvedPath = this.pathSystem.join(this.directoryPath, field.path);
|
|
3350
|
+
resolvedPath = this.pathSystem.normalize(resolvedPath);
|
|
3351
|
+
}
|
|
3352
|
+
const fullPath = this.pathSystem.join(resolvedPath, `${relationValue}.md`);
|
|
3160
3353
|
return new _DocFileMdReference({
|
|
3161
3354
|
path: fullPath,
|
|
3162
3355
|
fileSystem: this.fileSystem,
|
|
@@ -3168,16 +3361,28 @@ var DocFileMdReference = class _DocFileMdReference {
|
|
|
3168
3361
|
*/
|
|
3169
3362
|
async getDirectoryIndex() {
|
|
3170
3363
|
const indexPath = this.pathSystem.join(this.directoryPath, "index.md");
|
|
3171
|
-
const
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3364
|
+
const exists = await this.fileSystem.exists(indexPath);
|
|
3365
|
+
if (exists) {
|
|
3366
|
+
return new DocFileIndexReference({
|
|
3367
|
+
path: indexPath,
|
|
3368
|
+
fileSystem: this.fileSystem,
|
|
3369
|
+
pathSystem: this.pathSystem
|
|
3370
|
+
});
|
|
3371
|
+
}
|
|
3372
|
+
const archivedIndexPath = this.pathSystem.join(
|
|
3373
|
+
this.directoryPath,
|
|
3374
|
+
"_",
|
|
3375
|
+
"index.md"
|
|
3376
|
+
);
|
|
3377
|
+
const archivedExists = await this.fileSystem.exists(archivedIndexPath);
|
|
3378
|
+
if (archivedExists) {
|
|
3379
|
+
return new DocFileIndexReference({
|
|
3380
|
+
path: archivedIndexPath,
|
|
3381
|
+
fileSystem: this.fileSystem,
|
|
3382
|
+
pathSystem: this.pathSystem
|
|
3383
|
+
});
|
|
3179
3384
|
}
|
|
3180
|
-
return
|
|
3385
|
+
return null;
|
|
3181
3386
|
}
|
|
3182
3387
|
/**
|
|
3183
3388
|
* 複数のリレーションを取得する
|
|
@@ -3193,12 +3398,16 @@ var DocFileMdReference = class _DocFileMdReference {
|
|
|
3193
3398
|
if (file instanceof Error) {
|
|
3194
3399
|
return [];
|
|
3195
3400
|
}
|
|
3196
|
-
const relationValues = file.content.frontMatter.multiRelation(key);
|
|
3401
|
+
const relationValues = file.content.frontMatter().multiRelation(key);
|
|
3197
3402
|
if (relationValues.length === 0) {
|
|
3198
3403
|
return [];
|
|
3199
3404
|
}
|
|
3200
|
-
const
|
|
3201
|
-
if (!
|
|
3405
|
+
const indexRef = await this.getDirectoryIndex();
|
|
3406
|
+
if (!indexRef) {
|
|
3407
|
+
return [];
|
|
3408
|
+
}
|
|
3409
|
+
const indexFile = await indexRef.read();
|
|
3410
|
+
if (indexFile instanceof Error) {
|
|
3202
3411
|
return [];
|
|
3203
3412
|
}
|
|
3204
3413
|
const schemaData = indexFile.content.frontMatter.value.schema;
|
|
@@ -3211,7 +3420,12 @@ var DocFileMdReference = class _DocFileMdReference {
|
|
|
3211
3420
|
return [];
|
|
3212
3421
|
}
|
|
3213
3422
|
return relationValues.map((relationValue) => {
|
|
3214
|
-
|
|
3423
|
+
let resolvedPath = field.path;
|
|
3424
|
+
if (field.path.startsWith("..")) {
|
|
3425
|
+
resolvedPath = this.pathSystem.join(this.directoryPath, field.path);
|
|
3426
|
+
resolvedPath = this.pathSystem.normalize(resolvedPath);
|
|
3427
|
+
}
|
|
3428
|
+
const fullPath = this.pathSystem.join(resolvedPath, `${relationValue}.md`);
|
|
3215
3429
|
return new _DocFileMdReference({
|
|
3216
3430
|
path: fullPath,
|
|
3217
3431
|
fileSystem: this.fileSystem,
|
|
@@ -3219,6 +3433,38 @@ var DocFileMdReference = class _DocFileMdReference {
|
|
|
3219
3433
|
});
|
|
3220
3434
|
});
|
|
3221
3435
|
}
|
|
3436
|
+
/**
|
|
3437
|
+
* FrontMatterを型安全に読み込む
|
|
3438
|
+
*/
|
|
3439
|
+
async readFrontMatter(zodSchema) {
|
|
3440
|
+
const entity = await this.read();
|
|
3441
|
+
if (entity instanceof Error) {
|
|
3442
|
+
return entity;
|
|
3443
|
+
}
|
|
3444
|
+
return entity.content.frontMatter(zodSchema);
|
|
3445
|
+
}
|
|
3446
|
+
/**
|
|
3447
|
+
* FrontMatterを型安全に更新
|
|
3448
|
+
*/
|
|
3449
|
+
async updateFrontMatter(key, value, zodSchema) {
|
|
3450
|
+
const entity = await this.read();
|
|
3451
|
+
if (entity instanceof Error) {
|
|
3452
|
+
return entity;
|
|
3453
|
+
}
|
|
3454
|
+
const currentFrontMatter = entity.content.frontMatter(zodSchema);
|
|
3455
|
+
const updatedFrontMatter = currentFrontMatter.withProperty(key, value);
|
|
3456
|
+
const baseContent = new DocFileContentMdValue(
|
|
3457
|
+
entity.content.value,
|
|
3458
|
+
zDocFileMdFrontMatter
|
|
3459
|
+
);
|
|
3460
|
+
const updatedContent = baseContent.withFrontMatter(
|
|
3461
|
+
updatedFrontMatter,
|
|
3462
|
+
zDocFileMdFrontMatter
|
|
3463
|
+
);
|
|
3464
|
+
const updatedEntity = entity.withContent(updatedContent);
|
|
3465
|
+
await this.write(updatedEntity);
|
|
3466
|
+
return void 0;
|
|
3467
|
+
}
|
|
3222
3468
|
};
|
|
3223
3469
|
|
|
3224
3470
|
// lib/entities/doc-file-unknown-entity.ts
|
|
@@ -3562,6 +3808,17 @@ var DocDirectoryReference = class _DocDirectoryReference {
|
|
|
3562
3808
|
}
|
|
3563
3809
|
return files;
|
|
3564
3810
|
}
|
|
3811
|
+
/**
|
|
3812
|
+
* Markdownファイルの参照とFrontMatterを型安全に取得
|
|
3813
|
+
*/
|
|
3814
|
+
async mdFilesWithFrontMatter(zodSchema) {
|
|
3815
|
+
const results = [];
|
|
3816
|
+
for await (const file of this.mdFilesGenerator()) {
|
|
3817
|
+
const frontMatter = await file.readFrontMatter(zodSchema);
|
|
3818
|
+
results.push({ reference: file, frontMatter });
|
|
3819
|
+
}
|
|
3820
|
+
return results;
|
|
3821
|
+
}
|
|
3565
3822
|
file(fileName) {
|
|
3566
3823
|
const filePath = this.pathSystem.join(this.relativePath, fileName);
|
|
3567
3824
|
if (fileName.endsWith(".md")) {
|
|
@@ -3603,6 +3860,21 @@ var DocDirectoryReference = class _DocDirectoryReference {
|
|
|
3603
3860
|
}
|
|
3604
3861
|
return entities;
|
|
3605
3862
|
}
|
|
3863
|
+
/**
|
|
3864
|
+
* Zodスキーマを使って型安全にMarkdownファイルのFrontMatterを読み込む
|
|
3865
|
+
*/
|
|
3866
|
+
async readMdFilesWithSchema(zodSchema) {
|
|
3867
|
+
const results = [];
|
|
3868
|
+
for await (const file of this.mdFilesGenerator()) {
|
|
3869
|
+
const entity = await file.read();
|
|
3870
|
+
if (entity instanceof Error) continue;
|
|
3871
|
+
const frontMatter = entity.content.frontMatter(
|
|
3872
|
+
zodSchema
|
|
3873
|
+
);
|
|
3874
|
+
results.push({ entity, frontMatter });
|
|
3875
|
+
}
|
|
3876
|
+
return results;
|
|
3877
|
+
}
|
|
3606
3878
|
async readUnknownFiles() {
|
|
3607
3879
|
const entities = [];
|
|
3608
3880
|
for await (const file of this.filesGenerator()) {
|
|
@@ -3914,7 +4186,12 @@ var DocFileTreeSystem = class {
|
|
|
3914
4186
|
if (await indexFile.exists()) {
|
|
3915
4187
|
const entity = await indexFile.read();
|
|
3916
4188
|
title = entity.value.content.title || fileName;
|
|
3917
|
-
|
|
4189
|
+
const content = entity.content;
|
|
4190
|
+
const frontMatter = content.frontMatter;
|
|
4191
|
+
if (frontMatter instanceof DocFrontMatterIndexValue) {
|
|
4192
|
+
const iconValue = frontMatter.icon();
|
|
4193
|
+
icon = iconValue || "\u{1F4C1}";
|
|
4194
|
+
}
|
|
3918
4195
|
}
|
|
3919
4196
|
const children = await this.buildFileTree(filePath);
|
|
3920
4197
|
return DocTreeDirectoryNodeValue.from({
|
|
@@ -3975,7 +4252,12 @@ var DocFileTreeSystem = class {
|
|
|
3975
4252
|
if (await indexFile.exists()) {
|
|
3976
4253
|
const entity = await indexFile.read();
|
|
3977
4254
|
title = entity.value.content.title || fileName;
|
|
3978
|
-
|
|
4255
|
+
const content = entity.content;
|
|
4256
|
+
const frontMatter = content.frontMatter;
|
|
4257
|
+
if (frontMatter instanceof DocFrontMatterIndexValue) {
|
|
4258
|
+
const iconValue = frontMatter.icon();
|
|
4259
|
+
icon = iconValue || "\u{1F4C1}";
|
|
4260
|
+
}
|
|
3979
4261
|
}
|
|
3980
4262
|
const children = await this.buildDirectoryTree(filePath);
|
|
3981
4263
|
return DocTreeDirectoryNodeValue.from({
|
|
@@ -4615,6 +4897,7 @@ export {
|
|
|
4615
4897
|
zDocSchema,
|
|
4616
4898
|
zDocSchemaField,
|
|
4617
4899
|
zDocSchemaFieldBoolean,
|
|
4900
|
+
zDocSchemaFieldMinimal,
|
|
4618
4901
|
zDocSchemaFieldMultiBoolean,
|
|
4619
4902
|
zDocSchemaFieldMultiNumber,
|
|
4620
4903
|
zDocSchemaFieldMultiRelation,
|
|
@@ -4627,6 +4910,7 @@ export {
|
|
|
4627
4910
|
zDocSchemaFieldSelectText,
|
|
4628
4911
|
zDocSchemaFieldText,
|
|
4629
4912
|
zDocSchemaFieldType,
|
|
4913
|
+
zDocSchemaMinimal,
|
|
4630
4914
|
zDocTreeDirectoryNode,
|
|
4631
4915
|
zDocTreeFileNode,
|
|
4632
4916
|
zDocTreeNode
|