@living-architecture/riviere-cli 0.2.4 → 0.3.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.
Files changed (3) hide show
  1. package/dist/bin.js +106 -72
  2. package/dist/index.js +106 -72
  3. package/package.json +4 -4
package/dist/bin.js CHANGED
@@ -6802,7 +6802,7 @@ var require_dist = __commonJS({
6802
6802
  });
6803
6803
 
6804
6804
  // src/cli.ts
6805
- import { Command as Command20 } from "commander";
6805
+ import { Command as Command21 } from "commander";
6806
6806
  import { createRequire } from "module";
6807
6807
 
6808
6808
  // src/commands/builder/add-component.ts
@@ -6954,11 +6954,6 @@ var riviere_schema_default = {
6954
6954
  },
6955
6955
  sourceLocation: {
6956
6956
  $ref: "#/definitions/sourceLocation"
6957
- },
6958
- metadata: {
6959
- type: "object",
6960
- description: "Extensible metadata for custom properties",
6961
- additionalProperties: true
6962
6957
  }
6963
6958
  }
6964
6959
  },
@@ -6973,7 +6968,6 @@ var riviere_schema_default = {
6973
6968
  module: { type: "string", minLength: 1 },
6974
6969
  description: { type: "string" },
6975
6970
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
6976
- metadata: { type: "object", additionalProperties: true },
6977
6971
  route: { type: "string", description: "URL route where UI component is rendered", minLength: 1 }
6978
6972
  },
6979
6973
  additionalProperties: false
@@ -6989,7 +6983,6 @@ var riviere_schema_default = {
6989
6983
  module: { type: "string", minLength: 1 },
6990
6984
  description: { type: "string" },
6991
6985
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
6992
- metadata: { type: "object", additionalProperties: true },
6993
6986
  apiType: { const: "REST" },
6994
6987
  httpMethod: { type: "string", enum: ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"] },
6995
6988
  path: { type: "string", description: "API path" }
@@ -7007,7 +7000,6 @@ var riviere_schema_default = {
7007
7000
  module: { type: "string", minLength: 1 },
7008
7001
  description: { type: "string" },
7009
7002
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
7010
- metadata: { type: "object", additionalProperties: true },
7011
7003
  apiType: { const: "GraphQL" },
7012
7004
  operationName: { type: "string", description: "GraphQL operation name" }
7013
7005
  },
@@ -7024,7 +7016,6 @@ var riviere_schema_default = {
7024
7016
  module: { type: "string", minLength: 1 },
7025
7017
  description: { type: "string" },
7026
7018
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
7027
- metadata: { type: "object", additionalProperties: true },
7028
7019
  apiType: { const: "other" }
7029
7020
  },
7030
7021
  additionalProperties: false
@@ -7039,8 +7030,7 @@ var riviere_schema_default = {
7039
7030
  domain: { type: "string", minLength: 1 },
7040
7031
  module: { type: "string", minLength: 1 },
7041
7032
  description: { type: "string" },
7042
- sourceLocation: { $ref: "#/definitions/sourceLocation" },
7043
- metadata: { type: "object", additionalProperties: true }
7033
+ sourceLocation: { $ref: "#/definitions/sourceLocation" }
7044
7034
  },
7045
7035
  additionalProperties: false
7046
7036
  },
@@ -7055,7 +7045,6 @@ var riviere_schema_default = {
7055
7045
  module: { type: "string", minLength: 1 },
7056
7046
  description: { type: "string" },
7057
7047
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
7058
- metadata: { type: "object", additionalProperties: true },
7059
7048
  operationName: { type: "string", description: "Operation name" },
7060
7049
  entity: { type: "string", description: "Entity name" },
7061
7050
  signature: { $ref: "#/definitions/operationSignature" },
@@ -7076,7 +7065,6 @@ var riviere_schema_default = {
7076
7065
  module: { type: "string", minLength: 1 },
7077
7066
  description: { type: "string" },
7078
7067
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
7079
- metadata: { type: "object", additionalProperties: true },
7080
7068
  eventName: { type: "string", description: "Event name" },
7081
7069
  eventSchema: { type: "string", description: "Event schema definition" }
7082
7070
  },
@@ -7093,7 +7081,6 @@ var riviere_schema_default = {
7093
7081
  module: { type: "string", minLength: 1 },
7094
7082
  description: { type: "string" },
7095
7083
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
7096
- metadata: { type: "object", additionalProperties: true },
7097
7084
  subscribedEvents: { type: "array", items: { type: "string" }, description: "Events this handler subscribes to" }
7098
7085
  },
7099
7086
  additionalProperties: false
@@ -7109,7 +7096,6 @@ var riviere_schema_default = {
7109
7096
  module: { type: "string", minLength: 1 },
7110
7097
  description: { type: "string" },
7111
7098
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
7112
- metadata: { type: "object", additionalProperties: true },
7113
7099
  customTypeName: { type: "string", description: "Name of the custom type (must match a key in metadata.customTypes)", minLength: 1 }
7114
7100
  },
7115
7101
  additionalProperties: false
@@ -7153,11 +7139,6 @@ var riviere_schema_default = {
7153
7139
  },
7154
7140
  sourceLocation: {
7155
7141
  $ref: "#/definitions/sourceLocation"
7156
- },
7157
- metadata: {
7158
- type: "object",
7159
- description: "Extensible metadata for custom properties",
7160
- additionalProperties: true
7161
7142
  }
7162
7143
  },
7163
7144
  additionalProperties: false
@@ -7191,11 +7172,6 @@ var riviere_schema_default = {
7191
7172
  },
7192
7173
  sourceLocation: {
7193
7174
  $ref: "#/definitions/sourceLocation"
7194
- },
7195
- metadata: {
7196
- type: "object",
7197
- description: "Extensible metadata for custom properties",
7198
- additionalProperties: true
7199
7175
  }
7200
7176
  },
