@carthooks/arcubase-cli 0.1.2 → 0.1.4
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/bundle/arcubase-admin.mjs +1238 -16
- package/bundle/arcubase.mjs +1238 -16
- package/dist/bin/arcubase-admin.js +0 -0
- package/dist/bin/arcubase.js +0 -0
- package/dist/runtime/command_registry.d.ts +8 -0
- package/dist/runtime/command_registry.d.ts.map +1 -1
- package/dist/runtime/command_registry.js +35 -0
- package/dist/runtime/entity_save_schema.d.ts +15 -0
- package/dist/runtime/entity_save_schema.d.ts.map +1 -0
- package/dist/runtime/entity_save_schema.js +641 -0
- package/dist/runtime/errors.d.ts +11 -0
- package/dist/runtime/errors.d.ts.map +1 -1
- package/dist/runtime/execute.d.ts.map +1 -1
- package/dist/runtime/execute.js +294 -12
- package/dist/runtime/upload.d.ts +13 -0
- package/dist/runtime/upload.d.ts.map +1 -0
- package/dist/runtime/upload.js +148 -0
- package/dist/runtime/zod_registry.d.ts +6 -0
- package/dist/runtime/zod_registry.d.ts.map +1 -1
- package/dist/runtime/zod_registry.js +136 -0
- package/dist/tests/command_registry.test.js +5 -0
- package/dist/tests/entity_save_schema.test.d.ts +2 -0
- package/dist/tests/entity_save_schema.test.d.ts.map +1 -0
- package/dist/tests/entity_save_schema.test.js +221 -0
- package/dist/tests/execute_validation.test.js +603 -0
- package/dist/tests/help.test.js +49 -0
- package/dist/tests/upload.test.d.ts +2 -0
- package/dist/tests/upload.test.d.ts.map +1 -0
- package/dist/tests/upload.test.js +107 -0
- package/package.json +1 -1
- package/sdk-dist/docs/runtime-reference/README.md +187 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/README.md +120 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/address.md +34 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/boolean.md +37 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/button.md +47 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/checkbox.md +61 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/datasets.md +35 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/datetime.md +40 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/department.md +33 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/departments.md +34 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/divider.md +39 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/file.md +53 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/formula.md +44 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/image.md +52 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/linkto.md +67 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/location.md +32 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/lookup.md +41 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/member.md +37 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/members.md +31 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/number.md +70 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/query.md +50 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/radio.md +53 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/relation.md +55 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/relationfield.md +38 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/rollup.md +54 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/select.md +63 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/selects.md +51 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/serialnumber.md +48 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/signature.md +31 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/status.md +70 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/subform.md +74 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/tags.md +19 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/text.md +76 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/textarea.md +47 -0
- package/sdk-dist/docs/runtime-reference/entity-schema/workflow_status.md +17 -0
- package/sdk-dist/docs/runtime-reference/entity-schema.md +197 -0
- package/sdk-dist/docs/runtime-reference/examples/README.md +51 -0
- package/sdk-dist/docs/runtime-reference/examples/crm-01/README.md +20 -0
- package/sdk-dist/docs/runtime-reference/examples/mes-01/README.md +21 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/README.md +183 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/app-overview.md +79 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/create-app.json +3 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/goods-receipt.create-entity.json +3 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/goods-receipt.schema.json +159 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/item-master.create-entity.json +3 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/item-master.schema.json +179 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/picking-list.create-entity.json +3 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/picking-list.schema.json +168 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/purchase-order.create-entity.json +3 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/purchase-order.schema.json +417 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.bulk-update.json +22 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.create-entity.json +3 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.query.json +10 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.row.insert.json +28 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.schema.json +398 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.selection.condition.json +13 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/sales-order.selection.ids.json +7 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/stock-issue.create-entity.json +3 -0
- package/sdk-dist/docs/runtime-reference/examples/oms-01/stock-issue.schema.json +137 -0
- package/sdk-dist/docs/runtime-reference/examples/wms-01/README.md +21 -0
- package/sdk-dist/docs/runtime-reference/row-crud.md +188 -0
- package/sdk-dist/docs/runtime-reference/search-and-bulk-actions.md +494 -0
- package/sdk-dist/docs/runtime-reference/table-lifecycle.md +135 -0
- package/sdk-dist/docs/runtime-reference/uploads.md +106 -0
- package/sdk-dist/docs/runtime-reference/workflow/README.md +19 -0
- package/src/runtime/command_registry.ts +47 -0
- package/src/runtime/entity_save_schema.ts +708 -0
- package/src/runtime/errors.ts +12 -0
- package/src/runtime/execute.ts +367 -12
- package/src/runtime/upload.ts +196 -0
- package/src/runtime/zod_registry.ts +156 -0
- package/src/tests/command_registry.test.ts +6 -0
- package/src/tests/entity_save_schema.test.ts +236 -0
- package/src/tests/execute_validation.test.ts +781 -0
- package/src/tests/help.test.ts +60 -0
- package/src/tests/upload.test.ts +133 -0
package/bundle/arcubase.mjs
CHANGED
|
@@ -4738,6 +4738,41 @@ function listModules(scope) {
|
|
|
4738
4738
|
function listModuleCommands(scope, moduleName) {
|
|
4739
4739
|
return listCommands(scope).filter((item) => item.commandPath[0] === moduleName);
|
|
4740
4740
|
}
|
|
4741
|
+
function levenshtein(a, b) {
|
|
4742
|
+
const dp = Array.from({ length: a.length + 1 }, () => new Array(b.length + 1).fill(0));
|
|
4743
|
+
for (let i = 0; i <= a.length; i += 1) dp[i][0] = i;
|
|
4744
|
+
for (let j = 0; j <= b.length; j += 1) dp[0][j] = j;
|
|
4745
|
+
for (let i = 1; i <= a.length; i += 1) {
|
|
4746
|
+
for (let j = 1; j <= b.length; j += 1) {
|
|
4747
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
4748
|
+
dp[i][j] = Math.min(
|
|
4749
|
+
dp[i - 1][j] + 1,
|
|
4750
|
+
dp[i][j - 1] + 1,
|
|
4751
|
+
dp[i - 1][j - 1] + cost
|
|
4752
|
+
);
|
|
4753
|
+
}
|
|
4754
|
+
}
|
|
4755
|
+
return dp[a.length][b.length];
|
|
4756
|
+
}
|
|
4757
|
+
function findCommandSuggestions(moduleName, commandName, limit = 3) {
|
|
4758
|
+
const suggestions = [];
|
|
4759
|
+
for (const scope of ["admin", "user"]) {
|
|
4760
|
+
for (const command of listCommands(scope)) {
|
|
4761
|
+
const [candidateModule, candidateCommand] = command.commandPath;
|
|
4762
|
+
const moduleScore = candidateModule === moduleName ? 0 : levenshtein(candidateModule, moduleName || "");
|
|
4763
|
+
const commandScore = candidateCommand === commandName ? 0 : levenshtein(candidateCommand, commandName || "");
|
|
4764
|
+
const score = commandScore * 3 + moduleScore;
|
|
4765
|
+
suggestions.push({
|
|
4766
|
+
scope,
|
|
4767
|
+
moduleName: candidateModule,
|
|
4768
|
+
commandName: candidateCommand,
|
|
4769
|
+
binary: scope === "admin" ? "arcubase-admin" : "arcubase",
|
|
4770
|
+
score
|
|
4771
|
+
});
|
|
4772
|
+
}
|
|
4773
|
+
}
|
|
4774
|
+
return suggestions.sort((a, b) => a.score - b.score || a.binary.localeCompare(b.binary) || a.moduleName.localeCompare(b.moduleName) || a.commandName.localeCompare(b.commandName)).slice(0, limit);
|
|
4775
|
+
}
|
|
4741
4776
|
|
|
4742
4777
|
// src/runtime/body_loader.ts
|
|
4743
4778
|
import fs from "fs";
|
|
@@ -5241,8 +5276,8 @@ function getErrorMap() {
|
|
|
5241
5276
|
|
|
5242
5277
|
// node_modules/zod/v3/helpers/parseUtil.js
|
|
5243
5278
|
var makeIssue = (params) => {
|
|
5244
|
-
const { data, path, errorMaps, issueData } = params;
|
|
5245
|
-
const fullPath = [...
|
|
5279
|
+
const { data, path: path2, errorMaps, issueData } = params;
|
|
5280
|
+
const fullPath = [...path2, ...issueData.path || []];
|
|
5246
5281
|
const fullIssue = {
|
|
5247
5282
|
...issueData,
|
|
5248
5283
|
path: fullPath
|
|
@@ -5358,11 +5393,11 @@ var errorUtil;
|
|
|
5358
5393
|
|
|
5359
5394
|
// node_modules/zod/v3/types.js
|
|
5360
5395
|
var ParseInputLazyPath = class {
|
|
5361
|
-
constructor(parent, value,
|
|
5396
|
+
constructor(parent, value, path2, key) {
|
|
5362
5397
|
this._cachedPath = [];
|
|
5363
5398
|
this.parent = parent;
|
|
5364
5399
|
this.data = value;
|
|
5365
|
-
this._path =
|
|
5400
|
+
this._path = path2;
|
|
5366
5401
|
this._key = key;
|
|
5367
5402
|
}
|
|
5368
5403
|
get path() {
|
|
@@ -9661,10 +9696,671 @@ var typeIndex = {
|
|
|
9661
9696
|
}
|
|
9662
9697
|
};
|
|
9663
9698
|
|
|
9699
|
+
// src/runtime/entity_save_schema.ts
|
|
9700
|
+
var simpleFieldTypes = [
|
|
9701
|
+
"text",
|
|
9702
|
+
"textarea",
|
|
9703
|
+
"number",
|
|
9704
|
+
"datetime",
|
|
9705
|
+
"boolean",
|
|
9706
|
+
"button",
|
|
9707
|
+
"address",
|
|
9708
|
+
"datasets",
|
|
9709
|
+
"department",
|
|
9710
|
+
"departments",
|
|
9711
|
+
"divider",
|
|
9712
|
+
"file",
|
|
9713
|
+
"image",
|
|
9714
|
+
"location",
|
|
9715
|
+
"member",
|
|
9716
|
+
"members",
|
|
9717
|
+
"signature",
|
|
9718
|
+
"tags",
|
|
9719
|
+
"workflow_status",
|
|
9720
|
+
"mobile"
|
|
9721
|
+
];
|
|
9722
|
+
var enumFieldTypes = ["select", "selects", "radio", "checkbox", "status"];
|
|
9723
|
+
var relationFieldTypes = ["linkto", "relation", "query"];
|
|
9724
|
+
var strictFieldTypes = /* @__PURE__ */ new Set([
|
|
9725
|
+
...simpleFieldTypes,
|
|
9726
|
+
...enumFieldTypes,
|
|
9727
|
+
...relationFieldTypes,
|
|
9728
|
+
"formula",
|
|
9729
|
+
"lookup",
|
|
9730
|
+
"relationfield",
|
|
9731
|
+
"rollup",
|
|
9732
|
+
"serialnumber",
|
|
9733
|
+
"subform"
|
|
9734
|
+
]);
|
|
9735
|
+
var relationTypeSchema = external_exports.union([external_exports.literal("entity"), external_exports.literal("aggregation")]);
|
|
9736
|
+
var linkModeSchema = external_exports.union([external_exports.literal("manual"), external_exports.literal("auto")]);
|
|
9737
|
+
var linkStructureSchema = external_exports.union([external_exports.literal("single"), external_exports.literal("multiple")]);
|
|
9738
|
+
var enumItemSchema = external_exports.object({
|
|
9739
|
+
key: external_exports.union([external_exports.number(), external_exports.string()]).optional(),
|
|
9740
|
+
value: external_exports.string().min(1)
|
|
9741
|
+
}).passthrough();
|
|
9742
|
+
var statusItemSchema = external_exports.object({
|
|
9743
|
+
key: external_exports.union([external_exports.number(), external_exports.string()]).optional(),
|
|
9744
|
+
code: external_exports.union([external_exports.number(), external_exports.string()]),
|
|
9745
|
+
value: external_exports.string().min(1)
|
|
9746
|
+
}).passthrough();
|
|
9747
|
+
var sortConfigSchema = external_exports.object({
|
|
9748
|
+
column: external_exports.string().min(1),
|
|
9749
|
+
order: external_exports.union([external_exports.literal("asc"), external_exports.literal("desc")])
|
|
9750
|
+
}).strict();
|
|
9751
|
+
var relationOptionsSchema = external_exports.object({
|
|
9752
|
+
entity_id: external_exports.number().int().positive(),
|
|
9753
|
+
app_id: external_exports.number().int().positive(),
|
|
9754
|
+
type: relationTypeSchema,
|
|
9755
|
+
show_fields: external_exports.array(external_exports.number().int().positive()).optional(),
|
|
9756
|
+
condition: external_exports.record(external_exports.string(), external_exports.any()).optional(),
|
|
9757
|
+
sorts: external_exports.array(sortConfigSchema).optional(),
|
|
9758
|
+
queryFields: external_exports.array(external_exports.number().int().positive()).optional(),
|
|
9759
|
+
subform_id: external_exports.number().int().positive().optional()
|
|
9760
|
+
}).strict();
|
|
9761
|
+
var lookupRelationSchema = external_exports.object({
|
|
9762
|
+
local_linkto_field_id: external_exports.number().int().min(1001),
|
|
9763
|
+
target_field_id: external_exports.number().int().min(1001),
|
|
9764
|
+
target_field_type: external_exports.string().min(1)
|
|
9765
|
+
}).strict();
|
|
9766
|
+
var relationFieldRelationSchema = external_exports.object({
|
|
9767
|
+
app_id: external_exports.number().int().positive(),
|
|
9768
|
+
entity_id: external_exports.number().int().positive(),
|
|
9769
|
+
type: relationTypeSchema.optional(),
|
|
9770
|
+
show_fields: external_exports.array(external_exports.number().int().positive()).optional(),
|
|
9771
|
+
condition: external_exports.record(external_exports.string(), external_exports.any()).optional(),
|
|
9772
|
+
sorts: external_exports.array(sortConfigSchema).optional(),
|
|
9773
|
+
queryFields: external_exports.array(external_exports.number().int().positive()).optional(),
|
|
9774
|
+
subform_id: external_exports.number().int().positive().optional()
|
|
9775
|
+
}).strict();
|
|
9776
|
+
var formulaSchema = external_exports.object({
|
|
9777
|
+
code: external_exports.string().min(1),
|
|
9778
|
+
jsonlogic: external_exports.record(external_exports.string(), external_exports.any())
|
|
9779
|
+
}).strict();
|
|
9780
|
+
var serialPartBuildinStringSchema = external_exports.object({
|
|
9781
|
+
mode: external_exports.literal("buildin"),
|
|
9782
|
+
type: external_exports.literal("string"),
|
|
9783
|
+
options: external_exports.object({
|
|
9784
|
+
value: external_exports.string()
|
|
9785
|
+
}).strict()
|
|
9786
|
+
}).strict();
|
|
9787
|
+
var serialPartBuildinDateSchema = external_exports.object({
|
|
9788
|
+
mode: external_exports.literal("buildin"),
|
|
9789
|
+
type: external_exports.literal("date"),
|
|
9790
|
+
options: external_exports.object({
|
|
9791
|
+
format: external_exports.string().optional(),
|
|
9792
|
+
perdefined: external_exports.boolean().optional(),
|
|
9793
|
+
perdefinedFormat: external_exports.string().optional()
|
|
9794
|
+
}).strict().refine((value) => Boolean(value.format || value.perdefinedFormat), {
|
|
9795
|
+
message: "date serial part requires format or perdefinedFormat"
|
|
9796
|
+
})
|
|
9797
|
+
}).strict();
|
|
9798
|
+
var serialPartBuildinSerialSchema = external_exports.object({
|
|
9799
|
+
mode: external_exports.literal("buildin"),
|
|
9800
|
+
type: external_exports.literal("serial"),
|
|
9801
|
+
options: external_exports.object({
|
|
9802
|
+
length: external_exports.number().int().min(1),
|
|
9803
|
+
lenfixed: external_exports.boolean().optional(),
|
|
9804
|
+
random: external_exports.boolean().optional(),
|
|
9805
|
+
reset: external_exports.string().optional()
|
|
9806
|
+
}).strict()
|
|
9807
|
+
}).strict();
|
|
9808
|
+
var serialPartFieldSchema = external_exports.object({
|
|
9809
|
+
mode: external_exports.literal("field"),
|
|
9810
|
+
field_id: external_exports.number().int().min(1001)
|
|
9811
|
+
}).passthrough();
|
|
9812
|
+
var serialPartSchema = external_exports.union([
|
|
9813
|
+
serialPartBuildinStringSchema,
|
|
9814
|
+
serialPartBuildinDateSchema,
|
|
9815
|
+
serialPartBuildinSerialSchema,
|
|
9816
|
+
serialPartFieldSchema
|
|
9817
|
+
]);
|
|
9818
|
+
var fieldCommonShape = {
|
|
9819
|
+
id: external_exports.number().int().min(1001),
|
|
9820
|
+
label: external_exports.string().min(1),
|
|
9821
|
+
required: external_exports.boolean(),
|
|
9822
|
+
unique: external_exports.boolean(),
|
|
9823
|
+
editable: external_exports.boolean(),
|
|
9824
|
+
visible: external_exports.boolean(),
|
|
9825
|
+
show_label: external_exports.boolean(),
|
|
9826
|
+
scannable: external_exports.boolean(),
|
|
9827
|
+
default_value_mode: external_exports.number(),
|
|
9828
|
+
description: external_exports.string(),
|
|
9829
|
+
value: external_exports.any(),
|
|
9830
|
+
number_decimal: external_exports.number().int().min(0),
|
|
9831
|
+
depends: external_exports.array(external_exports.number().int().min(1001)),
|
|
9832
|
+
key: external_exports.string(),
|
|
9833
|
+
code_index: external_exports.boolean(),
|
|
9834
|
+
transfers: external_exports.array(external_exports.any()).nullable()
|
|
9835
|
+
};
|
|
9836
|
+
function isRecord(value) {
|
|
9837
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
9838
|
+
}
|
|
9839
|
+
function cloneJSON(value) {
|
|
9840
|
+
return JSON.parse(JSON.stringify(value));
|
|
9841
|
+
}
|
|
9842
|
+
function makeSimpleFieldSchema(type) {
|
|
9843
|
+
return external_exports.object({
|
|
9844
|
+
...fieldCommonShape,
|
|
9845
|
+
type: external_exports.literal(type),
|
|
9846
|
+
options: external_exports.record(external_exports.string(), external_exports.any()).nullable(),
|
|
9847
|
+
children: external_exports.null()
|
|
9848
|
+
}).strict();
|
|
9849
|
+
}
|
|
9850
|
+
function makeEnumFieldSchema(type) {
|
|
9851
|
+
const itemSchema = type === "status" ? statusItemSchema : enumItemSchema;
|
|
9852
|
+
return external_exports.object({
|
|
9853
|
+
...fieldCommonShape,
|
|
9854
|
+
type: external_exports.literal(type),
|
|
9855
|
+
options: external_exports.object({
|
|
9856
|
+
options: external_exports.object({
|
|
9857
|
+
items: external_exports.array(itemSchema).min(1)
|
|
9858
|
+
}).passthrough()
|
|
9859
|
+
}).passthrough(),
|
|
9860
|
+
children: external_exports.null()
|
|
9861
|
+
}).strict();
|
|
9862
|
+
}
|
|
9863
|
+
var simpleFieldSchemas = simpleFieldTypes.map((type) => makeSimpleFieldSchema(type));
|
|
9864
|
+
var enumFieldSchemas = enumFieldTypes.map((type) => makeEnumFieldSchema(type));
|
|
9865
|
+
var formulaFieldSchema = external_exports.object({
|
|
9866
|
+
...fieldCommonShape,
|
|
9867
|
+
type: external_exports.literal("formula"),
|
|
9868
|
+
options: external_exports.object({
|
|
9869
|
+
formula: formulaSchema
|
|
9870
|
+
}).passthrough(),
|
|
9871
|
+
children: external_exports.null()
|
|
9872
|
+
}).strict();
|
|
9873
|
+
var relationFieldSchemas = relationFieldTypes.map(
|
|
9874
|
+
(type) => external_exports.object({
|
|
9875
|
+
...fieldCommonShape,
|
|
9876
|
+
type: external_exports.literal(type),
|
|
9877
|
+
options: external_exports.object({
|
|
9878
|
+
relation: relationOptionsSchema,
|
|
9879
|
+
mode: linkModeSchema.optional(),
|
|
9880
|
+
structure: linkStructureSchema.optional(),
|
|
9881
|
+
multiple: external_exports.boolean().optional(),
|
|
9882
|
+
backfill: external_exports.array(external_exports.object({
|
|
9883
|
+
id: external_exports.number().int().min(1001),
|
|
9884
|
+
local_id: external_exports.number().int().min(1001)
|
|
9885
|
+
}).strict()).optional(),
|
|
9886
|
+
addValue: external_exports.boolean().optional(),
|
|
9887
|
+
placeholder: external_exports.string().optional()
|
|
9888
|
+
}).passthrough(),
|
|
9889
|
+
children: external_exports.null()
|
|
9890
|
+
}).strict()
|
|
9891
|
+
);
|
|
9892
|
+
var lookupFieldSchema = external_exports.object({
|
|
9893
|
+
...fieldCommonShape,
|
|
9894
|
+
type: external_exports.literal("lookup"),
|
|
9895
|
+
options: external_exports.object({
|
|
9896
|
+
relation: lookupRelationSchema
|
|
9897
|
+
}).passthrough(),
|
|
9898
|
+
children: external_exports.null()
|
|
9899
|
+
}).strict();
|
|
9900
|
+
var relationFieldFieldSchema = external_exports.object({
|
|
9901
|
+
...fieldCommonShape,
|
|
9902
|
+
type: external_exports.literal("relationfield"),
|
|
9903
|
+
options: external_exports.object({
|
|
9904
|
+
relation: relationFieldRelationSchema
|
|
9905
|
+
}).passthrough(),
|
|
9906
|
+
children: external_exports.null()
|
|
9907
|
+
}).strict();
|
|
9908
|
+
var rollupFieldSchema = external_exports.object({
|
|
9909
|
+
...fieldCommonShape,
|
|
9910
|
+
type: external_exports.literal("rollup"),
|
|
9911
|
+
options: external_exports.object({
|
|
9912
|
+
relation: lookupRelationSchema,
|
|
9913
|
+
aggregation_formula: formulaSchema
|
|
9914
|
+
}).passthrough(),
|
|
9915
|
+
children: external_exports.null()
|
|
9916
|
+
}).strict();
|
|
9917
|
+
var serialNumberFieldSchema = external_exports.object({
|
|
9918
|
+
...fieldCommonShape,
|
|
9919
|
+
type: external_exports.literal("serialnumber"),
|
|
9920
|
+
options: external_exports.object({
|
|
9921
|
+
parts: external_exports.array(serialPartSchema).min(1)
|
|
9922
|
+
}).passthrough(),
|
|
9923
|
+
children: external_exports.null()
|
|
9924
|
+
}).strict();
|
|
9925
|
+
var genericFieldSchema = external_exports.object({
|
|
9926
|
+
...fieldCommonShape,
|
|
9927
|
+
type: external_exports.string().min(1).refine((value) => !strictFieldTypes.has(value), {
|
|
9928
|
+
message: "known field type must use dedicated schema"
|
|
9929
|
+
}),
|
|
9930
|
+
options: external_exports.record(external_exports.string(), external_exports.any()).nullable(),
|
|
9931
|
+
children: external_exports.null()
|
|
9932
|
+
}).strict();
|
|
9933
|
+
var baseFieldSchemaVariants = [
|
|
9934
|
+
...simpleFieldSchemas,
|
|
9935
|
+
...enumFieldSchemas,
|
|
9936
|
+
...relationFieldSchemas,
|
|
9937
|
+
formulaFieldSchema,
|
|
9938
|
+
lookupFieldSchema,
|
|
9939
|
+
relationFieldFieldSchema,
|
|
9940
|
+
rollupFieldSchema,
|
|
9941
|
+
serialNumberFieldSchema,
|
|
9942
|
+
genericFieldSchema
|
|
9943
|
+
];
|
|
9944
|
+
var BaseFieldSchema = external_exports.union(baseFieldSchemaVariants);
|
|
9945
|
+
var SubformFieldSchema = external_exports.lazy(
|
|
9946
|
+
() => external_exports.object({
|
|
9947
|
+
...fieldCommonShape,
|
|
9948
|
+
type: external_exports.literal("subform"),
|
|
9949
|
+
options: external_exports.record(external_exports.string(), external_exports.any()).nullable(),
|
|
9950
|
+
children: external_exports.array(BaseFieldSchema),
|
|
9951
|
+
layout: external_exports.array(external_exports.array(external_exports.number().int().min(1001))).optional()
|
|
9952
|
+
}).strict()
|
|
9953
|
+
);
|
|
9954
|
+
var FieldVOSchema = external_exports.lazy(
|
|
9955
|
+
() => external_exports.union([
|
|
9956
|
+
SubformFieldSchema,
|
|
9957
|
+
BaseFieldSchema
|
|
9958
|
+
])
|
|
9959
|
+
);
|
|
9960
|
+
function normalizeEntitySaveInput(value) {
|
|
9961
|
+
if (!isRecord(value)) {
|
|
9962
|
+
return value;
|
|
9963
|
+
}
|
|
9964
|
+
const entity = cloneJSON(value);
|
|
9965
|
+
if (entity.layout === null) {
|
|
9966
|
+
entity.layout = [];
|
|
9967
|
+
}
|
|
9968
|
+
if (entity.current_serial === null) {
|
|
9969
|
+
delete entity.current_serial;
|
|
9970
|
+
}
|
|
9971
|
+
if (isRecord(entity.options)) {
|
|
9972
|
+
if (entity.options.Buttons === null) {
|
|
9973
|
+
entity.options.Buttons = [];
|
|
9974
|
+
}
|
|
9975
|
+
if (entity.options.CustomActions === null) {
|
|
9976
|
+
entity.options.CustomActions = [];
|
|
9977
|
+
}
|
|
9978
|
+
if (entity.options.FrontendEvents === null) {
|
|
9979
|
+
entity.options.FrontendEvents = [];
|
|
9980
|
+
}
|
|
9981
|
+
if (entity.options.misc === null) {
|
|
9982
|
+
entity.options.misc = {};
|
|
9983
|
+
}
|
|
9984
|
+
if (isRecord(entity.options.TitleFormat)) {
|
|
9985
|
+
if (entity.options.TitleFormat.Fields === null) {
|
|
9986
|
+
entity.options.TitleFormat.Fields = [];
|
|
9987
|
+
}
|
|
9988
|
+
if (entity.options.TitleFormat.Parts === null) {
|
|
9989
|
+
entity.options.TitleFormat.Parts = [];
|
|
9990
|
+
}
|
|
9991
|
+
}
|
|
9992
|
+
}
|
|
9993
|
+
return entity;
|
|
9994
|
+
}
|
|
9995
|
+
function collectAllFieldIds(fields) {
|
|
9996
|
+
const out = [];
|
|
9997
|
+
for (const field of fields) {
|
|
9998
|
+
out.push(field.id);
|
|
9999
|
+
if (field.type === "subform" && Array.isArray(field.children)) {
|
|
10000
|
+
for (const child of field.children) {
|
|
10001
|
+
out.push(child.id);
|
|
10002
|
+
}
|
|
10003
|
+
}
|
|
10004
|
+
}
|
|
10005
|
+
return out;
|
|
10006
|
+
}
|
|
10007
|
+
function collectTopLevelFieldIds(fields) {
|
|
10008
|
+
return fields.map((field) => field.id);
|
|
10009
|
+
}
|
|
10010
|
+
function extractFormulaFieldIds(value) {
|
|
10011
|
+
if (!value || typeof value !== "string") return [];
|
|
10012
|
+
const ids = [...value.matchAll(/:(\d+)\]\]/g)].map((match) => Number(match[1]));
|
|
10013
|
+
return ids.filter((id) => Number.isInteger(id) && id > 0);
|
|
10014
|
+
}
|
|
10015
|
+
var EntitySaveReqVOBaseSchema = external_exports.object({
|
|
10016
|
+
app_id: external_exports.number().optional(),
|
|
10017
|
+
current_serial: EntitySerialUpdaterVOSchema.optional(),
|
|
10018
|
+
field_id_seq: external_exports.number().int(),
|
|
10019
|
+
fields: external_exports.array(FieldVOSchema),
|
|
10020
|
+
id: external_exports.number().optional(),
|
|
10021
|
+
layout: external_exports.array(external_exports.array(external_exports.number().int().min(1001))).optional(),
|
|
10022
|
+
name: external_exports.string().optional(),
|
|
10023
|
+
options: EntityOptionsSchema.optional(),
|
|
10024
|
+
prototypes: external_exports.array(external_exports.number()).optional(),
|
|
10025
|
+
schema_version: external_exports.number().optional(),
|
|
10026
|
+
workflow_enabled: external_exports.boolean().optional()
|
|
10027
|
+
}).strict().superRefine((entity, ctx) => {
|
|
10028
|
+
const fields = entity.fields;
|
|
10029
|
+
const topLevelIds = new Set(collectTopLevelFieldIds(fields));
|
|
10030
|
+
const allIds = collectAllFieldIds(fields);
|
|
10031
|
+
const allIdSet = /* @__PURE__ */ new Set();
|
|
10032
|
+
for (const id of allIds) {
|
|
10033
|
+
if (allIdSet.has(id)) {
|
|
10034
|
+
ctx.addIssue({
|
|
10035
|
+
code: external_exports.ZodIssueCode.custom,
|
|
10036
|
+
path: ["fields"],
|
|
10037
|
+
message: `duplicate field id: ${id}`
|
|
10038
|
+
});
|
|
10039
|
+
}
|
|
10040
|
+
allIdSet.add(id);
|
|
10041
|
+
}
|
|
10042
|
+
const maxFieldId = allIds.length > 0 ? Math.max(...allIds) : 1e3;
|
|
10043
|
+
if (entity.field_id_seq <= maxFieldId) {
|
|
10044
|
+
ctx.addIssue({
|
|
10045
|
+
code: external_exports.ZodIssueCode.custom,
|
|
10046
|
+
path: ["field_id_seq"],
|
|
10047
|
+
message: `field_id_seq must be greater than max field id ${maxFieldId}`
|
|
10048
|
+
});
|
|
10049
|
+
}
|
|
10050
|
+
for (const [rowIndex, row] of (entity.layout ?? []).entries()) {
|
|
10051
|
+
for (const [colIndex, fieldId] of row.entries()) {
|
|
10052
|
+
if (!topLevelIds.has(fieldId)) {
|
|
10053
|
+
ctx.addIssue({
|
|
10054
|
+
code: external_exports.ZodIssueCode.custom,
|
|
10055
|
+
path: ["layout", rowIndex, colIndex],
|
|
10056
|
+
message: `layout references unknown top-level field id ${fieldId}`
|
|
10057
|
+
});
|
|
10058
|
+
}
|
|
10059
|
+
}
|
|
10060
|
+
}
|
|
10061
|
+
for (const [fieldIndex, field] of fields.entries()) {
|
|
10062
|
+
if (field.type !== "subform" && field.children !== null) {
|
|
10063
|
+
ctx.addIssue({
|
|
10064
|
+
code: external_exports.ZodIssueCode.custom,
|
|
10065
|
+
path: ["fields", fieldIndex, "children"],
|
|
10066
|
+
message: "only subform field can define children"
|
|
10067
|
+
});
|
|
10068
|
+
}
|
|
10069
|
+
if (field.type === "subform") {
|
|
10070
|
+
const childIds = new Set((field.children ?? []).map((child) => child.id));
|
|
10071
|
+
for (const [rowIndex, row] of (field.layout ?? []).entries()) {
|
|
10072
|
+
for (const [colIndex, fieldId] of row.entries()) {
|
|
10073
|
+
if (!childIds.has(fieldId)) {
|
|
10074
|
+
ctx.addIssue({
|
|
10075
|
+
code: external_exports.ZodIssueCode.custom,
|
|
10076
|
+
path: ["fields", fieldIndex, "layout", rowIndex, colIndex],
|
|
10077
|
+
message: `subform layout references non-child field id ${fieldId}`
|
|
10078
|
+
});
|
|
10079
|
+
}
|
|
10080
|
+
}
|
|
10081
|
+
}
|
|
10082
|
+
}
|
|
10083
|
+
if (field.type === "lookup" || field.type === "rollup") {
|
|
10084
|
+
const localLinktoFieldId = field.options?.relation?.local_linkto_field_id;
|
|
10085
|
+
if (typeof localLinktoFieldId === "number") {
|
|
10086
|
+
const target = fields.find((item) => item.id === localLinktoFieldId);
|
|
10087
|
+
if (!target || target.type !== "linkto") {
|
|
10088
|
+
ctx.addIssue({
|
|
10089
|
+
code: external_exports.ZodIssueCode.custom,
|
|
10090
|
+
path: ["fields", fieldIndex, "options", "relation", "local_linkto_field_id"],
|
|
10091
|
+
message: "local_linkto_field_id must reference a linkto field"
|
|
10092
|
+
});
|
|
10093
|
+
}
|
|
10094
|
+
}
|
|
10095
|
+
}
|
|
10096
|
+
if (field.type === "formula" || field.type === "rollup") {
|
|
10097
|
+
const formulaCode = field.type === "formula" ? field.options?.formula?.code : field.options?.aggregation_formula?.code;
|
|
10098
|
+
for (const referencedFieldId of extractFormulaFieldIds(formulaCode)) {
|
|
10099
|
+
if (!allIdSet.has(referencedFieldId)) {
|
|
10100
|
+
ctx.addIssue({
|
|
10101
|
+
code: external_exports.ZodIssueCode.custom,
|
|
10102
|
+
path: ["fields", fieldIndex, "options"],
|
|
10103
|
+
message: `formula references unknown field id ${referencedFieldId}`
|
|
10104
|
+
});
|
|
10105
|
+
}
|
|
10106
|
+
}
|
|
10107
|
+
}
|
|
10108
|
+
}
|
|
10109
|
+
});
|
|
10110
|
+
var EntitySaveReqVOSchemaOverride = external_exports.preprocess(normalizeEntitySaveInput, EntitySaveReqVOBaseSchema);
|
|
10111
|
+
var queryOrderSchema = external_exports.object({
|
|
10112
|
+
column: external_exports.string().min(1),
|
|
10113
|
+
order: external_exports.string().min(1)
|
|
10114
|
+
}).strict();
|
|
10115
|
+
var AppCreateByTenantsReqVOSchemaOverride = external_exports.object({
|
|
10116
|
+
icon_color: external_exports.string().optional(),
|
|
10117
|
+
icon_name: external_exports.string().optional(),
|
|
10118
|
+
name: external_exports.string().min(1).max(20)
|
|
10119
|
+
}).strict();
|
|
10120
|
+
var EntityQueryReqVOSchemaOverride = external_exports.object({
|
|
10121
|
+
limit: external_exports.number().int().positive().optional(),
|
|
10122
|
+
offset: external_exports.number().int().min(0).optional(),
|
|
10123
|
+
policy_id: external_exports.string().optional(),
|
|
10124
|
+
search: external_exports.record(external_exports.string(), external_exports.any()).optional(),
|
|
10125
|
+
sorts: external_exports.array(queryOrderSchema).optional(),
|
|
10126
|
+
view_mode: external_exports.string().optional(),
|
|
10127
|
+
viewMode: external_exports.never().optional(),
|
|
10128
|
+
withSubForm: external_exports.boolean().optional()
|
|
10129
|
+
}).strict();
|
|
10130
|
+
var InsertReqVOSchemaOverride = external_exports.object({
|
|
10131
|
+
policy_id: external_exports.string().optional(),
|
|
10132
|
+
fields: external_exports.record(external_exports.string(), external_exports.any())
|
|
10133
|
+
}).strict().superRefine((body, ctx) => {
|
|
10134
|
+
for (const key of Object.keys(body.fields ?? {})) {
|
|
10135
|
+
if (!/^\d+$/.test(key)) {
|
|
10136
|
+
ctx.addIssue({
|
|
10137
|
+
code: external_exports.ZodIssueCode.custom,
|
|
10138
|
+
path: ["fields", key],
|
|
10139
|
+
message: "row fields must use numeric field ids as keys"
|
|
10140
|
+
});
|
|
10141
|
+
}
|
|
10142
|
+
}
|
|
10143
|
+
});
|
|
10144
|
+
var EntityUpdateReqVOSchemaOverride = external_exports.object({
|
|
10145
|
+
changed_fields: external_exports.array(external_exports.number().int().positive()).min(1),
|
|
10146
|
+
data: external_exports.record(external_exports.string(), external_exports.any()),
|
|
10147
|
+
policy_id: external_exports.string().optional(),
|
|
10148
|
+
tags: external_exports.array(external_exports.string()).optional(),
|
|
10149
|
+
fields: external_exports.never().optional()
|
|
10150
|
+
}).strict().superRefine((body, ctx) => {
|
|
10151
|
+
const dataFieldIds = /* @__PURE__ */ new Set();
|
|
10152
|
+
for (const key of Object.keys(body.data ?? {})) {
|
|
10153
|
+
if (!/^\d+$/.test(key)) {
|
|
10154
|
+
ctx.addIssue({
|
|
10155
|
+
code: external_exports.ZodIssueCode.custom,
|
|
10156
|
+
path: ["data", key],
|
|
10157
|
+
message: "row data must use numeric field ids as keys"
|
|
10158
|
+
});
|
|
10159
|
+
continue;
|
|
10160
|
+
}
|
|
10161
|
+
dataFieldIds.add(Number(key));
|
|
10162
|
+
}
|
|
10163
|
+
for (const [index, fieldId] of body.changed_fields.entries()) {
|
|
10164
|
+
if (!dataFieldIds.has(fieldId)) {
|
|
10165
|
+
ctx.addIssue({
|
|
10166
|
+
code: external_exports.ZodIssueCode.custom,
|
|
10167
|
+
path: ["changed_fields", index],
|
|
10168
|
+
message: `changed_fields references ${fieldId}, but data does not contain that field id`
|
|
10169
|
+
});
|
|
10170
|
+
}
|
|
10171
|
+
}
|
|
10172
|
+
});
|
|
10173
|
+
var entitySelectionSortSchema = external_exports.object({
|
|
10174
|
+
column: external_exports.string().min(1),
|
|
10175
|
+
order: external_exports.string().min(1)
|
|
10176
|
+
}).strict();
|
|
10177
|
+
var entitySelectionIdsSchema = external_exports.object({
|
|
10178
|
+
type: external_exports.literal("ids"),
|
|
10179
|
+
ids: external_exports.array(external_exports.number().int().positive()).min(1),
|
|
10180
|
+
length: external_exports.number().int().positive().optional(),
|
|
10181
|
+
sorts: external_exports.array(entitySelectionSortSchema).optional(),
|
|
10182
|
+
condition: external_exports.record(external_exports.string(), external_exports.any()).optional()
|
|
10183
|
+
}).strict().superRefine((selection, ctx) => {
|
|
10184
|
+
if (selection.length !== void 0 && selection.length !== selection.ids.length) {
|
|
10185
|
+
ctx.addIssue({
|
|
10186
|
+
code: external_exports.ZodIssueCode.custom,
|
|
10187
|
+
path: ["length"],
|
|
10188
|
+
message: "length must match ids.length when provided"
|
|
10189
|
+
});
|
|
10190
|
+
}
|
|
10191
|
+
});
|
|
10192
|
+
var entitySelectionConditionSchema = external_exports.object({
|
|
10193
|
+
type: external_exports.literal("condition"),
|
|
10194
|
+
length: external_exports.number().int().positive(),
|
|
10195
|
+
condition: external_exports.record(external_exports.string(), external_exports.any()).superRefine((condition, ctx) => {
|
|
10196
|
+
if (!Object.keys(condition).length) {
|
|
10197
|
+
ctx.addIssue({
|
|
10198
|
+
code: external_exports.ZodIssueCode.custom,
|
|
10199
|
+
message: "condition selection requires a non-empty condition object"
|
|
10200
|
+
});
|
|
10201
|
+
return;
|
|
10202
|
+
}
|
|
10203
|
+
if (condition.selectAll !== true) {
|
|
10204
|
+
ctx.addIssue({
|
|
10205
|
+
code: external_exports.ZodIssueCode.custom,
|
|
10206
|
+
path: ["selectAll"],
|
|
10207
|
+
message: "condition selection must set selectAll to true"
|
|
10208
|
+
});
|
|
10209
|
+
}
|
|
10210
|
+
const filterKeys = Object.keys(condition).filter((key) => key !== "selectAll");
|
|
10211
|
+
if (filterKeys.length === 0) {
|
|
10212
|
+
return;
|
|
10213
|
+
}
|
|
10214
|
+
const hasSupportedQueryKey = filterKeys.some((key) => key === "q" || key === "tab" || key.startsWith("filter_"));
|
|
10215
|
+
if (!hasSupportedQueryKey) {
|
|
10216
|
+
ctx.addIssue({
|
|
10217
|
+
code: external_exports.ZodIssueCode.custom,
|
|
10218
|
+
message: "condition selection extra keys must use q, tab, or filter_*"
|
|
10219
|
+
});
|
|
10220
|
+
}
|
|
10221
|
+
}),
|
|
10222
|
+
sorts: external_exports.array(entitySelectionSortSchema).optional(),
|
|
10223
|
+
ids: external_exports.array(external_exports.number().int().positive()).optional()
|
|
10224
|
+
}).strict();
|
|
10225
|
+
var entitySelectionAllSchema = external_exports.object({
|
|
10226
|
+
type: external_exports.literal("all"),
|
|
10227
|
+
length: external_exports.number().int().positive().optional(),
|
|
10228
|
+
ids: external_exports.array(external_exports.number().int().positive()).optional(),
|
|
10229
|
+
condition: external_exports.record(external_exports.string(), external_exports.any()).optional(),
|
|
10230
|
+
sorts: external_exports.array(entitySelectionSortSchema).optional()
|
|
10231
|
+
}).strict();
|
|
10232
|
+
var entitySelectionSchema = external_exports.union([
|
|
10233
|
+
entitySelectionIdsSchema,
|
|
10234
|
+
entitySelectionConditionSchema,
|
|
10235
|
+
entitySelectionAllSchema
|
|
10236
|
+
]);
|
|
10237
|
+
var entitySelectionLooseSchema = external_exports.union([
|
|
10238
|
+
entitySelectionSchema,
|
|
10239
|
+
entitySelectionAllSchema
|
|
10240
|
+
]);
|
|
10241
|
+
var EntitySelectionActionReqVOSchemaOverride = external_exports.lazy(
|
|
10242
|
+
() => external_exports.object({
|
|
10243
|
+
limit: external_exports.number().int().positive().optional(),
|
|
10244
|
+
offset: external_exports.number().int().min(0).optional(),
|
|
10245
|
+
policy_id: external_exports.string().optional(),
|
|
10246
|
+
selection: entitySelectionSchema
|
|
10247
|
+
}).strict()
|
|
10248
|
+
);
|
|
10249
|
+
var bulkUpdateActionSchema = external_exports.object({
|
|
10250
|
+
type: external_exports.string().min(1),
|
|
10251
|
+
value: external_exports.any().optional(),
|
|
10252
|
+
text_search: external_exports.string().optional(),
|
|
10253
|
+
text_replace: external_exports.string().optional(),
|
|
10254
|
+
text_append: external_exports.string().optional(),
|
|
10255
|
+
text_prepend: external_exports.string().optional(),
|
|
10256
|
+
number_add: external_exports.number().optional(),
|
|
10257
|
+
number_mul: external_exports.number().optional(),
|
|
10258
|
+
number_sub: external_exports.number().optional(),
|
|
10259
|
+
datetime_add: external_exports.number().optional(),
|
|
10260
|
+
datetime_sub: external_exports.number().optional()
|
|
10261
|
+
}).strict().superRefine((action, ctx) => {
|
|
10262
|
+
switch (action.type) {
|
|
10263
|
+
case "set":
|
|
10264
|
+
if (!("value" in action)) {
|
|
10265
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["value"], message: "set action requires value" });
|
|
10266
|
+
}
|
|
10267
|
+
break;
|
|
10268
|
+
case "text_replace":
|
|
10269
|
+
if (!action.text_search) {
|
|
10270
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["text_search"], message: "text_replace requires text_search" });
|
|
10271
|
+
}
|
|
10272
|
+
if (!action.text_replace) {
|
|
10273
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["text_replace"], message: "text_replace requires text_replace" });
|
|
10274
|
+
}
|
|
10275
|
+
break;
|
|
10276
|
+
case "text_append":
|
|
10277
|
+
if (!action.text_append) {
|
|
10278
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["text_append"], message: "text_append requires text_append" });
|
|
10279
|
+
}
|
|
10280
|
+
break;
|
|
10281
|
+
case "text_prepend":
|
|
10282
|
+
if (!action.text_prepend) {
|
|
10283
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["text_prepend"], message: "text_prepend requires text_prepend" });
|
|
10284
|
+
}
|
|
10285
|
+
break;
|
|
10286
|
+
case "number_add":
|
|
10287
|
+
if (typeof action.number_add !== "number") {
|
|
10288
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["number_add"], message: "number_add requires number_add" });
|
|
10289
|
+
}
|
|
10290
|
+
break;
|
|
10291
|
+
case "number_sub":
|
|
10292
|
+
if (typeof action.number_sub !== "number") {
|
|
10293
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["number_sub"], message: "number_sub requires number_sub" });
|
|
10294
|
+
}
|
|
10295
|
+
break;
|
|
10296
|
+
case "number_mul":
|
|
10297
|
+
if (typeof action.number_mul !== "number") {
|
|
10298
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["number_mul"], message: "number_mul requires number_mul" });
|
|
10299
|
+
}
|
|
10300
|
+
break;
|
|
10301
|
+
case "datetime_add":
|
|
10302
|
+
if (typeof action.datetime_add !== "number") {
|
|
10303
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["datetime_add"], message: "datetime_add requires datetime_add" });
|
|
10304
|
+
}
|
|
10305
|
+
break;
|
|
10306
|
+
case "datetime_sub":
|
|
10307
|
+
if (typeof action.datetime_sub !== "number") {
|
|
10308
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["datetime_sub"], message: "datetime_sub requires datetime_sub" });
|
|
10309
|
+
}
|
|
10310
|
+
break;
|
|
10311
|
+
case "datetime_now":
|
|
10312
|
+
case "formula":
|
|
10313
|
+
break;
|
|
10314
|
+
default:
|
|
10315
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["type"], message: `unsupported bulk update action type: ${action.type}` });
|
|
10316
|
+
}
|
|
10317
|
+
});
|
|
10318
|
+
var EntityBulkUpdateReqVOSchemaOverride = external_exports.object({
|
|
10319
|
+
policy_id: external_exports.string().optional(),
|
|
10320
|
+
selection: entitySelectionSchema,
|
|
10321
|
+
fields: external_exports.array(external_exports.object({
|
|
10322
|
+
id: external_exports.number().int().min(1001),
|
|
10323
|
+
action: bulkUpdateActionSchema
|
|
10324
|
+
}).strict()).min(1)
|
|
10325
|
+
}).strict();
|
|
10326
|
+
var EntityTagsSelectionReqVOSchemaOverride = external_exports.object({
|
|
10327
|
+
policy_id: external_exports.string(),
|
|
10328
|
+
selection: entitySelectionSchema
|
|
10329
|
+
}).strict();
|
|
10330
|
+
var EntityTagsBatchReqVOSchemaOverride = external_exports.object({
|
|
10331
|
+
policy_id: external_exports.string(),
|
|
10332
|
+
selection: entitySelectionSchema,
|
|
10333
|
+
tag_names: external_exports.array(external_exports.string().min(1)).min(1)
|
|
10334
|
+
}).strict();
|
|
10335
|
+
var EntityInvokeBatchOperatorReqVOSchemaOverride = external_exports.object({
|
|
10336
|
+
id: external_exports.string().min(1),
|
|
10337
|
+
data: external_exports.object({
|
|
10338
|
+
action_id: external_exports.string().min(1),
|
|
10339
|
+
policy_id: external_exports.string().optional(),
|
|
10340
|
+
selection: entitySelectionLooseSchema
|
|
10341
|
+
}).strict(),
|
|
10342
|
+
params: external_exports.record(external_exports.string(), external_exports.any()).optional()
|
|
10343
|
+
}).strict();
|
|
10344
|
+
|
|
9664
10345
|
// src/runtime/zod_registry.ts
|
|
10346
|
+
var schemaOverrides = {
|
|
10347
|
+
AppCreateByTenantsReqVO: AppCreateByTenantsReqVOSchemaOverride,
|
|
10348
|
+
EntityBulkUpdateReqVO: EntityBulkUpdateReqVOSchemaOverride,
|
|
10349
|
+
"EntityInvokeBatchOperatorReqVO & InvokeRequestVO": EntityInvokeBatchOperatorReqVOSchemaOverride,
|
|
10350
|
+
EntityQueryReqVO: EntityQueryReqVOSchemaOverride,
|
|
10351
|
+
EntitySaveReqVO: EntitySaveReqVOSchemaOverride,
|
|
10352
|
+
EntitySelectionActionReqVO: EntitySelectionActionReqVOSchemaOverride,
|
|
10353
|
+
"{ policy_id: string selection: any }": EntityTagsSelectionReqVOSchemaOverride,
|
|
10354
|
+
"{ policy_id: string selection: any tag_names: string[] }": EntityTagsBatchReqVOSchemaOverride,
|
|
10355
|
+
EntityUpdateReqVO: EntityUpdateReqVOSchemaOverride,
|
|
10356
|
+
InsertReqVO: InsertReqVOSchemaOverride
|
|
10357
|
+
};
|
|
9665
10358
|
function getBodySchema(typeName) {
|
|
9666
10359
|
const name = String(typeName || "").trim();
|
|
9667
10360
|
if (!name) return null;
|
|
10361
|
+
if (schemaOverrides[name]) {
|
|
10362
|
+
return schemaOverrides[name];
|
|
10363
|
+
}
|
|
9668
10364
|
return bodySchemas[name] ?? null;
|
|
9669
10365
|
}
|
|
9670
10366
|
function getUnsupportedBodySchemaReason(typeName) {
|
|
@@ -9672,6 +10368,59 @@ function getUnsupportedBodySchemaReason(typeName) {
|
|
|
9672
10368
|
if (!name) return null;
|
|
9673
10369
|
return unsupportedBodySchemas[name] ?? null;
|
|
9674
10370
|
}
|
|
10371
|
+
var examplesIndexDocHint = {
|
|
10372
|
+
title: "Examples index",
|
|
10373
|
+
file: "/opt/arcubase-sdk/docs/runtime-reference/examples/README.md"
|
|
10374
|
+
};
|
|
10375
|
+
var docHintIndex = {
|
|
10376
|
+
AppCreateByTenantsReqVO: [
|
|
10377
|
+
{ title: "Table lifecycle", file: "/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md" },
|
|
10378
|
+
examplesIndexDocHint
|
|
10379
|
+
],
|
|
10380
|
+
AppCreateEntityReqVO: [
|
|
10381
|
+
{ title: "Table lifecycle", file: "/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md" },
|
|
10382
|
+
examplesIndexDocHint
|
|
10383
|
+
],
|
|
10384
|
+
EntitySaveReqVO: [
|
|
10385
|
+
{ title: "Entity schema", file: "/opt/arcubase-sdk/docs/runtime-reference/entity-schema.md" },
|
|
10386
|
+
examplesIndexDocHint
|
|
10387
|
+
],
|
|
10388
|
+
EntityQueryReqVO: [
|
|
10389
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" },
|
|
10390
|
+
{ title: "Search and bulk actions", file: "/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md" },
|
|
10391
|
+
examplesIndexDocHint
|
|
10392
|
+
],
|
|
10393
|
+
EntityUpdateReqVO: [
|
|
10394
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" },
|
|
10395
|
+
{ title: "Uploads", file: "/opt/arcubase-sdk/docs/runtime-reference/uploads.md" },
|
|
10396
|
+
examplesIndexDocHint
|
|
10397
|
+
],
|
|
10398
|
+
EntitySelectionActionReqVO: [
|
|
10399
|
+
{ title: "Search and bulk actions", file: "/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md" },
|
|
10400
|
+
examplesIndexDocHint
|
|
10401
|
+
],
|
|
10402
|
+
InsertReqVO: [
|
|
10403
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" },
|
|
10404
|
+
{ title: "Uploads", file: "/opt/arcubase-sdk/docs/runtime-reference/uploads.md" },
|
|
10405
|
+
examplesIndexDocHint
|
|
10406
|
+
],
|
|
10407
|
+
EntityBulkUpdateReqVO: [
|
|
10408
|
+
{ title: "Search and bulk actions", file: "/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md" },
|
|
10409
|
+
examplesIndexDocHint
|
|
10410
|
+
],
|
|
10411
|
+
"EntityInvokeBatchOperatorReqVO & InvokeRequestVO": [
|
|
10412
|
+
{ title: "Search and bulk actions", file: "/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md" },
|
|
10413
|
+
examplesIndexDocHint
|
|
10414
|
+
],
|
|
10415
|
+
"{ policy_id: string selection: any }": [
|
|
10416
|
+
{ title: "Search and bulk actions", file: "/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md" },
|
|
10417
|
+
examplesIndexDocHint
|
|
10418
|
+
],
|
|
10419
|
+
"{ policy_id: string selection: any tag_names: string[] }": [
|
|
10420
|
+
{ title: "Search and bulk actions", file: "/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md" },
|
|
10421
|
+
examplesIndexDocHint
|
|
10422
|
+
]
|
|
10423
|
+
};
|
|
9675
10424
|
function getTypeHints(typeName) {
|
|
9676
10425
|
const name = String(typeName || "").trim();
|
|
9677
10426
|
if (!name) return [];
|
|
@@ -9694,41 +10443,273 @@ function getTypeHints(typeName) {
|
|
|
9694
10443
|
}
|
|
9695
10444
|
return out;
|
|
9696
10445
|
}
|
|
10446
|
+
function getDocHints(typeName) {
|
|
10447
|
+
const name = String(typeName || "").trim();
|
|
10448
|
+
if (!name) return [];
|
|
10449
|
+
return docHintIndex[name] ?? [];
|
|
10450
|
+
}
|
|
10451
|
+
var commandDocHintIndex = {
|
|
10452
|
+
"admin.app.createAppByTenants": [
|
|
10453
|
+
{ title: "Table lifecycle", file: "/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md" },
|
|
10454
|
+
examplesIndexDocHint
|
|
10455
|
+
],
|
|
10456
|
+
"admin.app.createEntity": [
|
|
10457
|
+
{ title: "Table lifecycle", file: "/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md" },
|
|
10458
|
+
examplesIndexDocHint
|
|
10459
|
+
],
|
|
10460
|
+
"admin.entity.adminGetEntityInfo": [
|
|
10461
|
+
{ title: "Table lifecycle", file: "/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md" },
|
|
10462
|
+
examplesIndexDocHint
|
|
10463
|
+
],
|
|
10464
|
+
"admin.entity.adminSaveEntity": [
|
|
10465
|
+
{ title: "Entity schema", file: "/opt/arcubase-sdk/docs/runtime-reference/entity-schema.md" },
|
|
10466
|
+
{ title: "Table lifecycle", file: "/opt/arcubase-sdk/docs/runtime-reference/table-lifecycle.md" },
|
|
10467
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" },
|
|
10468
|
+
examplesIndexDocHint
|
|
10469
|
+
],
|
|
10470
|
+
"user.workflow.insertEntity": [
|
|
10471
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" },
|
|
10472
|
+
{ title: "Uploads", file: "/opt/arcubase-sdk/docs/runtime-reference/uploads.md" },
|
|
10473
|
+
examplesIndexDocHint
|
|
10474
|
+
],
|
|
10475
|
+
"user.workflow.queryEntity": [
|
|
10476
|
+
{ title: "Search and bulk actions", file: "/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md" },
|
|
10477
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" },
|
|
10478
|
+
examplesIndexDocHint
|
|
10479
|
+
],
|
|
10480
|
+
"user.workflow.getEntityRow": [
|
|
10481
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" },
|
|
10482
|
+
examplesIndexDocHint
|
|
10483
|
+
],
|
|
10484
|
+
"user.workflow.updateEntityRow": [
|
|
10485
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" },
|
|
10486
|
+
{ title: "Uploads", file: "/opt/arcubase-sdk/docs/runtime-reference/uploads.md" },
|
|
10487
|
+
examplesIndexDocHint
|
|
10488
|
+
],
|
|
10489
|
+
"user.workflow.queryEntitySelection": [
|
|
10490
|
+
{ title: "Search and bulk actions", file: "/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md" },
|
|
10491
|
+
examplesIndexDocHint
|
|
10492
|
+
],
|
|
10493
|
+
"user.workflow.deleteEntityRow": [
|
|
10494
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" },
|
|
10495
|
+
examplesIndexDocHint
|
|
10496
|
+
],
|
|
10497
|
+
"user.workflow.restoreEntityRow": [
|
|
10498
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" },
|
|
10499
|
+
examplesIndexDocHint
|
|
10500
|
+
],
|
|
10501
|
+
"user.entity.updateEntityBulk": [
|
|
10502
|
+
{ title: "Search and bulk actions", file: "/opt/arcubase-sdk/docs/runtime-reference/search-and-bulk-actions.md" },
|
|
10503
|
+
examplesIndexDocHint
|
|
10504
|
+
]
|
|
10505
|
+
};
|
|
10506
|
+
function getCommandDocHints(operation) {
|
|
10507
|
+
const key = String(operation || "").trim();
|
|
10508
|
+
if (!key) return [];
|
|
10509
|
+
return commandDocHintIndex[key] ?? [];
|
|
10510
|
+
}
|
|
10511
|
+
|
|
10512
|
+
// src/runtime/upload.ts
|
|
10513
|
+
import fs2 from "fs";
|
|
10514
|
+
import path from "path";
|
|
10515
|
+
function readUploadSource(sourcePath) {
|
|
10516
|
+
const absolutePath = path.resolve(sourcePath);
|
|
10517
|
+
if (!fs2.existsSync(absolutePath)) {
|
|
10518
|
+
throw new CLIError("UPLOAD_SOURCE_NOT_FOUND", `upload source file does not exist: ${sourcePath}`, 2);
|
|
10519
|
+
}
|
|
10520
|
+
const stat = fs2.statSync(absolutePath);
|
|
10521
|
+
if (!stat.isFile()) {
|
|
10522
|
+
throw new CLIError("UPLOAD_SOURCE_INVALID", `upload source path must be a file: ${sourcePath}`, 2);
|
|
10523
|
+
}
|
|
10524
|
+
return {
|
|
10525
|
+
absolutePath,
|
|
10526
|
+
bytes: fs2.readFileSync(absolutePath)
|
|
10527
|
+
};
|
|
10528
|
+
}
|
|
10529
|
+
function parseJSONResponse(raw) {
|
|
10530
|
+
try {
|
|
10531
|
+
return raw ? JSON.parse(raw) : null;
|
|
10532
|
+
} catch {
|
|
10533
|
+
return raw;
|
|
10534
|
+
}
|
|
10535
|
+
}
|
|
10536
|
+
function requireTokenPayload(payload) {
|
|
10537
|
+
if (payload && typeof payload === "object" && payload.error) {
|
|
10538
|
+
const upstreamError = payload.error;
|
|
10539
|
+
const message = typeof upstreamError === "object" && upstreamError && "message" in upstreamError && typeof upstreamError.message === "string" ? upstreamError.message : typeof upstreamError === "string" ? upstreamError : JSON.stringify(upstreamError);
|
|
10540
|
+
throw new CLIError("UPSTREAM_BODY_ERROR", message, 1, {
|
|
10541
|
+
endpoint: "/upload/token",
|
|
10542
|
+
method: "POST",
|
|
10543
|
+
traceId: typeof payload.trace_id === "string" ? payload.trace_id : void 0,
|
|
10544
|
+
upstreamError
|
|
10545
|
+
});
|
|
10546
|
+
}
|
|
10547
|
+
if (!payload?.data || typeof payload.data !== "object") {
|
|
10548
|
+
throw new CLIError("UPLOAD_TOKEN_INVALID", "upload token response did not include data", 1);
|
|
10549
|
+
}
|
|
10550
|
+
return payload.data;
|
|
10551
|
+
}
|
|
10552
|
+
function renderUploadHelp() {
|
|
10553
|
+
return [
|
|
10554
|
+
"arcubase upload <local-file> [flags]",
|
|
10555
|
+
"",
|
|
10556
|
+
"purpose:",
|
|
10557
|
+
" - upload one local file through Arcubase",
|
|
10558
|
+
" - return a field value that can be used directly in file or image row payloads",
|
|
10559
|
+
"",
|
|
10560
|
+
"flags:",
|
|
10561
|
+
" --filename <name> override the uploaded filename stored in Arcubase",
|
|
10562
|
+
" --global request a global upload token instead of a tenant-scoped token",
|
|
10563
|
+
"",
|
|
10564
|
+
"result shape:",
|
|
10565
|
+
" - data is a JSON array",
|
|
10566
|
+
" - use that array directly as the value of a file or image field in insert/update payloads",
|
|
10567
|
+
"",
|
|
10568
|
+
"example:",
|
|
10569
|
+
" arcubase upload ./contract.pdf",
|
|
10570
|
+
" arcubase upload ./photo.jpg --filename lead-photo.jpg",
|
|
10571
|
+
"",
|
|
10572
|
+
"docs:",
|
|
10573
|
+
" - Uploads: /opt/arcubase-sdk/docs/runtime-reference/uploads.md",
|
|
10574
|
+
" - Row CRUD: /opt/arcubase-sdk/docs/runtime-reference/row-crud.md",
|
|
10575
|
+
" - File field: /opt/arcubase-sdk/docs/runtime-reference/entity-schema/file.md",
|
|
10576
|
+
" - Image field: /opt/arcubase-sdk/docs/runtime-reference/entity-schema/image.md"
|
|
10577
|
+
].join("\n");
|
|
10578
|
+
}
|
|
10579
|
+
async function uploadLocalFile(env, sourcePath, options, fetchImpl = fetch) {
|
|
10580
|
+
const { absolutePath, bytes } = readUploadSource(sourcePath);
|
|
10581
|
+
const filename = options.filename && options.filename.trim() || path.basename(absolutePath);
|
|
10582
|
+
const tokenResponse = await fetchImpl(buildURL(env.ARCUBASE_BASE_URL, "/upload/token"), {
|
|
10583
|
+
method: "POST",
|
|
10584
|
+
headers: {
|
|
10585
|
+
...buildRequestHeaders(env),
|
|
10586
|
+
"Content-Type": "application/json"
|
|
10587
|
+
},
|
|
10588
|
+
body: JSON.stringify({
|
|
10589
|
+
global: Boolean(options.global)
|
|
10590
|
+
})
|
|
10591
|
+
});
|
|
10592
|
+
const tokenRaw = await tokenResponse.text();
|
|
10593
|
+
const tokenParsed = parseJSONResponse(tokenRaw);
|
|
10594
|
+
if (!tokenResponse.ok) {
|
|
10595
|
+
throw new CLIError("UPLOAD_TOKEN_REQUEST_FAILED", typeof tokenParsed === "string" ? tokenParsed : JSON.stringify(tokenParsed), 1, {
|
|
10596
|
+
endpoint: "/upload/token",
|
|
10597
|
+
method: "POST"
|
|
10598
|
+
});
|
|
10599
|
+
}
|
|
10600
|
+
const tokenData = requireTokenPayload(tokenParsed);
|
|
10601
|
+
if (tokenData.mode !== "aliyun-oss" && tokenData.mode !== "s3-post-policy") {
|
|
10602
|
+
throw new CLIError("UPLOAD_MODE_UNSUPPORTED", `unsupported upload mode: ${String(tokenData.mode || "")}`, 1);
|
|
10603
|
+
}
|
|
10604
|
+
if (!tokenData.token_data?.dir || !tokenData.token_data.policy || !tokenData.token_data.host) {
|
|
10605
|
+
throw new CLIError("UPLOAD_TOKEN_INVALID", "upload token response is missing required token_data fields", 1);
|
|
10606
|
+
}
|
|
10607
|
+
if (tokenData.id === void 0 || tokenData.id === null || tokenData.id === "") {
|
|
10608
|
+
throw new CLIError("UPLOAD_TOKEN_INVALID", "upload token response is missing id", 1);
|
|
10609
|
+
}
|
|
10610
|
+
const form = new FormData();
|
|
10611
|
+
form.append("key", `${tokenData.token_data.dir}${filename}`);
|
|
10612
|
+
form.append("policy", tokenData.token_data.policy);
|
|
10613
|
+
if (tokenData.mode === "aliyun-oss") {
|
|
10614
|
+
if (!tokenData.token_data.accessid || !tokenData.token_data.signature) {
|
|
10615
|
+
throw new CLIError("UPLOAD_TOKEN_INVALID", "upload token response is missing required token_data fields", 1);
|
|
10616
|
+
}
|
|
10617
|
+
form.append("OSSAccessKeyId", tokenData.token_data.accessid);
|
|
10618
|
+
form.append("success_action_status", "200");
|
|
10619
|
+
form.append("signature", tokenData.token_data.signature);
|
|
10620
|
+
} else {
|
|
10621
|
+
if (!tokenData.token_data.x_amz_algorithm || !tokenData.token_data.x_amz_credential || !tokenData.token_data.x_amz_date || !tokenData.token_data.x_amz_signature) {
|
|
10622
|
+
throw new CLIError("UPLOAD_TOKEN_INVALID", "upload token response is missing required s3 token_data fields", 1);
|
|
10623
|
+
}
|
|
10624
|
+
form.append("x-amz-algorithm", tokenData.token_data.x_amz_algorithm);
|
|
10625
|
+
form.append("x-amz-credential", tokenData.token_data.x_amz_credential);
|
|
10626
|
+
form.append("x-amz-date", tokenData.token_data.x_amz_date);
|
|
10627
|
+
form.append("x-amz-signature", tokenData.token_data.x_amz_signature);
|
|
10628
|
+
}
|
|
10629
|
+
form.append("file", new Blob([new Uint8Array(bytes)]), filename);
|
|
10630
|
+
const uploadResponse = await fetchImpl(tokenData.token_data.host, {
|
|
10631
|
+
method: "POST",
|
|
10632
|
+
body: form
|
|
10633
|
+
});
|
|
10634
|
+
const uploadRaw = await uploadResponse.text();
|
|
10635
|
+
if (!uploadResponse.ok) {
|
|
10636
|
+
throw new CLIError("UPLOAD_TRANSFER_FAILED", uploadRaw || `upload failed with status ${uploadResponse.status}`, 1, {
|
|
10637
|
+
endpoint: tokenData.token_data.host,
|
|
10638
|
+
method: "POST"
|
|
10639
|
+
});
|
|
10640
|
+
}
|
|
10641
|
+
return [
|
|
10642
|
+
{
|
|
10643
|
+
upload_id: tokenData.id,
|
|
10644
|
+
file: filename,
|
|
10645
|
+
file_name: filename,
|
|
10646
|
+
meta: {}
|
|
10647
|
+
}
|
|
10648
|
+
];
|
|
10649
|
+
}
|
|
9697
10650
|
|
|
9698
10651
|
// src/runtime/execute.ts
|
|
9699
10652
|
function renderRootHelp(scope) {
|
|
9700
10653
|
const binary = scope === "admin" ? "arcubase-admin" : "arcubase";
|
|
10654
|
+
const items = listModules(scope).map((item) => ` - ${item}`);
|
|
9701
10655
|
return [
|
|
9702
10656
|
`${binary} <module> <command> [flags]`,
|
|
9703
10657
|
"",
|
|
10658
|
+
...scope === "admin" ? ["use arcubase-admin for app, entity shell, and schema management", ""] : ["use arcubase for row CRUD, search, selection actions, and bulk actions", ""],
|
|
9704
10659
|
"modules:",
|
|
9705
|
-
...
|
|
10660
|
+
...items,
|
|
10661
|
+
...scope === "user" ? ["", "special commands:", " - upload <local-file>"] : []
|
|
9706
10662
|
].join("\n");
|
|
9707
10663
|
}
|
|
9708
10664
|
function renderModuleHelp(scope, moduleName) {
|
|
9709
10665
|
const items = listModuleCommands(scope, moduleName);
|
|
9710
10666
|
if (items.length === 0) {
|
|
9711
|
-
|
|
10667
|
+
const suggestions = findCommandSuggestions(moduleName, "").map((item) => `${item.binary} ${item.moduleName} ${item.commandName}`);
|
|
10668
|
+
throw new CLIError("UNKNOWN_MODULE", `unknown module: ${moduleName}`, 2, suggestions.length > 0 ? { suggestions } : void 0);
|
|
9712
10669
|
}
|
|
9713
10670
|
return [
|
|
9714
10671
|
`${scope === "admin" ? "arcubase-admin" : "arcubase"} ${moduleName} <command> [flags]`,
|
|
9715
10672
|
"",
|
|
10673
|
+
...scope === "admin" ? ["use arcubase-admin for app, entity shell, and schema management", ""] : ["use arcubase for row CRUD, search, selection actions, and bulk actions", ""],
|
|
9716
10674
|
"commands:",
|
|
9717
10675
|
...items.map((item) => ` - ${item.commandPath[1]}`)
|
|
9718
10676
|
].join("\n");
|
|
9719
10677
|
}
|
|
10678
|
+
function buildUnknownCommandDetails(scope, moduleName, commandName) {
|
|
10679
|
+
const suggestions = findCommandSuggestions(moduleName, commandName).map((item) => `${item.binary} ${item.moduleName} ${item.commandName}`);
|
|
10680
|
+
if (scope === "admin" && moduleName === "workflow" && suggestions.some((item) => item.startsWith("arcubase workflow "))) {
|
|
10681
|
+
return {
|
|
10682
|
+
suggestions,
|
|
10683
|
+
reason: `${moduleName} ${commandName} is a row operation, not an arcubase-admin command`,
|
|
10684
|
+
hint: `use: arcubase ${moduleName} ${commandName}`
|
|
10685
|
+
};
|
|
10686
|
+
}
|
|
10687
|
+
return suggestions.length > 0 ? { suggestions } : void 0;
|
|
10688
|
+
}
|
|
9720
10689
|
function renderCommandHelp(scope, moduleName, commandName) {
|
|
9721
10690
|
const command = findCommand(scope, moduleName, commandName);
|
|
9722
10691
|
if (!command) {
|
|
9723
|
-
throw new CLIError("UNKNOWN_COMMAND", `unknown command: ${moduleName} ${commandName}`, 2);
|
|
10692
|
+
throw new CLIError("UNKNOWN_COMMAND", `unknown command: ${moduleName} ${commandName}`, 2, buildUnknownCommandDetails(scope, moduleName, commandName));
|
|
9724
10693
|
}
|
|
10694
|
+
const docHints = [
|
|
10695
|
+
...getCommandDocHints(`${scope}.${command.module}.${command.functionName}`),
|
|
10696
|
+
...command.requestType ? getDocHints(command.requestType) : []
|
|
10697
|
+
].filter((item, index, list) => list.findIndex((candidate) => candidate.file === item.file) === index);
|
|
9725
10698
|
return [
|
|
9726
10699
|
`${scope === "admin" ? "arcubase-admin" : "arcubase"} ${moduleName} ${commandName}`,
|
|
9727
10700
|
`method: ${command.method}`,
|
|
9728
10701
|
`endpoint: ${normalizeExternalEndpoint(command.endpoint)}`,
|
|
9729
10702
|
command.requestType ? `body: ${command.requestType} via --body-file` : "body: none",
|
|
10703
|
+
"query flags: --query-file",
|
|
9730
10704
|
command.endpointParams.length ? `path flags: ${command.endpointParams.map((item) => `--${item.replace(/_/g, "-")}`).join(", ")}` : "path flags: none",
|
|
9731
|
-
command.scalarParams.length ? `scalar flags: ${command.scalarParams.map((item) => `--${item.name.replace(/([A-Z])/g, "-$1").toLowerCase()}`).join(", ")}` : "scalar flags: none"
|
|
10705
|
+
command.scalarParams.length ? `scalar flags: ${command.scalarParams.map((item) => `--${item.name.replace(/([A-Z])/g, "-$1").toLowerCase()}`).join(", ")}` : "scalar flags: none",
|
|
10706
|
+
...scope === "admin" && moduleName === "entity" && commandName === "admin-save-entity" ? [
|
|
10707
|
+
"next step:",
|
|
10708
|
+
" - switch to arcubase for row operations",
|
|
10709
|
+
" - row insert: arcubase workflow insert-entity --app-id <app_id> --entity-id <entity_id> --body-file insert.json",
|
|
10710
|
+
" - row query: arcubase workflow query-entity --app-id <app_id> --entity-id <entity_id> --body-file query.json"
|
|
10711
|
+
] : [],
|
|
10712
|
+
...docHints.length > 0 ? ["docs:", ...docHints.map((item) => ` - ${item.title}: ${item.file}`)] : []
|
|
9732
10713
|
].join("\n");
|
|
9733
10714
|
}
|
|
9734
10715
|
function coerceScalar(value, typeText) {
|
|
@@ -9772,8 +10753,221 @@ function buildScalarQuery(command, flags) {
|
|
|
9772
10753
|
}
|
|
9773
10754
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
9774
10755
|
}
|
|
9775
|
-
|
|
10756
|
+
function isRecord2(value) {
|
|
10757
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
10758
|
+
}
|
|
10759
|
+
function extractEntityFields(payload) {
|
|
10760
|
+
const candidate = isRecord2(payload) && isRecord2(payload.data) ? payload.data : payload;
|
|
10761
|
+
if (!isRecord2(candidate) || !Array.isArray(candidate.fields)) {
|
|
10762
|
+
return [];
|
|
10763
|
+
}
|
|
10764
|
+
return candidate.fields.filter((item) => isRecord2(item)).filter((item) => typeof item.id === "number" && typeof item.type === "string").map((item) => ({
|
|
10765
|
+
id: item.id,
|
|
10766
|
+
type: item.type,
|
|
10767
|
+
label: typeof item.label === "string" ? item.label : void 0
|
|
10768
|
+
}));
|
|
10769
|
+
}
|
|
10770
|
+
async function fetchEntityFields(runtimeEnv, appId, entityId, fetchImpl) {
|
|
10771
|
+
const response = await fetchImpl(buildURL(runtimeEnv.ARCUBASE_BASE_URL, `/entity/${encodeURIComponent(appId)}/${encodeURIComponent(entityId)}`), {
|
|
10772
|
+
method: "GET",
|
|
10773
|
+
headers: buildRequestHeaders(runtimeEnv)
|
|
10774
|
+
});
|
|
10775
|
+
const raw = await response.text();
|
|
10776
|
+
let parsedResponse = raw;
|
|
10777
|
+
try {
|
|
10778
|
+
parsedResponse = raw ? JSON.parse(raw) : null;
|
|
10779
|
+
} catch {
|
|
10780
|
+
parsedResponse = raw;
|
|
10781
|
+
}
|
|
10782
|
+
if (!response.ok) {
|
|
10783
|
+
throw new CLIError("UPSTREAM_REQUEST_FAILED", typeof parsedResponse === "string" ? parsedResponse : JSON.stringify(parsedResponse), 1);
|
|
10784
|
+
}
|
|
10785
|
+
if (isRecord2(parsedResponse) && parsedResponse.error) {
|
|
10786
|
+
const upstreamError = parsedResponse.error;
|
|
10787
|
+
const upstreamMessage = isRecord2(upstreamError) && typeof upstreamError.message === "string" ? upstreamError.message : typeof upstreamError === "string" ? upstreamError : JSON.stringify(upstreamError);
|
|
10788
|
+
throw new CLIError("UPSTREAM_BODY_ERROR", upstreamMessage, 1, {
|
|
10789
|
+
endpoint: `/entity/${appId}/${entityId}`,
|
|
10790
|
+
method: "GET",
|
|
10791
|
+
upstreamError
|
|
10792
|
+
});
|
|
10793
|
+
}
|
|
10794
|
+
const fields = extractEntityFields(parsedResponse);
|
|
10795
|
+
return new Map(fields.map((field) => [field.id, field]));
|
|
10796
|
+
}
|
|
10797
|
+
function looksLikeLocalFilePath(value) {
|
|
10798
|
+
return value.startsWith("./") || value.startsWith("../") || value.startsWith("/") || value.startsWith("~/") || /\.(pdf|png|jpe?g|gif|webp|bmp|svg|heic|txt|csv|xlsx?|docx?|pptx?|zip)$/i.test(value);
|
|
10799
|
+
}
|
|
10800
|
+
function isValidUploadEntry(value) {
|
|
10801
|
+
if (!isRecord2(value)) {
|
|
10802
|
+
return false;
|
|
10803
|
+
}
|
|
10804
|
+
const hasUploadId = typeof value.upload_id === "number" || typeof value.upload_id === "string";
|
|
10805
|
+
const hasAssetsId = typeof value.assets_id === "number" || typeof value.assets_id === "string";
|
|
10806
|
+
return (hasUploadId || hasAssetsId) && typeof value.file === "string" && typeof value.file_name === "string";
|
|
10807
|
+
}
|
|
10808
|
+
async function validateFileFieldPayloads(scope, command, runtimeEnv, flags, body, fetchImpl) {
|
|
10809
|
+
if (!isRecord2(body)) {
|
|
10810
|
+
return;
|
|
10811
|
+
}
|
|
10812
|
+
const container = command.functionName === "updateEntityRow" ? body.data : body.fields;
|
|
10813
|
+
if (!isRecord2(container)) {
|
|
10814
|
+
return;
|
|
10815
|
+
}
|
|
10816
|
+
const appId = flagValue(flags, "app-id");
|
|
10817
|
+
const entityId = flagValue(flags, "entity-id");
|
|
10818
|
+
if (!appId || !entityId) {
|
|
10819
|
+
return;
|
|
10820
|
+
}
|
|
10821
|
+
const fieldsById = await fetchEntityFields(runtimeEnv, appId, entityId, fetchImpl);
|
|
10822
|
+
for (const [fieldIdText, value] of Object.entries(container)) {
|
|
10823
|
+
if (!/^\d+$/.test(fieldIdText)) {
|
|
10824
|
+
continue;
|
|
10825
|
+
}
|
|
10826
|
+
const fieldId = Number(fieldIdText);
|
|
10827
|
+
const field = fieldsById.get(fieldId);
|
|
10828
|
+
if (!field || field.type !== "file" && field.type !== "image") {
|
|
10829
|
+
continue;
|
|
10830
|
+
}
|
|
10831
|
+
const fieldPath = command.functionName === "updateEntityRow" ? `body.data.${fieldId}` : `body.fields.${fieldId}`;
|
|
10832
|
+
const fieldName = field.label ? `${field.label} (${field.type})` : `${field.type} field ${fieldId}`;
|
|
10833
|
+
if (typeof value === "string") {
|
|
10834
|
+
const guidance = looksLikeLocalFilePath(value) ? `do not put a local file path directly into ${fieldName}; run "arcubase upload ${value}" first and use the returned data array as the field value` : `${fieldName} must be an array returned by "arcubase upload <local-file>", not a string`;
|
|
10835
|
+
throw new CLIError("BODY_VALIDATION_FAILED", guidance, 2, {
|
|
10836
|
+
operation: `${scope}.${command.module}.${command.functionName}`,
|
|
10837
|
+
requestType: command.requestType ?? void 0,
|
|
10838
|
+
issues: [{ path: fieldPath, message: guidance }],
|
|
10839
|
+
docHints: [
|
|
10840
|
+
{ title: "Uploads", file: "/opt/arcubase-sdk/docs/runtime-reference/uploads.md" },
|
|
10841
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" }
|
|
10842
|
+
]
|
|
10843
|
+
});
|
|
10844
|
+
}
|
|
10845
|
+
if (isRecord2(value)) {
|
|
10846
|
+
const guidance = `${fieldName} must be an array. Run "arcubase upload <local-file>" and use the returned data array directly as the field value`;
|
|
10847
|
+
throw new CLIError("BODY_VALIDATION_FAILED", guidance, 2, {
|
|
10848
|
+
operation: `${scope}.${command.module}.${command.functionName}`,
|
|
10849
|
+
requestType: command.requestType ?? void 0,
|
|
10850
|
+
issues: [{ path: fieldPath, message: guidance }],
|
|
10851
|
+
docHints: [
|
|
10852
|
+
{ title: "Uploads", file: "/opt/arcubase-sdk/docs/runtime-reference/uploads.md" },
|
|
10853
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" }
|
|
10854
|
+
]
|
|
10855
|
+
});
|
|
10856
|
+
}
|
|
10857
|
+
if (!Array.isArray(value)) {
|
|
10858
|
+
const guidance = `${fieldName} must be an array returned by "arcubase upload <local-file>"`;
|
|
10859
|
+
throw new CLIError("BODY_VALIDATION_FAILED", guidance, 2, {
|
|
10860
|
+
operation: `${scope}.${command.module}.${command.functionName}`,
|
|
10861
|
+
requestType: command.requestType ?? void 0,
|
|
10862
|
+
issues: [{ path: fieldPath, message: guidance }],
|
|
10863
|
+
docHints: [
|
|
10864
|
+
{ title: "Uploads", file: "/opt/arcubase-sdk/docs/runtime-reference/uploads.md" },
|
|
10865
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" }
|
|
10866
|
+
]
|
|
10867
|
+
});
|
|
10868
|
+
}
|
|
10869
|
+
for (const [index, item] of value.entries()) {
|
|
10870
|
+
if (!isValidUploadEntry(item)) {
|
|
10871
|
+
const guidance = `${fieldName} entries must include upload_id or assets_id plus file and file_name. Use "arcubase upload <local-file>" and copy the returned array item as-is`;
|
|
10872
|
+
throw new CLIError("BODY_VALIDATION_FAILED", guidance, 2, {
|
|
10873
|
+
operation: `${scope}.${command.module}.${command.functionName}`,
|
|
10874
|
+
requestType: command.requestType ?? void 0,
|
|
10875
|
+
issues: [{ path: `${fieldPath}.${index}`, message: guidance }],
|
|
10876
|
+
docHints: [
|
|
10877
|
+
{ title: "Uploads", file: "/opt/arcubase-sdk/docs/runtime-reference/uploads.md" },
|
|
10878
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" }
|
|
10879
|
+
]
|
|
10880
|
+
});
|
|
10881
|
+
}
|
|
10882
|
+
}
|
|
10883
|
+
}
|
|
10884
|
+
}
|
|
10885
|
+
function throwBodyValidationFailure(message, requestType, path2, scope, command) {
|
|
10886
|
+
throw new CLIError("BODY_VALIDATION_FAILED", message, 2, {
|
|
10887
|
+
operation: `${scope}.${command.module}.${command.functionName}`,
|
|
10888
|
+
requestType,
|
|
10889
|
+
issues: [
|
|
10890
|
+
{
|
|
10891
|
+
path: path2,
|
|
10892
|
+
message
|
|
10893
|
+
}
|
|
10894
|
+
],
|
|
10895
|
+
tsHints: getTypeHints(requestType),
|
|
10896
|
+
docHints: getDocHints(requestType)
|
|
10897
|
+
});
|
|
10898
|
+
}
|
|
10899
|
+
function validateActionSpecificBody(scope, command, flags, body) {
|
|
10900
|
+
if (!isRecord2(body) || !command.requestType) {
|
|
10901
|
+
return;
|
|
10902
|
+
}
|
|
10903
|
+
if (command.module === "workflow" && command.functionName === "queryEntitySelection") {
|
|
10904
|
+
const action = flagValue(flags, "action");
|
|
10905
|
+
const selection = body.selection;
|
|
10906
|
+
if (!isRecord2(selection) || typeof selection.type !== "string") {
|
|
10907
|
+
return;
|
|
10908
|
+
}
|
|
10909
|
+
const type = selection.type;
|
|
10910
|
+
const condition = isRecord2(selection.condition) ? selection.condition : void 0;
|
|
10911
|
+
const conditionKeys = condition ? Object.keys(condition).filter((key) => key !== "selectAll") : [];
|
|
10912
|
+
if (action === "query") {
|
|
10913
|
+
if (type === "condition") {
|
|
10914
|
+
throwBodyValidationFailure(
|
|
10915
|
+
"selection.type=condition is not supported for action=query; use selection.type=ids or selection.type=all, or use workflow query-entity for search conditions",
|
|
10916
|
+
command.requestType,
|
|
10917
|
+
"body.selection.type",
|
|
10918
|
+
scope,
|
|
10919
|
+
command
|
|
10920
|
+
);
|
|
10921
|
+
}
|
|
10922
|
+
return;
|
|
10923
|
+
}
|
|
10924
|
+
if ((action === "archive" || action === "delete" || action === "batch_print") && type === "all") {
|
|
10925
|
+
throwBodyValidationFailure(
|
|
10926
|
+
`selection.type=all is not supported for action=${action}; use ids or condition`,
|
|
10927
|
+
command.requestType,
|
|
10928
|
+
"body.selection.type",
|
|
10929
|
+
scope,
|
|
10930
|
+
command
|
|
10931
|
+
);
|
|
10932
|
+
}
|
|
10933
|
+
if ((action === "archive" || action === "delete") && type === "condition" && conditionKeys.length === 0) {
|
|
10934
|
+
throwBodyValidationFailure(
|
|
10935
|
+
`selection.condition for action=${action} requires at least one q, tab, or filter_* key in addition to selectAll`,
|
|
10936
|
+
command.requestType,
|
|
10937
|
+
"body.selection.condition",
|
|
10938
|
+
scope,
|
|
10939
|
+
command
|
|
10940
|
+
);
|
|
10941
|
+
}
|
|
10942
|
+
}
|
|
10943
|
+
}
|
|
10944
|
+
async function executeCLI(scope, argv, env, fetchImpl = fetch) {
|
|
9776
10945
|
const parsed = parseCLIArgs(argv);
|
|
10946
|
+
if (scope === "user" && parsed.commandTokens[0] === "upload") {
|
|
10947
|
+
if (hasFlag(parsed.flags, "help") || parsed.commandTokens.length === 1) {
|
|
10948
|
+
return { kind: "help", text: renderUploadHelp() };
|
|
10949
|
+
}
|
|
10950
|
+
const sourcePath = parsed.commandTokens[1];
|
|
10951
|
+
if (!sourcePath) {
|
|
10952
|
+
throw new CLIError("UPLOAD_SOURCE_REQUIRED", "upload requires a local file path", 2);
|
|
10953
|
+
}
|
|
10954
|
+
const runtimeEnv2 = env ?? loadRuntimeEnv(scope);
|
|
10955
|
+
const data = await uploadLocalFile(
|
|
10956
|
+
runtimeEnv2,
|
|
10957
|
+
sourcePath,
|
|
10958
|
+
{
|
|
10959
|
+
filename: flagValue(parsed.flags, "filename"),
|
|
10960
|
+
global: hasFlag(parsed.flags, "global")
|
|
10961
|
+
},
|
|
10962
|
+
fetchImpl
|
|
10963
|
+
);
|
|
10964
|
+
return {
|
|
10965
|
+
kind: "result",
|
|
10966
|
+
commandPath: ["upload", sourcePath],
|
|
10967
|
+
status: 200,
|
|
10968
|
+
data
|
|
10969
|
+
};
|
|
10970
|
+
}
|
|
9777
10971
|
if (parsed.commandTokens.length === 0) {
|
|
9778
10972
|
return { kind: "help", text: renderRootHelp(scope) };
|
|
9779
10973
|
}
|
|
@@ -9787,15 +10981,17 @@ async function executeCLI(scope, argv, env = loadRuntimeEnv(scope), fetchImpl =
|
|
|
9787
10981
|
if (hasFlag(parsed.flags, "help")) {
|
|
9788
10982
|
return { kind: "help", text: renderCommandHelp(scope, moduleName, commandName) };
|
|
9789
10983
|
}
|
|
10984
|
+
const runtimeEnv = env ?? loadRuntimeEnv(scope);
|
|
9790
10985
|
const command = findCommand(scope, moduleName, commandName);
|
|
9791
10986
|
if (!command) {
|
|
9792
|
-
throw new CLIError("UNKNOWN_COMMAND", `unknown command: ${moduleName} ${commandName}`, 2);
|
|
10987
|
+
throw new CLIError("UNKNOWN_COMMAND", `unknown command: ${moduleName} ${commandName}`, 2, buildUnknownCommandDetails(scope, moduleName, commandName));
|
|
9793
10988
|
}
|
|
9794
10989
|
const endpoint = normalizeExternalEndpoint(resolveEndpoint(command.endpoint, parsed.flags));
|
|
9795
10990
|
const scalarQuery = buildScalarQuery(command, parsed.flags);
|
|
9796
10991
|
const fileQuery = loadQueryFromFlags(parsed.flags);
|
|
9797
10992
|
const query = { ...scalarQuery ?? {}, ...fileQuery ?? {} };
|
|
9798
10993
|
const body = loadBodyFromFlags(parsed.flags);
|
|
10994
|
+
let validatedBody = body;
|
|
9799
10995
|
if (command.requestType) {
|
|
9800
10996
|
if (body === void 0) {
|
|
9801
10997
|
throw new CLIError("MISSING_BODY_FILE", `command requires --body-file for ${command.requestType}`, 2);
|
|
@@ -9815,10 +11011,13 @@ async function executeCLI(scope, argv, env = loadRuntimeEnv(scope), fetchImpl =
|
|
|
9815
11011
|
path: issue.path.length > 0 ? `body.${issue.path.join(".")}` : "body",
|
|
9816
11012
|
message: issue.message
|
|
9817
11013
|
})),
|
|
9818
|
-
tsHints: getTypeHints(command.requestType)
|
|
11014
|
+
tsHints: getTypeHints(command.requestType),
|
|
11015
|
+
docHints: getDocHints(command.requestType)
|
|
9819
11016
|
}
|
|
9820
11017
|
);
|
|
9821
11018
|
}
|
|
11019
|
+
validatedBody = parsedBody.data;
|
|
11020
|
+
validateActionSpecificBody(scope, command, parsed.flags, validatedBody);
|
|
9822
11021
|
} else {
|
|
9823
11022
|
const unsupportedReason = getUnsupportedBodySchemaReason(command.requestType);
|
|
9824
11023
|
if (unsupportedReason) {
|
|
@@ -9826,19 +11025,22 @@ async function executeCLI(scope, argv, env = loadRuntimeEnv(scope), fetchImpl =
|
|
|
9826
11025
|
operation: `${scope}.${command.module}.${command.functionName}`,
|
|
9827
11026
|
requestType: command.requestType,
|
|
9828
11027
|
reason: unsupportedReason,
|
|
9829
|
-
tsHints: getTypeHints(command.requestType)
|
|
11028
|
+
tsHints: getTypeHints(command.requestType),
|
|
11029
|
+
docHints: getDocHints(command.requestType)
|
|
9830
11030
|
});
|
|
9831
11031
|
}
|
|
9832
11032
|
}
|
|
9833
11033
|
}
|
|
9834
|
-
|
|
9835
|
-
|
|
11034
|
+
if (scope === "user" && (command.functionName === "insertEntity" || command.functionName === "updateEntityRow")) {
|
|
11035
|
+
await validateFileFieldPayloads(scope, command, runtimeEnv, parsed.flags, validatedBody, fetchImpl);
|
|
11036
|
+
}
|
|
11037
|
+
const response = await fetchImpl(buildURL(runtimeEnv.ARCUBASE_BASE_URL, endpoint, Object.keys(query).length > 0 ? query : void 0), {
|
|
9836
11038
|
method: command.method,
|
|
9837
11039
|
headers: {
|
|
9838
|
-
...
|
|
11040
|
+
...buildRequestHeaders(runtimeEnv),
|
|
9839
11041
|
"Content-Type": "application/json"
|
|
9840
11042
|
},
|
|
9841
|
-
body:
|
|
11043
|
+
body: validatedBody === void 0 || command.method === "GET" ? void 0 : JSON.stringify(validatedBody)
|
|
9842
11044
|
});
|
|
9843
11045
|
const raw = await response.text();
|
|
9844
11046
|
let parsedResponse = raw;
|
|
@@ -9849,6 +11051,26 @@ async function executeCLI(scope, argv, env = loadRuntimeEnv(scope), fetchImpl =
|
|
|
9849
11051
|
if (!response.ok) {
|
|
9850
11052
|
throw new CLIError("UPSTREAM_REQUEST_FAILED", typeof parsedResponse === "string" ? parsedResponse : JSON.stringify(parsedResponse), 1);
|
|
9851
11053
|
}
|
|
11054
|
+
if (parsedResponse && typeof parsedResponse === "object" && "error" in parsedResponse && parsedResponse.error) {
|
|
11055
|
+
const upstreamError = parsedResponse.error;
|
|
11056
|
+
const upstreamMessage = typeof upstreamError === "object" && upstreamError && "message" in upstreamError && typeof upstreamError.message === "string" ? upstreamError.message : typeof upstreamError === "string" ? upstreamError : JSON.stringify(upstreamError);
|
|
11057
|
+
const traceId = typeof parsedResponse.trace_id === "string" ? parsedResponse.trace_id : typeof parsedResponse.request_id === "string" ? parsedResponse.request_id : void 0;
|
|
11058
|
+
const uploadBindFailure = upstreamMessage.includes("failed to bind upload to assets");
|
|
11059
|
+
throw new CLIError("UPSTREAM_BODY_ERROR", upstreamMessage, 1, {
|
|
11060
|
+
endpoint,
|
|
11061
|
+
method: command.method,
|
|
11062
|
+
traceId,
|
|
11063
|
+
upstreamError,
|
|
11064
|
+
...uploadBindFailure ? {
|
|
11065
|
+
reason: "the row payload used a file/image upload entry, but Arcubase could not bind that upload into an asset record",
|
|
11066
|
+
hint: "verify the upload storage host is reachable from the Arcubase server, then rerun arcubase upload and retry the row insert/update",
|
|
11067
|
+
docHints: [
|
|
11068
|
+
{ title: "Uploads", file: "/opt/arcubase-sdk/docs/runtime-reference/uploads.md" },
|
|
11069
|
+
{ title: "Row CRUD", file: "/opt/arcubase-sdk/docs/runtime-reference/row-crud.md" }
|
|
11070
|
+
]
|
|
11071
|
+
} : {}
|
|
11072
|
+
});
|
|
11073
|
+
}
|
|
9852
11074
|
return {
|
|
9853
11075
|
kind: "result",
|
|
9854
11076
|
commandPath: command.commandPath,
|