patram 0.5.0 → 0.6.0
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/lib/build-graph-identity.js +42 -1
- package/lib/build-graph.js +1 -1
- package/lib/check-directive-metadata.js +160 -5
- package/lib/check-directive-path-target.js +173 -0
- package/lib/check-directive-value.js +122 -125
- package/lib/directive-validation-test-helpers.js +87 -0
- package/lib/load-patram-config.js +95 -8
- package/lib/load-project-graph.js +16 -6
- package/lib/parse-claims.js +95 -8
- package/lib/parse-claims.types.ts +7 -0
- package/lib/parse-markdown-claims.js +9 -3
- package/lib/parse-markdown-directives.js +48 -25
- package/lib/parse-yaml-claims.js +472 -0
- package/lib/source-file-defaults.js +3 -0
- package/package.json +2 -1
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
* @import { MappingDefinition } from './patram-config.types.ts';
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
createPathClassDiagnostics,
|
|
9
|
+
createPathExistenceDiagnostics,
|
|
10
|
+
} from './check-directive-path-target.js';
|
|
8
11
|
import { createOriginDiagnostic } from './directive-diagnostics.js';
|
|
9
12
|
import {
|
|
10
13
|
formatQuotedList,
|
|
@@ -40,45 +43,31 @@ export function checkDirectiveValue(
|
|
|
40
43
|
directive_name,
|
|
41
44
|
mapping_definition,
|
|
42
45
|
);
|
|
43
|
-
|
|
44
46
|
if (!validation_field_name || typeof claim.value !== 'string') {
|
|
45
47
|
return [];
|
|
46
48
|
}
|
|
47
|
-
|
|
49
|
+
const directive_value = claim.value;
|
|
48
50
|
if (validation_field_name === '$class') {
|
|
49
|
-
return checkClassValue(claim, directive_name, repo_config);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (isStructuralDirectiveField(validation_field_name)) {
|
|
53
|
-
return [];
|
|
51
|
+
return checkClassValue(claim, directive_name, directive_value, repo_config);
|
|
54
52
|
}
|
|
55
|
-
|
|
56
53
|
const type_definition = repo_config.fields?.[validation_field_name];
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const type_diagnostic = createInvalidTypeDiagnostic(
|
|
67
|
-
claim,
|
|
68
|
-
directive_name,
|
|
69
|
-
type_definition,
|
|
70
|
-
claim.value,
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
if (type_diagnostic) {
|
|
74
|
-
return [type_diagnostic];
|
|
54
|
+
if (isStructuralDirectiveField(validation_field_name) || !type_definition) {
|
|
55
|
+
return collectUntypedPathDiagnostics(
|
|
56
|
+
claim,
|
|
57
|
+
directive_name,
|
|
58
|
+
mapping_definition,
|
|
59
|
+
document_entity_keys,
|
|
60
|
+
document_node_references,
|
|
61
|
+
document_paths,
|
|
62
|
+
);
|
|
75
63
|
}
|
|
76
|
-
|
|
77
|
-
return createPathClassDiagnostics(
|
|
64
|
+
return checkTypedDirectiveValue(
|
|
78
65
|
claim,
|
|
79
66
|
directive_name,
|
|
67
|
+
directive_value,
|
|
80
68
|
mappings,
|
|
81
69
|
repo_config,
|
|
70
|
+
mapping_definition,
|
|
82
71
|
type_definition,
|
|
83
72
|
document_entity_keys,
|
|
84
73
|
document_node_references,
|
|
@@ -89,14 +78,12 @@ export function checkDirectiveValue(
|
|
|
89
78
|
/**
|
|
90
79
|
* @param {PatramClaim} claim
|
|
91
80
|
* @param {string} directive_name
|
|
81
|
+
* @param {string} class_name
|
|
92
82
|
* @param {PatramRepoConfig} repo_config
|
|
93
83
|
* @returns {PatramDiagnostic[]}
|
|
94
84
|
*/
|
|
95
|
-
function checkClassValue(claim, directive_name, repo_config) {
|
|
96
|
-
if (
|
|
97
|
-
typeof claim.value !== 'string' ||
|
|
98
|
-
repo_config.classes?.[claim.value] !== undefined
|
|
99
|
-
) {
|
|
85
|
+
function checkClassValue(claim, directive_name, class_name, repo_config) {
|
|
86
|
+
if (repo_config.classes?.[class_name] !== undefined) {
|
|
100
87
|
return [];
|
|
101
88
|
}
|
|
102
89
|
|
|
@@ -112,44 +99,85 @@ function checkClassValue(claim, directive_name, repo_config) {
|
|
|
112
99
|
/**
|
|
113
100
|
* @param {PatramClaim} claim
|
|
114
101
|
* @param {string} directive_name
|
|
115
|
-
* @param {string
|
|
102
|
+
* @param {string} directive_value
|
|
103
|
+
* @param {Record<string, MappingDefinition>} mappings
|
|
104
|
+
* @param {PatramRepoConfig} repo_config
|
|
105
|
+
* @param {MappingDefinition | null} mapping_definition
|
|
106
|
+
* @param {DirectiveTypeConfig} type_definition
|
|
107
|
+
* @param {Map<string, string>} document_entity_keys
|
|
108
|
+
* @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
|
|
109
|
+
* @param {Set<string>} document_paths
|
|
116
110
|
* @returns {PatramDiagnostic[]}
|
|
117
111
|
*/
|
|
118
|
-
function
|
|
119
|
-
|
|
120
|
-
|
|
112
|
+
function checkTypedDirectiveValue(
|
|
113
|
+
claim,
|
|
114
|
+
directive_name,
|
|
115
|
+
directive_value,
|
|
116
|
+
mappings,
|
|
117
|
+
repo_config,
|
|
118
|
+
mapping_definition,
|
|
119
|
+
type_definition,
|
|
120
|
+
document_entity_keys,
|
|
121
|
+
document_node_references,
|
|
122
|
+
document_paths,
|
|
123
|
+
) {
|
|
124
|
+
if (type_definition.type === 'enum') {
|
|
125
|
+
return checkEnumValue(
|
|
126
|
+
claim,
|
|
127
|
+
directive_name,
|
|
128
|
+
directive_value,
|
|
129
|
+
type_definition.values,
|
|
130
|
+
);
|
|
121
131
|
}
|
|
122
132
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
133
|
+
if (!isDirectiveValueValid(type_definition, directive_value)) {
|
|
134
|
+
return [
|
|
135
|
+
createOriginDiagnostic(
|
|
136
|
+
claim,
|
|
137
|
+
'directive.invalid_type',
|
|
138
|
+
getInvalidTypeMessage(directive_name, type_definition.type),
|
|
139
|
+
),
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return collectPathDiagnostics(
|
|
144
|
+
claim,
|
|
145
|
+
directive_name,
|
|
146
|
+
mappings,
|
|
147
|
+
repo_config,
|
|
148
|
+
mapping_definition,
|
|
149
|
+
type_definition,
|
|
150
|
+
document_entity_keys,
|
|
151
|
+
document_node_references,
|
|
152
|
+
document_paths,
|
|
153
|
+
);
|
|
130
154
|
}
|
|
131
155
|
|
|
132
156
|
/**
|
|
133
157
|
* @param {PatramClaim} claim
|
|
134
158
|
* @param {string} directive_name
|
|
135
|
-
* @param {
|
|
136
|
-
* @param {string}
|
|
137
|
-
* @
|
|
159
|
+
* @param {MappingDefinition | null} mapping_definition
|
|
160
|
+
* @param {Map<string, string>} document_entity_keys
|
|
161
|
+
* @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
|
|
162
|
+
* @param {Set<string>} document_paths
|
|
163
|
+
* @returns {PatramDiagnostic[]}
|
|
138
164
|
*/
|
|
139
|
-
function
|
|
165
|
+
function collectUntypedPathDiagnostics(
|
|
140
166
|
claim,
|
|
141
167
|
directive_name,
|
|
142
|
-
|
|
143
|
-
|
|
168
|
+
mapping_definition,
|
|
169
|
+
document_entity_keys,
|
|
170
|
+
document_node_references,
|
|
171
|
+
document_paths,
|
|
144
172
|
) {
|
|
145
|
-
|
|
146
|
-
return null;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return createOriginDiagnostic(
|
|
173
|
+
return createPathExistenceDiagnostics(
|
|
150
174
|
claim,
|
|
151
|
-
|
|
152
|
-
|
|
175
|
+
directive_name,
|
|
176
|
+
mapping_definition,
|
|
177
|
+
undefined,
|
|
178
|
+
document_entity_keys,
|
|
179
|
+
document_node_references,
|
|
180
|
+
document_paths,
|
|
153
181
|
);
|
|
154
182
|
}
|
|
155
183
|
|
|
@@ -158,90 +186,70 @@ function createInvalidTypeDiagnostic(
|
|
|
158
186
|
* @param {string} directive_name
|
|
159
187
|
* @param {Record<string, MappingDefinition>} mappings
|
|
160
188
|
* @param {PatramRepoConfig} repo_config
|
|
189
|
+
* @param {MappingDefinition | null} mapping_definition
|
|
161
190
|
* @param {Exclude<DirectiveTypeConfig, { type: 'enum' }>} type_definition
|
|
162
191
|
* @param {Map<string, string>} document_entity_keys
|
|
163
192
|
* @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
|
|
164
193
|
* @param {Set<string>} document_paths
|
|
165
194
|
* @returns {PatramDiagnostic[]}
|
|
166
195
|
*/
|
|
167
|
-
function
|
|
196
|
+
function collectPathDiagnostics(
|
|
168
197
|
claim,
|
|
169
198
|
directive_name,
|
|
170
199
|
mappings,
|
|
171
200
|
repo_config,
|
|
201
|
+
mapping_definition,
|
|
172
202
|
type_definition,
|
|
173
203
|
document_entity_keys,
|
|
174
204
|
document_node_references,
|
|
175
205
|
document_paths,
|
|
176
206
|
) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
207
|
+
return createPathClassDiagnostics(
|
|
208
|
+
claim,
|
|
209
|
+
directive_name,
|
|
210
|
+
mappings,
|
|
211
|
+
repo_config,
|
|
212
|
+
type_definition,
|
|
213
|
+
document_entity_keys,
|
|
214
|
+
document_node_references,
|
|
215
|
+
document_paths,
|
|
216
|
+
).concat(
|
|
217
|
+
createPathExistenceDiagnostics(
|
|
182
218
|
claim,
|
|
183
|
-
|
|
219
|
+
directive_name,
|
|
220
|
+
mapping_definition,
|
|
221
|
+
type_definition,
|
|
184
222
|
document_entity_keys,
|
|
185
223
|
document_node_references,
|
|
186
224
|
document_paths,
|
|
187
|
-
repo_config,
|
|
188
|
-
)
|
|
189
|
-
) {
|
|
190
|
-
return [];
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
return [
|
|
194
|
-
createOriginDiagnostic(
|
|
195
|
-
claim,
|
|
196
|
-
'directive.invalid_path_class',
|
|
197
|
-
`Directive "${directive_name}" must point to path class "${type_definition.path_class}".`,
|
|
198
225
|
),
|
|
199
|
-
|
|
226
|
+
);
|
|
200
227
|
}
|
|
201
228
|
|
|
202
229
|
/**
|
|
203
|
-
* @param {Record<string, MappingDefinition>} mappings
|
|
204
230
|
* @param {PatramClaim} claim
|
|
205
|
-
* @param {string}
|
|
206
|
-
* @param {
|
|
207
|
-
* @param {
|
|
208
|
-
* @
|
|
209
|
-
* @param {PatramRepoConfig} repo_config
|
|
210
|
-
* @returns {boolean}
|
|
231
|
+
* @param {string} directive_name
|
|
232
|
+
* @param {string} directive_value
|
|
233
|
+
* @param {string[]} allowed_values
|
|
234
|
+
* @returns {PatramDiagnostic[]}
|
|
211
235
|
*/
|
|
212
|
-
function
|
|
213
|
-
mappings,
|
|
236
|
+
function checkEnumValue(
|
|
214
237
|
claim,
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
document_paths,
|
|
219
|
-
repo_config,
|
|
238
|
+
directive_name,
|
|
239
|
+
directive_value,
|
|
240
|
+
allowed_values,
|
|
220
241
|
) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
if (!path_class_definition) {
|
|
224
|
-
return true;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const mapping_definition = resolveDirectiveMapping(mappings, claim);
|
|
228
|
-
const target_kind = mapping_definition?.emit?.target_class ?? 'document';
|
|
229
|
-
const resolved_target = resolveTargetReference(
|
|
230
|
-
target_kind,
|
|
231
|
-
'path',
|
|
232
|
-
claim,
|
|
233
|
-
document_entity_keys,
|
|
234
|
-
document_node_references,
|
|
235
|
-
document_paths,
|
|
236
|
-
);
|
|
237
|
-
|
|
238
|
-
if (!resolved_target.path) {
|
|
239
|
-
return false;
|
|
242
|
+
if (allowed_values.includes(directive_value)) {
|
|
243
|
+
return [];
|
|
240
244
|
}
|
|
241
245
|
|
|
242
|
-
return
|
|
243
|
-
|
|
244
|
-
|
|
246
|
+
return [
|
|
247
|
+
createOriginDiagnostic(
|
|
248
|
+
claim,
|
|
249
|
+
'directive.invalid_enum',
|
|
250
|
+
`Directive "${directive_name}" must be one of ${formatQuotedList(allowed_values)}.`,
|
|
251
|
+
),
|
|
252
|
+
];
|
|
245
253
|
}
|
|
246
254
|
|
|
247
255
|
/**
|
|
@@ -263,11 +271,7 @@ function resolveDirectiveMapping(mappings, claim) {
|
|
|
263
271
|
* @returns {string}
|
|
264
272
|
*/
|
|
265
273
|
function getDirectiveValidationFieldName(directive_name, mapping_definition) {
|
|
266
|
-
|
|
267
|
-
return mapping_definition.node.field;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
return directive_name;
|
|
274
|
+
return mapping_definition?.node?.field ?? directive_name;
|
|
271
275
|
}
|
|
272
276
|
|
|
273
277
|
/**
|
|
@@ -282,10 +286,3 @@ function isStructuralDirectiveField(field_name) {
|
|
|
282
286
|
field_name === 'title'
|
|
283
287
|
);
|
|
284
288
|
}
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* @param {PatramClaim} claim
|
|
288
|
-
* @param {string} code
|
|
289
|
-
* @param {string} message
|
|
290
|
-
* @returns {PatramDiagnostic}
|
|
291
|
-
*/
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import { MappingDefinition } from './patram-config.types.ts';
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @returns {Record<string, { prefixes: string[] }>}
|
|
7
|
+
*/
|
|
8
|
+
export function createDirectivePathClasses() {
|
|
9
|
+
return {
|
|
10
|
+
decision_docs: {
|
|
11
|
+
prefixes: ['docs/decisions/'],
|
|
12
|
+
},
|
|
13
|
+
plan_docs: {
|
|
14
|
+
prefixes: ['docs/plans/'],
|
|
15
|
+
},
|
|
16
|
+
task_docs: {
|
|
17
|
+
prefixes: ['docs/tasks/'],
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @returns {Record<string, { from: string[], to: string[] }>}
|
|
24
|
+
*/
|
|
25
|
+
export function createDirectiveRelations() {
|
|
26
|
+
return {
|
|
27
|
+
decided_by: {
|
|
28
|
+
from: ['document'],
|
|
29
|
+
to: ['document'],
|
|
30
|
+
},
|
|
31
|
+
tracked_in: {
|
|
32
|
+
from: ['document'],
|
|
33
|
+
to: ['document'],
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @returns {Record<string, MappingDefinition>}
|
|
40
|
+
*/
|
|
41
|
+
export function createMarkdownDirectiveMappings() {
|
|
42
|
+
return {
|
|
43
|
+
'markdown.directive.decided_by': createRelationMapping('decided_by'),
|
|
44
|
+
'markdown.directive.kind': createNodeMapping('$class'),
|
|
45
|
+
'markdown.directive.status': createNodeMapping('status'),
|
|
46
|
+
'markdown.directive.tracked_in': createRelationMapping('tracked_in'),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @returns {Record<string, MappingDefinition>}
|
|
52
|
+
*/
|
|
53
|
+
export function createJsdocDirectiveMappings() {
|
|
54
|
+
return {
|
|
55
|
+
'jsdoc.directive.decided_by': createRelationMapping('decided_by'),
|
|
56
|
+
'jsdoc.directive.kind': createNodeMapping('$class'),
|
|
57
|
+
'jsdoc.directive.status': createNodeMapping('status'),
|
|
58
|
+
'jsdoc.directive.tracked_in': createRelationMapping('tracked_in'),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @param {string} field_name
|
|
64
|
+
* @returns {MappingDefinition}
|
|
65
|
+
*/
|
|
66
|
+
function createNodeMapping(field_name) {
|
|
67
|
+
return {
|
|
68
|
+
node: {
|
|
69
|
+
class: 'document',
|
|
70
|
+
field: field_name,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @param {string} relation_name
|
|
77
|
+
* @returns {MappingDefinition}
|
|
78
|
+
*/
|
|
79
|
+
function createRelationMapping(relation_name) {
|
|
80
|
+
return {
|
|
81
|
+
emit: {
|
|
82
|
+
relation: relation_name,
|
|
83
|
+
target: 'path',
|
|
84
|
+
target_class: 'document',
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -40,6 +40,14 @@ import { DEFAULT_INCLUDE_PATTERNS } from './source-file-defaults.js';
|
|
|
40
40
|
|
|
41
41
|
const CONFIG_FILE_NAME = '.patram.json';
|
|
42
42
|
const RESERVED_STRUCTURAL_FIELD_NAMES = new Set(['$class', '$id', '$path']);
|
|
43
|
+
const MARKDOWN_STYLE_NAMES = [
|
|
44
|
+
'front_matter',
|
|
45
|
+
'visible_line',
|
|
46
|
+
'list_item',
|
|
47
|
+
'hidden_tag',
|
|
48
|
+
];
|
|
49
|
+
const MARKDOWN_STYLE_NAME_SET = new Set(MARKDOWN_STYLE_NAMES);
|
|
50
|
+
const MIXED_STYLE_VALUES = new Set(['ignore', 'error']);
|
|
43
51
|
|
|
44
52
|
/**
|
|
45
53
|
* @typedef {object} PatramDiagnostic
|
|
@@ -224,6 +232,7 @@ const metadata_field_schema = z.discriminatedUnion('type', [
|
|
|
224
232
|
*/
|
|
225
233
|
const class_field_rule_schema = z
|
|
226
234
|
.object({
|
|
235
|
+
markdown_styles: z.array(z.string().min(1)).optional(),
|
|
227
236
|
presence: z.enum(['required', 'optional', 'forbidden']),
|
|
228
237
|
})
|
|
229
238
|
.strict();
|
|
@@ -235,6 +244,8 @@ const class_schema_schema = z
|
|
|
235
244
|
.object({
|
|
236
245
|
document_path_class: z.string().min(1).optional(),
|
|
237
246
|
fields: z.record(z.string().min(1), class_field_rule_schema).default({}),
|
|
247
|
+
markdown_styles: z.array(z.string().min(1)).optional(),
|
|
248
|
+
mixed_styles: z.string().min(1).optional(),
|
|
238
249
|
unknown_fields: z.enum(['ignore', 'error']).optional(),
|
|
239
250
|
})
|
|
240
251
|
.strict();
|
|
@@ -926,17 +937,32 @@ function collectClassSchemaConfigDiagnostics(
|
|
|
926
937
|
continue;
|
|
927
938
|
}
|
|
928
939
|
|
|
940
|
+
collectMarkdownStylesDiagnostic(
|
|
941
|
+
diagnostics,
|
|
942
|
+
`classes.${class_name}.schema.markdown_styles`,
|
|
943
|
+
schema_definition.markdown_styles,
|
|
944
|
+
);
|
|
945
|
+
collectMixedStylesDiagnostic(
|
|
946
|
+
diagnostics,
|
|
947
|
+
`classes.${class_name}.schema.mixed_styles`,
|
|
948
|
+
schema_definition.mixed_styles,
|
|
949
|
+
);
|
|
950
|
+
|
|
929
951
|
for (const field_name of Object.keys(schema_definition.fields)) {
|
|
930
952
|
if (fields[field_name]) {
|
|
931
|
-
|
|
953
|
+
collectMarkdownStylesDiagnostic(
|
|
954
|
+
diagnostics,
|
|
955
|
+
`classes.${class_name}.schema.fields.${field_name}.markdown_styles`,
|
|
956
|
+
schema_definition.fields[field_name].markdown_styles,
|
|
957
|
+
);
|
|
958
|
+
} else {
|
|
959
|
+
diagnostics.push(
|
|
960
|
+
createConfigDiagnostic(
|
|
961
|
+
`classes.${class_name}.schema.fields.${field_name}`,
|
|
962
|
+
`Unknown field "${field_name}".`,
|
|
963
|
+
),
|
|
964
|
+
);
|
|
932
965
|
}
|
|
933
|
-
|
|
934
|
-
diagnostics.push(
|
|
935
|
-
createConfigDiagnostic(
|
|
936
|
-
`classes.${class_name}.schema.fields.${field_name}`,
|
|
937
|
-
`Unknown field "${field_name}".`,
|
|
938
|
-
),
|
|
939
|
-
);
|
|
940
966
|
}
|
|
941
967
|
}
|
|
942
968
|
|
|
@@ -963,6 +989,67 @@ function collectClassSchemaConfigDiagnostics(
|
|
|
963
989
|
}
|
|
964
990
|
}
|
|
965
991
|
|
|
992
|
+
/**
|
|
993
|
+
* @param {PatramDiagnostic[]} diagnostics
|
|
994
|
+
* @param {string} diagnostic_path
|
|
995
|
+
* @param {string[] | undefined} markdown_styles
|
|
996
|
+
*/
|
|
997
|
+
function collectMarkdownStylesDiagnostic(
|
|
998
|
+
diagnostics,
|
|
999
|
+
diagnostic_path,
|
|
1000
|
+
markdown_styles,
|
|
1001
|
+
) {
|
|
1002
|
+
if (markdown_styles === undefined) {
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
if (markdown_styles.length === 0) {
|
|
1007
|
+
diagnostics.push(
|
|
1008
|
+
createConfigDiagnostic(
|
|
1009
|
+
diagnostic_path,
|
|
1010
|
+
'Markdown styles must contain at least one style.',
|
|
1011
|
+
),
|
|
1012
|
+
);
|
|
1013
|
+
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
for (const markdown_style of markdown_styles) {
|
|
1018
|
+
if (MARKDOWN_STYLE_NAME_SET.has(markdown_style)) {
|
|
1019
|
+
continue;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
diagnostics.push(
|
|
1023
|
+
createConfigDiagnostic(
|
|
1024
|
+
diagnostic_path,
|
|
1025
|
+
`Unknown markdown style "${markdown_style}".`,
|
|
1026
|
+
),
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
/**
|
|
1032
|
+
* @param {PatramDiagnostic[]} diagnostics
|
|
1033
|
+
* @param {string} diagnostic_path
|
|
1034
|
+
* @param {string | undefined} mixed_styles
|
|
1035
|
+
*/
|
|
1036
|
+
function collectMixedStylesDiagnostic(
|
|
1037
|
+
diagnostics,
|
|
1038
|
+
diagnostic_path,
|
|
1039
|
+
mixed_styles,
|
|
1040
|
+
) {
|
|
1041
|
+
if (mixed_styles === undefined || MIXED_STYLE_VALUES.has(mixed_styles)) {
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
diagnostics.push(
|
|
1046
|
+
createConfigDiagnostic(
|
|
1047
|
+
diagnostic_path,
|
|
1048
|
+
'Mixed styles must be "ignore" or "error".',
|
|
1049
|
+
),
|
|
1050
|
+
);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
966
1053
|
/**
|
|
967
1054
|
* @param {PatramRepoConfig['classes']} classes
|
|
968
1055
|
* @returns {Record<string, ClassDefinition>}
|
|
@@ -10,7 +10,7 @@ import { resolve } from 'node:path';
|
|
|
10
10
|
import { buildGraph } from './build-graph.js';
|
|
11
11
|
import { listSourceFiles } from './list-source-files.js';
|
|
12
12
|
import { loadPatramConfig } from './load-patram-config.js';
|
|
13
|
-
import { parseSourceFile } from './parse-claims.js';
|
|
13
|
+
import { createParseOptions, parseSourceFile } from './parse-claims.js';
|
|
14
14
|
import { resolvePatramGraphConfig } from './resolve-patram-graph-config.js';
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -68,6 +68,7 @@ export async function loadProjectGraph(project_directory) {
|
|
|
68
68
|
project_directory,
|
|
69
69
|
);
|
|
70
70
|
const collect_result = await collectClaims(
|
|
71
|
+
repo_config,
|
|
71
72
|
source_file_paths,
|
|
72
73
|
project_directory,
|
|
73
74
|
);
|
|
@@ -96,25 +97,34 @@ export async function loadProjectGraph(project_directory) {
|
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
/**
|
|
100
|
+
* @param {PatramRepoConfig} repo_config
|
|
99
101
|
* @param {string[]} source_file_paths
|
|
100
102
|
* @param {string} project_directory
|
|
101
103
|
* @returns {Promise<{ claims: PatramClaim[], diagnostics: PatramDiagnostic[] }>}
|
|
102
104
|
*/
|
|
103
|
-
async function collectClaims(
|
|
105
|
+
async function collectClaims(
|
|
106
|
+
repo_config,
|
|
107
|
+
source_file_paths,
|
|
108
|
+
project_directory,
|
|
109
|
+
) {
|
|
104
110
|
/** @type {PatramClaim[]} */
|
|
105
111
|
const claims = [];
|
|
106
112
|
/** @type {PatramDiagnostic[]} */
|
|
107
113
|
const diagnostics = [];
|
|
114
|
+
const parse_options = createParseOptions(repo_config);
|
|
108
115
|
|
|
109
116
|
for (const source_file_path of source_file_paths) {
|
|
110
117
|
const source_text = await readFile(
|
|
111
118
|
resolve(project_directory, source_file_path),
|
|
112
119
|
'utf8',
|
|
113
120
|
);
|
|
114
|
-
const parse_result = parseSourceFile(
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
121
|
+
const parse_result = parseSourceFile(
|
|
122
|
+
{
|
|
123
|
+
path: source_file_path,
|
|
124
|
+
source: source_text,
|
|
125
|
+
},
|
|
126
|
+
parse_options,
|
|
127
|
+
);
|
|
118
128
|
|
|
119
129
|
claims.push(...parse_result.claims);
|
|
120
130
|
diagnostics.push(...parse_result.diagnostics);
|