7201
7177
  additionalProperties: false
@@ -7276,7 +7252,7 @@ var riviere_schema_default = {
7276
7252
  description: "Classification of domain's role in system"
7277
7253
  }
7278
7254
  },
7279
- additionalProperties: true
7255
+ additionalProperties: false
7280
7256
  },
7281
7257
  customTypeDefinition: {
7282
7258
  type: "object",
@@ -21523,22 +21499,6 @@ function validateCustomTypes(graph) {
21523
21499
  message: `Custom type '${customTypeName}' is not defined in metadata.customTypes`,
21524
21500
  code: "INVALID_TYPE"
21525
21501
  });
21526
- return;
21527
- }
21528
- const typeDefinition = customTypes[customTypeName];
21529
- const requiredProperties = typeDefinition?.requiredProperties;
21530
- const hasNoRequiredProperties = requiredProperties === void 0;
21531
- if (hasNoRequiredProperties)
21532
- return;
21533
- const requiredPropertyNames = Object.keys(requiredProperties);
21534
- const componentMetadata = component.metadata;
21535
- const missingProperties = componentMetadata ? requiredPropertyNames.filter((prop) => !(prop in componentMetadata)) : requiredPropertyNames;
21536
- if (missingProperties.length > 0) {
21537
- errors.push({
21538
- path: `/components/${index}`,
21539
- message: `Custom component is missing required properties for type '${customTypeName}': ${missingProperties.join(", ")}`,
21540
- code: "INVALID_TYPE"
21541
- });
21542
21502
  }
21543
21503
  });
21544
21504
  return errors;
@@ -22575,8 +22535,7 @@ var RiviereBuilder = class _RiviereBuilder {
22575
22535
  module: input.module,
22576
22536
  route: input.route,
22577
22537
  sourceLocation: input.sourceLocation,
22578
- ...input.description !== void 0 && { description: input.description },
22579
- ...input.metadata !== void 0 && { metadata: input.metadata }
22538
+ ...input.description !== void 0 && { description: input.description }
22580
22539
  };
22581
22540
  return this.registerComponent(component);
22582
22541
  }
@@ -22614,8 +22573,7 @@ var RiviereBuilder = class _RiviereBuilder {
22614
22573
  ...input.httpMethod !== void 0 && { httpMethod: input.httpMethod },
22615
22574
  ...input.path !== void 0 && { path: input.path },
22616
22575
  ...input.operationName !== void 0 && { operationName: input.operationName },
22617
- ...input.description !== void 0 && { description: input.description },
22618
- ...input.metadata !== void 0 && { metadata: input.metadata }
22576
+ ...input.description !== void 0 && { description: input.description }
22619
22577
  };
22620
22578
  return this.registerComponent(component);
22621
22579
  }
@@ -22646,8 +22604,7 @@ var RiviereBuilder = class _RiviereBuilder {
22646
22604
  domain: input.domain,
22647
22605
  module: input.module,
22648
22606
  sourceLocation: input.sourceLocation,
22649
- ...input.description !== void 0 && { description: input.description },
22650
- ...input.metadata !== void 0 && { metadata: input.metadata }
22607
+ ...input.description !== void 0 && { description: input.description }
22651
22608
  };
22652
22609
  return this.registerComponent(component);
22653
22610
  }
@@ -22689,8 +22646,7 @@ var RiviereBuilder = class _RiviereBuilder {
22689
22646
  ...input.behavior !== void 0 && { behavior: input.behavior },
22690
22647
  ...input.stateChanges !== void 0 && { stateChanges: input.stateChanges },
22691
22648
  ...input.businessRules !== void 0 && { businessRules: input.businessRules },
22692
- ...input.description !== void 0 && { description: input.description },
22693
- ...input.metadata !== void 0 && { metadata: input.metadata }
22649
+ ...input.description !== void 0 && { description: input.description }
22694
22650
  };
22695
22651
  return this.registerComponent(component);
22696
22652
  }
@@ -22724,8 +22680,7 @@ var RiviereBuilder = class _RiviereBuilder {
22724
22680
  eventName: input.eventName,
22725
22681
  sourceLocation: input.sourceLocation,
22726
22682
  ...input.eventSchema !== void 0 && { eventSchema: input.eventSchema },
22727
- ...input.description !== void 0 && { description: input.description },
22728
- ...input.metadata !== void 0 && { metadata: input.metadata }
22683
+ ...input.description !== void 0 && { description: input.description }
22729
22684
  };
22730
22685
  return this.registerComponent(component);
22731
22686
  }
@@ -22758,8 +22713,7 @@ var RiviereBuilder = class _RiviereBuilder {
22758
22713
  module: input.module,
22759
22714
  subscribedEvents: input.subscribedEvents,
22760
22715
  sourceLocation: input.sourceLocation,
22761
- ...input.description !== void 0 && { description: input.description },
22762
- ...input.metadata !== void 0 && { metadata: input.metadata }
22716
+ ...input.description !== void 0 && { description: input.description }
22763
22717
  };
