@geolonia/geonicdb-cli 0.6.1 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -303,9 +303,13 @@ function entityToFeature(entity) {
303
303
  // src/commands/help.ts
304
304
  import chalk2 from "chalk";
305
305
  var examplesMap = /* @__PURE__ */ new WeakMap();
306
+ var notesMap = /* @__PURE__ */ new WeakMap();
306
307
  function addExamples(cmd, examples) {
307
308
  examplesMap.set(cmd, examples);
308
309
  }
310
+ function addNotes(cmd, notes) {
311
+ notesMap.set(cmd, notes);
312
+ }
309
313
  function header(title) {
310
314
  return chalk2.yellow.bold(title);
311
315
  }
@@ -451,6 +455,15 @@ function formatCommandDetails(program2, cmd, path) {
451
455
  lines.push("");
452
456
  }
453
457
  }
458
+ const notes = notesMap.get(cmd);
459
+ if (notes && notes.length > 0) {
460
+ lines.push("");
461
+ lines.push(header("NOTES"));
462
+ lines.push("");
463
+ for (const note of notes) {
464
+ lines.push(` ${note}`);
465
+ }
466
+ }
454
467
  lines.push("");
455
468
  lines.push(formatGlobalParameters(program2));
456
469
  return lines.join("\n");
@@ -924,6 +937,16 @@ var GdbClientError = class extends Error {
924
937
  };
925
938
 
926
939
  // src/helpers.ts
940
+ var SCOPES_HELP_NOTES = [
941
+ "Valid scopes:",
942
+ " read:entities, write:entities, read:subscriptions, write:subscriptions,",
943
+ " read:registrations, write:registrations, read:rules, write:rules,",
944
+ " read:custom-data-models, write:custom-data-models,",
945
+ " admin:users, admin:tenants, admin:policies, admin:oauth-clients,",
946
+ " admin:api-keys, admin:metrics",
947
+ "",
948
+ "write:X implies read:X. admin:X implies both read:X and write:X."
949
+ ];
927
950
  function resolveOptions(cmd) {
928
951
  const opts = cmd.optsWithGlobals();
929
952
  const config = loadConfig(opts.profile);
@@ -1348,6 +1371,7 @@ function addMeOAuthClientsSubcommand(me) {
1348
1371
  printSuccess("OAuth client created.");
1349
1372
  })
1350
1373
  );
