zinkee 0.1.11 → 0.1.15
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/AGENTS.md +42 -0
- package/README.md +7 -0
- package/dist/index.js +268 -59
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/api/records.ts +7 -0
- package/src/cli-examples.ts +18 -36
- package/src/cli-runner.ts +10 -2
- package/src/command-registry.ts +7 -0
- package/src/commands/automations.test.ts +5 -5
- package/src/commands/displays.test.ts +2 -2
- package/src/commands/records.test.ts +58 -0
- package/src/commands/records.ts +19 -0
- package/src/index.test.ts +52 -0
- package/src/utils/argv-rewrite.test.ts +149 -0
- package/src/utils/argv-rewrite.ts +269 -0
- package/src/utils/examples.ts +32 -21
- package/src/utils/schema-fields.ts +11 -9
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
|
|
3
|
+
export const HOISTABLE_GLOBAL_FLAGS = {
|
|
4
|
+
"--profile": "value",
|
|
5
|
+
"--base-url": "value",
|
|
6
|
+
"--api-key": "value",
|
|
7
|
+
"--read-only": "boolean",
|
|
8
|
+
"--json": "boolean",
|
|
9
|
+
} as const satisfies Record<string, "value" | "boolean">;
|
|
10
|
+
|
|
11
|
+
type HoistableFlagName = keyof typeof HOISTABLE_GLOBAL_FLAGS;
|
|
12
|
+
|
|
13
|
+
function isHoistableFlag(flagName: string): flagName is HoistableFlagName {
|
|
14
|
+
return Object.hasOwn(HOISTABLE_GLOBAL_FLAGS, flagName);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface OptionMetadata {
|
|
18
|
+
valueFlags: Set<string>;
|
|
19
|
+
booleanFlags: Set<string>;
|
|
20
|
+
localOptionsByCommand: Map<string, Set<string>>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getCommandPath(command: Command): string {
|
|
24
|
+
const parts: string[] = [];
|
|
25
|
+
let cursor: Command | null = command;
|
|
26
|
+
while (cursor && cursor.parent) {
|
|
27
|
+
parts.unshift(cursor.name());
|
|
28
|
+
cursor = cursor.parent;
|
|
29
|
+
}
|
|
30
|
+
return parts.join(" ");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function buildOptionMetadata(program: Command): OptionMetadata {
|
|
34
|
+
const valueFlags = new Set<string>();
|
|
35
|
+
const booleanFlags = new Set<string>();
|
|
36
|
+
const localOptionsByCommand = new Map<string, Set<string>>();
|
|
37
|
+
|
|
38
|
+
function visit(command: Command, isRoot: boolean): void {
|
|
39
|
+
const localFlags = new Set<string>();
|
|
40
|
+
|
|
41
|
+
for (const option of command.options) {
|
|
42
|
+
if (!option.long) continue;
|
|
43
|
+
|
|
44
|
+
if (option.required || option.optional) {
|
|
45
|
+
valueFlags.add(option.long);
|
|
46
|
+
} else {
|
|
47
|
+
booleanFlags.add(option.long);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!isRoot) {
|
|
51
|
+
localFlags.add(option.long);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!isRoot) {
|
|
56
|
+
localOptionsByCommand.set(getCommandPath(command), localFlags);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
for (const sub of command.commands) {
|
|
60
|
+
visit(sub, false);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
visit(program, true);
|
|
65
|
+
return { valueFlags, booleanFlags, localOptionsByCommand };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function createDefaultOptionMetadata(): OptionMetadata {
|
|
69
|
+
return {
|
|
70
|
+
valueFlags: new Set([
|
|
71
|
+
"--profile",
|
|
72
|
+
"--base-url",
|
|
73
|
+
"--api-key",
|
|
74
|
+
"--install-completion",
|
|
75
|
+
"--show-completion",
|
|
76
|
+
]),
|
|
77
|
+
booleanFlags: new Set([
|
|
78
|
+
"--read-only",
|
|
79
|
+
"--json",
|
|
80
|
+
"--example",
|
|
81
|
+
"--help",
|
|
82
|
+
]),
|
|
83
|
+
localOptionsByCommand: new Map(),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
interface FlagSplit {
|
|
88
|
+
flagName: string;
|
|
89
|
+
inlineValue: string | undefined;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function isFlagToken(token: string): boolean {
|
|
93
|
+
return token.length > 1 && token.startsWith("-");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function splitFlagToken(token: string): FlagSplit {
|
|
97
|
+
if (token.startsWith("--") && token.includes("=")) {
|
|
98
|
+
const eqIdx = token.indexOf("=");
|
|
99
|
+
return {
|
|
100
|
+
flagName: token.slice(0, eqIdx),
|
|
101
|
+
inlineValue: token.slice(eqIdx + 1),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return { flagName: token, inlineValue: undefined };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function flagConsumesValue(flagName: string, optionMeta: OptionMetadata): boolean {
|
|
108
|
+
if (optionMeta.valueFlags.has(flagName)) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
if (optionMeta.booleanFlags.has(flagName)) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
interface OperandPosition {
|
|
118
|
+
index: number;
|
|
119
|
+
token: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function collectOperandTokens(
|
|
123
|
+
userArgs: readonly string[],
|
|
124
|
+
optionMeta: OptionMetadata,
|
|
125
|
+
options: { skipFlag?: string } = {},
|
|
126
|
+
): OperandPosition[] {
|
|
127
|
+
const operands: OperandPosition[] = [];
|
|
128
|
+
let i = 0;
|
|
129
|
+
while (i < userArgs.length) {
|
|
130
|
+
const token = userArgs[i] as string;
|
|
131
|
+
|
|
132
|
+
if (token === "--") {
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (isFlagToken(token)) {
|
|
137
|
+
const { flagName, inlineValue } = splitFlagToken(token);
|
|
138
|
+
|
|
139
|
+
if (options.skipFlag !== undefined && flagName === options.skipFlag) {
|
|
140
|
+
i += 1;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (inlineValue !== undefined) {
|
|
145
|
+
i += 1;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const consumes = flagConsumesValue(flagName, optionMeta);
|
|
150
|
+
const next = userArgs[i + 1];
|
|
151
|
+
if (consumes && next !== undefined && !isFlagToken(next)) {
|
|
152
|
+
i += 2;
|
|
153
|
+
} else {
|
|
154
|
+
i += 1;
|
|
155
|
+
}
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
operands.push({ index: i, token });
|
|
160
|
+
i += 1;
|
|
161
|
+
}
|
|
162
|
+
return operands;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface CommandPathMatch {
|
|
166
|
+
commandName: string;
|
|
167
|
+
firstArgvIndex: number;
|
|
168
|
+
lastArgvIndex: number;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function findCommandPath(
|
|
172
|
+
operands: readonly OperandPosition[],
|
|
173
|
+
registry: Record<string, unknown>,
|
|
174
|
+
): CommandPathMatch | null {
|
|
175
|
+
if (operands.length === 0) return null;
|
|
176
|
+
|
|
177
|
+
const commandsByLength = Object.keys(registry).sort(
|
|
178
|
+
(left, right) => right.split(" ").length - left.split(" ").length,
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
for (let start = 0; start < operands.length; start += 1) {
|
|
182
|
+
for (const commandName of commandsByLength) {
|
|
183
|
+
const parts = commandName.split(" ");
|
|
184
|
+
if (start + parts.length > operands.length) continue;
|
|
185
|
+
|
|
186
|
+
let matches = true;
|
|
187
|
+
for (let j = 0; j < parts.length; j += 1) {
|
|
188
|
+
if (operands[start + j]!.token !== parts[j]) {
|
|
189
|
+
matches = false;
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (matches) {
|
|
195
|
+
return {
|
|
196
|
+
commandName,
|
|
197
|
+
firstArgvIndex: operands[start]!.index,
|
|
198
|
+
lastArgvIndex: operands[start + parts.length - 1]!.index,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export function hoistGlobalOptions(
|
|
208
|
+
argv: readonly string[],
|
|
209
|
+
optionMeta: OptionMetadata,
|
|
210
|
+
registry: Record<string, unknown>,
|
|
211
|
+
): string[] {
|
|
212
|
+
if (argv.length < 3) return [...argv];
|
|
213
|
+
|
|
214
|
+
const userArgs = argv.slice(2);
|
|
215
|
+
const operands = collectOperandTokens(userArgs, optionMeta);
|
|
216
|
+
const cmdPath = findCommandPath(operands, registry);
|
|
217
|
+
|
|
218
|
+
if (!cmdPath) return [...argv];
|
|
219
|
+
|
|
220
|
+
const localOptions =
|
|
221
|
+
optionMeta.localOptionsByCommand.get(cmdPath.commandName) ?? new Set<string>();
|
|
222
|
+
|
|
223
|
+
const hoisted: string[] = [];
|
|
224
|
+
const remaining: string[] = [];
|
|
225
|
+
let i = 0;
|
|
226
|
+
|
|
227
|
+
while (i < userArgs.length) {
|
|
228
|
+
const token = userArgs[i] as string;
|
|
229
|
+
|
|
230
|
+
if (token === "--") {
|
|
231
|
+
remaining.push(...userArgs.slice(i));
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (!isFlagToken(token)) {
|
|
236
|
+
remaining.push(token);
|
|
237
|
+
i += 1;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const { flagName, inlineValue } = splitFlagToken(token);
|
|
242
|
+
|
|
243
|
+
if (!isHoistableFlag(flagName)) {
|
|
244
|
+
remaining.push(token);
|
|
245
|
+
i += 1;
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const isAfterCommandPath = i > cmdPath.lastArgvIndex;
|
|
250
|
+
const collidesWithLocal = localOptions.has(flagName);
|
|
251
|
+
|
|
252
|
+
const target = isAfterCommandPath && collidesWithLocal ? remaining : hoisted;
|
|
253
|
+
target.push(token);
|
|
254
|
+
|
|
255
|
+
const spec = HOISTABLE_GLOBAL_FLAGS[flagName];
|
|
256
|
+
if (spec === "value" && inlineValue === undefined) {
|
|
257
|
+
const next = userArgs[i + 1];
|
|
258
|
+
if (next !== undefined && !isFlagToken(next)) {
|
|
259
|
+
target.push(next);
|
|
260
|
+
i += 2;
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
i += 1;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return [argv[0] as string, argv[1] as string, ...hoisted, ...remaining];
|
|
269
|
+
}
|
package/src/utils/examples.ts
CHANGED
|
@@ -411,11 +411,11 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
|
|
|
411
411
|
{
|
|
412
412
|
description: "Patch formula field (formula text).",
|
|
413
413
|
command:
|
|
414
|
-
`zinkee --json schemas fields update contacts formula-total --raw '{"type":"FormulaField","config":{"formulaText":"
|
|
414
|
+
`zinkee --json schemas fields update contacts formula-total --raw '{"type":"FormulaField","config":{"formulaText":"c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.10","uiFormatKind":"number","status":"ACTIVE","numberFormatOptions":{"format":"number","decimals":2,"thousandsSeparator":true},"conditionalFormatting":[]}}'`,
|
|
415
415
|
raw: `{
|
|
416
416
|
"type": "FormulaField",
|
|
417
417
|
"config": {
|
|
418
|
-
"formulaText": "
|
|
418
|
+
"formulaText": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.10",
|
|
419
419
|
"uiFormatKind": "number",
|
|
420
420
|
"status": "ACTIVE",
|
|
421
421
|
"numberFormatOptions": {
|
|
@@ -1398,9 +1398,9 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
|
|
|
1398
1398
|
}`,
|
|
1399
1399
|
},
|
|
1400
1400
|
{
|
|
1401
|
-
description: "Create a
|
|
1401
|
+
description: "Create a bars CHART widget with a time-serie x-axis and two y-axis series.",
|
|
1402
1402
|
command:
|
|
1403
|
-
`zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type CHART --name "Revenue by month" --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":8,"h":6}' --chart-type
|
|
1403
|
+
`zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type CHART --name "Revenue by month" --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":8,"h":6}' --chart-type bars --x-axis-field due-date --x-axis-date-format MONTH --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#4B9CD3","axisType":"PRIMARY"}' --y-axis-serie '{"typeCalc":"COUNT","fieldCalc":"id","color":"#E57373","axisType":"SECONDARY"}' --legend '{"position":"bottom"}'`,
|
|
1404
1404
|
raw: `{
|
|
1405
1405
|
"type": "CHART",
|
|
1406
1406
|
"source": {
|
|
@@ -1412,7 +1412,7 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
|
|
|
1412
1412
|
},
|
|
1413
1413
|
"presentation": { "name": "Revenue by month" },
|
|
1414
1414
|
"chart": {
|
|
1415
|
-
"chartType": "
|
|
1415
|
+
"chartType": "bars",
|
|
1416
1416
|
"xAxisFieldId": "due-date",
|
|
1417
1417
|
"xAxisDateFormat": "MONTH",
|
|
1418
1418
|
"xAxisAsTimeSerie": true,
|
|
@@ -1421,13 +1421,13 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
|
|
|
1421
1421
|
"typeCalc": "SUM",
|
|
1422
1422
|
"fieldCalc": "amount",
|
|
1423
1423
|
"color": "#4B9CD3",
|
|
1424
|
-
"axisType": "
|
|
1424
|
+
"axisType": "PRIMARY"
|
|
1425
1425
|
},
|
|
1426
1426
|
{
|
|
1427
1427
|
"typeCalc": "COUNT",
|
|
1428
1428
|
"fieldCalc": "id",
|
|
1429
1429
|
"color": "#E57373",
|
|
1430
|
-
"axisType": "
|
|
1430
|
+
"axisType": "SECONDARY"
|
|
1431
1431
|
}
|
|
1432
1432
|
],
|
|
1433
1433
|
"legend": { "position": "bottom" }
|
|
@@ -1582,12 +1582,12 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
|
|
|
1582
1582
|
}`,
|
|
1583
1583
|
},
|
|
1584
1584
|
{
|
|
1585
|
-
description: "Replace the chart series with
|
|
1585
|
+
description: "Replace the chart series with weekly lines.",
|
|
1586
1586
|
command:
|
|
1587
|
-
`zinkee --json displays widgets update 0f6f062f-1478-4df2-96a1-c495d037d260 22222222-2222-4222-a222-222222222222 --chart-type
|
|
1587
|
+
`zinkee --json displays widgets update 0f6f062f-1478-4df2-96a1-c495d037d260 22222222-2222-4222-a222-222222222222 --chart-type lines --x-axis-field due-date --x-axis-date-format WEEK --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#2E7D32","axisType":"PRIMARY"}'`,
|
|
1588
1588
|
raw: `{
|
|
1589
1589
|
"chart": {
|
|
1590
|
-
"chartType": "
|
|
1590
|
+
"chartType": "lines",
|
|
1591
1591
|
"xAxisFieldId": "due-date",
|
|
1592
1592
|
"xAxisDateFormat": "WEEK",
|
|
1593
1593
|
"xAxisAsTimeSerie": true,
|
|
@@ -1596,7 +1596,7 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
|
|
|
1596
1596
|
"typeCalc": "SUM",
|
|
1597
1597
|
"fieldCalc": "amount",
|
|
1598
1598
|
"color": "#2E7D32",
|
|
1599
|
-
"axisType": "
|
|
1599
|
+
"axisType": "PRIMARY"
|
|
1600
1600
|
}
|
|
1601
1601
|
]
|
|
1602
1602
|
}
|
|
@@ -1932,7 +1932,7 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
|
|
|
1932
1932
|
"required": false,
|
|
1933
1933
|
"system": false,
|
|
1934
1934
|
"config": {
|
|
1935
|
-
"formulaText": "
|
|
1935
|
+
"formulaText": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.21",
|
|
1936
1936
|
"uiFormatKind": "number",
|
|
1937
1937
|
"status": "ACTIVE",
|
|
1938
1938
|
"defaultValue": null,
|
|
@@ -1947,12 +1947,12 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
|
|
|
1947
1947
|
{
|
|
1948
1948
|
"id": "6d7e8f90-1234-5678-9abc-def012345678",
|
|
1949
1949
|
"type": "FormulaField",
|
|
1950
|
-
"slug": "formula-
|
|
1951
|
-
"label": "
|
|
1950
|
+
"slug": "formula-period",
|
|
1951
|
+
"label": "Formula Period",
|
|
1952
1952
|
"required": false,
|
|
1953
1953
|
"system": false,
|
|
1954
1954
|
"config": {
|
|
1955
|
-
"formulaText": "
|
|
1955
|
+
"formulaText": "date_format(d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90, \"AAAA-MM\")",
|
|
1956
1956
|
"uiFormatKind": "date",
|
|
1957
1957
|
"status": "ACTIVE",
|
|
1958
1958
|
"defaultValue": null,
|
|
@@ -2234,6 +2234,17 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
|
|
|
2234
2234
|
response: `{
|
|
2235
2235
|
"recordId": "550e8400-e29b-41d4-a716-446655440000",
|
|
2236
2236
|
"deleted": true
|
|
2237
|
+
}`,
|
|
2238
|
+
},
|
|
2239
|
+
]),
|
|
2240
|
+
"records clear": buildCommandExamples([
|
|
2241
|
+
{
|
|
2242
|
+
description:
|
|
2243
|
+
"Delete every record from a schema's table. Heritage rules (CASCADE / SET NULL) propagate to child schemas asynchronously via the CDC pipeline.",
|
|
2244
|
+
command: "zinkee --json records clear contacts",
|
|
2245
|
+
response: `{
|
|
2246
|
+
"schemaId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
|
|
2247
|
+
"cleared": true
|
|
2237
2248
|
}`,
|
|
2238
2249
|
},
|
|
2239
2250
|
]),
|
|
@@ -3353,7 +3364,7 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
|
|
|
3353
3364
|
description:
|
|
3354
3365
|
"Add a search-records action whose condition pulls its value from the trigger payload using --condition-json.",
|
|
3355
3366
|
command:
|
|
3356
|
-
`zinkee --json automations actions add automation-1 --type search_records --name "Find duplicates" --target-schema followups --condition-json '{"field":"email","comparator":"eq","values":[{"rawValue":null,"source":{"type":"TRIGGER","id":"
|
|
3367
|
+
`zinkee --json automations actions add automation-1 --type search_records --name "Find duplicates" --target-schema followups --condition-json '{"field":"email","comparator":"eq","values":[{"rawValue":null,"source":{"type":"TRIGGER","id":"f1e1d000-0000-0000-0000-000000000005"}}]}'`,
|
|
3357
3368
|
raw: `{
|
|
3358
3369
|
"type": "search_records",
|
|
3359
3370
|
"name": "Find duplicates",
|
|
@@ -3368,7 +3379,7 @@ const specificExamples: Record<string, readonly CommandExample[]> = {
|
|
|
3368
3379
|
"rawValue": null,
|
|
3369
3380
|
"source": {
|
|
3370
3381
|
"type": "TRIGGER",
|
|
3371
|
-
"id": "
|
|
3382
|
+
"id": "f1e1d000-0000-0000-0000-000000000005"
|
|
3372
3383
|
}
|
|
3373
3384
|
}
|
|
3374
3385
|
]
|
|
@@ -3965,7 +3976,7 @@ async function buildDynamicAutomationExamples(
|
|
|
3965
3976
|
{
|
|
3966
3977
|
description:
|
|
3967
3978
|
`Add a create-record action with literal and trigger-based mappings targeting ${schemaField.schemaRef}.`,
|
|
3968
|
-
command: `zinkee --json automations actions add ${automationId} --type create_record --name "Create follow-up order" --target-schema ${schemaField.schemaRef} --map ${schemaField.fieldRef}=pending --map-json owner='{"rawValue":null,"source":{"type":"TRIGGER","id":"
|
|
3979
|
+
command: `zinkee --json automations actions add ${automationId} --type create_record --name "Create follow-up order" --target-schema ${schemaField.schemaRef} --map ${schemaField.fieldRef}=pending --map-json owner='{"rawValue":null,"source":{"type":"TRIGGER","id":"${schemaField.fieldId}"}}'`,
|
|
3969
3980
|
raw: `{
|
|
3970
3981
|
"type": "create_record",
|
|
3971
3982
|
"name": "Create follow-up order",
|
|
@@ -3980,7 +3991,7 @@ async function buildDynamicAutomationExamples(
|
|
|
3980
3991
|
"rawValue": null,
|
|
3981
3992
|
"source": {
|
|
3982
3993
|
"type": "TRIGGER",
|
|
3983
|
-
"id": "
|
|
3994
|
+
"id": "${schemaField.fieldId}"
|
|
3984
3995
|
}
|
|
3985
3996
|
}
|
|
3986
3997
|
}
|
|
@@ -4008,7 +4019,7 @@ async function buildDynamicAutomationExamples(
|
|
|
4008
4019
|
},
|
|
4009
4020
|
{
|
|
4010
4021
|
description: `Add a search-records action with a trigger-based condition on ${schemaField.schemaRef}.`,
|
|
4011
|
-
command: `zinkee --json automations actions add ${automationId} --type search_records --name "Find duplicates" --target-schema ${schemaField.schemaRef} --condition-json '{"field":"${schemaField.fieldRef}","comparator":"eq","values":[{"rawValue":null,"source":{"type":"TRIGGER","id":"
|
|
4022
|
+
command: `zinkee --json automations actions add ${automationId} --type search_records --name "Find duplicates" --target-schema ${schemaField.schemaRef} --condition-json '{"field":"${schemaField.fieldRef}","comparator":"eq","values":[{"rawValue":null,"source":{"type":"TRIGGER","id":"${schemaField.fieldId}"}}]}'`,
|
|
4012
4023
|
raw: `{
|
|
4013
4024
|
"type": "search_records",
|
|
4014
4025
|
"name": "Find duplicates",
|
|
@@ -4023,7 +4034,7 @@ async function buildDynamicAutomationExamples(
|
|
|
4023
4034
|
"rawValue": null,
|
|
4024
4035
|
"source": {
|
|
4025
4036
|
"type": "TRIGGER",
|
|
4026
|
-
"id": "
|
|
4037
|
+
"id": "${schemaField.fieldId}"
|
|
4027
4038
|
}
|
|
4028
4039
|
}
|
|
4029
4040
|
]
|
|
@@ -450,17 +450,18 @@ const fieldTypeDefinitions = [
|
|
|
450
450
|
aliases: ["formula", "FormulaField"],
|
|
451
451
|
description: "Calculated field from a formula.",
|
|
452
452
|
rawShape:
|
|
453
|
-
'{"type":"FormulaField","slug":"formula-
|
|
453
|
+
'{"type":"FormulaField","slug":"formula-code","label":"Formula Code","config":{"formulaText":"concat(\\"CUST-\\", f1e1d000-0000-0000-0000-000000000005)","uiFormatKind":"none"}}',
|
|
454
454
|
examplePayloads: [
|
|
455
455
|
{
|
|
456
456
|
name: "Formula field (none)",
|
|
457
457
|
payload: {
|
|
458
458
|
type: "FormulaField",
|
|
459
|
-
slug: "formula-
|
|
460
|
-
label: "Formula
|
|
459
|
+
slug: "formula-code",
|
|
460
|
+
label: "Formula Code",
|
|
461
461
|
required: false,
|
|
462
462
|
config: {
|
|
463
|
-
formulaText:
|
|
463
|
+
formulaText:
|
|
464
|
+
'concat("CUST-", f1e1d000-0000-0000-0000-000000000005)',
|
|
464
465
|
uiFormatKind: "none",
|
|
465
466
|
status: "ACTIVE",
|
|
466
467
|
conditionalFormatting: [],
|
|
@@ -475,7 +476,7 @@ const fieldTypeDefinitions = [
|
|
|
475
476
|
label: "Formula Total",
|
|
476
477
|
required: false,
|
|
477
478
|
config: {
|
|
478
|
-
formulaText: "
|
|
479
|
+
formulaText: "c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.21",
|
|
479
480
|
uiFormatKind: "number",
|
|
480
481
|
status: "ACTIVE",
|
|
481
482
|
numberFormatOptions: {
|
|
@@ -491,11 +492,12 @@ const fieldTypeDefinitions = [
|
|
|
491
492
|
name: "Formula field (date)",
|
|
492
493
|
payload: {
|
|
493
494
|
type: "FormulaField",
|
|
494
|
-
slug: "formula-
|
|
495
|
-
label: "
|
|
495
|
+
slug: "formula-period",
|
|
496
|
+
label: "Formula Period",
|
|
496
497
|
required: false,
|
|
497
498
|
config: {
|
|
498
|
-
formulaText:
|
|
499
|
+
formulaText:
|
|
500
|
+
'date_format(d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90, "AAAA-MM")',
|
|
499
501
|
uiFormatKind: "date",
|
|
500
502
|
status: "ACTIVE",
|
|
501
503
|
dateFormatOptions: {
|
|
@@ -515,7 +517,7 @@ const fieldTypeDefinitions = [
|
|
|
515
517
|
label: "Computed Assignee",
|
|
516
518
|
required: false,
|
|
517
519
|
config: {
|
|
518
|
-
formulaText: "
|
|
520
|
+
formulaText: "a7b8c9d0-e1f2-3a4b-5c6d-7e8f90123456",
|
|
519
521
|
uiFormatKind: "member",
|
|
520
522
|
status: "ACTIVE",
|
|
521
523
|
conditionalFormatting: [],
|