22764
22718
  return this.registerComponent(component);
22765
22719
  }
@@ -22831,8 +22785,7 @@ var RiviereBuilder = class _RiviereBuilder {
22831
22785
  domain: input.domain,
22832
22786
  module: input.module,
22833
22787
  sourceLocation: input.sourceLocation,
22834
- ...input.description !== void 0 && { description: input.description },
22835
- ...input.metadata !== void 0 && { metadata: input.metadata }
22788
+ ...input.description !== void 0 && { description: input.description }
22836
22789
  };
22837
22790
  return this.registerComponent(component);
22838
22791
  }
@@ -22977,8 +22930,7 @@ var RiviereBuilder = class _RiviereBuilder {
22977
22930
  target: input.target,
22978
22931
  ...input.type !== void 0 && { type: input.type },
22979
22932
  ...input.description !== void 0 && { description: input.description },
22980
- ...input.sourceLocation !== void 0 && { sourceLocation: input.sourceLocation },
22981
- ...input.metadata !== void 0 && { metadata: input.metadata }
22933
+ ...input.sourceLocation !== void 0 && { sourceLocation: input.sourceLocation }
22982
22934
  };
22983
22935
  this.graph.externalLinks.push(externalLink);
22984
22936
  return externalLink;
@@ -24165,8 +24117,89 @@ Examples:
24165
24117
  });
24166
24118
  }
24167
24119
 
24168
- // src/commands/query/entry-points.ts
24120
+ // src/commands/builder/define-custom-type.ts
24169
24121
  import { Command as Command14 } from "commander";
24122
+ import { writeFile as writeFile10 } from "node:fs/promises";
24123
+ var VALID_PROPERTY_TYPES = ["string", "number", "boolean", "array", "object"];
24124
+ function isValidPropertyType(value) {
24125
+ return VALID_PROPERTY_TYPES.some((t) => t === value);
24126
+ }
24127
+ function parsePropertySpec(spec) {
24128
+ const parts = spec.split(":");
24129
+ if (parts.length < 2 || parts.length > 3) {
24130
+ return { error: `Invalid property format: "${spec}". Expected "name:type" or "name:type:description"` };
24131
+ }
24132
+ const [name, type, description] = parts;
24133
+ if (!name || name.trim() === "") {
24134
+ return { error: "Property name cannot be empty" };
24135
+ }
24136
+ if (!type || !isValidPropertyType(type)) {
24137
+ return { error: `Invalid property type: "${type}". Valid types: ${VALID_PROPERTY_TYPES.join(", ")}` };
24138
+ }
24139
+ const definition = { type };
24140
+ if (description && description.trim() !== "") {
24141
+ definition.description = description;
24142
+ }
24143
+ return { name: name.trim(), definition };
24144
+ }
24145
+ function parsePropertySpecs(specs) {
24146
+ if (specs === void 0 || specs.length === 0) {
24147
+ return { success: true, properties: {} };
24148
+ }
24149
+ const properties = {};
24150
+ for (const spec of specs) {
24151
+ const result = parsePropertySpec(spec);
24152
+ if ("error" in result) {
24153
+ return { success: false, error: result.error };
24154
+ }
24155
+ if (properties[result.name] !== void 0) {
24156
+ return { success: false, error: `Duplicate property name: "${result.name}"` };
24157
+ }
24158
+ properties[result.name] = result.definition;
24159
+ }
24160
+ return { success: true, properties };
24161
+ }
24162
+ function collect(value, previous) {
24163
+ return previous.concat([value]);
24164
+ }
24165
+ function createDefineCustomTypeCommand() {
24166
+ return new Command14("define-custom-type").description("Define a custom component type").requiredOption("--name <name>", "Custom type name").option("--description <desc>", "Custom type description").option("--required-property <spec>", "Required property (format: name:type[:description])", collect, []).option("--optional-property <spec>", "Optional property (format: name:type[:description])", collect, []).option("--graph <path>", getDefaultGraphPathDescription()).option("--json", "Output result as JSON").action(async (options) => {
24167
+ const requiredResult = parsePropertySpecs(options.requiredProperty);
24168
+ if (!requiredResult.success) {
24169
+ console.log(JSON.stringify(formatError2("VALIDATION_ERROR" /* ValidationError */, requiredResult.error, [])));
24170
+ return;
24171
+ }
24172
+ const optionalResult = parsePropertySpecs(options.optionalProperty);
24173
+ if (!optionalResult.success) {
24174
+ console.log(JSON.stringify(formatError2("VALIDATION_ERROR" /* ValidationError */, optionalResult.error, [])));
24175
+ return;
24176
+ }
24177
+ await withGraphBuilder(options.graph, async (builder, graphPath) => {
24178
+ builder.defineCustomType({
24179
+ name: options.name,
24180
+ ...options.description !== void 0 && { description: options.description },
24181
+ ...Object.keys(requiredResult.properties).length > 0 && { requiredProperties: requiredResult.properties },
24182
+ ...Object.keys(optionalResult.properties).length > 0 && { optionalProperties: optionalResult.properties }
24183
+ });
24184
+ await writeFile10(graphPath, builder.serialize(), "utf-8");
24185
+ if (options.json === true) {
24186
+ console.log(
24187
+ JSON.stringify(
24188
+ formatSuccess({
24189
+ name: options.name,
24190
+ ...options.description !== void 0 && { description: options.description },
24191
+ ...Object.keys(requiredResult.properties).length > 0 && { requiredProperties: requiredResult.properties },
24192
+ ...Object.keys(optionalResult.properties).length > 0 && { optionalProperties: optionalResult.properties }
24193
+ })
24194
+ )
24195
+ );
24196
+ }
24197
+ });
24198
+ });
24199
+ }
24200
+
24201
+ // src/commands/query/entry-points.ts
24202
+ import { Command as Command15 } from "commander";
24170
24203
 