1374
+ addNotes(create, SCOPES_HELP_NOTES);
1351
1375
  addExamples(create, [
1352
1376
  {
1353
1377
  description: "Create an OAuth client with flags",
@@ -1465,6 +1489,7 @@ function addMeApiKeysSubcommand(me) {
1465
1489
  console.error("API key created.");
1466
1490
  })
1467
1491
  );
1492
+ addNotes(create, SCOPES_HELP_NOTES);
1468
1493
  addExamples(create, [
1469
1494
  {
1470
1495
  description: "Create an API key with flags",
@@ -1969,7 +1994,9 @@ function addAttrsSubcommands(attrs) {
1969
1994
  command: "geonic entities attrs get urn:ngsi-ld:Sensor:001 temperature"
1970
1995
  }
1971
1996
  ]);
1972
- const add = attrs.command("add").description("Add attributes to an entity").argument("<entityId>", "Entity ID").argument("[json]", "JSON payload (inline, @file, - for stdin, or omit for interactive/pipe)").action(
1997
+ const add = attrs.command("add").description(
1998
+ 'Add attributes to an entity\n\nJSON payload example:\n {"humidity": {"type": "Property", "value": 60}}'
1999
+ ).argument("<entityId>", "Entity ID").argument("[json]", "JSON payload (inline, @file, - for stdin, or omit for interactive/pipe)").action(
1973
2000
  withErrorHandler(
1974
2001
  async (entityId, json, _opts, cmd) => {
1975
2002
  const client = createClient(cmd);
@@ -1983,12 +2010,22 @@ function addAttrsSubcommands(attrs) {
1983
2010
  )
1984
2011
  );
1985
2012
  addExamples(add, [
2013
+ {
2014
+ description: "Add an attribute with inline JSON",
2015
+ command: `geonic entities attrs add urn:ngsi-ld:Sensor:001 '{"humidity":{"type":"Property","value":60}}'`
2016
+ },
1986
2017
  {
1987
2018
  description: "Add attributes from a file",
1988
2019
  command: "geonic entities attrs add urn:ngsi-ld:Sensor:001 @attrs.json"
2020
+ },
2021
+ {
2022
+ description: "Add from stdin pipe",
2023
+ command: "cat attrs.json | geonic entities attrs add urn:ngsi-ld:Sensor:001"
1989
2024
  }
1990
2025
  ]);
1991
- const attrUpdate = attrs.command("update").description("Update a specific attribute of an entity").argument("<entityId>", "Entity ID").argument("<attrName>", "Attribute name").argument("[json]", "JSON payload (inline, @file, - for stdin, or omit for interactive/pipe)").action(
2026
+ const attrUpdate = attrs.command("update").description(
2027
+ 'Update a specific attribute of an entity\n\nJSON payload example:\n {"type": "Property", "value": 25}'
2028
+ ).argument("<entityId>", "Entity ID").argument("<attrName>", "Attribute name").argument("[json]", "JSON payload (inline, @file, - for stdin, or omit for interactive/pipe)").action(
1992
2029
  withErrorHandler(
1993
2030
  async (entityId, attrName, json, _opts, cmd) => {
1994
2031
  const client = createClient(cmd);
@@ -2003,8 +2040,12 @@ function addAttrsSubcommands(attrs) {
2003
2040
  );
2004
2041
  addExamples(attrUpdate, [
2005
2042
  {
2006
- description: "Update a specific attribute",
2007
- command: `geonic entities attrs update urn:ngsi-ld:Sensor:001 temperature '{"value":25}'`
2043
+ description: "Update a Property value",
2044
+ command: `geonic entities attrs update urn:ngsi-ld:Sensor:001 temperature '{"type":"Property","value":25}'`
2045
+ },
2046
+ {
2047
+ description: "Update from a file",
2048
+ command: "geonic entities attrs update urn:ngsi-ld:Sensor:001 temperature @attr.json"
2008
2049
  }
2009
2050
  ]);
2010
2051
  const del = attrs.command("delete").description("Delete a specific attribute from an entity").argument("<entityId>", "Entity ID").argument("<attrName>", "Attribute name").action(
@@ -2147,7 +2188,9 @@ function registerEntitiesCommand(program2) {
2147
2188
  command: "geonic entities get urn:ngsi-ld:Sensor:001 --key-values"
2148
2189
  }
2149
2190
  ]);
2150
- const create = entities.command("create").description("Create a new entity").argument("[json]", "JSON payload (inline, @file, - for stdin, or omit for interactive/pipe)").action(
2191
+ const create = entities.command("create").description(
2192
+ 'Create a new entity\n\nJSON payload example:\n {\n "id": "urn:ngsi-ld:Sensor:001",\n "type": "Sensor",\n "temperature": {"type": "Property", "value": 25}\n }'
2193
+ ).argument("[json]", "JSON payload (inline, @file, - for stdin, or omit for interactive/pipe)").action(
2151
2194
  withErrorHandler(async (json, _opts, cmd) => {
2152
2195
  const client = createClient(cmd);
2153
2196
  const data = await parseJsonInput(json);
@@ -2157,9 +2200,13 @@ function registerEntitiesCommand(program2) {
2157
2200
  );
2158
2201
  addExamples(create, [
2159
2202
  {
2160
- description: "Create from inline JSON",
2203
+ description: "Create from inline JSON (minimal)",
2161
2204
  command: `geonic entities create '{"id":"urn:ngsi-ld:Sensor:001","type":"Sensor"}'`
2162
2205
  },
2206
+ {
2207
+ description: "Create with attributes",
2208
+ command: `geonic entities create '{"id":"urn:ngsi-ld:Sensor:001","type":"Sensor","temperature":{"type":"Property","value":25},"location":{"type":"GeoProperty","value":{"type":"Point","coordinates":[139.77,35.68]}}}'`
2209
+ },
2163
2210
  {
2164
2211
  description: "Create from a file",
2165
2212
  command: "geonic entities create @entity.json"
@@ -2167,9 +2214,15 @@ function registerEntitiesCommand(program2) {
2167
2214
  {
2168
2215
  description: "Create from stdin pipe",
2169
2216
  command: "cat entity.json | geonic entities create"
2217
+ },
2218
+ {
2219
+ description: "Interactive mode (omit JSON argument)",
2220
+ command: "geonic entities create"
2170
2221
  }
2171
2222
  ]);
2172
- const update = entities.command("update").description("Update attributes of an entity (PATCH)").argument("<id>", "Entity ID").argument("[json]", "JSON payload (inline, @file, - for stdin, or omit for interactive/pipe)").action(
2223
+ const update = entities.command("update").description(
2224
+ 'Update attributes of an entity (PATCH)\n\nJSON payload: only specified attributes are modified.\n e.g. {"temperature": {"type": "Property", "value": 30}}'
2225
+ ).argument("<id>", "Entity ID").argument("[json]", "JSON payload (inline, @file, - for stdin, or omit for interactive/pipe)").action(
2173
2226
  withErrorHandler(
2174
2227
  async (id, json, _opts, cmd) => {
2175
2228
  const client = createClient(cmd);
@@ -2184,15 +2237,21 @@ function registerEntitiesCommand(program2) {
2184
2237
  );
2185
2238
  addExamples(update, [
2186
2239
  {
2187
- description: "Update entity attributes from inline JSON",
2188
- command: `geonic entities update urn:ngsi-ld:Sensor:001 '{"temperature":{"value":25}}'`
2240
+ description: "Update a Property attribute",
2241
+ command: `geonic entities update urn:ngsi-ld:Sensor:001 '{"temperature":{"type":"Property","value":30}}'`
2189
2242
  },
2190
2243
  {
2191
- description: "Update entity attributes from a file",
2244
+ description: "Update from a file",
2192
2245
  command: "geonic entities update urn:ngsi-ld:Sensor:001 @attrs.json"
2246
+ },
2247
+ {
2248
+ description: "Update from stdin pipe",
2249
+ command: "cat attrs.json | geonic entities update urn:ngsi-ld:Sensor:001"
2193
2250
  }
2194
2251
  ]);
2195
- const replace = entities.command("replace").description("Replace all attributes of an entity (PUT)").argument("<id>", "Entity ID").argument("[json]", "JSON payload (inline, @file, - for stdin, or omit for interactive/pipe)").action(
2252
+ const replace = entities.command("replace").description(
2253
+ 'Replace all attributes of an entity (PUT)\n\nJSON payload: all existing attributes are replaced.\n e.g. {"temperature": {"type": "Property", "value": 20}}'
2254
+ ).argument("<id>", "Entity ID").argument("[json]", "JSON payload (inline, @file, - for stdin, or omit for interactive/pipe)").action(
2196
2255
  withErrorHandler(
2197
2256
  async (id, json, _opts, cmd) => {
2198
2257
  const client = createClient(cmd);
@@ -2207,8 +2266,16 @@ function registerEntitiesCommand(program2) {
2207
2266
  );
2208
2267
  addExamples(replace, [
2209
2268
  {
2210
- description: "Replace all attributes from a file",
2269
+ description: "Replace all attributes with inline JSON",
2270
+ command: `geonic entities replace urn:ngsi-ld:Sensor:001 '{"temperature":{"type":"Property","value":20}}'`
2271
+ },
2272
+ {
2273
+ description: "Replace from a file",
2211
2274
  command: "geonic entities replace urn:ngsi-ld:Sensor:001 @attrs.json"
2275
+ },
2276
+ {
2277
+ description: "Replace from stdin pipe",
2278
+ command: "cat attrs.json | geonic entities replace urn:ngsi-ld:Sensor:001"
2212
2279
  }
2213
2280
  ]);
2214
2281
  const upsert = entities.command("upsert").description("Create or update entities").argument("[json]", "JSON payload (inline, @file, - for stdin, or omit for interactive/pipe)").action(
@@ -2248,7 +2315,9 @@ function registerEntitiesCommand(program2) {
2248
2315
  // src/commands/batch.ts
2249
2316
  function registerBatchCommand(program2) {
2250
2317
  const batch = program2.command("entityOperations").alias("batch").description("Perform batch operations on entities");
2251
- const create = batch.command("create [json]").description("Batch create entities").action(
2318
+ const create = batch.command("create [json]").description(
2319
+ 'Batch create entities\n\nJSON payload: an array of NGSI-LD entities.\n e.g. [{"id": "urn:ngsi-ld:Sensor:001", "type": "Sensor"}, ...]'
2320
+ ).action(
2252
2321
  withErrorHandler(async (json, _opts, cmd) => {
2253
2322
  const client = createClient(cmd);
2254
2323
  const format = getFormat(cmd);
@@ -2258,16 +2327,22 @@ function registerBatchCommand(program2) {
2258
2327
  })
2259
2328
  );
2260
2329
  addExamples(create, [
2330
+ {
2331
+ description: "Batch create with inline JSON",
2332
+ command: `geonic batch create '[{"id":"urn:ngsi-ld:Sensor:001","type":"Sensor"},{"id":"urn:ngsi-ld:Sensor:002","type":"Sensor"}]'`
2333
+ },
2261
2334
  {
2262
2335
  description: "Batch create from a file",
2263
2336
  command: "geonic batch create @entities.json"
2264
2337
  },
2265
2338
  {
2266
- description: "Batch create from stdin",
2339
+ description: "Batch create from stdin pipe",
2267
2340
  command: "cat entities.json | geonic batch create"
2268
2341
  }
2269
2342
  ]);
2270
- const upsert = batch.command("upsert [json]").description("Batch upsert entities").action(
2343
+ const upsert = batch.command("upsert [json]").description(
2344
+ "Batch upsert entities\n\nJSON payload: an array of NGSI-LD entities.\nCreates entities that don't exist, updates those that do."
2345
+ ).action(
2271
2346
  withErrorHandler(async (json, _opts, cmd) => {
2272
2347
  const client = createClient(cmd);
2273
2348
  const format = getFormat(cmd);
@@ -2277,16 +2352,22 @@ function registerBatchCommand(program2) {
2277
2352
  })
2278
2353
  );
2279
2354
  addExamples(upsert, [
2355
+ {
2356
+ description: "Batch upsert with inline JSON",
2357
+ command: `geonic batch upsert '[{"id":"urn:ngsi-ld:Sensor:001","type":"Sensor","temperature":{"type":"Property","value":25}}]'`
2358
+ },
2280
2359
  {
2281
2360
  description: "Batch upsert from a file",
2282
2361
  command: "geonic batch upsert @entities.json"
2283
2362
  },
2284
2363
  {
2285
- description: "Batch upsert from stdin",
2364
+ description: "Batch upsert from stdin pipe",
2286
2365
  command: "cat entities.json | geonic batch upsert"
2287
2366
  }
2288
2367
  ]);
2289
- const update = batch.command("update [json]").description("Batch update entity attributes").action(
2368
+ const update = batch.command("update [json]").description(
2369
+ "Batch update entity attributes\n\nJSON payload: an array of NGSI-LD entities with attributes to update.\nEach entity must include id and type; only specified attributes are modified."
2370
+ ).action(
2290
2371
  withErrorHandler(async (json, _opts, cmd) => {
2291
2372
  const client = createClient(cmd);
2292
2373
  const format = getFormat(cmd);
@@ -2305,7 +2386,9 @@ function registerBatchCommand(program2) {
2305
2386
  command: "cat updates.json | geonic batch update"
2306
2387
  }
2307
2388
  ]);
2308
- const del = batch.command("delete [json]").description("Batch delete entities by ID").action(
2389
+ const del = batch.command("delete [json]").description(
2390
+ 'Batch delete entities by ID\n\nJSON payload: an array of entity ID strings.\n e.g. ["urn:ngsi-ld:Sensor:001","urn:ngsi-ld:Sensor:002"]'
2391
+ ).action(
2309
2392
  withErrorHandler(async (json, _opts, cmd) => {
2310
2393
  const client = createClient(cmd);
2311
2394
  const format = getFormat(cmd);
@@ -2315,16 +2398,22 @@ function registerBatchCommand(program2) {
2315
2398
  })
2316
2399
  );
2317
2400
  addExamples(del, [
2401
+ {
2402
+ description: "Batch delete with inline JSON",
2403
+ command: `geonic batch delete '["urn:ngsi-ld:Sensor:001","urn:ngsi-ld:Sensor:002"]'`
2404
+ },
2318
2405
  {
2319
2406
  description: "Batch delete from a file",
2320
2407
  command: "geonic batch delete @entity-ids.json"
2321
2408
  },
2322
2409
  {
2323
- description: "Batch delete from stdin",
2410
+ description: "Batch delete from stdin pipe",
2324
2411
  command: "cat entity-ids.json | geonic batch delete"
2325
2412
  }
2326
2413
  ]);
2327
- const query = batch.command("query [json]").description("Query entities by posting a query payload").action(
2414
+ const query = batch.command("query [json]").description(
2415
+ 'Query entities by posting a query payload\n\nJSON payload example:\n {\n "entities": [{"type": "Sensor"}],\n "attrs": ["temperature"],\n "q": "temperature>30"\n }'
2416
+ ).action(
2328
2417
  withErrorHandler(async (json, _opts, cmd) => {
2329
2418
  const client = createClient(cmd);
2330
2419
  const format = getFormat(cmd);
@@ -2335,15 +2424,21 @@ function registerBatchCommand(program2) {
2335
2424
  );
2336
2425
  addExamples(query, [
2337
2426
  {
2338
- description: "Query entities from a file",
2427
+ description: "Query with inline JSON",
2428
+ command: `geonic batch query '{"entities":[{"type":"Sensor"}],"attrs":["temperature"]}'`
2429
+ },
2430
+ {
2431
+ description: "Query from a file",
2339
2432
  command: "geonic batch query @query.json"
2340
2433
  },
2341
2434
  {
2342
- description: "Query entities from stdin",
2435
+ description: "Query from stdin pipe",
2343
2436
  command: "cat query.json | geonic batch query"
2344
2437
  }
2345
2438
  ]);
2346
- const merge = batch.command("merge [json]").description("Batch merge-patch entities").action(
2439
+ const merge = batch.command("merge [json]").description(
2440
+ "Batch merge-patch entities\n\nJSON payload: an array of NGSI-LD entities.\nEach entity must include id and type; attributes are merge-patched."
2441
+ ).action(
2347
2442
  withErrorHandler(async (json, _opts, cmd) => {
2348
2443
  const client = createClient(cmd);
2349
2444
  const format = getFormat(cmd);
@@ -2410,7 +2505,9 @@ function registerSubscriptionsCommand(program2) {
2410
2505
  command: "geonic subscriptions get urn:ngsi-ld:Subscription:001"
2411
2506
  }
2412
2507
  ]);
2413
- const create = subscriptions.command("create [json]").description("Create a subscription").action(
2508
+ const create = subscriptions.command("create [json]").description(
2509
+ 'Create a subscription\n\nJSON payload example:\n {\n "type": "Subscription",\n "entities": [{"type": "Sensor"}],\n "watchedAttributes": ["temperature"],\n "notification": {"endpoint": {"uri": "http://localhost:3000/notify"}}\n }'
2510
+ ).action(
2414
2511
  withErrorHandler(async (json, _opts, cmd) => {
2415
2512
  const client = createClient(cmd);
2416
2513
  const format = getFormat(cmd);
@@ -2421,16 +2518,26 @@ function registerSubscriptionsCommand(program2) {
2421
2518
  })
2422
2519
  );
2423
2520
  addExamples(create, [
2521
+ {
2522
+ description: "Create with inline JSON",
2523
+ command: `geonic subscriptions create '{"type":"Subscription","entities":[{"type":"Sensor"}],"watchedAttributes":["temperature"],"notification":{"endpoint":{"uri":"http://localhost:3000/notify"}}}'`
2524
+ },
2424
2525
  {
2425
2526
  description: "Create from a JSON file",
2426
2527
  command: "geonic subscriptions create @subscription.json"
2427
2528
  },
2428
2529
  {
2429
- description: "Create from stdin",
2530
+ description: "Create from stdin pipe",
2430
2531
  command: "cat subscription.json | geonic subscriptions create"
2532
+ },
2533
+ {
2534
+ description: "Interactive mode",
2535
+ command: "geonic subscriptions create"
2431
2536
  }
2432
2537
  ]);
2433
- const update = subscriptions.command("update <id> [json]").description("Update a subscription").action(
2538
+ const update = subscriptions.command("update <id> [json]").description(
2539
+ 'Update a subscription\n\nJSON payload: only specified fields are updated.\n e.g. {"description": "Updated subscription"}'
2540
+ ).action(
2434
2541
  withErrorHandler(
2435
2542
  async (id, json, _opts, cmd) => {
2436
2543
  const client = createClient(cmd);
@@ -2447,8 +2554,16 @@ function registerSubscriptionsCommand(program2) {
2447
2554
  );
2448
2555
  addExamples(update, [
2449
2556
  {
2450
- description: "Update a subscription from a file",
2557
+ description: "Update description",
2558
+ command: `geonic subscriptions update urn:ngsi-ld:Subscription:001 '{"description":"Updated subscription"}'`
2559
+ },
2560
+ {
2561
+ description: "Update from a file",
2451
2562
  command: "geonic subscriptions update urn:ngsi-ld:Subscription:001 @sub.json"
2563
+ },
2564
+ {
2565
+ description: "Update from stdin pipe",
2566
+ command: "cat sub.json | geonic subscriptions update urn:ngsi-ld:Subscription:001"
2452
2567
  }
2453
2568
  ]);
2454
2569
  const del = subscriptions.command("delete <id>").description("Delete a subscription").action(
@@ -2510,7 +2625,9 @@ function registerRegistrationsCommand(program2) {
2510
2625
  command: "geonic registrations get urn:ngsi-ld:ContextSourceRegistration:001"
2511
2626
  }
2512
2627
  ]);
2513
- const create = registrations.command("create [json]").description("Create a registration").action(
2628
+ const create = registrations.command("create [json]").description(
2629
+ 'Create a registration\n\nJSON payload example:\n {\n "type": "ContextSourceRegistration",\n "information": [{"entities": [{"type": "Room"}]}],\n "endpoint": "http://localhost:4000/source"\n }'
2630
+ ).action(
2514
2631
  withErrorHandler(async (json, _opts, cmd) => {
2515
2632
  const client = createClient(cmd);
2516
2633
  const format = getFormat(cmd);
@@ -2522,8 +2639,16 @@ function registerRegistrationsCommand(program2) {
2522
2639
  );
2523
2640
  addExamples(create, [
2524
2641
  {
2525
- description: "Create a registration from a file",
2642
+ description: "Create with inline JSON",
2643
+ command: `geonic registrations create '{"type":"ContextSourceRegistration","information":[{"entities":[{"type":"Room"}]}],"endpoint":"http://localhost:4000/source"}'`
2644
+ },
2645
+ {
2646
+ description: "Create from a file",
2526
2647
  command: "geonic registrations create @registration.json"
2648
+ },
2649
+ {
2650
+ description: "Create from stdin pipe",
2651
+ command: "cat registration.json | geonic registrations create"
2527
2652
  }
2528
2653
  ]);
2529
2654
  const regUpdate = registrations.command("update <id> [json]").description("Update a registration").action(
@@ -2543,8 +2668,16 @@ function registerRegistrationsCommand(program2) {
2543
2668
  );
2544
2669
  addExamples(regUpdate, [
2545
2670
  {
2546
- description: "Update a registration from a file",
2671
+ description: "Update endpoint",
2672
+ command: `geonic registrations update urn:ngsi-ld:ContextSourceRegistration:001 '{"endpoint":"http://localhost:5000/source"}'`
2673
+ },
2674
+ {
2675
+ description: "Update from a file",
2547
2676
  command: "geonic registrations update urn:ngsi-ld:ContextSourceRegistration:001 @registration.json"
2677
+ },
2678
+ {
2679
+ description: "Update from stdin pipe",
2680
+ command: "cat registration.json | geonic registrations update urn:ngsi-ld:ContextSourceRegistration:001"
2548
2681
  }
2549
2682
  ]);
2550
2683
  const del = registrations.command("delete <id>").description("Delete a registration").action(
@@ -2722,11 +2855,21 @@ function registerTemporalCommand(program2) {
2722
2855
  command: "geonic temporal entities get urn:ngsi-ld:Sensor:001 --last-n 10"
2723
2856
  }
2724
2857
  ]);
2725
- const create = entities.command("create [json]").description("Create a temporal entity").action(createCreateAction());
2858
+ const create = entities.command("create [json]").description(
2859
+ "Create a temporal entity\n\nJSON payload: an NGSI-LD entity with temporal attribute instances.\nEach attribute value is an array of {value, observedAt} objects."
2860
+ ).action(createCreateAction());
2726
2861
  addExamples(create, [
2727
2862
  {
2728
- description: "Create temporal entity from a file",
2863
+ description: "Create from a file",
2729
2864
  command: "geonic temporal entities create @temporal-entity.json"
2865
+ },
2866
+ {
2867
+ description: "Create from stdin pipe",
2868
+ command: "cat temporal-entity.json | geonic temporal entities create"
2869
+ },
2870
+ {
2871
+ description: "Interactive mode",
2872
+ command: "geonic temporal entities create"
2730
2873
  }
2731
2874
  ]);
2732
2875
  const del = entities.command("delete <id>").description("Delete a temporal entity by ID").action(createDeleteAction());
@@ -2741,6 +2884,10 @@ function registerTemporalCommand(program2) {
2741
2884
  );
2742
2885
  opsQuery.action(createQueryAction());
2743
2886
  addExamples(opsQuery, [
2887
+ {
2888
+ description: "Query with inline JSON",
2889
+ command: `geonic temporal entityOperations query '{"entities":[{"type":"Sensor"}],"attrs":["temperature"]}'`
2890
+ },
2744
2891
  {
2745
2892
  description: "Query with aggregation (hourly count)",
2746
2893
  command: "geonic temporal entityOperations query @query.json --aggr-methods totalCount --aggr-period PT1H"
@@ -2888,7 +3035,9 @@ function registerTenantsCommand(parent) {
2888
3035
  command: "geonic admin tenants get <tenant-id>"
2889
3036
  }
2890
3037
  ]);
2891
- const create = tenants.command("create [json]").description("Create a new tenant").action(
3038
+ const create = tenants.command("create [json]").description(
3039
+ 'Create a new tenant\n\nJSON payload example:\n {\n "name": "production",\n "description": "Production environment tenant"\n }'
3040
+ ).action(
2892
3041
  withErrorHandler(async (json, _opts, cmd) => {
2893
3042
  const body = await parseJsonInput(json);
2894
3043
  const client = createClient(cmd);
@@ -2902,11 +3051,29 @@ function registerTenantsCommand(parent) {
2902
3051
  );
2903
3052
  addExamples(create, [
2904
3053
  {
2905
- description: "Create a tenant from a JSON file",
3054
+ description: "Create with inline JSON",
3055
+ command: `geonic admin tenants create '{"name":"my-tenant","description":"My first tenant"}'`
3056
+ },
3057
+ {
3058
+ description: "Minimal (name only)",
3059
+ command: `geonic admin tenants create '{"name":"production"}'`
3060
+ },
3061
+ {
3062
+ description: "Create from a JSON file",
2906
3063
  command: "geonic admin tenants create @tenant.json"
3064
+ },
3065
+ {
3066
+ description: "Create from stdin pipe",
3067
+ command: "cat tenant.json | geonic admin tenants create"
3068
+ },
3069
+ {
3070
+ description: "Interactive mode (omit JSON argument)",
3071
+ command: "geonic admin tenants create"
2907
3072
  }
2908
3073
  ]);
2909
- const update = tenants.command("update <id> [json]").description("Update a tenant").action(
3074
+ const update = tenants.command("update <id> [json]").description(
3075
+ 'Update a tenant\n\nJSON payload: only specified fields are updated.\n e.g. {"name": "new-name", "description": "Updated description"}'
3076
+ ).action(
2910
3077
  withErrorHandler(
2911
3078
  async (id, json, _opts, cmd) => {
2912
3079
  const body = await parseJsonInput(json);
@@ -2924,8 +3091,24 @@ function registerTenantsCommand(parent) {
2924
3091
  );
2925
3092
  addExamples(update, [
2926
3093
  {
2927
- description: "Update a tenant from a JSON file",
2928
- command: "geonic admin tenants update <tenant-id> @tenant.json"
3094
+ description: "Update description with inline JSON",
3095
+ command: `geonic admin tenants update <tenant-id> '{"description":"Updated description"}'`
3096
+ },
3097
+ {
3098
+ description: "Rename a tenant",
3099
+ command: `geonic admin tenants update <tenant-id> '{"name":"new-name"}'`
3100
+ },
3101
+ {
3102
+ description: "Update from a JSON file",
3103
+ command: "geonic admin tenants update <tenant-id> @patch.json"
3104
+ },
3105
+ {
3106
+ description: "Update from stdin pipe",
3107
+ command: "cat patch.json | geonic admin tenants update <tenant-id>"
3108
+ },
3109
+ {
3110
+ description: "Interactive mode",
3111
+ command: "geonic admin tenants update <tenant-id>"
2929
3112
  }
2930
3113
  ]);
2931
3114
  const del = tenants.command("delete <id>").description("Delete a tenant").action(
@@ -3012,7 +3195,9 @@ function registerUsersCommand(parent) {
3012
3195
  command: "geonic admin users get <user-id>"
3013
3196
  }
3014
3197
  ]);
3015
- const create = users.command("create [json]").description("Create a new user").action(
3198
+ const create = users.command("create [json]").description(
3199
+ 'Create a new user\n\nJSON payload example:\n {\n "email": "user@example.com",\n "password": "SecurePassword123!",\n "role": "super_admin"\n }'
3200
+ ).action(
3016
3201
  withErrorHandler(async (json, _opts, cmd) => {
3017
3202
  const body = await parseJsonInput(json);
3018
3203
  const client = createClient(cmd);
@@ -3026,11 +3211,21 @@ function registerUsersCommand(parent) {
3026
3211
  );
3027
3212
  addExamples(create, [
3028
3213
  {
3029
- description: "Create a user from a JSON file",
3214
+ description: "Create with inline JSON",
3215
+ command: `geonic admin users create '{"email":"user@example.com","password":"SecurePassword123!","role":"super_admin"}'`
3216
+ },
3217
+ {
3218
+ description: "Create from a JSON file",
3030
3219
  command: "geonic admin users create @user.json"
3220
+ },
3221
+ {
3222
+ description: "Create from stdin pipe",
3223
+ command: "cat user.json | geonic admin users create"
3031
3224
  }
3032
3225
  ]);
3033
- const update = users.command("update <id> [json]").description("Update a user").action(
3226
+ const update = users.command("update <id> [json]").description(
3227
+ 'Update a user\n\nJSON payload: only specified fields are updated.\n e.g. {"role": "admin"}'
3228
+ ).action(
3034
3229
  withErrorHandler(
3035
3230
  async (id, json, _opts, cmd) => {
3036
3231
  const body = await parseJsonInput(json);
@@ -3048,8 +3243,16 @@ function registerUsersCommand(parent) {
3048
3243
  );
3049
3244
  addExamples(update, [
3050
3245
  {
3051
- description: "Update a user from a JSON file",
3246
+ description: "Update role with inline JSON",
3247
+ command: `geonic admin users update <user-id> '{"role":"admin"}'`
3248
+ },
3249
+ {
3250
+ description: "Update from a JSON file",
3052
3251
  command: "geonic admin users update <user-id> @user.json"
3252
+ },
3253
+ {
3254
+ description: "Update from stdin pipe",
3255
+ command: "cat user.json | geonic admin users update <user-id>"
3053
3256
  }
3054
3257
  ]);
3055
3258
  const del = users.command("delete <id>").description("Delete a user").action(
@@ -3152,7 +3355,9 @@ function registerPoliciesCommand(parent) {
3152
3355
  command: "geonic admin policies get <policy-id>"
3153
3356
  }
3154
3357
  ]);
3155
- const create = policies.command("create [json]").description("Create a new policy").action(
3358
+ const create = policies.command("create [json]").description(
3359
+ 'Create a new policy\n\nJSON payload example:\n {\n "description": "Allow all entities",\n "rules": [{"ruleId": "allow-all", "effect": "Permit"}]\n }'
3360
+ ).action(
3156
3361
  withErrorHandler(async (json, _opts, cmd) => {
3157
3362
  const body = await parseJsonInput(json);
3158
3363
  const client = createClient(cmd);
@@ -3166,11 +3371,21 @@ function registerPoliciesCommand(parent) {
3166
3371
  );
3167
3372
  addExamples(create, [
3168
3373
  {
3169
- description: "Create a policy from a JSON file",
3374
+ description: "Create with inline JSON",
3375
+ command: `geonic admin policies create '{"description":"Allow all entities","rules":[{"ruleId":"allow-all","effect":"Permit"}]}'`
3376
+ },
3377
+ {
3378
+ description: "Create from a JSON file",
3170
3379
  command: "geonic admin policies create @policy.json"
3380
+ },
3381
+ {
3382
+ description: "Create from stdin pipe",
3383
+ command: "cat policy.json | geonic admin policies create"
3171
3384
  }
3172
3385
  ]);
3173
- const update = policies.command("update <id> [json]").description("Update a policy").action(
3386
+ const update = policies.command("update <id> [json]").description(
3387
+ 'Update a policy\n\nJSON payload: only specified fields are updated.\n e.g. {"description": "Updated policy"}'
3388
+ ).action(
3174
3389
  withErrorHandler(
3175
3390
  async (id, json, _opts, cmd) => {
3176
3391
  const body = await parseJsonInput(json);
@@ -3188,8 +3403,16 @@ function registerPoliciesCommand(parent) {
3188
3403
  );
3189
3404
  addExamples(update, [
3190
3405
  {
3191
- description: "Update a policy from a JSON file",
3406
+ description: "Update description",
3407
+ command: `geonic admin policies update <policy-id> '{"description":"Updated policy"}'`
3408
+ },
3409
+ {
3410
+ description: "Update from a JSON file",
3192
3411
  command: "geonic admin policies update <policy-id> @policy.json"
3412
+ },
3413
+ {
3414
+ description: "Update from stdin pipe",
3415
+ command: "cat policy.json | geonic admin policies update <policy-id>"
3193
3416
  }
3194
3417
  ]);
3195
3418
  const del = policies.command("delete <id>").description("Delete a policy").action(
@@ -3276,7 +3499,9 @@ function registerOAuthClientsCommand(parent) {
3276
3499
  command: "geonic admin oauth-clients get <client-id>"
3277
3500
  }
3278
3501
  ]);
3279
- const create = oauthClients.command("create [json]").description("Create a new OAuth client").action(
3502
+ const create = oauthClients.command("create [json]").description(
3503
+ 'Create a new OAuth client\n\nJSON payload example:\n {\n "clientName": "my-app",\n "allowedScopes": ["read:entities", "write:entities"]\n }'
3504
+ ).action(
3280
3505
  withErrorHandler(async (json, _opts, cmd) => {
3281
3506
  const body = await parseJsonInput(json);
3282
3507
  const client = createClient(cmd);
@@ -3290,11 +3515,21 @@ function registerOAuthClientsCommand(parent) {
3290
3515
  );
3291
3516
  addExamples(create, [
3292
3517
  {
3293
- description: "Create an OAuth client from a JSON file",
3518
+ description: "Create with inline JSON",
3519
+ command: `geonic admin oauth-clients create '{"clientName":"my-app","allowedScopes":["read:entities","write:entities"]}'`
3520
+ },
3521
+ {
3522
+ description: "Create from a JSON file",
3294
3523
  command: "geonic admin oauth-clients create @client.json"
3524
+ },
3525
+ {
3526
+ description: "Create from stdin pipe",
3527
+ command: "cat client.json | geonic admin oauth-clients create"
3295
3528
  }
3296
3529
  ]);
3297
- const update = oauthClients.command("update <id> [json]").description("Update an OAuth client").action(
3530
+ const update = oauthClients.command("update <id> [json]").description(
3531
+ 'Update an OAuth client\n\nJSON payload: only specified fields are updated.\n e.g. {"description": "Updated client"}'
3532
+ ).action(
3298
3533
  withErrorHandler(
3299
3534
  async (id, json, _opts, cmd) => {
3300
3535
  const body = await parseJsonInput(json);
@@ -3312,8 +3547,16 @@ function registerOAuthClientsCommand(parent) {
3312
3547
  );
3313
3548
  addExamples(update, [
3314
3549
  {
3315
- description: "Update an OAuth client from a JSON file",
3550
+ description: "Update description",
3551
+ command: `geonic admin oauth-clients update <client-id> '{"description":"Updated client"}'`
3552
+ },
3553
+ {
3554
+ description: "Update from a JSON file",
3316
3555
  command: "geonic admin oauth-clients update <client-id> @client.json"
3556
+ },
3557
+ {
3558
+ description: "Update from stdin pipe",
3559
+ command: "cat client.json | geonic admin oauth-clients update <client-id>"
3317
3560
  }
3318
3561
  ]);
3319
3562
  const del = oauthClients.command("delete <id>").description("Delete an OAuth client").action(
@@ -3349,7 +3592,9 @@ function registerCaddeCommand(parent) {
3349
3592
  command: "geonic admin cadde get"
3350
3593
  }
3351
3594
  ]);
3352
- const caddeSet = cadde.command("set [json]").description("Set CADDE configuration").action(
3595
+ const caddeSet = cadde.command("set [json]").description(
3596
+ 'Set CADDE configuration\n\nJSON payload example:\n {\n "provider": "my-provider",\n "endpoint": "http://localhost:6000"\n }'
3597
+ ).action(
3353
3598
  withErrorHandler(async (json, _opts, cmd) => {
3354
3599
  const body = await parseJsonInput(json);
3355
3600
  const client = createClient(cmd);
@@ -3363,8 +3608,16 @@ function registerCaddeCommand(parent) {
3363
3608
  );
3364
3609
  addExamples(caddeSet, [
3365
3610
  {
3366
- description: "Set CADDE configuration from a JSON file",
3611
+ description: "Set with inline JSON",
3612
+ command: `geonic admin cadde set '{"provider":"my-provider","endpoint":"http://localhost:6000"}'`
3613
+ },
3614
+ {
3615
+ description: "Set from a JSON file",
3367
3616
  command: "geonic admin cadde set @cadde-config.json"
3617
+ },
3618
+ {
3619
+ description: "Set from stdin pipe",
3620
+ command: "cat cadde-config.json | geonic admin cadde set"
3368
3621
  }
3369
3622
  ]);
3370
3623
  const caddeDelete = cadde.command("delete").description("Delete CADDE configuration").action(
@@ -3503,10 +3756,11 @@ function registerApiKeysCommand(parent) {
3503
3756
  console.error("API key created.");
3504
3757
  })
3505
3758
  );
3759
+ addNotes(create, SCOPES_HELP_NOTES);
3506
3760
  addExamples(create, [
3507
3761
  {
3508
3762
  description: "Create an API key with flags",
3509
- command: "geonic admin api-keys create --name my-key --scopes entities:read,entities:write --origins '*'"
3763
+ command: "geonic admin api-keys create --name my-key --scopes read:entities,write:entities --origins '*'"
3510
3764
  },
3511
3765
  {
3512
3766
  description: "Create an API key with DPoP required",
@@ -3543,6 +3797,7 @@ function registerApiKeysCommand(parent) {
3543
3797
  }
3544
3798
  )
3545
3799
  );
3800
+ addNotes(update, SCOPES_HELP_NOTES);
3546
3801
  addExamples(update, [
3547
3802
  {
3548
3803
  description: "Update an API key name",
@@ -3624,7 +3879,9 @@ function registerRulesCommand(program2) {
3624
3879
  command: "geonic rules get <rule-id>"
3625
3880
  }
3626
3881
  ]);
3627
- const create = rules.command("create [json]").description("Create a new rule").action(
3882
+ const create = rules.command("create [json]").description(
3883
+ 'Create a new rule\n\nJSON payload example:\n {\n "name": "high-temp-alert",\n "description": "Alert on high temperature",\n "conditions": [{"type": "celExpression", "expression": "entity.temperature > 30"}],\n "actions": [{"type": "webhook", "url": "http://localhost:5000/alert", "method": "POST"}]\n }'
3884
+ ).action(
3628
3885
  withErrorHandler(async (json, _opts, cmd) => {
3629
3886
  const body = await parseJsonInput(json);
3630
3887
  const client = createClient(cmd);
@@ -3636,11 +3893,21 @@ function registerRulesCommand(program2) {
3636
3893
  );
3637
3894
  addExamples(create, [
3638
3895
  {
3639
- description: "Create a rule from a file",
3896
+ description: "Create with inline JSON",
3897
+ command: `geonic rules create '{"name":"high-temp-alert","conditions":[{"type":"celExpression","expression":"entity.temperature > 30"}],"actions":[{"type":"webhook","url":"http://localhost:5000/alert","method":"POST"}]}'`
3898
+ },
3899
+ {
3900
+ description: "Create from a file",
3640
3901
  command: "geonic rules create @rule.json"
3902
+ },
3903
+ {
3904
+ description: "Create from stdin pipe",
3905
+ command: "cat rule.json | geonic rules create"
3641
3906
  }
3642
3907
  ]);
3643
- const update = rules.command("update <id> [json]").description("Update a rule").action(
3908
+ const update = rules.command("update <id> [json]").description(
3909
+ 'Update a rule\n\nJSON payload: only specified fields are updated.\n e.g. {"description": "Updated rule"}'
3910
+ ).action(
3644
3911
  withErrorHandler(
3645
3912
  async (id, json, _opts, cmd) => {
3646
3913
  const body = await parseJsonInput(json);
@@ -3658,8 +3925,16 @@ function registerRulesCommand(program2) {
3658
3925
  );
3659
3926
  addExamples(update, [
3660
3927
  {
3661
- description: "Update a rule from a file",
3928
+ description: "Update description",
3929
+ command: `geonic rules update <rule-id> '{"description":"Updated rule"}'`
3930
+ },
3931
+ {
3932
+ description: "Update from a file",
3662
3933
  command: "geonic rules update <rule-id> @rule.json"
3934
+ },
3935
+ {
3936
+ description: "Update from stdin pipe",
3937
+ command: "cat rule.json | geonic rules update <rule-id>"
3663
3938
  }
3664
3939
  ]);
3665
3940
  const del = rules.command("delete <id>").description("Delete a rule").action(
@@ -3746,7 +4021,9 @@ function registerModelsCommand(program2) {
3746
4021
  command: "geonic models get <model-id>"
3747
4022
  }
3748
4023
  ]);
3749
- const create = models.command("create [json]").description("Create a new model").action(
4024
+ const create = models.command("create [json]").description(
4025
+ 'Create a new model\n\nJSON payload example:\n {\n "type": "Sensor",\n "domain": "iot",\n "description": "IoT Sensor",\n "propertyDetails": {\n "temperature": {"ngsiType": "Property", "valueType": "Number", "example": 25}\n }\n }'
4026
+ ).action(
3750
4027
  withErrorHandler(async (json, _opts, cmd) => {
3751
4028
  const body = await parseJsonInput(json);
3752
4029
  const client = createClient(cmd);
@@ -3758,11 +4035,21 @@ function registerModelsCommand(program2) {
3758
4035
  );
3759
4036
  addExamples(create, [
3760
4037
  {
3761
- description: "Create a model from a file",
4038
+ description: "Create with inline JSON",
4039
+ command: `geonic models create '{"type":"Sensor","domain":"iot","description":"IoT Sensor","propertyDetails":{"temperature":{"ngsiType":"Property","valueType":"Number","example":25}}}'`
4040
+ },
4041
+ {
4042
+ description: "Create from a file",
3762
4043
  command: "geonic models create @model.json"
4044
+ },
4045
+ {
4046
+ description: "Create from stdin pipe",
4047
+ command: "cat model.json | geonic models create"
3763
4048
  }
3764
4049
  ]);
3765
- const update = models.command("update <id> [json]").description("Update a model").action(
4050
+ const update = models.command("update <id> [json]").description(
4051
+ 'Update a model\n\nJSON payload: only specified fields are updated.\n e.g. {"description": "Updated model"}'
4052
+ ).action(
3766
4053
  withErrorHandler(
3767
4054
  async (id, json, _opts, cmd) => {
3768
4055
  const body = await parseJsonInput(json);
@@ -3780,8 +4067,16 @@ function registerModelsCommand(program2) {
3780
4067
  );
3781
4068
  addExamples(update, [
3782
4069
  {
3783
- description: "Update a model from a file",
4070
+ description: "Update description",
4071
+ command: `geonic models update <model-id> '{"description":"Updated description"}'`
4072
+ },
4073
+ {
4074
+ description: "Update from a file",
3784
4075
  command: "geonic models update <model-id> @model.json"
4076
+ },
4077
+ {
4078
+ description: "Update from stdin pipe",
4079
+ command: "cat model.json | geonic models update <model-id>"
3785
4080
  }
3786
4081
  ]);
3787
4082
  const del = models.command("delete <id>").description("Delete a model").action(