@api-client/core 0.18.18 → 0.18.19

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 (36) hide show
  1. package/build/src/modeling/DataDomain.d.ts +35 -1
  2. package/build/src/modeling/DataDomain.d.ts.map +1 -1
  3. package/build/src/modeling/DataDomain.js +120 -0
  4. package/build/src/modeling/DataDomain.js.map +1 -1
  5. package/build/src/modeling/DomainProperty.d.ts +10 -0
  6. package/build/src/modeling/DomainProperty.d.ts.map +1 -1
  7. package/build/src/modeling/DomainProperty.js +26 -2
  8. package/build/src/modeling/DomainProperty.js.map +1 -1
  9. package/build/src/modeling/definitions/SKU.d.ts.map +1 -1
  10. package/build/src/modeling/definitions/SKU.js +2 -0
  11. package/build/src/modeling/definitions/SKU.js.map +1 -1
  12. package/build/src/modeling/helpers/Intelisense.d.ts +472 -0
  13. package/build/src/modeling/helpers/Intelisense.d.ts.map +1 -0
  14. package/build/src/modeling/helpers/Intelisense.js +1200 -0
  15. package/build/src/modeling/helpers/Intelisense.js.map +1 -0
  16. package/build/src/modeling/templates/blog-domain.d.ts +40 -0
  17. package/build/src/modeling/templates/blog-domain.d.ts.map +1 -0
  18. package/build/src/modeling/templates/blog-domain.js +621 -0
  19. package/build/src/modeling/templates/blog-domain.js.map +1 -0
  20. package/build/src/modeling/templates/ecommerce-domain.d.ts +39 -0
  21. package/build/src/modeling/templates/ecommerce-domain.d.ts.map +1 -0
  22. package/build/src/modeling/templates/ecommerce-domain.js +663 -0
  23. package/build/src/modeling/templates/ecommerce-domain.js.map +1 -0
  24. package/build/src/modeling/types.d.ts +49 -0
  25. package/build/src/modeling/types.d.ts.map +1 -1
  26. package/build/src/modeling/types.js.map +1 -1
  27. package/build/tsconfig.tsbuildinfo +1 -1
  28. package/package.json +1 -1
  29. package/src/modeling/DataDomain.ts +144 -0
  30. package/src/modeling/DomainProperty.ts +23 -0
  31. package/src/modeling/definitions/SKU.ts +2 -0
  32. package/src/modeling/helpers/Intelisense.ts +1345 -0
  33. package/src/modeling/templates/blog-domain.ts +787 -0
  34. package/src/modeling/templates/ecommerce-domain.ts +834 -0
  35. package/src/modeling/types.ts +63 -0
  36. package/tests/unit/modeling/DataDomain.search.spec.ts +188 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@api-client/core",
3
3
  "description": "The API Client's core client library. Works in NodeJS and in a ES enabled browser.",
4
- "version": "0.18.18",
4
+ "version": "0.18.19",
5
5
  "license": "Apache-2.0",