24171
24204
  // src/commands/query/load-graph.ts
24172
24205
  import { readFile as readFile3 } from "node:fs/promises";
@@ -24214,7 +24247,7 @@ async function withGraph(graphPathOption, handler) {
24214
24247
 
24215
24248
  // src/commands/query/entry-points.ts
24216
24249
  function createEntryPointsCommand() {
24217
- return new Command14("entry-points").description("List entry points (APIs, UIs, EventHandlers with no incoming links)").addHelpText(
24250
+ return new Command15("entry-points").description("List entry points (APIs, UIs, EventHandlers with no incoming links)").addHelpText(
24218
24251
  "after",
24219
24252
  `
24220
24253
  Examples:
@@ -24232,9 +24265,9 @@ Examples:
24232
24265
  }
24233
24266
 
24234
24267
  // src/commands/query/domains.ts
24235
- import { Command as Command15 } from "commander";
24268
+ import { Command as Command16 } from "commander";
24236
24269
  function createDomainsCommand() {
24237
- return new Command15("domains").description("List domains with component counts").addHelpText(
24270
+ return new Command16("domains").description("List domains with component counts").addHelpText(
24238
24271
  "after",
24239
24272
  `
24240
24273
  Examples:
@@ -24252,9 +24285,9 @@ Examples:
24252
24285
  }
24253
24286
 
24254
24287
  // src/commands/query/trace.ts
24255
- import { Command as Command16 } from "commander";
24288
+ import { Command as Command17 } from "commander";
24256
24289
  function createTraceCommand() {
24257
- return new Command16("trace").description("Trace flow from a component (bidirectional)").addHelpText(
24290
+ return new Command17("trace").description("Trace flow from a component (bidirectional)").addHelpText(
24258
24291
  "after",
24259
24292
  `
24260
24293
  Examples:
@@ -24288,9 +24321,9 @@ Examples:
24288
24321
  }
24289
24322
 
24290
24323
  // src/commands/query/orphans.ts
24291
- import { Command as Command17 } from "commander";
24324
+ import { Command as Command18 } from "commander";
24292
24325
  function createOrphansCommand() {
24293
- return new Command17("orphans").description("Find orphan components with no links").addHelpText(
24326
+ return new Command18("orphans").description("Find orphan components with no links").addHelpText(
24294
24327
  "after",
24295
24328
  `
24296
24329
  Examples:
@@ -24308,7 +24341,7 @@ Examples:
24308
24341
  }
24309
24342
 
24310
24343
  // src/commands/query/components.ts
24311
- import { Command as Command18 } from "commander";
24344
+ import { Command as Command19 } from "commander";
24312
24345
 
24313
24346
  // src/commands/query/component-output.ts
24314
24347
  function toComponentOutput(component) {
@@ -24322,7 +24355,7 @@ function toComponentOutput(component) {
24322
24355
 
24323
24356
  // src/commands/query/components.ts
24324
24357
  function createComponentsCommand() {
24325
- return new Command18("components").description("List components with optional filtering").addHelpText(
24358
+ return new Command19("components").description("List components with optional filtering").addHelpText(
24326
24359
  "after",
24327
24360
  `
24328
24361
  Examples:
@@ -24355,9 +24388,9 @@ Examples:
24355
24388
  }
24356
24389
 
24357
24390
  // src/commands/query/search.ts
24358
- import { Command as Command19 } from "commander";
24391
+ import { Command as Command20 } from "commander";
24359
24392
  function createSearchCommand() {
24360
- return new Command19("search").description("Search components by name").addHelpText(
24393
+ return new Command20("search").description("Search components by name").addHelpText(
24361
24394
  "after",
24362
24395
  `
24363
24396
  Examples:
@@ -24391,7 +24424,7 @@ function loadPackageJson() {
24391
24424
  }
24392
24425
  var packageJson = loadPackageJson();
24393
24426
  function createProgram() {
24394
- const program2 = new Command20();
24427
+ const program2 = new Command21();
24395
24428
  program2.name("riviere").version(packageJson.version);
24396
24429
  const builderCmd = program2.command("builder").description("Commands for building a graph");
24397
24430
  builderCmd.addCommand(createAddComponentCommand());
@@ -24407,6 +24440,7 @@ function createProgram() {
24407
24440
  builderCmd.addCommand(createComponentSummaryCommand());
24408
24441
  builderCmd.addCommand(createComponentChecklistCommand());
24409
24442
  builderCmd.addCommand(createCheckConsistencyCommand());
24443
+ builderCmd.addCommand(createDefineCustomTypeCommand());
24410
24444
  const queryCmd = program2.command("query").description("Commands for querying a graph");
24411
24445
  queryCmd.addCommand(createEntryPointsCommand());
24412
24446
  queryCmd.addCommand(createDomainsCommand());
package/dist/index.js CHANGED
@@ -6801,7 +6801,7 @@ var require_dist = __commonJS({
6801
6801
  });
6802
6802
 
6803
6803
  // src/cli.ts
6804
- import { Command as Command20 } from "commander";
6804
+ import { Command as Command21 } from "commander";
6805
6805
  import { createRequire } from "module";
6806
6806
 
6807
6807
  // src/commands/builder/add-component.ts
@@ -6953,11 +6953,6 @@ var riviere_schema_default = {
6953
6953
  },
6954
6954
  sourceLocation: {
6955
6955
  $ref: "#/definitions/sourceLocation"
6956
- },
6957
- metadata: {
6958
- type: "object",
6959
- description: "Extensible metadata for custom properties",
6960
- additionalProperties: true
6961
6956
  }
6962
6957
  }
6963
6958
  },
@@ -6972,7 +6967,6 @@ var riviere_schema_default = {
6972
6967
  module: { type: "string", minLength: 1 },
6973
6968
  description: { type: "string" },
6974
6969
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
6975
- metadata: { type: "object", additionalProperties: true },
6976
6970
  route: { type: "string", description: "URL route where UI component is rendered", minLength: 1 }
6977
6971
  },
6978
6972
  additionalProperties: false
@@ -6988,7 +6982,6 @@ var riviere_schema_default = {
6988
6982
  module: { type: "string", minLength: 1 },
6989
6983
  description: { type: "string" },
6990
6984
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
6991
- metadata: { type: "object", additionalProperties: true },
6992
6985
  apiType: { const: "REST" },
6993
6986
  httpMethod: { type: "string", enum: ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"] },
6994
6987
  path: { type: "string", description: "API path" }
@@ -7006,7 +6999,6 @@ var riviere_schema_default = {
7006
6999
  module: { type: "string", minLength: 1 },
7007
7000
  description: { type: "string" },
7008
7001
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
7009
- metadata: { type: "object", additionalProperties: true },
7010
7002
  apiType: { const: "GraphQL" },
7011
7003
  operationName: { type: "string", description: "GraphQL operation name" }
7012
7004
  },
@@ -7023,7 +7015,6 @@ var riviere_schema_default = {
7023
7015
  module: { type: "string", minLength: 1 },
7024
7016
  description: { type: "string" },
7025
7017
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
7026
- metadata: { type: "object", additionalProperties: true },
7027
7018
  apiType: { const: "other" }
7028
7019
  },
7029
7020
  additionalProperties: false
@@ -7038,8 +7029,7 @@ var riviere_schema_default = {
7038
7029
  domain: { type: "string", minLength: 1 },
7039
7030
  module: { type: "string", minLength: 1 },
7040
7031
  description: { type: "string" },
7041
- sourceLocation: { $ref: "#/definitions/sourceLocation" },
7042
- metadata: { type: "object", additionalProperties: true }
7032
+ sourceLocation: { $ref: "#/definitions/sourceLocation" }
7043
7033
  },
7044
7034
  additionalProperties: false
7045
7035
  },
@@ -7054,7 +7044,6 @@ var riviere_schema_default = {
7054
7044
  module: { type: "string", minLength: 1 },
7055
7045
  description: { type: "string" },
7056
7046
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
7057
- metadata: { type: "object", additionalProperties: true },
7058
7047
  operationName: { type: "string", description: "Operation name" },
7059
7048
  entity: { type: "string", description: "Entity name" },
7060
7049
  signature: { $ref: "#/definitions/operationSignature" },
@@ -7075,7 +7064,6 @@ var riviere_schema_default = {
7075
7064
  module: { type: "string", minLength: 1 },
7076
7065
  description: { type: "string" },
7077
7066
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
7078
- metadata: { type: "object", additionalProperties: true },
7079
7067
  eventName: { type: "string", description: "Event name" },
7080
7068
  eventSchema: { type: "string", description: "Event schema definition" }
7081
7069
  },
@@ -7092,7 +7080,6 @@ var riviere_schema_default = {
7092
7080
  module: { type: "string", minLength: 1 },
7093
7081
  description: { type: "string" },
7094
7082
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
7095
- metadata: { type: "object", additionalProperties: true },
7096
7083
  subscribedEvents: { type: "array", items: { type: "string" }, description: "Events this handler subscribes to" }
7097
7084
  },
7098
7085
  additionalProperties: false
@@ -7108,7 +7095,6 @@ var riviere_schema_default = {
7108
7095
  module: { type: "string", minLength: 1 },
7109
7096
  description: { type: "string" },
7110
7097
  sourceLocation: { $ref: "#/definitions/sourceLocation" },
7111
- metadata: { type: "object", additionalProperties: true },
7112
7098
  customTypeName: { type: "string", description: "Name of the custom type (must match a key in metadata.customTypes)", minLength: 1 }
7113
7099
  },
7114
7100
  additionalProperties: false
@@ -7152,11 +7138,6 @@ var riviere_schema_default = {
7152
7138
  },
7153
7139
  sourceLocation: {
7154
7140
  $ref: "#/definitions/sourceLocation"
7155
- },
7156
- metadata: {
7157
- type: "object",
7158
- description: "Extensible metadata for custom properties",
7159
- additionalProperties: true
7160
7141
  }
7161
7142
  },
7162
7143
  additionalProperties: false
@@ -7190,11 +7171,6 @@ var riviere_schema_default = {
7190
7171
  },
7191
7172
  sourceLocation: {
7192
7173
  $ref: "#/definitions/sourceLocation"
7193
- },
7194
- metadata: {
7195
- type: "object",
7196
- description: "Extensible metadata for custom properties",
7197
- additionalProperties: true
7198
7174
  }
7199
7175
  },
7200
7176
  additionalProperties: false
@@ -7275,7 +7251,7 @@ var riviere_schema_default = {
7275
7251
  description: "Classification of domain's role in system"
7276
7252
  }
7277
7253
  },
7278
- additionalProperties: true
7254
+ additionalProperties: false
7279
7255
  },
7280
7256
  customTypeDefinition: {
7281
7257
  type: "object",
@@ -21522,22 +21498,6 @@ function validateCustomTypes(graph) {
21522
21498
  message: `Custom type '${customTypeName}' is not defined in metadata.customTypes`,
21523
21499
  code: "INVALID_TYPE"
21524
21500
  });
21525
- return;
21526
- }
21527
- const typeDefinition = customTypes[customTypeName];
21528
- const requiredProperties = typeDefinition?.requiredProperties;
21529
- const hasNoRequiredProperties = requiredProperties === void 0;
21530
- if (hasNoRequiredProperties)
21531
- return;
21532
- const requiredPropertyNames = Object.keys(requiredProperties);
21533
- const componentMetadata = component.metadata;
21534
- const missingProperties = componentMetadata ? requiredPropertyNames.filter((prop) => !(prop in componentMetadata)) : requiredPropertyNames;
21535
- if (missingProperties.length > 0) {
21536
- errors.push({
21537
- path: `/components/${index}`,
21538
- message: `Custom component is missing required properties for type '${customTypeName}': ${missingProperties.join(", ")}`,
21539
- code: "INVALID_TYPE"
21540
- });
21541
21501
  }
21542
21502
  });
21543
21503
  return errors;
@@ -22574,8 +22534,7 @@ var RiviereBuilder = class _RiviereBuilder {
22574
22534
  module: input.module,
22575
22535
  route: input.route,
22576
22536
  sourceLocation: input.sourceLocation,
22577
- ...input.description !== void 0 && { description: input.description },
22578
- ...input.metadata !== void 0 && { metadata: input.metadata }
22537
+ ...input.description !== void 0 && { description: input.description }
22579
22538
  };
22580
22539
  return this.registerComponent(component);
22581
22540
  }
@@ -22613,8 +22572,7 @@ var RiviereBuilder = class _RiviereBuilder {
22613
22572
  ...input.httpMethod !== void 0 && { httpMethod: input.httpMethod },
22614
22573
  ...input.path !== void 0 && { path: input.path },
22615
22574
  ...input.operationName !== void 0 && { operationName: input.operationName },
22616
- ...input.description !== void 0 && { description: input.description },
22617
- ...input.metadata !== void 0 && { metadata: input.metadata }
22575
+ ...input.description !== void 0 && { description: input.description }
22618
22576
  };
22619
22577
  return this.registerComponent(component);
22620
22578
  }
@@ -22645,8 +22603,7 @@ var RiviereBuilder = class _RiviereBuilder {
22645
22603
  domain: input.domain,
22646
22604
  module: input.module,
22647
22605
  sourceLocation: input.sourceLocation,
22648
- ...input.description !== void 0 && { description: input.description },
22649
- ...input.metadata !== void 0 && { metadata: input.metadata }
22606
+ ...input.description !== void 0 && { description: input.description }
22650
22607
  };
22651
22608
  return this.registerComponent(component);
22652
22609
  }
@@ -22688,8 +22645,7 @@ var RiviereBuilder = class _RiviereBuilder {
22688
22645
  ...input.behavior !== void 0 && { behavior: input.behavior },
22689
22646
  ...input.stateChanges !== void 0 && { stateChanges: input.stateChanges },
22690
22647
  ...input.businessRules !== void 0 && { businessRules: input.businessRules },
22691
- ...input.description !== void 0 && { description: input.description },
22692
- ...input.metadata !== void 0 && { metadata: input.metadata }
22648
+ ...input.description !== void 0 && { description: input.description }
22693
22649
  };
22694
22650
  return this.registerComponent(component);
22695
22651
  }
@@ -22723,8 +22679,7 @@ var RiviereBuilder = class _RiviereBuilder {
22723
22679
  eventName: input.eventName,
22724
22680
  sourceLocation: input.sourceLocation,
22725
22681
  ...input.eventSchema !== void 0 && { eventSchema: input.eventSchema },
22726
- ...input.description !== void 0 && { description: input.description },
22727
- ...input.metadata !== void 0 && { metadata: input.metadata }
22682
+ ...input.description !== void 0 && { description: input.description }
22728
22683
  };
22729
22684
  return this.registerComponent(component);
22730
22685
  }
