velocious 1.0.469 → 1.0.470
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/README.md +1 -1
- package/build/environment-handlers/node/cli/commands/generate/frontend-models.js +125 -2
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts +34 -0
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +114 -3
- package/package.json +1 -1
- package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +125 -2
package/package.json
CHANGED
|
@@ -1474,10 +1474,15 @@ export default class DbGenerateFrontendModels extends BaseCommand {
|
|
|
1474
1474
|
|
|
1475
1475
|
if (metadata.args.length > 0) {
|
|
1476
1476
|
const parameterNames = metadata.args.map((arg) => arg.name)
|
|
1477
|
+
// A single args object whose every field is optional accepts `{}`, so default
|
|
1478
|
+
// the parameter and mark it optional — callers can then omit it entirely
|
|
1479
|
+
// (`record.command()` instead of `record.command({})`). Required-field args keep
|
|
1480
|
+
// the mandatory parameter (a `{}` default wouldn't satisfy their type).
|
|
1481
|
+
const defaultsToEmptyObject = metadata.args.length === 1 && this.argTypeAcceptsEmptyObject(metadata.args[0].type)
|
|
1477
1482
|
|
|
1478
1483
|
return {
|
|
1479
|
-
paramDocs: metadata.args.map((arg) => ` * @param {${arg.type}} ${arg.name} - Command argument.\n`).join(""),
|
|
1480
|
-
parameters: parameterNames.join(", "),
|
|
1484
|
+
paramDocs: metadata.args.map((arg) => ` * @param {${arg.type}} ${defaultsToEmptyObject ? `[${arg.name}]` : arg.name} - Command argument.\n`).join(""),
|
|
1485
|
+
parameters: defaultsToEmptyObject ? `${parameterNames[0]} = {}` : parameterNames.join(", "),
|
|
1481
1486
|
payloadArguments: `[${parameterNames.join(", ")}]`,
|
|
1482
1487
|
returnType
|
|
1483
1488
|
}
|
|
@@ -1491,6 +1496,124 @@ export default class DbGenerateFrontendModels extends BaseCommand {
|
|
|
1491
1496
|
}
|
|
1492
1497
|
}
|
|
1493
1498
|
|
|
1499
|
+
/**
|
|
1500
|
+
* Whether a single command-args JSDoc type is known to accept an empty object `{}`:
|
|
1501
|
+
* a single balanced object literal whose top-level members are all optional (`name?:`)
|
|
1502
|
+
* or index signatures (`[k: ...]:`). Anything else returns false so the parameter stays
|
|
1503
|
+
* required — including a required member, a non-object-literal (a positional `number`,
|
|
1504
|
+
* a `Record<...>` / `Partial<...>` whose key/wrapper may still require data), and any
|
|
1505
|
+
* intersection/union (e.g. `{a?: x} & {b: string}`), where `{}` is not assignable.
|
|
1506
|
+
* @param {string} type - The arg's JSDoc type string.
|
|
1507
|
+
* @returns {boolean} - Whether the generated parameter can default to `{}`.
|
|
1508
|
+
*/
|
|
1509
|
+
argTypeAcceptsEmptyObject(type) {
|
|
1510
|
+
const trimmedType = type.trim()
|
|
1511
|
+
|
|
1512
|
+
// Must be a single balanced object literal: starts with `{`, ends with `}`, and the
|
|
1513
|
+
// opening brace closes only at the final character. This rejects intersections/unions
|
|
1514
|
+
// like `{a?: x} & {b: string}` that merely happen to start `{` and end `}`.
|
|
1515
|
+
if (!(trimmedType.startsWith("{") && trimmedType.endsWith("}"))) return false
|
|
1516
|
+
if (!this.isSingleBalancedObjectLiteral(trimmedType)) return false
|
|
1517
|
+
|
|
1518
|
+
const inner = trimmedType.slice(1, -1)
|
|
1519
|
+
|
|
1520
|
+
for (const member of this.splitTopLevelTypeMembers(inner)) {
|
|
1521
|
+
const colonIndex = this.topLevelColonIndex(member)
|
|
1522
|
+
|
|
1523
|
+
// No top-level colon: a call/construct/mapped signature or malformed member —
|
|
1524
|
+
// can't confirm it's optional, so treat the type as not empty-defaultable.
|
|
1525
|
+
if (colonIndex < 0) return false
|
|
1526
|
+
|
|
1527
|
+
const key = member.slice(0, colonIndex).trim()
|
|
1528
|
+
|
|
1529
|
+
// Index signatures (`[k: string]`) don't require a value; optional props end in `?`.
|
|
1530
|
+
// Anything else is a required property, so `{}` would not satisfy the type.
|
|
1531
|
+
if (!key.startsWith("[") && !key.endsWith("?")) return false
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
return true
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
/**
|
|
1538
|
+
* Splits the inner body of an object-literal type into its top-level members,
|
|
1539
|
+
* respecting nested `{}` / `[]` / `<>` / `()` so field types like `string[] | null`
|
|
1540
|
+
* or `{a: b}` aren't split mid-type. Members are separated by `,` or `;`.
|
|
1541
|
+
* @param {string} inner - Object-literal body (without the outer braces).
|
|
1542
|
+
* @returns {string[]} - Trimmed non-empty top-level members.
|
|
1543
|
+
*/
|
|
1544
|
+
splitTopLevelTypeMembers(inner) {
|
|
1545
|
+
const members = []
|
|
1546
|
+
let depth = 0
|
|
1547
|
+
let start = 0
|
|
1548
|
+
|
|
1549
|
+
for (let index = 0; index < inner.length; index += 1) {
|
|
1550
|
+
const character = inner[index]
|
|
1551
|
+
|
|
1552
|
+
if (character === "{" || character === "[" || character === "<" || character === "(") {
|
|
1553
|
+
depth += 1
|
|
1554
|
+
} else if (character === "}" || character === "]" || character === ">" || character === ")") {
|
|
1555
|
+
depth -= 1
|
|
1556
|
+
} else if ((character === "," || character === ";") && depth === 0) {
|
|
1557
|
+
members.push(inner.slice(start, index))
|
|
1558
|
+
start = index + 1
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
members.push(inner.slice(start))
|
|
1563
|
+
|
|
1564
|
+
return members.map((member) => member.trim()).filter((member) => member.length > 0)
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
/**
|
|
1568
|
+
* Index of the first top-level `:` in an object-literal member, ignoring colons
|
|
1569
|
+
* nested inside `{}` / `[]` / `<>` / `()` (e.g. an index signature `[k: string]`).
|
|
1570
|
+
* @param {string} member - A single object-literal member.
|
|
1571
|
+
* @returns {number} - The colon index, or -1 when none is found at the top level.
|
|
1572
|
+
*/
|
|
1573
|
+
topLevelColonIndex(member) {
|
|
1574
|
+
let depth = 0
|
|
1575
|
+
|
|
1576
|
+
for (let index = 0; index < member.length; index += 1) {
|
|
1577
|
+
const character = member[index]
|
|
1578
|
+
|
|
1579
|
+
if (character === "{" || character === "[" || character === "<" || character === "(") {
|
|
1580
|
+
depth += 1
|
|
1581
|
+
} else if (character === "}" || character === "]" || character === ">" || character === ")") {
|
|
1582
|
+
depth -= 1
|
|
1583
|
+
} else if (character === ":" && depth === 0) {
|
|
1584
|
+
return index
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
return -1
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
/**
|
|
1592
|
+
* Whether the type is a single balanced object literal — its leading `{` closes only
|
|
1593
|
+
* at the final character. Rejects top-level intersections/unions like `{a?: x} & {b: y}`
|
|
1594
|
+
* or `{a?: x} | string` whose brace depth returns to 0 before the end.
|
|
1595
|
+
* @param {string} type - A trimmed type string that starts with `{` and ends with `}`.
|
|
1596
|
+
* @returns {boolean} - Whether the braces wrap the whole type.
|
|
1597
|
+
*/
|
|
1598
|
+
isSingleBalancedObjectLiteral(type) {
|
|
1599
|
+
let depth = 0
|
|
1600
|
+
|
|
1601
|
+
for (let index = 0; index < type.length; index += 1) {
|
|
1602
|
+
const character = type[index]
|
|
1603
|
+
|
|
1604
|
+
if (character === "{" || character === "[" || character === "<" || character === "(") {
|
|
1605
|
+
depth += 1
|
|
1606
|
+
} else if (character === "}" || character === "]" || character === ">" || character === ")") {
|
|
1607
|
+
depth -= 1
|
|
1608
|
+
|
|
1609
|
+
// The opening brace balanced before the end, so something follows the literal.
|
|
1610
|
+
if (depth === 0 && index < type.length - 1) return false
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
return depth === 0
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1494
1617
|
/**
|
|
1495
1618
|
* Enriches custom-command metadata by deriving a command's typed args and return
|
|
1496
1619
|
* type from the backend resource method's `@param`/`@returns` JSDoc when they are
|