6
6
  "exports": {
7
7
  "./browser.js": {
@@ -15,6 +15,9 @@ import type {
15
15
  DomainGraphEdge,
16
16
  DomainGraphNodeType,
17
17
  SerializedGraph,
18
+ DomainSearchCriteria,
19
+ DomainSearchResult,
20
+ SearchableNodeType,
18
21
  } from './types.js'
19
22
  import { type DomainNamespaceSchema, DomainNamespace, type NamespaceOrderedItem } from './DomainNamespace.js'
20
23
  import { type DomainModelSchema, DomainModel } from './DomainModel.js'
@@ -1361,4 +1364,145 @@ export class DataDomain extends DependentModel {
1361
1364
  throw new Error(`Unknown kind ${kind} for the object ${key}`)
1362
1365
  }
1363
1366
  }
1367
+
1368
+ /**
1369
+ * Searches domain nodes by text content and/or node type.
1370
+ *
1371
+ * This function traverses the graph and filters nodes based on the provided search criteria.
1372
+ * It can search through name, displayName, and description fields of domain objects,
1373
+ * and optionally filter by specific node types.
1374
+ *
1375
+ * @param criteria Search criteria including query string/regex and filtering options.
1376
+ * @returns An array of search results containing matching nodes and metadata.
1377
+ *
1378
+ * @example
1379
+ * ```typescript
1380
+ * // Search for nodes containing "user" in any text field
1381
+ * const results = dataDomain.search({ query: 'user' });
1382
+ *
1383
+ * // Search for entities only
1384
+ * const entityResults = dataDomain.search({
1385
+ * nodeTypes: [DomainEntityKind]
1386
+ * });
1387
+ *
1388
+ * // Search for "user" in entities and properties with case-sensitive matching
1389
+ * const specificResults = dataDomain.search({
1390
+ * query: 'User',
1391
+ * nodeTypes: [DomainEntityKind, DomainPropertyKind],
1392
+ * caseSensitive: true
1393
+ * });
1394
+ *
1395
+ * // Search using regex pattern
1396
+ * const regexResults = dataDomain.search({
1397
+ * query: /^user/i
1398
+ * });
1399
+ * ```
1400
+ */
1401
+ search(criteria: DomainSearchCriteria = {}): DomainSearchResult[] {
1402
+ const { query, nodeTypes, includeForeignDomains = false, caseSensitive = false } = criteria
1403
+
1404
+ const results: DomainSearchResult[] = []
1405
+
1406
+ // If no criteria provided, return all nodes
1407
+ const shouldReturnAll = !query && (!nodeTypes || nodeTypes.length === 0)
1408
+
1409
+ // Helper function to check if a node matches the type filter
1410
+ const matchesNodeType = (nodeKind: string): boolean => {
1411
+ if (!nodeTypes || nodeTypes.length === 0) {
1412
+ return true
1413
+ }
1414
+ return nodeTypes.includes(nodeKind as SearchableNodeType)
1415
+ }
1416
+
1417
+ // Helper function to check if text matches the query
1418
+ const matchesQuery = (text: string | undefined): boolean => {
1419
+ if (!text || !query) {
1420
+ return !query // If no query, consider it a match
1421
+ }
1422
+
1423
+ if (query instanceof RegExp) {
1424
+ return query.test(text)
1425
+ }
1426
+
1427
+ // String query
1428
+ const searchText = caseSensitive ? text : text.toLowerCase()
1429
+ const searchQuery = caseSensitive ? query : query.toLowerCase()
1430
+ return searchText.includes(searchQuery)
1431
+ }
1432
+
1433
+ // Helper function to get matched fields for a node
1434
+ const getMatchedFields = (node: DomainGraphNodeType): ('name' | 'displayName' | 'description')[] => {
1435
+ if (!query) {
1436
+ return [] // No query means no specific field matching
1437
+ }
1438
+
1439
+ const matched: ('name' | 'displayName' | 'description')[] = []
1440
+ const { info } = node
1441
+
1442
+ if (matchesQuery(info.name)) {
1443
+ matched.push('name')
1444
+ }
1445
+ if (matchesQuery(info.displayName)) {
1446
+ matched.push('displayName')
1447
+ }
1448
+ if (matchesQuery(info.description)) {
1449
+ matched.push('description')
1450
+ }
1451
+
1452
+ return matched
1453
+ }
1454
+
1455
+ // Helper function to determine if a node key belongs to a foreign domain
1456
+ const isForeignNode = (nodeKey: string): boolean => {
1457
+ return nodeKey.includes(':')
1458
+ }
1459
+
1460
+ // Iterate through all nodes in the graph
1461
+ for (const nodeKey of this.graph.nodes()) {
1462
+ const node = this.graph.node(nodeKey) as DomainGraphNodeType
1463
+
1464
+ // Skip if node doesn't exist or doesn't have required properties
1465
+ if (!node || !node.info) {
1466
+ continue
1467
+ }
1468
+
1469
+ const isForeign = isForeignNode(nodeKey)
1470
+
1471
+ // Skip foreign nodes if not requested
1472
+ if (isForeign && !includeForeignDomains) {
1473
+ continue
1474
+ }
1475
+
1476
+ // Check node type filter
1477
+ if (!matchesNodeType(node.kind)) {
1478
+ continue
1479
+ }
1480
+
1481
+ // If returning all nodes (no specific criteria), add the node
1482
+ if (shouldReturnAll) {
1483
+ results.push({
1484
+ node,
1485
+ matchedFields: [],
1486
+ key: nodeKey,
1487
+ isForeign,
1488
+ })
1489
+ continue
1490
+ }
1491
+
1492
+ // Check text query match
1493
+ const matchedFields = getMatchedFields(node)
1494
+ const hasTextMatch = !query || matchedFields.length > 0
1495
+
1496
+ if (hasTextMatch) {
1497
+ results.push({
1498
+ node,
1499
+ matchedFields,
1500
+ key: nodeKey,
1501
+ isForeign,
1502
+ })
1503
+ }
1504
+ }
1505
+
1506
+ return results
1507
+ }
1364
1508
  }