@@ -22757,8 +22712,7 @@ var RiviereBuilder = class _RiviereBuilder {
22757
22712
  module: input.module,
22758
22713
  subscribedEvents: input.subscribedEvents,
22759
22714
  sourceLocation: input.sourceLocation,
22760
- ...input.description !== void 0 && { description: input.description },
22761
- ...input.metadata !== void 0 && { metadata: input.metadata }
22715
+ ...input.description !== void 0 && { description: input.description }
22762
22716
  };
22763
22717
  return this.registerComponent(component);
22764
22718
  }
@@ -22830,8 +22784,7 @@ var RiviereBuilder = class _RiviereBuilder {
22830
22784
  domain: input.domain,
22831
22785
  module: input.module,
22832
22786
  sourceLocation: input.sourceLocation,
22833
- ...input.description !== void 0 && { description: input.description },
22834
- ...input.metadata !== void 0 && { metadata: input.metadata }
22787
+ ...input.description !== void 0 && { description: input.description }
22835
22788
  };
22836
22789
  return this.registerComponent(component);
22837
22790
  }
@@ -22976,8 +22929,7 @@ var RiviereBuilder = class _RiviereBuilder {
22976
22929
  target: input.target,
22977
22930
  ...input.type !== void 0 && { type: input.type },
22978
22931
  ...input.description !== void 0 && { description: input.description },
22979
- ...input.sourceLocation !== void 0 && { sourceLocation: input.sourceLocation },
22980
- ...input.metadata !== void 0 && { metadata: input.metadata }
22932
+ ...input.sourceLocation !== void 0 && { sourceLocation: input.sourceLocation }
22981
22933
  };
