@principal-ai/principal-view-cli 0.2.0 → 0.2.2
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/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +41 -4
- package/dist/index.cjs +39 -6
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+pCpC,wBAAgB,qBAAqB,IAAI,OAAO,CAiI/C"}
|
|
@@ -396,8 +396,9 @@ function hasOtelFeatures(canvas) {
|
|
|
396
396
|
* - Edge types reference defined types in pv.edgeTypes or library.edgeComponents
|
|
397
397
|
* - Node types reference defined types in pv.nodeTypes or library.nodeComponents
|
|
398
398
|
* - Canvas has pv extension with name and version
|
|
399
|
+
* - OTEL nodes have source file references and the files exist
|
|
399
400
|
*/
|
|
400
|
-
function validateCanvas(canvas, filePath, library) {
|
|
401
|
+
function validateCanvas(canvas, filePath, library, repositoryPath) {
|
|
401
402
|
const issues = [];
|
|
402
403
|
if (!canvas || typeof canvas !== 'object') {
|
|
403
404
|
issues.push({ type: 'error', message: 'Canvas must be an object' });
|
|
@@ -633,6 +634,37 @@ function validateCanvas(canvas, filePath, library) {
|
|
|
633
634
|
if (nodePv.otel && typeof nodePv.otel === 'object') {
|
|
634
635
|
checkUnknownFields(nodePv.otel, ALLOWED_CANVAS_FIELDS.nodePvOtel, `${nodePath}.pv.otel`, issues);
|
|
635
636
|
}
|
|
637
|
+
// Validate source file references for OTEL event nodes
|
|
638
|
+
const hasOtelFeatures = nodePv.otel !== undefined || nodePv.events !== undefined;
|
|
639
|
+
if (hasOtelFeatures) {
|
|
640
|
+
// OTEL nodes must have at least one source file reference
|
|
641
|
+
if (!Array.isArray(nodePv.sources) || nodePv.sources.length === 0) {
|
|
642
|
+
issues.push({
|
|
643
|
+
type: 'error',
|
|
644
|
+
message: `Node "${nodeLabel}" has OTEL features but is missing required "pv.sources" field`,
|
|
645
|
+
path: `${nodePath}.pv.sources`,
|
|
646
|
+
suggestion: 'Add at least one source file reference, e.g.: "sources": ["src/services/MyService.ts"]',
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
// Validate that all source files exist (if repository path is provided)
|
|
651
|
+
if (Array.isArray(nodePv.sources) && repositoryPath) {
|
|
652
|
+
nodePv.sources.forEach((source, sourceIndex) => {
|
|
653
|
+
if (typeof source === 'string') {
|
|
654
|
+
// Remove glob patterns (* characters) to get the base path
|
|
655
|
+
const cleanPath = source.replace(/\*/g, '');
|
|
656
|
+
const fullPath = resolve(repositoryPath, cleanPath);
|
|
657
|
+
if (!existsSync(fullPath)) {
|
|
658
|
+
issues.push({
|
|
659
|
+
type: 'error',
|
|
660
|
+
message: `Node "${nodeLabel}" references non-existent source file: ${source}`,
|
|
661
|
+
path: `${nodePath}.pv.sources[${sourceIndex}]`,
|
|
662
|
+
suggestion: `Verify the file path is correct relative to repository root: ${repositoryPath}`,
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
});
|
|
667
|
+
}
|
|
636
668
|
if (Array.isArray(nodePv.actions)) {
|
|
637
669
|
nodePv.actions.forEach((action, actionIndex) => {
|
|
638
670
|
if (action && typeof action === 'object') {
|
|
@@ -855,7 +887,7 @@ function validateCanvas(canvas, filePath, library) {
|
|
|
855
887
|
/**
|
|
856
888
|
* Validate a single .canvas file
|
|
857
889
|
*/
|
|
858
|
-
function validateFile(filePath, library) {
|
|
890
|
+
function validateFile(filePath, library, repositoryPath) {
|
|
859
891
|
const absolutePath = resolve(filePath);
|
|
860
892
|
const relativePath = relative(process.cwd(), absolutePath);
|
|
861
893
|
if (!existsSync(absolutePath)) {
|
|
@@ -868,7 +900,7 @@ function validateFile(filePath, library) {
|
|
|
868
900
|
try {
|
|
869
901
|
const content = readFileSync(absolutePath, 'utf8');
|
|
870
902
|
const canvas = JSON.parse(content);
|
|
871
|
-
const issues = validateCanvas(canvas, relativePath, library);
|
|
903
|
+
const issues = validateCanvas(canvas, relativePath, library, repositoryPath);
|
|
872
904
|
const hasErrors = issues.some((i) => i.type === 'error');
|
|
873
905
|
return {
|
|
874
906
|
file: relativePath,
|
|
@@ -892,6 +924,7 @@ export function createValidateCommand() {
|
|
|
892
924
|
.argument('[files...]', 'Files or glob patterns to validate (defaults to .principal-views/*.canvas)')
|
|
893
925
|
.option('-q, --quiet', 'Only output errors')
|
|
894
926
|
.option('--json', 'Output results as JSON')
|
|
927
|
+
.option('-r, --repository <path>', 'Repository root path for validating source file references (defaults to current directory)')
|
|
895
928
|
.action(async (files, options) => {
|
|
896
929
|
try {
|
|
897
930
|
// Default to .principal-views/*.canvas if no files specified
|
|
@@ -914,6 +947,10 @@ export function createValidateCommand() {
|
|
|
914
947
|
// Load library from .principal-views directory (used for type validation)
|
|
915
948
|
const principalViewsDir = resolve(process.cwd(), '.principal-views');
|
|
916
949
|
const library = loadLibrary(principalViewsDir);
|
|
950
|
+
// Determine repository path for source file validation
|
|
951
|
+
const repositoryPath = options.repository
|
|
952
|
+
? resolve(options.repository)
|
|
953
|
+
: process.cwd();
|
|
917
954
|
// Validate library if present
|
|
918
955
|
let libraryResult = null;
|
|
919
956
|
if (library && Object.keys(library.raw).length > 0) {
|
|
@@ -926,7 +963,7 @@ export function createValidateCommand() {
|
|
|
926
963
|
};
|
|
927
964
|
}
|
|
928
965
|
// Validate all canvas files
|
|
929
|
-
const results = matchedFiles.map((f) => validateFile(f, library));
|
|
966
|
+
const results = matchedFiles.map((f) => validateFile(f, library, repositoryPath));
|
|
930
967
|
// Combine results
|
|
931
968
|
const allResults = libraryResult ? [libraryResult, ...results] : results;
|
|
932
969
|
const validCount = allResults.filter((r) => r.isValid).length;
|
package/dist/index.cjs
CHANGED
|
@@ -228747,7 +228747,7 @@ function hasOtelFeatures(canvas) {
|
|
|
228747
228747
|
}
|
|
228748
228748
|
return false;
|
|
228749
228749
|
}
|
|
228750
|
-
function validateCanvas(canvas, filePath, library) {
|
|
228750
|
+
function validateCanvas(canvas, filePath, library, repositoryPath) {
|
|
228751
228751
|
const issues = [];
|
|
228752
228752
|
if (!canvas || typeof canvas !== "object") {
|
|
228753
228753
|
issues.push({ type: "error", message: "Canvas must be an object" });
|
|
@@ -229019,6 +229019,33 @@ function validateCanvas(canvas, filePath, library) {
|
|
|
229019
229019
|
issues
|
|
229020
229020
|
);
|
|
229021
229021
|
}
|
|
229022
|
+
const hasOtelFeatures2 = nodePv.otel !== void 0 || nodePv.events !== void 0;
|
|
229023
|
+
if (hasOtelFeatures2) {
|
|
229024
|
+
if (!Array.isArray(nodePv.sources) || nodePv.sources.length === 0) {
|
|
229025
|
+
issues.push({
|
|
229026
|
+
type: "error",
|
|
229027
|
+
message: `Node "${nodeLabel}" has OTEL features but is missing required "pv.sources" field`,
|
|
229028
|
+
path: `${nodePath2}.pv.sources`,
|
|
229029
|
+
suggestion: 'Add at least one source file reference, e.g.: "sources": ["src/services/MyService.ts"]'
|
|
229030
|
+
});
|
|
229031
|
+
}
|
|
229032
|
+
}
|
|
229033
|
+
if (Array.isArray(nodePv.sources) && repositoryPath) {
|
|
229034
|
+
nodePv.sources.forEach((source, sourceIndex) => {
|
|
229035
|
+
if (typeof source === "string") {
|
|
229036
|
+
const cleanPath = source.replace(/\*/g, "");
|
|
229037
|
+
const fullPath = (0, import_node_path5.resolve)(repositoryPath, cleanPath);
|
|
229038
|
+
if (!(0, import_node_fs4.existsSync)(fullPath)) {
|
|
229039
|
+
issues.push({
|
|
229040
|
+
type: "error",
|
|
229041
|
+
message: `Node "${nodeLabel}" references non-existent source file: ${source}`,
|
|
229042
|
+
path: `${nodePath2}.pv.sources[${sourceIndex}]`,
|
|
229043
|
+
suggestion: `Verify the file path is correct relative to repository root: ${repositoryPath}`
|
|
229044
|
+
});
|
|
229045
|
+
}
|
|
229046
|
+
}
|
|
229047
|
+
});
|
|
229048
|
+
}
|
|
229022
229049
|
if (Array.isArray(nodePv.actions)) {
|
|
229023
229050
|
nodePv.actions.forEach((action, actionIndex) => {
|
|
229024
229051
|
if (action && typeof action === "object") {
|
|
@@ -229230,7 +229257,7 @@ function validateCanvas(canvas, filePath, library) {
|
|
|
229230
229257
|
}
|
|
229231
229258
|
return issues;
|
|
229232
229259
|
}
|
|
229233
|
-
function validateFile(filePath, library) {
|
|
229260
|
+
function validateFile(filePath, library, repositoryPath) {
|
|
229234
229261
|
const absolutePath = (0, import_node_path5.resolve)(filePath);
|
|
229235
229262
|
const relativePath = (0, import_node_path5.relative)(process.cwd(), absolutePath);
|
|
229236
229263
|
if (!(0, import_node_fs4.existsSync)(absolutePath)) {
|
|
@@ -229243,7 +229270,7 @@ function validateFile(filePath, library) {
|
|
|
229243
229270
|
try {
|
|
229244
229271
|
const content = (0, import_node_fs4.readFileSync)(absolutePath, "utf8");
|
|
229245
229272
|
const canvas = JSON.parse(content);
|
|
229246
|
-
const issues = validateCanvas(canvas, relativePath, library);
|
|
229273
|
+
const issues = validateCanvas(canvas, relativePath, library, repositoryPath);
|
|
229247
229274
|
const hasErrors = issues.some((i) => i.type === "error");
|
|
229248
229275
|
return {
|
|
229249
229276
|
file: relativePath,
|
|
@@ -229264,7 +229291,10 @@ function createValidateCommand() {
|
|
|
229264
229291
|
command.description("Validate .canvas configuration files").argument(
|
|
229265
229292
|
"[files...]",
|
|
229266
229293
|
"Files or glob patterns to validate (defaults to .principal-views/*.canvas)"
|
|
229267
|
-
).option("-q, --quiet", "Only output errors").option("--json", "Output results as JSON").
|
|
229294
|
+
).option("-q, --quiet", "Only output errors").option("--json", "Output results as JSON").option(
|
|
229295
|
+
"-r, --repository <path>",
|
|
229296
|
+
"Repository root path for validating source file references (defaults to current directory)"
|
|
229297
|
+
).action(async (files, options) => {
|
|
229268
229298
|
try {
|
|
229269
229299
|
const patterns = files.length > 0 ? files : [".principal-views/*.canvas"];
|
|
229270
229300
|
const matchedFiles = await globby(patterns, {
|
|
@@ -229282,6 +229312,7 @@ function createValidateCommand() {
|
|
|
229282
229312
|
}
|
|
229283
229313
|
const principalViewsDir = (0, import_node_path5.resolve)(process.cwd(), ".principal-views");
|
|
229284
229314
|
const library = loadLibrary(principalViewsDir);
|
|
229315
|
+
const repositoryPath = options.repository ? (0, import_node_path5.resolve)(options.repository) : process.cwd();
|
|
229285
229316
|
let libraryResult = null;
|
|
229286
229317
|
if (library && Object.keys(library.raw).length > 0) {
|
|
229287
229318
|
const libraryIssues = validateLibrary(library);
|
|
@@ -229292,7 +229323,9 @@ function createValidateCommand() {
|
|
|
229292
229323
|
issues: libraryIssues
|
|
229293
229324
|
};
|
|
229294
229325
|
}
|
|
229295
|
-
const results = matchedFiles.map(
|
|
229326
|
+
const results = matchedFiles.map(
|
|
229327
|
+
(f) => validateFile(f, library, repositoryPath)
|
|
229328
|
+
);
|
|
229296
229329
|
const allResults = libraryResult ? [libraryResult, ...results] : results;
|
|
229297
229330
|
const validCount = allResults.filter((r) => r.isValid).length;
|
|
229298
229331
|
const invalidCount = allResults.length - validCount;
|
|
@@ -242886,7 +242919,7 @@ function createNarrativeCommand() {
|
|
|
242886
242919
|
}
|
|
242887
242920
|
|
|
242888
242921
|
// src/index.ts
|
|
242889
|
-
var VERSION2 = "0.2.
|
|
242922
|
+
var VERSION2 = "0.2.1";
|
|
242890
242923
|
var program2 = new Command();
|
|
242891
242924
|
program2.name("privu").description("Principal View CLI - Validate and manage .canvas configuration files").version(VERSION2);
|
|
242892
242925
|
program2.addCommand(createInitCommand());
|