@@ -44,6 +44,11 @@ export interface DomainPropertySchema extends DomainElementSchema {
44
44
  * Whether this property describes a primary key of the entity.
45
45
  */
46
46
  primary?: boolean
47
+ /**
48
+ * Whether this property describes a unique property of the entity.
49
+ * This is used to generate unique constraints in the database.
50
+ */
51
+ unique?: boolean
47
52
  /**
48
53
  * Whether this property describes an indexed property of the entity.
49
54
  */
@@ -158,6 +163,12 @@ export class DomainProperty extends DomainElement {
158
163
  */
159
164
  @observed() accessor primary: boolean | undefined
160
165
 
166
+ /**
167
+ * Whether this property describes a unique property of the entity.
168
+ * This is used to generate unique constraints in the database.
169
+ */
170
+ @observed() accessor unique: boolean | undefined
171
+
161
172
  /**
162
173
  * Whether this property describes an indexed property of the entity.
163
174
  */
@@ -230,6 +241,7 @@ export class DomainProperty extends DomainElement {
230
241
  type = DomainPropertyList.string,
231
242
  index,
232
243
  primary,
244
+ unique,
233
245
  readOnly,
234
246
  writeOnly,
235
247
  tags,
@@ -262,6 +274,9 @@ export class DomainProperty extends DomainElement {
262
274
  if (typeof primary === 'boolean') {
263
275
  result.primary = primary
264
276
  }
277
+ if (typeof unique === 'boolean') {
278
+ result.unique = unique
279
+ }
265
280
  if (typeof readOnly === 'boolean') {
266
281
  result.readOnly = readOnly
267
282
  }
@@ -339,6 +354,11 @@ export class DomainProperty extends DomainElement {
339
354
  } else {
340
355
  this.primary = undefined
341
356
  }
357
+ if (typeof init.unique === 'boolean') {
358
+ this.unique = init.unique
359
+ } else {
360
+ this.unique = undefined
361
+ }
342
362
  if (typeof init.readOnly === 'boolean') {
343
363
  this.readOnly = init.readOnly
344
364
  } else {
@@ -405,6 +425,9 @@ export class DomainProperty extends DomainElement {
405
425
  if (typeof this.primary === 'boolean') {
406
426
  result.primary = this.primary
407
427
  }
428
+ if (typeof this.unique === 'boolean') {
429
+ result.unique = this.unique
430
+ }
408
431
  if (typeof this.multiple === 'boolean') {
409
432
  result.multiple = this.multiple
410
433
  }
@@ -152,6 +152,8 @@ export const SKU_PRESETS = {
152
152
  caseMode: 'uppercase',
153
153
  prefix: 'PROD-',
154
154
  enforceUniqueness: true,
155
+ validateReservedWords: true,
156
+ reservedValues: ['ADMIN', 'TEST', 'NULL', 'DEFAULT'],
155
157
  }),
156
158
 
157
159
  /**