22982
22934
  this.graph.externalLinks.push(externalLink);
22983
22935
  return externalLink;
@@ -24181,8 +24133,89 @@ Examples:
24181
24133
  });
24182
24134
  }
24183
24135
 
24184
- // src/commands/query/entry-points.ts
24136
+ // src/commands/builder/define-custom-type.ts
24185
24137
  import { Command as Command14 } from "commander";
24138
+ import { writeFile as writeFile10 } from "node:fs/promises";
24139
+ var VALID_PROPERTY_TYPES = ["string", "number", "boolean", "array", "object"];
24140
+ function isValidPropertyType(value) {
24141
+ return VALID_PROPERTY_TYPES.some((t) => t === value);
24142
+ }
24143
+ function parsePropertySpec(spec) {
24144
+ const parts = spec.split(":");
24145
+ if (parts.length < 2 || parts.length > 3) {
24146
+ return { error: `Invalid property format: "${spec}". Expected "name:type" or "name:type:description"` };
24147
+ }
24148
+ const [name, type, description] = parts;
24149
+ if (!name || name.trim() === "") {
24150
+ return { error: "Property name cannot be empty" };
24151
+ }
24152
+ if (!type || !isValidPropertyType(type)) {
24153
+ return { error: `Invalid property type: "${type}". Valid types: ${VALID_PROPERTY_TYPES.join(", ")}` };
24154
+ }
24155
+ const definition = { type };
24156
+ if (description && description.trim() !== "") {
24157
+ definition.description = description;
24158
+ }
24159
+ return { name: name.trim(), definition };
24160
+ }
24161
+ function parsePropertySpecs(specs) {
24162
+ if (specs === void 0 || specs.length === 0) {
24163
+ return { success: true, properties: {} };
24164
+ }
24165
+ const properties = {};
24166
+ for (const spec of specs) {
24167
+ const result = parsePropertySpec(spec);
24168
+ if ("error" in result) {
24169
+ return { success: false, error: result.error };
24170
+ }
24171
+ if (properties[result.name] !== void 0) {
24172
+ return { success: false, error: `Duplicate property name: "${result.name}"` };
24173
+ }
24174
+ properties[result.name] = result.definition;
24175
+ }
24176
+ return { success: true, properties };
24177
+ }
24178
+ function collect(value, previous) {
24179
+ return previous.concat([value]);
24180
+ }
24181
+ function createDefineCustomTypeCommand() {
24182
+ return new Command14("define-custom-type").description("Define a custom component type").requiredOption("--name <name>", "Custom type name").option("--description <desc>", "Custom type description").option("--required-property <spec>", "Required property (format: name:type[:description])", collect, []).option("--optional-property <spec>", "Optional property (format: name:type[:description])", collect, []).option("--graph <path>", getDefaultGraphPathDescription()).option("--json", "Output result as JSON").action(async (options) => {
24183
+ const requiredResult = parsePropertySpecs(options.requiredProperty);
24184
+ if (!requiredResult.success) {
24185
+ console.log(JSON.stringify(formatError2("VALIDATION_ERROR" /* ValidationError */, requiredResult.error, [])));
24186
+ return;
24187
+ }
24188
+ const optionalResult = parsePropertySpecs(options.optionalProperty);
24189
+ if (!optionalResult.success) {
24190
+ console.log(JSON.stringify(formatError2("VALIDATION_ERROR" /* ValidationError */, optionalResult.error, [])));
24191
+ return;
24192
+ }
24193
+ await withGraphBuilder(options.graph, async (builder, graphPath) => {
24194
+ builder.defineCustomType({
24195
+ name: options.name,
24196
+ ...options.description !== void 0 && { description: options.description },
24197
+ ...Object.keys(requiredResult.properties).length > 0 && { requiredProperties: requiredResult.properties },
24198
+ ...Object.keys(optionalResult.properties).length > 0 && { optionalProperties: optionalResult.properties }
24199
+ });
24200
+ await writeFile10(graphPath, builder.serialize(), "utf-8");
24201
+ if (options.json === true) {
24202
+ console.log(
24203
+ JSON.stringify(
24204
+ formatSuccess({
24205
+ name: options.name,
24206
+ ...options.description !== void 0 && { description: options.description },
24207
+ ...Object.keys(requiredResult.properties).length > 0 && { requiredProperties: requiredResult.properties },
24208
+ ...Object.keys(optionalResult.properties).length > 0 && { optionalProperties: optionalResult.properties }
24209
+ })
24210
+ )
24211
+ );
24212
+ }
24213
+ });
24214
+ });
24215
+ }
24216
+
24217
+ // src/commands/query/entry-points.ts
24218
+ import { Command as Command15 } from "commander";
24186
24219
 
