zinkee 0.1.43 → 0.1.45
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 +9 -4
- package/dist/chunk-MHEVRMDX.js +1230 -0
- package/dist/chunk-MHEVRMDX.js.map +1 -0
- package/{src/utils/examples.ts → dist/examples-E6FFEVBE.js} +856 -1141
- package/dist/examples-E6FFEVBE.js.map +1 -0
- package/dist/index.js +1145 -8456
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
- package/.github/workflows/npm-publish.yml +0 -77
- package/.github/workflows/pr-checks.yml +0 -36
- package/AGENTS.md +0 -110
- package/docs/cli-contract.md +0 -41
- package/docs/npm-release.md +0 -64
- package/docs/superpowers/plans/2026-03-24-zinkee-cli-implementation.md +0 -837
- package/docs/superpowers/plans/2026-03-25-cli-backend-error-contract.md +0 -503
- package/docs/superpowers/plans/2026-03-26-display-freeform-create.md +0 -389
- package/docs/superpowers/specs/2026-03-24-zinkee-cli-backend-blockers.md +0 -172
- package/docs/superpowers/specs/2026-03-24-zinkee-cli-design.md +0 -1576
- package/docs/superpowers/specs/2026-03-24-zinkee-cli-e2e-checklist.md +0 -215
- package/docs/superpowers/specs/2026-03-24-zinkee-cli-e2e-design.md +0 -492
- package/docs/superpowers/specs/2026-03-24-zinkee-cli-e2e-status.md +0 -307
- package/docs/superpowers/specs/2026-07-30-cli-pr-checks-design.md +0 -37
- package/src/api/automations.ts +0 -404
- package/src/api/comments.ts +0 -51
- package/src/api/displays.ts +0 -337
- package/src/api/document-templates.ts +0 -110
- package/src/api/files.ts +0 -50
- package/src/api/formulas.test.ts +0 -65
- package/src/api/formulas.ts +0 -67
- package/src/api/logs.ts +0 -34
- package/src/api/navigation.ts +0 -70
- package/src/api/records.ts +0 -184
- package/src/api/schemas.ts +0 -148
- package/src/api/teamspace.ts +0 -110
- package/src/cli-examples.ts +0 -130
- package/src/cli-runner.ts +0 -95
- package/src/client.test.ts +0 -189
- package/src/client.ts +0 -269
- package/src/command-registry.ts +0 -882
- package/src/commands/automations.test.ts +0 -1030
- package/src/commands/automations.ts +0 -2102
- package/src/commands/comments.test.ts +0 -214
- package/src/commands/comments.ts +0 -303
- package/src/commands/config.test.ts +0 -81
- package/src/commands/config.ts +0 -150
- package/src/commands/displays.test.ts +0 -1105
- package/src/commands/displays.ts +0 -1442
- package/src/commands/document-templates.test.ts +0 -569
- package/src/commands/document-templates.ts +0 -563
- package/src/commands/files.test.ts +0 -284
- package/src/commands/files.ts +0 -280
- package/src/commands/formulas.test.ts +0 -194
- package/src/commands/formulas.ts +0 -243
- package/src/commands/logs.test.ts +0 -123
- package/src/commands/logs.ts +0 -159
- package/src/commands/navigation.test.ts +0 -211
- package/src/commands/navigation.ts +0 -348
- package/src/commands/profiles.test.ts +0 -191
- package/src/commands/profiles.ts +0 -303
- package/src/commands/records.test.ts +0 -860
- package/src/commands/records.ts +0 -883
- package/src/commands/schemas.test.ts +0 -1252
- package/src/commands/schemas.ts +0 -890
- package/src/commands/teamspace.test.ts +0 -229
- package/src/commands/teamspace.ts +0 -546
- package/src/completion/engine.test.ts +0 -138
- package/src/completion/engine.ts +0 -168
- package/src/completion/install.test.ts +0 -179
- package/src/completion/install.ts +0 -260
- package/src/completion/runtime.ts +0 -150
- package/src/completion/scripts.ts +0 -91
- package/src/config.test.ts +0 -362
- package/src/config.ts +0 -294
- package/src/index.test.ts +0 -217
- package/src/index.ts +0 -8
- package/src/parsers/expressions.test.ts +0 -95
- package/src/parsers/expressions.ts +0 -128
- package/src/parsers/kv.test.ts +0 -35
- package/src/parsers/kv.ts +0 -49
- package/src/parsers/selectors.test.ts +0 -23
- package/src/parsers/selectors.ts +0 -29
- package/src/program.ts +0 -64
- package/src/runtime-context.ts +0 -103
- package/src/types.ts +0 -76
- package/src/utils/argv-rewrite.test.ts +0 -149
- package/src/utils/argv-rewrite.ts +0 -269
- package/src/utils/errors.test.ts +0 -85
- package/src/utils/errors.ts +0 -191
- package/src/utils/examples.test.ts +0 -374
- package/src/utils/output.test.ts +0 -65
- package/src/utils/output.ts +0 -154
- package/src/utils/schema-fields.ts +0 -1016
- package/tsconfig.json +0 -20
- package/tsup.config.ts +0 -13
|
@@ -0,0 +1,1230 @@
|
|
|
1
|
+
// src/utils/output.ts
|
|
2
|
+
import { createRequire } from "module";
|
|
3
|
+
var require2 = createRequire(import.meta.url);
|
|
4
|
+
function stringifyCellValue(value) {
|
|
5
|
+
if (value === null || value === void 0) {
|
|
6
|
+
return "";
|
|
7
|
+
}
|
|
8
|
+
if (typeof value === "string") {
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
12
|
+
return String(value);
|
|
13
|
+
}
|
|
14
|
+
return JSON.stringify(value);
|
|
15
|
+
}
|
|
16
|
+
function buildJsonSuccess(data, meta = {}) {
|
|
17
|
+
return { data, meta };
|
|
18
|
+
}
|
|
19
|
+
function buildJsonError(error, meta = {}) {
|
|
20
|
+
return { error, meta };
|
|
21
|
+
}
|
|
22
|
+
var FOLDER_TABLE_KEYS = ["folderId", "folderName", "folderIsRoot"];
|
|
23
|
+
function folderColumns(folder) {
|
|
24
|
+
if (!folder) {
|
|
25
|
+
return { folderId: "", folderName: "", folderIsRoot: "" };
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
folderId: folder.id ?? "",
|
|
29
|
+
folderName: folder.name ?? (folder.isRoot === true ? "(root)" : ""),
|
|
30
|
+
folderIsRoot: folder.isRoot === void 0 ? "" : String(folder.isRoot)
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function printTable(rows, keys, writer) {
|
|
34
|
+
const output = writer ?? process.stdout;
|
|
35
|
+
const firstRow = rows[0];
|
|
36
|
+
if (!firstRow) {
|
|
37
|
+
output.write("No results.\n");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const headings = [...keys ?? Object.keys(firstRow)];
|
|
41
|
+
const Table = require2("cli-table3");
|
|
42
|
+
const table = new Table({
|
|
43
|
+
head: headings,
|
|
44
|
+
wordWrap: true
|
|
45
|
+
});
|
|
46
|
+
for (const row of rows) {
|
|
47
|
+
table.push(headings.map((heading) => stringifyCellValue(row[heading])));
|
|
48
|
+
}
|
|
49
|
+
output.write(`${table.toString()}
|
|
50
|
+
`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// src/client.ts
|
|
54
|
+
import { Readable, Transform } from "stream";
|
|
55
|
+
import { pipeline } from "stream/promises";
|
|
56
|
+
var ApiClientError = class extends Error {
|
|
57
|
+
name = "ApiClientError";
|
|
58
|
+
code;
|
|
59
|
+
url;
|
|
60
|
+
method;
|
|
61
|
+
status;
|
|
62
|
+
responseBody;
|
|
63
|
+
responseText;
|
|
64
|
+
cause;
|
|
65
|
+
constructor(code, message, details) {
|
|
66
|
+
super(message);
|
|
67
|
+
this.code = code;
|
|
68
|
+
this.url = details.url;
|
|
69
|
+
this.method = details.method;
|
|
70
|
+
this.status = details.status;
|
|
71
|
+
this.responseBody = details.responseBody;
|
|
72
|
+
this.responseText = details.responseText;
|
|
73
|
+
this.cause = details.cause;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
function isJsonContentType(contentType) {
|
|
77
|
+
return contentType ? /(^|\/|\+)json\b/i.test(contentType) : false;
|
|
78
|
+
}
|
|
79
|
+
function looksLikeJson(text) {
|
|
80
|
+
const trimmed = text.trim();
|
|
81
|
+
return trimmed.startsWith("{") || trimmed.startsWith("[") || trimmed === "null" || trimmed === "true" || trimmed === "false" || /^-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?$/.test(trimmed) || trimmed.startsWith('"');
|
|
82
|
+
}
|
|
83
|
+
function parseJsonBody(text, url, method) {
|
|
84
|
+
const trimmed = text.trim();
|
|
85
|
+
if (trimmed.length === 0) {
|
|
86
|
+
return void 0;
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
return JSON.parse(trimmed);
|
|
90
|
+
} catch (cause) {
|
|
91
|
+
throw new ApiClientError("invalid_json", `Failed to parse JSON response from ${method} ${url}.`, {
|
|
92
|
+
url,
|
|
93
|
+
method,
|
|
94
|
+
responseText: text,
|
|
95
|
+
cause
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function parseErrorBody(text, contentType) {
|
|
100
|
+
if (text.trim().length === 0) {
|
|
101
|
+
return void 0;
|
|
102
|
+
}
|
|
103
|
+
if (!isJsonContentType(contentType) && !looksLikeJson(text)) {
|
|
104
|
+
return text;
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
return JSON.parse(text);
|
|
108
|
+
} catch {
|
|
109
|
+
return text;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function summarizeNetworkCause(cause) {
|
|
113
|
+
const seen = /* @__PURE__ */ new Set();
|
|
114
|
+
let current = cause;
|
|
115
|
+
while (current && typeof current === "object" && !seen.has(current)) {
|
|
116
|
+
seen.add(current);
|
|
117
|
+
const candidate = current;
|
|
118
|
+
const message = typeof candidate.message === "string" ? candidate.message.trim() : "";
|
|
119
|
+
const code = typeof candidate.code === "string" ? candidate.code : void 0;
|
|
120
|
+
if (message && message !== "fetch failed") {
|
|
121
|
+
return code && !message.includes(code) ? `${message} (${code})` : message;
|
|
122
|
+
}
|
|
123
|
+
current = candidate.cause;
|
|
124
|
+
}
|
|
125
|
+
return void 0;
|
|
126
|
+
}
|
|
127
|
+
var ApiClient = class {
|
|
128
|
+
constructor(options) {
|
|
129
|
+
this.options = options;
|
|
130
|
+
this.fetchImpl = options.fetch ?? fetch;
|
|
131
|
+
}
|
|
132
|
+
fetchImpl;
|
|
133
|
+
getJson(path, init = {}) {
|
|
134
|
+
return this.requestJson(path, { ...init, method: "GET" });
|
|
135
|
+
}
|
|
136
|
+
requestJson(path, init = {}) {
|
|
137
|
+
return this.request(
|
|
138
|
+
path,
|
|
139
|
+
init,
|
|
140
|
+
async (response, url) => {
|
|
141
|
+
const text = await response.text();
|
|
142
|
+
return parseJsonBody(text, url, init.method ?? "GET");
|
|
143
|
+
},
|
|
144
|
+
"application/json"
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
download(path, destination, init = {}) {
|
|
148
|
+
return this.request(path, init, async (response, _url, signal) => {
|
|
149
|
+
let bytes = 0;
|
|
150
|
+
const counter = new Transform({
|
|
151
|
+
transform(chunk, _encoding, callback) {
|
|
152
|
+
bytes += chunk.length;
|
|
153
|
+
callback(null, chunk);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
const source = response.body ? Readable.fromWeb(response.body) : Readable.from([]);
|
|
157
|
+
await pipeline(source, counter, destination, { signal });
|
|
158
|
+
return bytes;
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
buildUrl(path) {
|
|
162
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
163
|
+
return new URL(normalizedPath, this.options.baseUrl).toString();
|
|
164
|
+
}
|
|
165
|
+
async request(path, init, consume, accept) {
|
|
166
|
+
const url = this.buildUrl(path);
|
|
167
|
+
const method = init.method ?? "GET";
|
|
168
|
+
const headers = new Headers(init.headers);
|
|
169
|
+
if (accept && !headers.has("accept")) {
|
|
170
|
+
headers.set("accept", accept);
|
|
171
|
+
}
|
|
172
|
+
if (this.options.apiKey && !headers.has("authorization")) {
|
|
173
|
+
headers.set("authorization", `Bearer ${this.options.apiKey}`);
|
|
174
|
+
}
|
|
175
|
+
const controller = new AbortController();
|
|
176
|
+
const timeoutMs = init.timeoutMs ?? this.options.timeoutMs;
|
|
177
|
+
let timedOut = false;
|
|
178
|
+
let timeoutHandle;
|
|
179
|
+
const abortListener = () => {
|
|
180
|
+
controller.abort(init.signal?.reason);
|
|
181
|
+
};
|
|
182
|
+
if (init.signal) {
|
|
183
|
+
if (init.signal.aborted) {
|
|
184
|
+
controller.abort(init.signal.reason);
|
|
185
|
+
} else {
|
|
186
|
+
init.signal.addEventListener("abort", abortListener, { once: true });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (timeoutMs !== void 0) {
|
|
190
|
+
timeoutHandle = setTimeout(() => {
|
|
191
|
+
if (!controller.signal.aborted) {
|
|
192
|
+
timedOut = true;
|
|
193
|
+
controller.abort();
|
|
194
|
+
}
|
|
195
|
+
}, timeoutMs);
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
controller.signal.throwIfAborted();
|
|
199
|
+
const response = await this.fetchImpl(url, {
|
|
200
|
+
...init,
|
|
201
|
+
headers,
|
|
202
|
+
signal: controller.signal
|
|
203
|
+
});
|
|
204
|
+
const responseUrl = response.url || url;
|
|
205
|
+
if (!response.ok) {
|
|
206
|
+
const text = await response.text();
|
|
207
|
+
throw this.buildHttpError(response, text, init, responseUrl);
|
|
208
|
+
}
|
|
209
|
+
return await consume(response, responseUrl, controller.signal);
|
|
210
|
+
} catch (cause) {
|
|
211
|
+
if (cause instanceof ApiClientError) {
|
|
212
|
+
throw cause;
|
|
213
|
+
}
|
|
214
|
+
if (timedOut) {
|
|
215
|
+
throw new ApiClientError("timeout", `Request timed out after ${timeoutMs}ms.`, {
|
|
216
|
+
url,
|
|
217
|
+
method,
|
|
218
|
+
cause
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
const causeSummary = summarizeNetworkCause(cause);
|
|
222
|
+
const message = causeSummary ? `Request failed for ${method} ${url}: ${causeSummary}.` : `Request failed for ${method} ${url}.`;
|
|
223
|
+
throw new ApiClientError("network_error", message, {
|
|
224
|
+
url,
|
|
225
|
+
method,
|
|
226
|
+
cause
|
|
227
|
+
});
|
|
228
|
+
} finally {
|
|
229
|
+
if (timeoutHandle !== void 0) {
|
|
230
|
+
clearTimeout(timeoutHandle);
|
|
231
|
+
}
|
|
232
|
+
if (init.signal) {
|
|
233
|
+
init.signal.removeEventListener("abort", abortListener);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
buildHttpError(response, text, init, url) {
|
|
238
|
+
const method = init.method ?? "GET";
|
|
239
|
+
const responseBody = parseErrorBody(text, response.headers.get("content-type"));
|
|
240
|
+
return new ApiClientError(
|
|
241
|
+
"http_error",
|
|
242
|
+
`Request failed with status ${response.status} for ${method} ${url}.`,
|
|
243
|
+
{
|
|
244
|
+
url,
|
|
245
|
+
method,
|
|
246
|
+
status: response.status,
|
|
247
|
+
responseBody,
|
|
248
|
+
responseText: responseBody === text ? text : void 0
|
|
249
|
+
}
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// src/utils/errors.ts
|
|
255
|
+
var cliExitCodeByErrorCode = {
|
|
256
|
+
unknown_error: 1,
|
|
257
|
+
invalid_cli_usage: 2,
|
|
258
|
+
configuration_error: 2,
|
|
259
|
+
command_not_allowed_in_read_only_mode: 7,
|
|
260
|
+
network_error: 1,
|
|
261
|
+
http_error: 1,
|
|
262
|
+
timeout: 1,
|
|
263
|
+
invalid_json: 1
|
|
264
|
+
};
|
|
265
|
+
var errorCodeByName = {
|
|
266
|
+
ProfileResolutionError: "configuration_error"
|
|
267
|
+
};
|
|
268
|
+
var CliError = class extends Error {
|
|
269
|
+
name = "CliError";
|
|
270
|
+
code;
|
|
271
|
+
exitCode;
|
|
272
|
+
details;
|
|
273
|
+
constructor(code, message, details = {}, exitCode = cliExitCodeByErrorCode[code]) {
|
|
274
|
+
super(message);
|
|
275
|
+
this.code = code;
|
|
276
|
+
this.exitCode = exitCode;
|
|
277
|
+
if (Object.keys(details).length > 0) {
|
|
278
|
+
this.details = details;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
toJSON() {
|
|
282
|
+
const payload = {
|
|
283
|
+
code: this.code,
|
|
284
|
+
message: this.message,
|
|
285
|
+
exitCode: this.exitCode
|
|
286
|
+
};
|
|
287
|
+
if (this.details) {
|
|
288
|
+
payload.details = this.details;
|
|
289
|
+
}
|
|
290
|
+
return payload;
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
function isRecord(value) {
|
|
294
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
295
|
+
}
|
|
296
|
+
function readString(value) {
|
|
297
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
298
|
+
}
|
|
299
|
+
function readNumber(value) {
|
|
300
|
+
return typeof value === "number" ? value : void 0;
|
|
301
|
+
}
|
|
302
|
+
function extractApiErrorDetails(error) {
|
|
303
|
+
const details = {};
|
|
304
|
+
const meta = {};
|
|
305
|
+
const responseBody = isRecord(error.responseBody) ? error.responseBody : void 0;
|
|
306
|
+
const errorBody = responseBody?.error;
|
|
307
|
+
const backendError = isRecord(errorBody) ? errorBody : responseBody;
|
|
308
|
+
const backendMeta = isRecord(responseBody?.meta) ? responseBody.meta : void 0;
|
|
309
|
+
const reason = readString(backendError?.reason) ?? readString(backendError?.code);
|
|
310
|
+
const action = readString(backendError?.action);
|
|
311
|
+
const requestId = readString(backendMeta?.requestId) ?? readString(responseBody?.requestId) ?? readString(backendError?.requestId);
|
|
312
|
+
const status = readNumber(backendError?.status) ?? readNumber(responseBody?.status) ?? error.status;
|
|
313
|
+
const backendMessage = readString(backendError?.message);
|
|
314
|
+
if (reason !== void 0) {
|
|
315
|
+
details.reason = reason;
|
|
316
|
+
}
|
|
317
|
+
if (action !== void 0) {
|
|
318
|
+
details.action = action;
|
|
319
|
+
}
|
|
320
|
+
if (requestId !== void 0) {
|
|
321
|
+
details.requestId = requestId;
|
|
322
|
+
meta.requestId = requestId;
|
|
323
|
+
}
|
|
324
|
+
if (status !== void 0) {
|
|
325
|
+
details.status = status;
|
|
326
|
+
meta.status = status;
|
|
327
|
+
}
|
|
328
|
+
return {
|
|
329
|
+
message: backendMessage ?? error.message,
|
|
330
|
+
details,
|
|
331
|
+
meta
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
function toCliError(error) {
|
|
335
|
+
if (error instanceof CliError) {
|
|
336
|
+
return error;
|
|
337
|
+
}
|
|
338
|
+
if (error instanceof ApiClientError) {
|
|
339
|
+
const apiError = extractApiErrorDetails(error);
|
|
340
|
+
return new CliError(error.code, apiError.message, apiError.details);
|
|
341
|
+
}
|
|
342
|
+
if (error instanceof Error) {
|
|
343
|
+
return new CliError(errorCodeByName[error.name] ?? "unknown_error", error.message);
|
|
344
|
+
}
|
|
345
|
+
return new CliError("unknown_error", "Unknown error");
|
|
346
|
+
}
|
|
347
|
+
function getExitCode(error) {
|
|
348
|
+
return toCliError(error).exitCode;
|
|
349
|
+
}
|
|
350
|
+
function buildJsonCliError(error, meta = {}) {
|
|
351
|
+
const cliError = toCliError(error);
|
|
352
|
+
const apiErrorMeta = error instanceof ApiClientError ? extractApiErrorDetails(error).meta : {};
|
|
353
|
+
return buildJsonError(cliError.toJSON(), { ...apiErrorMeta, ...meta });
|
|
354
|
+
}
|
|
355
|
+
function formatCliErrorText(error) {
|
|
356
|
+
return toCliError(error).message;
|
|
357
|
+
}
|
|
358
|
+
function formatCliErrorJson(error, meta = {}) {
|
|
359
|
+
return JSON.stringify(buildJsonCliError(error, meta));
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// src/utils/schema-fields.ts
|
|
363
|
+
function isJsonObject(value) {
|
|
364
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
365
|
+
}
|
|
366
|
+
function toJsonObject(value) {
|
|
367
|
+
return isJsonObject(value) ? value : void 0;
|
|
368
|
+
}
|
|
369
|
+
function toStringValue(value) {
|
|
370
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
371
|
+
}
|
|
372
|
+
function toNumberValue(value) {
|
|
373
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
374
|
+
return value;
|
|
375
|
+
}
|
|
376
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
377
|
+
const parsed = Number(value);
|
|
378
|
+
if (Number.isFinite(parsed)) {
|
|
379
|
+
return parsed;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return void 0;
|
|
383
|
+
}
|
|
384
|
+
var fieldTypeDefinitions = [
|
|
385
|
+
{
|
|
386
|
+
key: "text",
|
|
387
|
+
className: "TextField",
|
|
388
|
+
aliases: ["text", "TextField"],
|
|
389
|
+
description: "Plain text field.",
|
|
390
|
+
rawShape: '{"type":"TextField","slug":"name","label":"Name","config":{"textType":"NORMAL"}}',
|
|
391
|
+
examplePayloads: [
|
|
392
|
+
{
|
|
393
|
+
name: "Text field (normal)",
|
|
394
|
+
payload: {
|
|
395
|
+
type: "TextField",
|
|
396
|
+
slug: "customer-name",
|
|
397
|
+
label: "Customer Name",
|
|
398
|
+
required: true,
|
|
399
|
+
config: {
|
|
400
|
+
textType: "NORMAL",
|
|
401
|
+
defaultValue: null,
|
|
402
|
+
conditionalFormatting: []
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
name: "Text field (long)",
|
|
408
|
+
payload: {
|
|
409
|
+
type: "TextField",
|
|
410
|
+
slug: "customer-notes",
|
|
411
|
+
label: "Customer Notes",
|
|
412
|
+
required: false,
|
|
413
|
+
config: {
|
|
414
|
+
textType: "LONG",
|
|
415
|
+
defaultValue: "Add internal notes here...",
|
|
416
|
+
conditionalFormatting: []
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
]
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
key: "number",
|
|
424
|
+
className: "NumberField",
|
|
425
|
+
aliases: ["number", "NumberField"],
|
|
426
|
+
description: "Numeric field.",
|
|
427
|
+
rawShape: '{"type":"NumberField","slug":"quantity","label":"Quantity","config":{"defaultValue":"0","formatOptions":{"format":"number","decimals":0,"thousandsSeparator":false}}}',
|
|
428
|
+
examplePayloads: [
|
|
429
|
+
{
|
|
430
|
+
name: "Number field (plain integer)",
|
|
431
|
+
payload: {
|
|
432
|
+
type: "NumberField",
|
|
433
|
+
slug: "quantity",
|
|
434
|
+
label: "Quantity",
|
|
435
|
+
required: false,
|
|
436
|
+
config: {
|
|
437
|
+
defaultValue: "0",
|
|
438
|
+
formatOptions: {
|
|
439
|
+
format: "number",
|
|
440
|
+
decimals: 0,
|
|
441
|
+
thousandsSeparator: false
|
|
442
|
+
},
|
|
443
|
+
conditionalFormatting: []
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
name: "Number field (decimal with thousands)",
|
|
449
|
+
payload: {
|
|
450
|
+
type: "NumberField",
|
|
451
|
+
slug: "weight",
|
|
452
|
+
label: "Weight (kg)",
|
|
453
|
+
required: false,
|
|
454
|
+
config: {
|
|
455
|
+
defaultValue: "0",
|
|
456
|
+
formatOptions: {
|
|
457
|
+
format: "number",
|
|
458
|
+
decimals: 2,
|
|
459
|
+
thousandsSeparator: true,
|
|
460
|
+
negativesInRed: false
|
|
461
|
+
},
|
|
462
|
+
conditionalFormatting: []
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
name: "Number field (currency \u20AC prefix)",
|
|
468
|
+
payload: {
|
|
469
|
+
type: "NumberField",
|
|
470
|
+
slug: "amount-eur",
|
|
471
|
+
label: "Amount (EUR)",
|
|
472
|
+
required: false,
|
|
473
|
+
config: {
|
|
474
|
+
defaultValue: "0",
|
|
475
|
+
formatOptions: {
|
|
476
|
+
format: "currency",
|
|
477
|
+
decimals: 2,
|
|
478
|
+
negativesInRed: true,
|
|
479
|
+
thousandsSeparator: true,
|
|
480
|
+
symbolEnabled: true,
|
|
481
|
+
symbolPosition: "before",
|
|
482
|
+
symbolValue: "\u20AC"
|
|
483
|
+
},
|
|
484
|
+
conditionalFormatting: []
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
name: "Number field (currency $ suffix)",
|
|
490
|
+
payload: {
|
|
491
|
+
type: "NumberField",
|
|
492
|
+
slug: "amount-usd",
|
|
493
|
+
label: "Amount (USD)",
|
|
494
|
+
required: false,
|
|
495
|
+
config: {
|
|
496
|
+
defaultValue: "0",
|
|
497
|
+
formatOptions: {
|
|
498
|
+
format: "currency",
|
|
499
|
+
decimals: 2,
|
|
500
|
+
negativesInRed: false,
|
|
501
|
+
thousandsSeparator: true,
|
|
502
|
+
symbolEnabled: true,
|
|
503
|
+
symbolPosition: "right",
|
|
504
|
+
symbolValue: " $"
|
|
505
|
+
},
|
|
506
|
+
conditionalFormatting: []
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
name: "Number field (percentage)",
|
|
512
|
+
payload: {
|
|
513
|
+
type: "NumberField",
|
|
514
|
+
slug: "discount-rate",
|
|
515
|
+
label: "Discount Rate",
|
|
516
|
+
required: false,
|
|
517
|
+
config: {
|
|
518
|
+
defaultValue: "0",
|
|
519
|
+
formatOptions: {
|
|
520
|
+
format: "percentage",
|
|
521
|
+
decimals: 1,
|
|
522
|
+
negativesInRed: true
|
|
523
|
+
},
|
|
524
|
+
conditionalFormatting: []
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
name: "Number field (duration HH:MM)",
|
|
530
|
+
payload: {
|
|
531
|
+
type: "NumberField",
|
|
532
|
+
slug: "tracked-time",
|
|
533
|
+
label: "Tracked Time",
|
|
534
|
+
required: false,
|
|
535
|
+
config: {
|
|
536
|
+
defaultValue: "0",
|
|
537
|
+
formatOptions: {
|
|
538
|
+
format: "duration",
|
|
539
|
+
durationFormat: "HH:MM"
|
|
540
|
+
},
|
|
541
|
+
conditionalFormatting: []
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
]
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
key: "date",
|
|
549
|
+
className: "DateField",
|
|
550
|
+
aliases: ["date", "DateField"],
|
|
551
|
+
description: "Date or datetime field.",
|
|
552
|
+
rawShape: '{"type":"DateField","slug":"due-date","label":"Due Date","config":{"formatOptions":{"format":"date","dateFormat":"YYYY-MM-DD","showTime":false}}}',
|
|
553
|
+
examplePayloads: [
|
|
554
|
+
{
|
|
555
|
+
name: "Date field (date only)",
|
|
556
|
+
payload: {
|
|
557
|
+
type: "DateField",
|
|
558
|
+
slug: "birth-date",
|
|
559
|
+
label: "Birth Date",
|
|
560
|
+
required: false,
|
|
561
|
+
config: {
|
|
562
|
+
defaultValue: null,
|
|
563
|
+
formatOptions: {
|
|
564
|
+
format: "date",
|
|
565
|
+
dateFormat: "YYYY-MM-DD",
|
|
566
|
+
showTime: false
|
|
567
|
+
},
|
|
568
|
+
conditionalFormatting: []
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
name: "Date field (datetime EU)",
|
|
574
|
+
payload: {
|
|
575
|
+
type: "DateField",
|
|
576
|
+
slug: "due-date",
|
|
577
|
+
label: "Due Date",
|
|
578
|
+
required: false,
|
|
579
|
+
config: {
|
|
580
|
+
defaultValue: null,
|
|
581
|
+
formatOptions: {
|
|
582
|
+
format: "datetime",
|
|
583
|
+
dateFormat: "DD/MM/YYYY",
|
|
584
|
+
showTime: true
|
|
585
|
+
},
|
|
586
|
+
conditionalFormatting: []
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
name: "Date field (datetime US)",
|
|
592
|
+
payload: {
|
|
593
|
+
type: "DateField",
|
|
594
|
+
slug: "appointment-at",
|
|
595
|
+
label: "Appointment",
|
|
596
|
+
required: false,
|
|
597
|
+
config: {
|
|
598
|
+
defaultValue: null,
|
|
599
|
+
formatOptions: {
|
|
600
|
+
format: "datetime",
|
|
601
|
+
dateFormat: "MM/DD/YYYY",
|
|
602
|
+
showTime: true
|
|
603
|
+
},
|
|
604
|
+
conditionalFormatting: []
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
]
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
key: "option",
|
|
612
|
+
className: "OptionField",
|
|
613
|
+
aliases: ["option", "OptionField"],
|
|
614
|
+
description: "Dropdown/select field with options.",
|
|
615
|
+
rawShape: '{"type":"OptionField","slug":"status","label":"Status","config":{"options":[{"id":1,"name":"Open","color":"default"},{"id":2,"name":"Closed","color":"success"}]}}',
|
|
616
|
+
examplePayloads: [
|
|
617
|
+
{
|
|
618
|
+
name: "Option field (select dropdown)",
|
|
619
|
+
payload: {
|
|
620
|
+
type: "OptionField",
|
|
621
|
+
slug: "priority",
|
|
622
|
+
label: "Priority",
|
|
623
|
+
required: false,
|
|
624
|
+
config: {
|
|
625
|
+
options: [
|
|
626
|
+
{ id: 1, name: "Low", color: "default" },
|
|
627
|
+
{ id: 2, name: "Medium", color: "warning" },
|
|
628
|
+
{ id: 3, name: "High", color: "danger" }
|
|
629
|
+
],
|
|
630
|
+
defaultValue: 1,
|
|
631
|
+
conditionalFormatting: [],
|
|
632
|
+
buttonConfig: null
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
name: "Option field (button cycle)",
|
|
638
|
+
payload: {
|
|
639
|
+
type: "OptionField",
|
|
640
|
+
slug: "stage",
|
|
641
|
+
label: "Stage",
|
|
642
|
+
required: false,
|
|
643
|
+
config: {
|
|
644
|
+
options: [
|
|
645
|
+
{ id: 1, name: "To Do", color: "default" },
|
|
646
|
+
{ id: 2, name: "Doing", color: "warning" },
|
|
647
|
+
{ id: 3, name: "Done", color: "success" }
|
|
648
|
+
],
|
|
649
|
+
defaultValue: 1,
|
|
650
|
+
conditionalFormatting: [],
|
|
651
|
+
buttonConfig: {
|
|
652
|
+
displayMode: "button",
|
|
653
|
+
buttonBehavior: {
|
|
654
|
+
mode: "cycle",
|
|
655
|
+
cycleOrder: [1, 2, 3],
|
|
656
|
+
requireConfirmation: false,
|
|
657
|
+
lockAfterSelection: false,
|
|
658
|
+
allowReselect: true
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
name: "Option field (button dropdown w/ confirm)",
|
|
666
|
+
payload: {
|
|
667
|
+
type: "OptionField",
|
|
668
|
+
slug: "status",
|
|
669
|
+
label: "Status",
|
|
670
|
+
required: false,
|
|
671
|
+
config: {
|
|
672
|
+
options: [
|
|
673
|
+
{ id: 1, name: "Open", color: "default" },
|
|
674
|
+
{ id: 2, name: "In Progress", color: "warning" },
|
|
675
|
+
{ id: 3, name: "Done", color: "success" }
|
|
676
|
+
],
|
|
677
|
+
defaultValue: 1,
|
|
678
|
+
conditionalFormatting: [],
|
|
679
|
+
buttonConfig: {
|
|
680
|
+
displayMode: "button",
|
|
681
|
+
buttonBehavior: {
|
|
682
|
+
mode: "dropdown",
|
|
683
|
+
requireConfirmation: true,
|
|
684
|
+
confirmationMessage: "Confirm status change",
|
|
685
|
+
useFixedLabel: true,
|
|
686
|
+
buttonLabel: "Set status",
|
|
687
|
+
allowReselect: true
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
]
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
key: "file",
|
|
697
|
+
className: "FileField",
|
|
698
|
+
aliases: ["file", "FileField"],
|
|
699
|
+
description: "File attachment field.",
|
|
700
|
+
rawShape: '{"type":"FileField","slug":"attachment","label":"Attachment","config":{}}',
|
|
701
|
+
examplePayloads: [
|
|
702
|
+
{
|
|
703
|
+
name: "File field",
|
|
704
|
+
payload: {
|
|
705
|
+
type: "FileField",
|
|
706
|
+
slug: "attachment",
|
|
707
|
+
label: "Attachment",
|
|
708
|
+
required: false,
|
|
709
|
+
config: {}
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
]
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
key: "reference",
|
|
716
|
+
className: "ReferenceField",
|
|
717
|
+
aliases: ["reference", "ReferenceField"],
|
|
718
|
+
description: "Reference to another schema.",
|
|
719
|
+
rawShape: '{"type":"ReferenceField","slug":"company-ref","label":"Company","config":{"targetSchema":"<schema-uuid>","targetDisplayField":"<field-uuid>"}}',
|
|
720
|
+
examplePayloads: [
|
|
721
|
+
{
|
|
722
|
+
name: "Reference field (minimal)",
|
|
723
|
+
payload: {
|
|
724
|
+
type: "ReferenceField",
|
|
725
|
+
slug: "company-ref",
|
|
726
|
+
label: "Company",
|
|
727
|
+
required: false,
|
|
728
|
+
config: {
|
|
729
|
+
targetSchema: "5223cbc8-8c6c-4694-93bc-dd176364df9b",
|
|
730
|
+
targetDisplayField: "c60b8526-5835-4c9f-aecd-9a16c7704a34"
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
},
|
|
734
|
+
{
|
|
735
|
+
name: "Reference field (restrict + filter + description)",
|
|
736
|
+
payload: {
|
|
737
|
+
type: "ReferenceField",
|
|
738
|
+
slug: "customer-ref",
|
|
739
|
+
label: "Customer",
|
|
740
|
+
required: false,
|
|
741
|
+
config: {
|
|
742
|
+
targetSchema: "5223cbc8-8c6c-4694-93bc-dd176364df9b",
|
|
743
|
+
targetDisplayField: "c60b8526-5835-4c9f-aecd-9a16c7704a34",
|
|
744
|
+
deleteBehavior: "RESTRICT",
|
|
745
|
+
defaultValue: "CUST-12",
|
|
746
|
+
filterFields: [
|
|
747
|
+
{
|
|
748
|
+
fatherField: "c60b8526-5835-4c9f-aecd-9a16c7704a34",
|
|
749
|
+
currentField: "45c5da96-0dc2-4cc1-ba61-7660a9c6da32",
|
|
750
|
+
comparison: "EQUAL",
|
|
751
|
+
value: null
|
|
752
|
+
}
|
|
753
|
+
],
|
|
754
|
+
descriptionFields: [
|
|
755
|
+
{
|
|
756
|
+
id: "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
|
|
757
|
+
fieldType: "NumberField",
|
|
758
|
+
options: null,
|
|
759
|
+
format: "number"
|
|
760
|
+
}
|
|
761
|
+
],
|
|
762
|
+
conditionalFormatting: []
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
]
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
key: "formula",
|
|
770
|
+
className: "FormulaField",
|
|
771
|
+
aliases: ["formula", "FormulaField"],
|
|
772
|
+
description: "Calculated field from a formula.",
|
|
773
|
+
rawShape: '{"type":"FormulaField","slug":"formula-code","label":"Formula Code","config":{"formulaText":"concat(\\"CUST-\\", f1e1d000-0000-0000-0000-000000000005)","uiFormatKind":"none"}}',
|
|
774
|
+
examplePayloads: [
|
|
775
|
+
{
|
|
776
|
+
name: "Formula field (none)",
|
|
777
|
+
payload: {
|
|
778
|
+
type: "FormulaField",
|
|
779
|
+
slug: "formula-code",
|
|
780
|
+
label: "Formula Code",
|
|
781
|
+
required: false,
|
|
782
|
+
config: {
|
|
783
|
+
formulaText: 'concat("CUST-", f1e1d000-0000-0000-0000-000000000005)',
|
|
784
|
+
uiFormatKind: "none",
|
|
785
|
+
status: "ACTIVE",
|
|
786
|
+
conditionalFormatting: []
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
},
|
|
790
|
+
{
|
|
791
|
+
name: "Formula field (number)",
|
|
792
|
+
payload: {
|
|
793
|
+
type: "FormulaField",
|
|
794
|
+
slug: "formula-total",
|
|
795
|
+
label: "Formula Total",
|
|
796
|
+
required: false,
|
|
797
|
+
config: {
|
|
798
|
+
formulaText: "c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.21",
|
|
799
|
+
uiFormatKind: "number",
|
|
800
|
+
status: "ACTIVE",
|
|
801
|
+
numberFormatOptions: {
|
|
802
|
+
format: "number",
|
|
803
|
+
decimals: 2,
|
|
804
|
+
thousandsSeparator: true
|
|
805
|
+
},
|
|
806
|
+
conditionalFormatting: []
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
},
|
|
810
|
+
{
|
|
811
|
+
name: "Formula field (date)",
|
|
812
|
+
payload: {
|
|
813
|
+
type: "FormulaField",
|
|
814
|
+
slug: "formula-period",
|
|
815
|
+
label: "Formula Period",
|
|
816
|
+
required: false,
|
|
817
|
+
config: {
|
|
818
|
+
formulaText: 'date_format(d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90, "AAAA-MM")',
|
|
819
|
+
uiFormatKind: "date",
|
|
820
|
+
status: "ACTIVE",
|
|
821
|
+
dateFormatOptions: {
|
|
822
|
+
format: "date",
|
|
823
|
+
dateFormat: "DD/MM/YYYY",
|
|
824
|
+
showTime: false
|
|
825
|
+
},
|
|
826
|
+
conditionalFormatting: []
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
},
|
|
830
|
+
{
|
|
831
|
+
name: "Formula field (member)",
|
|
832
|
+
payload: {
|
|
833
|
+
type: "FormulaField",
|
|
834
|
+
slug: "formula-assignee",
|
|
835
|
+
label: "Computed Assignee",
|
|
836
|
+
required: false,
|
|
837
|
+
config: {
|
|
838
|
+
formulaText: "a7b8c9d0-e1f2-3a4b-5c6d-7e8f90123456",
|
|
839
|
+
uiFormatKind: "member",
|
|
840
|
+
status: "ACTIVE",
|
|
841
|
+
conditionalFormatting: []
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
]
|
|
846
|
+
},
|
|
847
|
+
{
|
|
848
|
+
key: "member",
|
|
849
|
+
className: "MemberField",
|
|
850
|
+
aliases: ["member", "MemberField"],
|
|
851
|
+
description: "Workspace member field.",
|
|
852
|
+
rawShape: '{"type":"MemberField","slug":"owner","label":"Owner","config":{"defaultValue":null}}',
|
|
853
|
+
examplePayloads: [
|
|
854
|
+
{
|
|
855
|
+
name: "Member field",
|
|
856
|
+
payload: {
|
|
857
|
+
type: "MemberField",
|
|
858
|
+
slug: "owner",
|
|
859
|
+
label: "Owner",
|
|
860
|
+
required: false,
|
|
861
|
+
config: {
|
|
862
|
+
defaultValue: null,
|
|
863
|
+
conditionalFormatting: []
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
]
|
|
868
|
+
},
|
|
869
|
+
{
|
|
870
|
+
key: "autoincremental",
|
|
871
|
+
className: "AutoIncrementalField",
|
|
872
|
+
aliases: [
|
|
873
|
+
"autoincremental",
|
|
874
|
+
"auto-incremental",
|
|
875
|
+
"auto_incremental",
|
|
876
|
+
"AutoIncrementalField"
|
|
877
|
+
],
|
|
878
|
+
description: "Auto-generated incremental counter.",
|
|
879
|
+
rawShape: '{"type":"AutoIncrementalField","slug":"order-number","label":"Order Number","config":{"segmentedByFieldId":null}}',
|
|
880
|
+
examplePayloads: [
|
|
881
|
+
{
|
|
882
|
+
name: "Autoincremental (global counter)",
|
|
883
|
+
payload: {
|
|
884
|
+
type: "AutoIncrementalField",
|
|
885
|
+
slug: "order-number",
|
|
886
|
+
label: "Order Number",
|
|
887
|
+
required: false,
|
|
888
|
+
config: {
|
|
889
|
+
segmentedByFieldId: null,
|
|
890
|
+
conditionalFormatting: []
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
},
|
|
894
|
+
{
|
|
895
|
+
name: "Autoincremental (segmented)",
|
|
896
|
+
payload: {
|
|
897
|
+
type: "AutoIncrementalField",
|
|
898
|
+
slug: "sequence-code",
|
|
899
|
+
label: "Sequence Code",
|
|
900
|
+
required: false,
|
|
901
|
+
config: {
|
|
902
|
+
segmentedByFieldId: "45c5da96-0dc2-4cc1-ba61-7660a9c6da32",
|
|
903
|
+
conditionalFormatting: []
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
]
|
|
908
|
+
},
|
|
909
|
+
{
|
|
910
|
+
key: "schedule",
|
|
911
|
+
className: "ScheduleField",
|
|
912
|
+
aliases: ["schedule", "ScheduleField"],
|
|
913
|
+
description: "Recurrence/schedule field bound to a number reference and a date period (frequency: monthly or daily).",
|
|
914
|
+
rawShape: '{"type":"ScheduleField","slug":"recurrence","label":"Recurrence","config":{"referenceField":"<number-field-uuid>","beginningPeriodField":"<date-field-uuid>","endingPeriodField":"<date-field-uuid>","frequency":"monthly"}}',
|
|
915
|
+
examplePayloads: [
|
|
916
|
+
{
|
|
917
|
+
name: "Schedule field (monthly)",
|
|
918
|
+
payload: {
|
|
919
|
+
type: "ScheduleField",
|
|
920
|
+
slug: "monthly-recurrence",
|
|
921
|
+
label: "Monthly Recurrence",
|
|
922
|
+
required: false,
|
|
923
|
+
config: {
|
|
924
|
+
referenceField: "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
|
|
925
|
+
beginningPeriodField: "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
|
926
|
+
endingPeriodField: "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
|
927
|
+
frequency: "monthly"
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
},
|
|
931
|
+
{
|
|
932
|
+
name: "Schedule field (daily)",
|
|
933
|
+
payload: {
|
|
934
|
+
type: "ScheduleField",
|
|
935
|
+
slug: "daily-recurrence",
|
|
936
|
+
label: "Daily Recurrence",
|
|
937
|
+
required: false,
|
|
938
|
+
config: {
|
|
939
|
+
referenceField: "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
|
|
940
|
+
beginningPeriodField: "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
|
941
|
+
endingPeriodField: "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
|
942
|
+
frequency: "daily"
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
]
|
|
947
|
+
}
|
|
948
|
+
];
|
|
949
|
+
var fieldTypeDefinitionByAlias = new Map(
|
|
950
|
+
fieldTypeDefinitions.flatMap(
|
|
951
|
+
(definition) => definition.aliases.map((alias) => [alias.trim().toLowerCase(), definition])
|
|
952
|
+
)
|
|
953
|
+
);
|
|
954
|
+
var fieldTypeDefinitionByClassName = new Map(
|
|
955
|
+
fieldTypeDefinitions.map((definition) => [definition.className, definition])
|
|
956
|
+
);
|
|
957
|
+
var optionValidationMessage = 'Option fields require an "options" array with at least one entry like {"id":1,"name":"Open","color":"default"}.';
|
|
958
|
+
function getSchemaFieldTypeDefinitions() {
|
|
959
|
+
return fieldTypeDefinitions;
|
|
960
|
+
}
|
|
961
|
+
function listSchemaFieldTypes() {
|
|
962
|
+
return fieldTypeDefinitions.map((definition) => definition.key);
|
|
963
|
+
}
|
|
964
|
+
function formatSchemaFieldTypes() {
|
|
965
|
+
return listSchemaFieldTypes().join(", ");
|
|
966
|
+
}
|
|
967
|
+
function resolveSchemaFieldType(input) {
|
|
968
|
+
if (!input) {
|
|
969
|
+
return void 0;
|
|
970
|
+
}
|
|
971
|
+
return fieldTypeDefinitionByAlias.get(input.trim().toLowerCase());
|
|
972
|
+
}
|
|
973
|
+
function resolveSchemaFieldTypeByClassName(className) {
|
|
974
|
+
if (!className) {
|
|
975
|
+
return void 0;
|
|
976
|
+
}
|
|
977
|
+
return fieldTypeDefinitionByClassName.get(className);
|
|
978
|
+
}
|
|
979
|
+
function normalizeSchemaFieldType(input) {
|
|
980
|
+
const definition = resolveSchemaFieldType(input);
|
|
981
|
+
if (definition) {
|
|
982
|
+
return definition.className;
|
|
983
|
+
}
|
|
984
|
+
if (/^[a-z]/.test(input) && !input.endsWith("Field")) {
|
|
985
|
+
return `${input.charAt(0).toUpperCase()}${input.slice(1)}Field`;
|
|
986
|
+
}
|
|
987
|
+
return input;
|
|
988
|
+
}
|
|
989
|
+
function assertSupportedSchemaFieldType(type) {
|
|
990
|
+
if (!resolveSchemaFieldTypeByClassName(type)) {
|
|
991
|
+
throw new CliError(
|
|
992
|
+
"invalid_cli_usage",
|
|
993
|
+
`Unsupported field type "${type}". Valid types: ${formatSchemaFieldTypes()}.`
|
|
994
|
+
);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
function normalizeOptionEntries(entries) {
|
|
998
|
+
return entries.flatMap((entry) => {
|
|
999
|
+
if (!isJsonObject(entry)) {
|
|
1000
|
+
return [];
|
|
1001
|
+
}
|
|
1002
|
+
const id = toNumberValue(entry.id);
|
|
1003
|
+
const name = toStringValue(entry.name) ?? toStringValue(entry.label);
|
|
1004
|
+
const color = toStringValue(entry.color) ?? "default";
|
|
1005
|
+
if (id === void 0 || !name) {
|
|
1006
|
+
return [];
|
|
1007
|
+
}
|
|
1008
|
+
return [{ id, name, color }];
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
function normalizeOptionPayload(input) {
|
|
1012
|
+
const additionalProperties = toJsonObject(input.additionalProperties) ?? {};
|
|
1013
|
+
const config = toJsonObject(input.config);
|
|
1014
|
+
const rootOptions = Array.isArray(input.options) ? input.options : void 0;
|
|
1015
|
+
const nestedOptions = Array.isArray(additionalProperties.options) ? additionalProperties.options : Array.isArray(config?.options) ? config.options : void 0;
|
|
1016
|
+
const optionObjects = normalizeOptionEntries(
|
|
1017
|
+
nestedOptions ?? (Array.isArray(rootOptions) ? rootOptions : [])
|
|
1018
|
+
);
|
|
1019
|
+
if (optionObjects.length === 0) {
|
|
1020
|
+
throw new CliError("invalid_cli_usage", optionValidationMessage);
|
|
1021
|
+
}
|
|
1022
|
+
const { options: _options, additionalProperties: _additionalProperties, ...rest } = input;
|
|
1023
|
+
const defaultValue = config?.defaultValue ?? input.defaultValue ?? additionalProperties.defaultValue;
|
|
1024
|
+
const conditionalFormatting = config?.conditionalFormatting ?? additionalProperties.conditionalFormatting;
|
|
1025
|
+
const buttonConfig = config?.buttonConfig ?? additionalProperties.buttonConfig;
|
|
1026
|
+
return {
|
|
1027
|
+
...rest,
|
|
1028
|
+
config: {
|
|
1029
|
+
...config ?? {},
|
|
1030
|
+
options: optionObjects,
|
|
1031
|
+
...defaultValue !== void 0 ? { defaultValue } : {},
|
|
1032
|
+
...conditionalFormatting !== void 0 ? { conditionalFormatting } : {},
|
|
1033
|
+
...buttonConfig !== void 0 ? { buttonConfig } : {}
|
|
1034
|
+
}
|
|
1035
|
+
};
|
|
1036
|
+
}
|
|
1037
|
+
function normalizeReferencePayload(input) {
|
|
1038
|
+
const additionalProperties = toJsonObject(input.additionalProperties) ?? {};
|
|
1039
|
+
const config = toJsonObject(input.config) ?? {};
|
|
1040
|
+
const targetSchema = config.targetSchema ?? input.targetSchema ?? additionalProperties.targetSchema;
|
|
1041
|
+
const targetDisplayField = config.targetDisplayField ?? input.targetDisplayField ?? additionalProperties.targetDisplayField;
|
|
1042
|
+
const deleteBehavior = config.deleteBehavior ?? input.deleteBehavior ?? additionalProperties.deleteBehavior;
|
|
1043
|
+
const defaultValue = config.defaultValue ?? input.defaultValue ?? additionalProperties.defaultValue;
|
|
1044
|
+
const filterFields = config.filterFields ?? input.filterFields ?? additionalProperties.filterFields;
|
|
1045
|
+
const descriptionFields = config.descriptionFields ?? input.descriptionFields ?? additionalProperties.descriptionFields;
|
|
1046
|
+
const conditionalFormatting = config.conditionalFormatting ?? input.conditionalFormatting ?? additionalProperties.conditionalFormatting;
|
|
1047
|
+
const normalized = {
|
|
1048
|
+
...input
|
|
1049
|
+
};
|
|
1050
|
+
normalized.config = {
|
|
1051
|
+
...config,
|
|
1052
|
+
...targetSchema !== void 0 ? { targetSchema } : {},
|
|
1053
|
+
...targetDisplayField !== void 0 ? { targetDisplayField } : {},
|
|
1054
|
+
...deleteBehavior !== void 0 ? { deleteBehavior } : {},
|
|
1055
|
+
...defaultValue !== void 0 ? { defaultValue } : {},
|
|
1056
|
+
...filterFields !== void 0 ? { filterFields } : {},
|
|
1057
|
+
...descriptionFields !== void 0 ? { descriptionFields } : {},
|
|
1058
|
+
...conditionalFormatting !== void 0 ? { conditionalFormatting } : {}
|
|
1059
|
+
};
|
|
1060
|
+
const normalizedConfig = toJsonObject(normalized.config) ?? {};
|
|
1061
|
+
if (!toStringValue(normalizedConfig.targetSchema) || !toStringValue(normalizedConfig.targetDisplayField)) {
|
|
1062
|
+
const definition = resolveSchemaFieldType("reference");
|
|
1063
|
+
throw new CliError(
|
|
1064
|
+
"invalid_cli_usage",
|
|
1065
|
+
`Reference fields require "targetSchema" and "targetDisplayField". Expected raw shape: ${definition.rawShape}`
|
|
1066
|
+
);
|
|
1067
|
+
}
|
|
1068
|
+
return normalized;
|
|
1069
|
+
}
|
|
1070
|
+
var scheduleAllowedFrequencies = /* @__PURE__ */ new Set(["monthly", "daily"]);
|
|
1071
|
+
function normalizeSchedulePayload(input) {
|
|
1072
|
+
const additionalProperties = toJsonObject(input.additionalProperties) ?? {};
|
|
1073
|
+
const config = toJsonObject(input.config) ?? {};
|
|
1074
|
+
const referenceField = config.referenceField ?? input.referenceField ?? additionalProperties.referenceField;
|
|
1075
|
+
const beginningPeriodField = config.beginningPeriodField ?? input.beginningPeriodField ?? additionalProperties.beginningPeriodField;
|
|
1076
|
+
const endingPeriodField = config.endingPeriodField ?? input.endingPeriodField ?? additionalProperties.endingPeriodField;
|
|
1077
|
+
const frequency = config.frequency ?? input.frequency ?? additionalProperties.frequency;
|
|
1078
|
+
const {
|
|
1079
|
+
referenceField: _referenceField,
|
|
1080
|
+
beginningPeriodField: _beginningPeriodField,
|
|
1081
|
+
endingPeriodField: _endingPeriodField,
|
|
1082
|
+
frequency: _frequency,
|
|
1083
|
+
additionalProperties: _additionalProperties,
|
|
1084
|
+
...rest
|
|
1085
|
+
} = input;
|
|
1086
|
+
const normalized = {
|
|
1087
|
+
...rest,
|
|
1088
|
+
config: {
|
|
1089
|
+
...config,
|
|
1090
|
+
...referenceField !== void 0 ? { referenceField } : {},
|
|
1091
|
+
...beginningPeriodField !== void 0 ? { beginningPeriodField } : {},
|
|
1092
|
+
...endingPeriodField !== void 0 ? { endingPeriodField } : {},
|
|
1093
|
+
...frequency !== void 0 ? { frequency } : {}
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
1096
|
+
const normalizedConfig = toJsonObject(normalized.config) ?? {};
|
|
1097
|
+
const definition = resolveSchemaFieldType("schedule");
|
|
1098
|
+
if (!toStringValue(normalizedConfig.referenceField) || !toStringValue(normalizedConfig.beginningPeriodField) || !toStringValue(normalizedConfig.endingPeriodField) || !toStringValue(normalizedConfig.frequency)) {
|
|
1099
|
+
throw new CliError(
|
|
1100
|
+
"invalid_cli_usage",
|
|
1101
|
+
`Schedule fields require "referenceField", "beginningPeriodField", "endingPeriodField" and "frequency". Expected raw shape: ${definition.rawShape}`
|
|
1102
|
+
);
|
|
1103
|
+
}
|
|
1104
|
+
const frequencyValue = toStringValue(normalizedConfig.frequency);
|
|
1105
|
+
if (!scheduleAllowedFrequencies.has(frequencyValue)) {
|
|
1106
|
+
throw new CliError(
|
|
1107
|
+
"invalid_cli_usage",
|
|
1108
|
+
`Schedule "frequency" must be "monthly" or "daily" (received "${frequencyValue}").`
|
|
1109
|
+
);
|
|
1110
|
+
}
|
|
1111
|
+
return normalized;
|
|
1112
|
+
}
|
|
1113
|
+
function normalizeFormulaPayload(input) {
|
|
1114
|
+
const { status: _status, ...rest } = input;
|
|
1115
|
+
const rawAdditionalProperties = toJsonObject(input.additionalProperties);
|
|
1116
|
+
const rawConfig = toJsonObject(input.config);
|
|
1117
|
+
const { status: _additionalStatus, ...additionalProperties } = rawAdditionalProperties ?? {};
|
|
1118
|
+
const { status: _configStatus, ...config } = rawConfig ?? {};
|
|
1119
|
+
const formulaText = config.formulaText ?? rest.formulaText ?? rest.expression ?? additionalProperties.formulaText ?? additionalProperties.expression;
|
|
1120
|
+
const normalized = {
|
|
1121
|
+
...rest
|
|
1122
|
+
};
|
|
1123
|
+
normalized.config = {
|
|
1124
|
+
...config,
|
|
1125
|
+
...formulaText !== void 0 ? { formulaText } : {},
|
|
1126
|
+
...config.uiFormatKind !== void 0 ? { uiFormatKind: config.uiFormatKind } : {},
|
|
1127
|
+
...config.defaultValue !== void 0 ? { defaultValue: config.defaultValue } : {},
|
|
1128
|
+
...config.numberFormatOptions !== void 0 ? { numberFormatOptions: config.numberFormatOptions } : {},
|
|
1129
|
+
...config.dateFormatOptions !== void 0 ? { dateFormatOptions: config.dateFormatOptions } : {},
|
|
1130
|
+
...config.conditionalFormatting !== void 0 ? { conditionalFormatting: config.conditionalFormatting } : {}
|
|
1131
|
+
};
|
|
1132
|
+
const normalizedConfig = toJsonObject(normalized.config) ?? {};
|
|
1133
|
+
if (!toStringValue(normalizedConfig.formulaText)) {
|
|
1134
|
+
const definition = resolveSchemaFieldType("formula");
|
|
1135
|
+
throw new CliError(
|
|
1136
|
+
"invalid_cli_usage",
|
|
1137
|
+
`Formula fields require "formulaText". Expected raw shape: ${definition.rawShape}`
|
|
1138
|
+
);
|
|
1139
|
+
}
|
|
1140
|
+
return normalized;
|
|
1141
|
+
}
|
|
1142
|
+
function normalizeSchemaFieldCreatePayload(input) {
|
|
1143
|
+
const rawType = toStringValue(input.type);
|
|
1144
|
+
const normalizedType = rawType ? normalizeSchemaFieldType(rawType) : void 0;
|
|
1145
|
+
const definition = resolveSchemaFieldTypeByClassName(normalizedType);
|
|
1146
|
+
if (!definition) {
|
|
1147
|
+
return input;
|
|
1148
|
+
}
|
|
1149
|
+
const normalizedWithType = {
|
|
1150
|
+
...input,
|
|
1151
|
+
type: definition.className
|
|
1152
|
+
};
|
|
1153
|
+
switch (definition.key) {
|
|
1154
|
+
case "option":
|
|
1155
|
+
return normalizeOptionPayload(normalizedWithType);
|
|
1156
|
+
case "reference":
|
|
1157
|
+
return normalizeReferencePayload(normalizedWithType);
|
|
1158
|
+
case "formula":
|
|
1159
|
+
return normalizeFormulaPayload(normalizedWithType);
|
|
1160
|
+
case "schedule":
|
|
1161
|
+
return normalizeSchedulePayload(normalizedWithType);
|
|
1162
|
+
case "autoincremental": {
|
|
1163
|
+
const config = toJsonObject(normalizedWithType.config) ?? {};
|
|
1164
|
+
const segmentedByFieldId = config.segmentedByFieldId ?? normalizedWithType.segmentedByFieldId ?? null;
|
|
1165
|
+
return {
|
|
1166
|
+
...normalizedWithType,
|
|
1167
|
+
config: {
|
|
1168
|
+
...config,
|
|
1169
|
+
segmentedByFieldId,
|
|
1170
|
+
...config.conditionalFormatting !== void 0 ? { conditionalFormatting: config.conditionalFormatting } : {}
|
|
1171
|
+
}
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
default:
|
|
1175
|
+
return normalizedWithType;
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
function normalizeSchemaFieldUpdatePayload(type, input) {
|
|
1179
|
+
const definition = resolveSchemaFieldTypeByClassName(type);
|
|
1180
|
+
if (definition?.key === "formula") {
|
|
1181
|
+
return normalizeFormulaPayload(input);
|
|
1182
|
+
}
|
|
1183
|
+
return input;
|
|
1184
|
+
}
|
|
1185
|
+
function buildSchemaFieldCreateHelpText() {
|
|
1186
|
+
const sections = fieldTypeDefinitions.map(
|
|
1187
|
+
(definition) => ` - ${definition.key}: ${definition.description}
|
|
1188
|
+
raw: ${definition.rawShape}`
|
|
1189
|
+
);
|
|
1190
|
+
return [
|
|
1191
|
+
"",
|
|
1192
|
+
"Valid field types:",
|
|
1193
|
+
` ${formatSchemaFieldTypes()}`,
|
|
1194
|
+
"",
|
|
1195
|
+
"Raw payload shapes by type:",
|
|
1196
|
+
...sections,
|
|
1197
|
+
"",
|
|
1198
|
+
'Use "zinkee --example schemas fields create --type <type>" to show a concrete example for one type.'
|
|
1199
|
+
].join("\n");
|
|
1200
|
+
}
|
|
1201
|
+
function buildSchemaFieldCreateValidationMessage(type) {
|
|
1202
|
+
const definition = resolveSchemaFieldTypeByClassName(type);
|
|
1203
|
+
if (!definition) {
|
|
1204
|
+
return `Invalid payload for field type "${type}". Valid types: ${formatSchemaFieldTypes()}.`;
|
|
1205
|
+
}
|
|
1206
|
+
return `Invalid payload for field type "${definition.key}". Expected raw shape: ${definition.rawShape}`;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
export {
|
|
1210
|
+
ApiClientError,
|
|
1211
|
+
ApiClient,
|
|
1212
|
+
buildJsonSuccess,
|
|
1213
|
+
FOLDER_TABLE_KEYS,
|
|
1214
|
+
folderColumns,
|
|
1215
|
+
printTable,
|
|
1216
|
+
CliError,
|
|
1217
|
+
getExitCode,
|
|
1218
|
+
formatCliErrorText,
|
|
1219
|
+
formatCliErrorJson,
|
|
1220
|
+
getSchemaFieldTypeDefinitions,
|
|
1221
|
+
formatSchemaFieldTypes,
|
|
1222
|
+
resolveSchemaFieldType,
|
|
1223
|
+
normalizeSchemaFieldType,
|
|
1224
|
+
assertSupportedSchemaFieldType,
|
|
1225
|
+
normalizeSchemaFieldCreatePayload,
|
|
1226
|
+
normalizeSchemaFieldUpdatePayload,
|
|
1227
|
+
buildSchemaFieldCreateHelpText,
|
|
1228
|
+
buildSchemaFieldCreateValidationMessage
|
|
1229
|
+
};
|
|
1230
|
+
//# sourceMappingURL=chunk-MHEVRMDX.js.map
|