@ikas/component-cli 1.4.0-beta.185 → 1.4.0-beta.187
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +191 -8
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +108 -19
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +11 -2
- package/dist/commands/publish.js.map +1 -1
- package/dist/types.d.ts +28 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/component-helpers.d.ts +59 -0
- package/dist/utils/component-helpers.d.ts.map +1 -1
- package/dist/utils/component-helpers.js +137 -2
- package/dist/utils/component-helpers.js.map +1 -1
- package/dist/utils/websocket-server.d.ts +35 -0
- package/dist/utils/websocket-server.d.ts.map +1 -1
- package/dist/utils/websocket-server.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiXpC,eAAO,MAAM,qBAAqB,SAAU;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,KAAG,OAA2D,CAAC;AAEhE;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,MAAM,GACf;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAqBlE;AAmyBD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CA0B1E;AAMD,eAAO,MAAM,kBAAkB,UAkB9B,CAAC;AAOF,eAAO,MAAM,oBAAoB,aACrB,MAAM,YACN,MAAM,gBACF,OAAO,KACpB,IAUF,CAAC;AAuEF,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAwBf;AAOD;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,oBAAoB,CAAC,EAAE,MAAM,EAAE,EAC/B,oBAAoB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GACjC,MAAM,GAAG,IAAI,CAuDf;AAoDD,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAoBf;AAUD,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,OAAO,EACd,eAAe,EACX;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAChE,SAAS,EACb,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAsCf;AASD,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAgBf;AA+FD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,GACd,MAAM,GAAG,IAAI,CAwBf;AAuiCD,wBAAgB,mBAAmB,IAAI,OAAO,CA+X7C"}
|
package/dist/commands/config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import * as fs from "fs";
|
|
3
3
|
import * as path from "path";
|
|
4
|
-
import { PROP_TYPES, toPascalCase, generateTypesFile, isBuiltInEnumTypeId, generateGlobalTypesFile, collectUsedEnumIds, generateComponentFile, generateStylesFile, generateProjectId, isValidProjectId, generateComponentId, generateUniqueId, updateBarrelExport, findPropGroup, collectPropGroupIds, movePropGroupInTree, validateFilteredComponentIds, } from "../utils/component-helpers.js";
|
|
4
|
+
import { PROP_TYPES, toPascalCase, generateTypesFile, isBuiltInEnumTypeId, generateGlobalTypesFile, collectUsedEnumIds, generateComponentFile, generateStylesFile, generateProjectId, isValidProjectId, generateComponentId, generateUniqueId, updateBarrelExport, findPropGroup, collectPropGroupIds, movePropGroupInTree, validateFilteredComponentIds, visibilityGateError, } from "../utils/component-helpers.js";
|
|
5
5
|
function loadConfig() {
|
|
6
6
|
const configPath = path.resolve(process.cwd(), "ikas.config.json");
|
|
7
7
|
if (!fs.existsSync(configPath)) {
|
|
@@ -168,6 +168,10 @@ const ALLOWED_PROP_FIELDS = new Set([
|
|
|
168
168
|
"filteredComponentIds",
|
|
169
169
|
"privateVarMap",
|
|
170
170
|
"numberRangeData",
|
|
171
|
+
"requiredProp",
|
|
172
|
+
"requiredPropValue",
|
|
173
|
+
"requiredEnumOptionId",
|
|
174
|
+
"requiredEnumOptionValue",
|
|
171
175
|
]);
|
|
172
176
|
// Emit the standard CLI error envelope and exit(1) when a validator returned a message; a no-op
|
|
173
177
|
// when the message is null. Collapses the repeated `if (err) { console.log(...); process.exit(1) }`
|
|
@@ -178,6 +182,24 @@ function failIf(error) {
|
|
|
178
182
|
process.exit(1);
|
|
179
183
|
}
|
|
180
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* A `--requiredPropValue` flag as a boolean. Commander hands every flag over as a string, and this is
|
|
187
|
+
* the one place that turns it back; anything other than true/false is refused rather than coerced,
|
|
188
|
+
* since "0" or "off" silently becoming `true` is exactly the kind of gate nobody would think to
|
|
189
|
+
* check.
|
|
190
|
+
*/
|
|
191
|
+
function parseRequiredPropValue(raw, where) {
|
|
192
|
+
if (raw === undefined)
|
|
193
|
+
return undefined;
|
|
194
|
+
if (typeof raw === "boolean")
|
|
195
|
+
return raw;
|
|
196
|
+
if (raw === "true")
|
|
197
|
+
return true;
|
|
198
|
+
if (raw === "false")
|
|
199
|
+
return false;
|
|
200
|
+
failIf(`--requiredPropValue for ${where} must be "true" or "false" (got "${raw}").`);
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
181
203
|
/**
|
|
182
204
|
* Validate/sanitize a numberRangeData object for a NUMBER_RANGE prop. Accepts an object
|
|
183
205
|
* or a JSON string. min/max/interval are truncated to integers; only a positive interval
|
|
@@ -434,9 +456,30 @@ async function parsePropsFlag(propsJson, config, configPath) {
|
|
|
434
456
|
...(propType === "NUMBER_RANGE"
|
|
435
457
|
? { numberRangeData: requireNumberRangeData(r.numberRangeData, r.name) }
|
|
436
458
|
: {}),
|
|
459
|
+
...(r.requiredProp !== undefined
|
|
460
|
+
? { requiredProp: r.requiredProp }
|
|
461
|
+
: {}),
|
|
462
|
+
...(r.requiredPropValue !== undefined
|
|
463
|
+
? { requiredPropValue: r.requiredPropValue }
|
|
464
|
+
: {}),
|
|
465
|
+
...(r.requiredEnumOptionId !== undefined
|
|
466
|
+
? { requiredEnumOptionId: r.requiredEnumOptionId }
|
|
467
|
+
: {}),
|
|
468
|
+
...(r.requiredEnumOptionValue !== undefined
|
|
469
|
+
? { requiredEnumOptionValue: r.requiredEnumOptionValue }
|
|
470
|
+
: {}),
|
|
437
471
|
};
|
|
438
472
|
props.push(prop);
|
|
439
473
|
}
|
|
474
|
+
// Gates are checked once the whole batch is parsed: a prop may name one declared after it, and
|
|
475
|
+
// cycle detection needs every prop in hand. The batch IS the component's prop list here — the
|
|
476
|
+
// component itself does not exist yet — so it stands in as one.
|
|
477
|
+
const batch = { name: "the new component", props };
|
|
478
|
+
for (const prop of props) {
|
|
479
|
+
failIf(visibilityGateError(batch, prop, `prop "${prop.name}"`, {
|
|
480
|
+
selfPropName: prop.name,
|
|
481
|
+
}));
|
|
482
|
+
}
|
|
440
483
|
return props;
|
|
441
484
|
}
|
|
442
485
|
// --- Subcommands ---
|
|
@@ -690,6 +733,7 @@ async function addProp(ref, options) {
|
|
|
690
733
|
const numError = validateNumberDefaultValue(options.defaultValue, options.name);
|
|
691
734
|
failIf(numError);
|
|
692
735
|
}
|
|
736
|
+
const parsedVisibilityValue = parseRequiredPropValue(options.requiredPropValue, `prop "${options.name}"`);
|
|
693
737
|
const parsedNumberRangeData = propType === "NUMBER_RANGE"
|
|
694
738
|
? requireNumberRangeData(options.numberRangeData, options.name)
|
|
695
739
|
: undefined;
|
|
@@ -714,7 +758,21 @@ async function addProp(ref, options) {
|
|
|
714
758
|
...(parsedNumberRangeData
|
|
715
759
|
? { numberRangeData: parsedNumberRangeData }
|
|
716
760
|
: {}),
|
|
761
|
+
...(options.requiredProp ? { requiredProp: options.requiredProp } : {}),
|
|
762
|
+
...(parsedVisibilityValue !== undefined
|
|
763
|
+
? { requiredPropValue: parsedVisibilityValue }
|
|
764
|
+
: {}),
|
|
765
|
+
...(options.requiredProp && options.requiredEnumOptionValue !== undefined
|
|
766
|
+
? {
|
|
767
|
+
// The editor has no separate option id; the value doubles as one.
|
|
768
|
+
requiredEnumOptionId: options.requiredEnumOptionValue,
|
|
769
|
+
requiredEnumOptionValue: options.requiredEnumOptionValue,
|
|
770
|
+
}
|
|
771
|
+
: {}),
|
|
717
772
|
};
|
|
773
|
+
failIf(visibilityGateError(component, newProp, `prop "${newProp.name}"`, {
|
|
774
|
+
selfPropName: newProp.name,
|
|
775
|
+
}));
|
|
718
776
|
component.props.push(newProp);
|
|
719
777
|
saveConfig(configPath, config);
|
|
720
778
|
// Regenerate types.ts and global types
|
|
@@ -727,7 +785,6 @@ async function addProp(ref, options) {
|
|
|
727
785
|
name: newProp.name,
|
|
728
786
|
displayName: newProp.displayName,
|
|
729
787
|
type: newProp.type,
|
|
730
|
-
required: newProp.required,
|
|
731
788
|
...(newProp.groupId ? { groupId: newProp.groupId } : {}),
|
|
732
789
|
...(newProp.enumTypeId ? { enumTypeId: newProp.enumTypeId } : {}),
|
|
733
790
|
...(newProp.filteredComponentIds
|
|
@@ -739,6 +796,14 @@ async function addProp(ref, options) {
|
|
|
739
796
|
...(newProp.numberRangeData
|
|
740
797
|
? { numberRangeData: newProp.numberRangeData }
|
|
741
798
|
: {}),
|
|
799
|
+
...(newProp.requiredProp
|
|
800
|
+
? {
|
|
801
|
+
requiredProp: newProp.requiredProp,
|
|
802
|
+
...(newProp.requiredEnumOptionValue !== undefined
|
|
803
|
+
? { requiredEnumOptionValue: newProp.requiredEnumOptionValue }
|
|
804
|
+
: { requiredPropValue: newProp.requiredPropValue ?? true }),
|
|
805
|
+
}
|
|
806
|
+
: {}),
|
|
742
807
|
},
|
|
743
808
|
}));
|
|
744
809
|
}
|
|
@@ -871,9 +936,9 @@ export function validateLinkDefaultValue(propType, value, propName) {
|
|
|
871
936
|
const links = value.links;
|
|
872
937
|
return firstError(links, (link, i) => validateSingleLink(link, propName, `.links[${i}]`));
|
|
873
938
|
}
|
|
874
|
-
const COMPONENT_SHAPE_HELP =
|
|
939
|
+
const COMPONENT_SHAPE_HELP = "A COMPONENT / COMPONENT_LIST default must be an object listing child code components: " +
|
|
875
940
|
'{ "components": [ { "codeComponentId": "<id>" } ] }. Only code components are allowed; each entry ' +
|
|
876
|
-
|
|
941
|
+
'needs a string "codeComponentId" (no componentId, no inline propValues).';
|
|
877
942
|
/**
|
|
878
943
|
* Validate a COMPONENT / COMPONENT_LIST defaultValue. Reference-only: each entry must name a code
|
|
879
944
|
* component via `codeComponentId`. Rejects non-CC (`componentId`) children, missing ids, more than
|
|
@@ -887,14 +952,19 @@ export function validateComponentDefaultValue(propType, value, propName, filtere
|
|
|
887
952
|
if (typeof value === "string") {
|
|
888
953
|
return `${where} is a JSON string but must be an object. ${COMPONENT_SHAPE_HELP}`;
|
|
889
954
|
}
|
|
890
|
-
if (!value ||
|
|
955
|
+
if (!value ||
|
|
956
|
+
typeof value !== "object" ||
|
|
957
|
+
Array.isArray(value) ||
|
|
958
|
+
!Array.isArray(value.components)) {
|
|
891
959
|
return `${where} must be an object with a "components" array. ${COMPONENT_SHAPE_HELP}`;
|
|
892
960
|
}
|
|
893
961
|
const components = value.components;
|
|
894
962
|
if (propType === "COMPONENT" && components.length > 1) {
|
|
895
963
|
return `${where}: a COMPONENT prop holds a single child — provide at most one entry (use COMPONENT_LIST for many).`;
|
|
896
964
|
}
|
|
897
|
-
const allow = filteredComponentIds && filteredComponentIds.length
|
|
965
|
+
const allow = filteredComponentIds && filteredComponentIds.length
|
|
966
|
+
? new Set(filteredComponentIds)
|
|
967
|
+
: null;
|
|
898
968
|
return firstError(components, (entry, i) => {
|
|
899
969
|
const at = `${where}.components[${i}]`;
|
|
900
970
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
@@ -904,7 +974,8 @@ export function validateComponentDefaultValue(propType, value, propName, filtere
|
|
|
904
974
|
if ("componentId" in e && !("codeComponentId" in e)) {
|
|
905
975
|
return `${at} references a non-code component (componentId). Only code components are allowed as defaults. ${COMPONENT_SHAPE_HELP}`;
|
|
906
976
|
}
|
|
907
|
-
if (typeof e.codeComponentId !== "string" ||
|
|
977
|
+
if (typeof e.codeComponentId !== "string" ||
|
|
978
|
+
e.codeComponentId.trim().length === 0) {
|
|
908
979
|
return `${at} must have a non-empty string "codeComponentId". ${COMPONENT_SHAPE_HELP}`;
|
|
909
980
|
}
|
|
910
981
|
if (allow && !allow.has(e.codeComponentId)) {
|
|
@@ -1338,6 +1409,33 @@ async function updateProp(ref, options) {
|
|
|
1338
1409
|
}
|
|
1339
1410
|
}
|
|
1340
1411
|
}
|
|
1412
|
+
if (options.requiredProp !== undefined) {
|
|
1413
|
+
if (options.requiredProp === "" || options.requiredProp === "none") {
|
|
1414
|
+
// Every field goes together — see `IProp.requiredPropId`.
|
|
1415
|
+
delete prop.requiredProp;
|
|
1416
|
+
delete prop.requiredPropValue;
|
|
1417
|
+
delete prop.requiredEnumOptionId;
|
|
1418
|
+
delete prop.requiredEnumOptionValue;
|
|
1419
|
+
}
|
|
1420
|
+
else {
|
|
1421
|
+
prop.requiredProp = options.requiredProp;
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
if (options.requiredEnumOptionValue !== undefined && prop.requiredProp) {
|
|
1425
|
+
prop.requiredEnumOptionId = options.requiredEnumOptionValue;
|
|
1426
|
+
prop.requiredEnumOptionValue = options.requiredEnumOptionValue;
|
|
1427
|
+
delete prop.requiredPropValue;
|
|
1428
|
+
}
|
|
1429
|
+
if (options.requiredPropValue !== undefined && prop.requiredProp) {
|
|
1430
|
+
delete prop.requiredEnumOptionId;
|
|
1431
|
+
delete prop.requiredEnumOptionValue;
|
|
1432
|
+
prop.requiredPropValue = parseRequiredPropValue(options.requiredPropValue, `prop "${prop.name}"`);
|
|
1433
|
+
}
|
|
1434
|
+
// Re-checked on every update, not only when a visibility flag is passed: flipping `required`, or
|
|
1435
|
+
// renaming the prop this one hangs on, can invalidate a gate that was sound when it was written.
|
|
1436
|
+
failIf(visibilityGateError(component, prop, `prop "${prop.name}"`, {
|
|
1437
|
+
selfPropName: prop.name,
|
|
1438
|
+
}));
|
|
1341
1439
|
saveConfig(configPath, config);
|
|
1342
1440
|
// Regenerate types.ts and global types
|
|
1343
1441
|
regenerateTypes(component, undefined, config);
|
|
@@ -1349,7 +1447,6 @@ async function updateProp(ref, options) {
|
|
|
1349
1447
|
name: prop.name,
|
|
1350
1448
|
displayName: prop.displayName,
|
|
1351
1449
|
type: prop.type,
|
|
1352
|
-
required: prop.required,
|
|
1353
1450
|
...(prop.groupId ? { groupId: prop.groupId } : {}),
|
|
1354
1451
|
...(prop.typeId ? { typeId: prop.typeId } : {}),
|
|
1355
1452
|
...(prop.enumTypeId ? { enumTypeId: prop.enumTypeId } : {}),
|
|
@@ -1360,6 +1457,14 @@ async function updateProp(ref, options) {
|
|
|
1360
1457
|
...(prop.numberRangeData
|
|
1361
1458
|
? { numberRangeData: prop.numberRangeData }
|
|
1362
1459
|
: {}),
|
|
1460
|
+
...(prop.requiredProp
|
|
1461
|
+
? {
|
|
1462
|
+
requiredProp: prop.requiredProp,
|
|
1463
|
+
...(prop.requiredEnumOptionValue !== undefined
|
|
1464
|
+
? { requiredEnumOptionValue: prop.requiredEnumOptionValue }
|
|
1465
|
+
: { requiredPropValue: prop.requiredPropValue ?? true }),
|
|
1466
|
+
}
|
|
1467
|
+
: {}),
|
|
1363
1468
|
},
|
|
1364
1469
|
}));
|
|
1365
1470
|
}
|
|
@@ -1446,7 +1551,24 @@ function addPropGroup(ref, options) {
|
|
|
1446
1551
|
id: options.id,
|
|
1447
1552
|
name: options.name,
|
|
1448
1553
|
...(options.description ? { description: options.description } : {}),
|
|
1554
|
+
...(options.requiredProp ? { requiredProp: options.requiredProp } : {}),
|
|
1555
|
+
...(options.requiredProp && options.requiredEnumOptionValue !== undefined
|
|
1556
|
+
? {
|
|
1557
|
+
requiredEnumOptionId: options.requiredEnumOptionValue,
|
|
1558
|
+
requiredEnumOptionValue: options.requiredEnumOptionValue,
|
|
1559
|
+
}
|
|
1560
|
+
: {}),
|
|
1561
|
+
...(options.requiredProp &&
|
|
1562
|
+
options.requiredEnumOptionValue === undefined &&
|
|
1563
|
+
options.requiredPropValue !== undefined
|
|
1564
|
+
? {
|
|
1565
|
+
requiredPropValue: parseRequiredPropValue(options.requiredPropValue, `group "${options.id}"`),
|
|
1566
|
+
}
|
|
1567
|
+
: {}),
|
|
1449
1568
|
};
|
|
1569
|
+
failIf(visibilityGateError(component, newGroup, `group "${newGroup.id}"`, {
|
|
1570
|
+
group: newGroup,
|
|
1571
|
+
}));
|
|
1450
1572
|
if (options.parent) {
|
|
1451
1573
|
const found = findPropGroup(component.propGroups, options.parent);
|
|
1452
1574
|
if (!found) {
|
|
@@ -1478,6 +1600,14 @@ function addPropGroup(ref, options) {
|
|
|
1478
1600
|
id: newGroup.id,
|
|
1479
1601
|
name: newGroup.name,
|
|
1480
1602
|
...(options.parent ? { parentId: options.parent } : {}),
|
|
1603
|
+
...(newGroup.requiredProp
|
|
1604
|
+
? {
|
|
1605
|
+
requiredProp: newGroup.requiredProp,
|
|
1606
|
+
...(newGroup.requiredEnumOptionValue !== undefined
|
|
1607
|
+
? { requiredEnumOptionValue: newGroup.requiredEnumOptionValue }
|
|
1608
|
+
: { requiredPropValue: newGroup.requiredPropValue ?? true }),
|
|
1609
|
+
}
|
|
1610
|
+
: {}),
|
|
1481
1611
|
},
|
|
1482
1612
|
}));
|
|
1483
1613
|
}
|
|
@@ -1503,6 +1633,34 @@ function updatePropGroup(ref, options) {
|
|
|
1503
1633
|
found.group.name = options.name;
|
|
1504
1634
|
if (options.description !== undefined)
|
|
1505
1635
|
found.group.description = options.description || undefined;
|
|
1636
|
+
if (options.requiredProp !== undefined) {
|
|
1637
|
+
if (options.requiredProp === "" || options.requiredProp === "none") {
|
|
1638
|
+
// Every field goes together — see `IThemePropGroup.requiredPropId`.
|
|
1639
|
+
delete found.group.requiredProp;
|
|
1640
|
+
delete found.group.requiredPropValue;
|
|
1641
|
+
delete found.group.requiredEnumOptionId;
|
|
1642
|
+
delete found.group.requiredEnumOptionValue;
|
|
1643
|
+
}
|
|
1644
|
+
else {
|
|
1645
|
+
found.group.requiredProp = options.requiredProp;
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
if (options.requiredEnumOptionValue !== undefined &&
|
|
1649
|
+
found.group.requiredProp) {
|
|
1650
|
+
found.group.requiredEnumOptionId = options.requiredEnumOptionValue;
|
|
1651
|
+
found.group.requiredEnumOptionValue = options.requiredEnumOptionValue;
|
|
1652
|
+
delete found.group.requiredPropValue;
|
|
1653
|
+
}
|
|
1654
|
+
if (options.requiredPropValue !== undefined && found.group.requiredProp) {
|
|
1655
|
+
delete found.group.requiredEnumOptionId;
|
|
1656
|
+
delete found.group.requiredEnumOptionValue;
|
|
1657
|
+
found.group.requiredPropValue = parseRequiredPropValue(options.requiredPropValue, `group "${found.group.id}"`);
|
|
1658
|
+
}
|
|
1659
|
+
// Re-checked on every update: moving a prop into this group can invalidate a gate that was sound
|
|
1660
|
+
// when it was written.
|
|
1661
|
+
failIf(visibilityGateError(component, found.group, `group "${found.group.id}"`, {
|
|
1662
|
+
group: found.group,
|
|
1663
|
+
}));
|
|
1506
1664
|
saveConfig(configPath, config);
|
|
1507
1665
|
console.log(JSON.stringify({
|
|
1508
1666
|
success: true,
|
|
@@ -1510,6 +1668,16 @@ function updatePropGroup(ref, options) {
|
|
|
1510
1668
|
updatedPropGroup: {
|
|
1511
1669
|
id: found.group.id,
|
|
1512
1670
|
name: found.group.name,
|
|
1671
|
+
...(found.group.requiredProp
|
|
1672
|
+
? {
|
|
1673
|
+
requiredProp: found.group.requiredProp,
|
|
1674
|
+
...(found.group.requiredEnumOptionValue !== undefined
|
|
1675
|
+
? {
|
|
1676
|
+
requiredEnumOptionValue: found.group.requiredEnumOptionValue,
|
|
1677
|
+
}
|
|
1678
|
+
: { requiredPropValue: found.group.requiredPropValue ?? true }),
|
|
1679
|
+
}
|
|
1680
|
+
: {}),
|
|
1513
1681
|
},
|
|
1514
1682
|
}));
|
|
1515
1683
|
}
|
|
@@ -1762,6 +1930,9 @@ function updateEnum(options) {
|
|
|
1762
1930
|
}
|
|
1763
1931
|
enumType.enumOptions = enumOptions;
|
|
1764
1932
|
}
|
|
1933
|
+
// Stamp so the editor accepts this as newer than its own copy (it otherwise
|
|
1934
|
+
// only adds unknown ids and would revert this edit on its next sync-types).
|
|
1935
|
+
enumType.updatedAt = Date.now();
|
|
1765
1936
|
saveConfig(configPath, config);
|
|
1766
1937
|
// Regenerate global types and all component types
|
|
1767
1938
|
regenerateGlobalTypes(config);
|
|
@@ -1859,6 +2030,9 @@ export function createConfigCommand() {
|
|
|
1859
2030
|
.option("--filteredComponentIds <json>", "JSON array of component IDs to restrict selection (for COMPONENT/COMPONENT_LIST)")
|
|
1860
2031
|
.option("--privateVarMap <json>", "JSON object mapping variable keys to {id, typeId} (for COMPONENT/COMPONENT_LIST)")
|
|
1861
2032
|
.option("--numberRangeData <json>", 'JSON slider config for NUMBER_RANGE props, e.g. \'{"min":0,"max":100,"interval":5,"unit":"px"}\'')
|
|
2033
|
+
.option("--requiredProp <propName>", 'Show this only while the named BOOLEAN or ENUM prop satisfies the condition ("Koşullu Prop")')
|
|
2034
|
+
.option("--requiredPropValue <boolean>", "For a BOOLEAN --requiredProp: which state shows it, true (default) or false")
|
|
2035
|
+
.option("--requiredEnumOptionValue <value>", "For an ENUM --requiredProp: the option value that shows it")
|
|
1862
2036
|
.action((options) => {
|
|
1863
2037
|
addProp({ id: options.componentId, name: options.component }, options);
|
|
1864
2038
|
});
|
|
@@ -1879,6 +2053,9 @@ export function createConfigCommand() {
|
|
|
1879
2053
|
.option("--filteredComponentIds <json>", "JSON array of component IDs (use 'none' to clear)")
|
|
1880
2054
|
.option("--privateVarMap <json>", "JSON object mapping variable keys to {id, typeId} (use 'none' to clear)")
|
|
1881
2055
|
.option("--numberRangeData <json>", "JSON slider config for NUMBER_RANGE props (use 'none' to clear)")
|
|
2056
|
+
.option("--requiredProp <propName>", "BOOLEAN or ENUM prop that gates this prop in the editor panel (use 'none' to clear)")
|
|
2057
|
+
.option("--requiredPropValue <boolean>", "For a BOOLEAN --requiredProp: which state shows it, true (default) or false")
|
|
2058
|
+
.option("--requiredEnumOptionValue <value>", "For an ENUM --requiredProp: the option value that shows it")
|
|
1882
2059
|
.action((options) => {
|
|
1883
2060
|
updateProp({ id: options.componentId, name: options.component }, options);
|
|
1884
2061
|
});
|
|
@@ -1920,6 +2097,9 @@ export function createConfigCommand() {
|
|
|
1920
2097
|
.requiredOption("--name <name>", "Display name in editor")
|
|
1921
2098
|
.option("--description <description>", "Group description")
|
|
1922
2099
|
.option("--parent <parentId>", "Parent group ID (for nesting, max 1 level)")
|
|
2100
|
+
.option("--requiredProp <propName>", 'Show this only while the named BOOLEAN or ENUM prop satisfies the condition ("Koşullu Prop")')
|
|
2101
|
+
.option("--requiredPropValue <boolean>", "For a BOOLEAN --requiredProp: which state shows it, true (default) or false")
|
|
2102
|
+
.option("--requiredEnumOptionValue <value>", "For an ENUM --requiredProp: the option value that shows it")
|
|
1923
2103
|
.action((options) => {
|
|
1924
2104
|
addPropGroup({ id: options.componentId, name: options.component }, options);
|
|
1925
2105
|
});
|
|
@@ -1931,6 +2111,9 @@ export function createConfigCommand() {
|
|
|
1931
2111
|
.requiredOption("--id <id>", "Group ID to update")
|
|
1932
2112
|
.option("--name <name>", "New display name")
|
|
1933
2113
|
.option("--description <description>", "New description")
|
|
2114
|
+
.option("--requiredProp <propName>", "BOOLEAN or ENUM prop that gates this group in the editor panel (use 'none' to clear)")
|
|
2115
|
+
.option("--requiredPropValue <boolean>", "For a BOOLEAN --requiredProp: which state shows it, true (default) or false")
|
|
2116
|
+
.option("--requiredEnumOptionValue <value>", "For an ENUM --requiredProp: the option value that shows it")
|
|
1934
2117
|
.action((options) => {
|
|
1935
2118
|
updatePropGroup({ id: options.componentId, name: options.component }, options);
|
|
1936
2119
|
});
|