24187
24220
  // src/commands/query/load-graph.ts
24188
24221
  import { readFile as readFile3 } from "node:fs/promises";
@@ -24230,7 +24263,7 @@ async function withGraph(graphPathOption, handler) {
24230
24263
 
24231
24264
  // src/commands/query/entry-points.ts
24232
24265
  function createEntryPointsCommand() {
24233
- return new Command14("entry-points").description("List entry points (APIs, UIs, EventHandlers with no incoming links)").addHelpText(
24266
+ return new Command15("entry-points").description("List entry points (APIs, UIs, EventHandlers with no incoming links)").addHelpText(
24234
24267
  "after",
24235
24268
  `
24236
24269
  Examples:
@@ -24248,9 +24281,9 @@ Examples:
24248
24281
  }
24249
24282
 
24250
24283
  // src/commands/query/domains.ts
24251
- import { Command as Command15 } from "commander";
24284
+ import { Command as Command16 } from "commander";
24252
24285
  function createDomainsCommand() {
24253
- return new Command15("domains").description("List domains with component counts").addHelpText(
24286
+ return new Command16("domains").description("List domains with component counts").addHelpText(
24254
24287
  "after",
24255
24288
  `
24256
24289
  Examples:
@@ -24268,9 +24301,9 @@ Examples:
24268
24301
  }
24269
24302
 
24270
24303
  // src/commands/query/trace.ts
24271
- import { Command as Command16 } from "commander";
24304
+ import { Command as Command17 } from "commander";
24272
24305
  function createTraceCommand() {
24273
- return new Command16("trace").description("Trace flow from a component (bidirectional)").addHelpText(
24306
+ return new Command17("trace").description("Trace flow from a component (bidirectional)").addHelpText(
24274
24307
  "after",
24275
24308
  `
24276
24309
  Examples:
@@ -24304,9 +24337,9 @@ Examples:
24304
24337
  }
24305
24338
 
24306
24339
  // src/commands/query/orphans.ts
24307
- import { Command as Command17 } from "commander";
24340
+ import { Command as Command18 } from "commander";
24308
24341
  function createOrphansCommand() {
24309
- return new Command17("orphans").description("Find orphan components with no links").addHelpText(
24342
+ return new Command18("orphans").description("Find orphan components with no links").addHelpText(
24310
24343
  "after",
24311
24344
  `
24312
24345
  Examples:
@@ -24324,7 +24357,7 @@ Examples:
24324
24357
  }
24325
24358
 
24326
24359
  // src/commands/query/components.ts
24327
- import { Command as Command18 } from "commander";
24360
+ import { Command as Command19 } from "commander";
24328
24361
 
24329
24362
  // src/commands/query/component-output.ts
24330
24363
  function toComponentOutput(component) {
@@ -24338,7 +24371,7 @@ function toComponentOutput(component) {
24338
24371
 
24339
24372
  // src/commands/query/components.ts
24340
24373
  function createComponentsCommand() {
24341
- return new Command18("components").description("List components with optional filtering").addHelpText(
24374
+ return new Command19("components").description("List components with optional filtering").addHelpText(
24342
24375
  "after",
24343
24376
  `
24344
24377
  Examples:
@@ -24371,9 +24404,9 @@ Examples:
24371
24404
  }
24372
24405
 
24373
24406
  // src/commands/query/search.ts
24374
- import { Command as Command19 } from "commander";
24407
+ import { Command as Command20 } from "commander";
24375
24408
  function createSearchCommand() {
24376
- return new Command19("search").description("Search components by name").addHelpText(
24409
+ return new Command20("search").description("Search components by name").addHelpText(
24377
24410
  "after",
24378
24411
  `
24379
24412
  Examples:
@@ -24407,7 +24440,7 @@ function loadPackageJson() {
24407
24440
  }
24408
24441
  var packageJson = loadPackageJson();
24409
24442
  function createProgram() {
24410
- const program = new Command20();
24443
+ const program = new Command21();
24411
24444
  program.name("riviere").version(packageJson.version);
24412
24445
  const builderCmd = program.command("builder").description("Commands for building a graph");
24413
24446
  builderCmd.addCommand(createAddComponentCommand());
@@ -24423,6 +24456,7 @@ function createProgram() {
24423
24456
  builderCmd.addCommand(createComponentSummaryCommand());
24424
24457
  builderCmd.addCommand(createComponentChecklistCommand());
24425
24458
  builderCmd.addCommand(createCheckConsistencyCommand());
24459
+ builderCmd.addCommand(createDefineCustomTypeCommand());
24426
24460
  const queryCmd = program.command("query").description("Commands for querying a graph");
24427
24461
  queryCmd.addCommand(createEntryPointsCommand());
24428
24462
  queryCmd.addCommand(createDomainsCommand());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@living-architecture/riviere-cli",
3
- "version": "0.2.4",
3
+ "version": "0.3.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -27,8 +27,8 @@
27
27
  "dependencies": {
28
28
  "commander": "^14.0.2",
29
29
  "tslib": "^2.3.0",
30
- "@living-architecture/riviere-builder": "0.2.3",
31
- "@living-architecture/riviere-query": "0.2.3",
32
- "@living-architecture/riviere-schema": "0.2.1"
30
+ "@living-architecture/riviere-builder": "0.2.4",
31
+ "@living-architecture/riviere-schema": "0.2.2",
32
+ "@living-architecture/riviere-query": "0.2.4"
33
33
  }
34
34
  }