@carthooks/arcubase-cli 0.1.15 → 0.1.17
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 +11 -11
- package/bundle/arcubase.mjs +11 -11
- package/dist/runtime/execute.js +10 -10
- package/package.json +1 -1
- package/sdk-dist/docs/runtime-reference/README.md +2 -0
- package/sdk-dist/docs/runtime-reference/access-rule.md +5 -5
- package/src/runtime/execute.ts +11 -11
- package/src/tests/execute_validation.test.ts +6 -5
- package/src/tests/help.test.ts +13 -0
|
@@ -17517,15 +17517,15 @@ function renderCommandHelp(scope, moduleName, commandName, env = process.env) {
|
|
|
17517
17517
|
' - {"update":["user_scope"],"options":{"user_scope":[{"type":"user","id":2188889901}]}}',
|
|
17518
17518
|
"success requires:",
|
|
17519
17519
|
" - result.enabled must be true",
|
|
17520
|
-
" - result.options.user_scope must contain the assigned numeric
|
|
17521
|
-
" - PermitUserScope.id must be numeric
|
|
17522
|
-
" - Do not copy
|
|
17520
|
+
" - result.options.user_scope must contain the assigned numeric arcubaseUserId values",
|
|
17521
|
+
" - PermitUserScope.id must be the numeric arcubaseUserId",
|
|
17522
|
+
" - Do not copy a non-numeric arcubaseUserId into PermitUserScope.id",
|
|
17523
17523
|
" - If result.enabled is false, enable the rule first and retry assign-users"
|
|
17524
17524
|
] : [],
|
|
17525
17525
|
...scope === "admin" && command.commandPath[0] === "app" && command.commandPath[1] === "create-from-bundle-url" ? [
|
|
17526
17526
|
"flags:",
|
|
17527
17527
|
" - --url must be a public http/https app bundle zip URL",
|
|
17528
|
-
" - --name
|
|
17528
|
+
" - --name is accepted for compatibility; imported app name comes from the bundle source app",
|
|
17529
17529
|
"success:",
|
|
17530
17530
|
" - returns task_id; use app watch-import-task to wait for completion"
|
|
17531
17531
|
] : [],
|
|
@@ -17534,7 +17534,7 @@ function renderCommandHelp(scope, moduleName, commandName, env = process.env) {
|
|
|
17534
17534
|
" - --task-id is returned by app create-from-bundle-url",
|
|
17535
17535
|
" - --ttl-seconds is a local wait limit and does not cancel the backend task",
|
|
17536
17536
|
"success:",
|
|
17537
|
-
" - returns finished task status with app_id and warnings"
|
|
17537
|
+
" - returns finished task status with app_id, name, and warnings"
|
|
17538
17538
|
] : [],
|
|
17539
17539
|
...scope === "user" && command.commandPath[0] === "row" && command.commandPath[1] === "import-excel" ? [
|
|
17540
17540
|
"mapping-file example:",
|
|
@@ -17996,8 +17996,8 @@ function buildAssignUsersValidationDetails(scope, command, requestType, path3, m
|
|
|
17996
17996
|
commonMistakes: [
|
|
17997
17997
|
"do not use user_scope at top level",
|
|
17998
17998
|
"do not use users or allowedUsers",
|
|
17999
|
-
"do not use
|
|
18000
|
-
"id must be numeric
|
|
17999
|
+
"do not use non-numeric arcubaseUserId as id",
|
|
18000
|
+
"id must be the numeric arcubaseUserId"
|
|
18001
18001
|
]
|
|
18002
18002
|
};
|
|
18003
18003
|
}
|
|
@@ -18310,7 +18310,7 @@ function validateAccessRuleUserScope(scope, command, requestType, userScope, env
|
|
|
18310
18310
|
}
|
|
18311
18311
|
if (typeof item.id !== "number" || !Number.isInteger(item.id) || item.id <= 0) {
|
|
18312
18312
|
throwBodyValidationFailure(
|
|
18313
|
-
"access-rule user_scope[].id must be numeric
|
|
18313
|
+
"access-rule user_scope[].id must be numeric arcubaseUserId, department ID, or actor ID",
|
|
18314
18314
|
requestType,
|
|
18315
18315
|
`${pathPrefix}.${index}.id`,
|
|
18316
18316
|
scope,
|
|
@@ -18515,7 +18515,7 @@ function validateActionSpecificBody(scope, command, flags, body, env) {
|
|
|
18515
18515
|
}
|
|
18516
18516
|
if (typeof item.id !== "number" || !Number.isInteger(item.id) || item.id <= 0) {
|
|
18517
18517
|
throwBodyValidationFailure(
|
|
18518
|
-
"access-rule assign-users requires body.options.user_scope[].id to be numeric
|
|
18518
|
+
"access-rule assign-users requires body.options.user_scope[].id to be numeric arcubaseUserId",
|
|
18519
18519
|
command.requestType,
|
|
18520
18520
|
`body.options.user_scope.${index}.id`,
|
|
18521
18521
|
scope,
|
|
@@ -19219,14 +19219,14 @@ async function executeCLI(scope, argv, env, fetchImpl = fetch) {
|
|
|
19219
19219
|
const hasUserScopeIDIssue = parsedBody.error.issues.some((issue2) => issue2.path.join(".") === "options.user_scope.0.id" || issue2.path.join(".").startsWith("options.user_scope."));
|
|
19220
19220
|
throw new CLIError(
|
|
19221
19221
|
"BODY_VALIDATION_FAILED",
|
|
19222
|
-
hasUserScopeIDIssue ? "access-rule assign-users requires body.options.user_scope[].id to be numeric
|
|
19222
|
+
hasUserScopeIDIssue ? "access-rule assign-users requires body.options.user_scope[].id to be numeric arcubaseUserId" : message,
|
|
19223
19223
|
2,
|
|
19224
19224
|
buildAssignUsersValidationDetails(
|
|
19225
19225
|
scope,
|
|
19226
19226
|
command,
|
|
19227
19227
|
command.requestType,
|
|
19228
19228
|
hasUserScopeIDIssue ? "body.options.user_scope" : "body",
|
|
19229
|
-
hasUserScopeIDIssue ? "access-rule assign-users requires body.options.user_scope[].id to be numeric
|
|
19229
|
+
hasUserScopeIDIssue ? "access-rule assign-users requires body.options.user_scope[].id to be numeric arcubaseUserId" : message,
|
|
19230
19230
|
runtimeEnv
|
|
19231
19231
|
)
|
|
19232
19232
|
);
|
package/bundle/arcubase.mjs
CHANGED
|
@@ -17517,15 +17517,15 @@ function renderCommandHelp(scope, moduleName, commandName, env = process.env) {
|
|
|
17517
17517
|
' - {"update":["user_scope"],"options":{"user_scope":[{"type":"user","id":2188889901}]}}',
|
|
17518
17518
|
"success requires:",
|
|
17519
17519
|
" - result.enabled must be true",
|
|
17520
|
-
" - result.options.user_scope must contain the assigned numeric
|
|
17521
|
-
" - PermitUserScope.id must be numeric
|
|
17522
|
-
" - Do not copy
|
|
17520
|
+
" - result.options.user_scope must contain the assigned numeric arcubaseUserId values",
|
|
17521
|
+
" - PermitUserScope.id must be the numeric arcubaseUserId",
|
|
17522
|
+
" - Do not copy a non-numeric arcubaseUserId into PermitUserScope.id",
|
|
17523
17523
|
" - If result.enabled is false, enable the rule first and retry assign-users"
|
|
17524
17524
|
] : [],
|
|
17525
17525
|
...scope === "admin" && command.commandPath[0] === "app" && command.commandPath[1] === "create-from-bundle-url" ? [
|
|
17526
17526
|
"flags:",
|
|
17527
17527
|
" - --url must be a public http/https app bundle zip URL",
|
|
17528
|
-
" - --name
|
|
17528
|
+
" - --name is accepted for compatibility; imported app name comes from the bundle source app",
|
|
17529
17529
|
"success:",
|
|
17530
17530
|
" - returns task_id; use app watch-import-task to wait for completion"
|
|
17531
17531
|
] : [],
|
|
@@ -17534,7 +17534,7 @@ function renderCommandHelp(scope, moduleName, commandName, env = process.env) {
|
|
|
17534
17534
|
" - --task-id is returned by app create-from-bundle-url",
|
|
17535
17535
|
" - --ttl-seconds is a local wait limit and does not cancel the backend task",
|
|
17536
17536
|
"success:",
|
|
17537
|
-
" - returns finished task status with app_id and warnings"
|
|
17537
|
+
" - returns finished task status with app_id, name, and warnings"
|
|
17538
17538
|
] : [],
|
|
17539
17539
|
...scope === "user" && command.commandPath[0] === "row" && command.commandPath[1] === "import-excel" ? [
|
|
17540
17540
|
"mapping-file example:",
|
|
@@ -17996,8 +17996,8 @@ function buildAssignUsersValidationDetails(scope, command, requestType, path3, m
|
|
|
17996
17996
|
commonMistakes: [
|
|
17997
17997
|
"do not use user_scope at top level",
|
|
17998
17998
|
"do not use users or allowedUsers",
|
|
17999
|
-
"do not use
|
|
18000
|
-
"id must be numeric
|
|
17999
|
+
"do not use non-numeric arcubaseUserId as id",
|
|
18000
|
+
"id must be the numeric arcubaseUserId"
|
|
18001
18001
|
]
|
|
18002
18002
|
};
|
|
18003
18003
|
}
|
|
@@ -18310,7 +18310,7 @@ function validateAccessRuleUserScope(scope, command, requestType, userScope, env
|
|
|
18310
18310
|
}
|
|
18311
18311
|
if (typeof item.id !== "number" || !Number.isInteger(item.id) || item.id <= 0) {
|
|
18312
18312
|
throwBodyValidationFailure(
|
|
18313
|
-
"access-rule user_scope[].id must be numeric
|
|
18313
|
+
"access-rule user_scope[].id must be numeric arcubaseUserId, department ID, or actor ID",
|
|
18314
18314
|
requestType,
|
|
18315
18315
|
`${pathPrefix}.${index}.id`,
|
|
18316
18316
|
scope,
|
|
@@ -18515,7 +18515,7 @@ function validateActionSpecificBody(scope, command, flags, body, env) {
|
|
|
18515
18515
|
}
|
|
18516
18516
|
if (typeof item.id !== "number" || !Number.isInteger(item.id) || item.id <= 0) {
|
|
18517
18517
|
throwBodyValidationFailure(
|
|
18518
|
-
"access-rule assign-users requires body.options.user_scope[].id to be numeric
|
|
18518
|
+
"access-rule assign-users requires body.options.user_scope[].id to be numeric arcubaseUserId",
|
|
18519
18519
|
command.requestType,
|
|
18520
18520
|
`body.options.user_scope.${index}.id`,
|
|
18521
18521
|
scope,
|
|
@@ -19219,14 +19219,14 @@ async function executeCLI(scope, argv, env, fetchImpl = fetch) {
|
|
|
19219
19219
|
const hasUserScopeIDIssue = parsedBody.error.issues.some((issue2) => issue2.path.join(".") === "options.user_scope.0.id" || issue2.path.join(".").startsWith("options.user_scope."));
|
|
19220
19220
|
throw new CLIError(
|
|
19221
19221
|
"BODY_VALIDATION_FAILED",
|
|
19222
|
-
hasUserScopeIDIssue ? "access-rule assign-users requires body.options.user_scope[].id to be numeric
|
|
19222
|
+
hasUserScopeIDIssue ? "access-rule assign-users requires body.options.user_scope[].id to be numeric arcubaseUserId" : message,
|
|
19223
19223
|
2,
|
|
19224
19224
|
buildAssignUsersValidationDetails(
|
|
19225
19225
|
scope,
|
|
19226
19226
|
command,
|
|
19227
19227
|
command.requestType,
|
|
19228
19228
|
hasUserScopeIDIssue ? "body.options.user_scope" : "body",
|
|
19229
|
-
hasUserScopeIDIssue ? "access-rule assign-users requires body.options.user_scope[].id to be numeric
|
|
19229
|
+
hasUserScopeIDIssue ? "access-rule assign-users requires body.options.user_scope[].id to be numeric arcubaseUserId" : message,
|
|
19230
19230
|
runtimeEnv
|
|
19231
19231
|
)
|
|
19232
19232
|
);
|
package/dist/runtime/execute.js
CHANGED
|
@@ -123,9 +123,9 @@ export function renderCommandHelp(scope, moduleName, commandName, env = process.
|
|
|
123
123
|
' - {"update":["user_scope"],"options":{"user_scope":[{"type":"user","id":2188889901}]}}',
|
|
124
124
|
'success requires:',
|
|
125
125
|
' - result.enabled must be true',
|
|
126
|
-
' - result.options.user_scope must contain the assigned numeric
|
|
127
|
-
' - PermitUserScope.id must be numeric
|
|
128
|
-
' - Do not copy
|
|
126
|
+
' - result.options.user_scope must contain the assigned numeric arcubaseUserId values',
|
|
127
|
+
' - PermitUserScope.id must be the numeric arcubaseUserId',
|
|
128
|
+
' - Do not copy a non-numeric arcubaseUserId into PermitUserScope.id',
|
|
129
129
|
' - If result.enabled is false, enable the rule first and retry assign-users',
|
|
130
130
|
]
|
|
131
131
|
: []),
|
|
@@ -133,7 +133,7 @@ export function renderCommandHelp(scope, moduleName, commandName, env = process.
|
|
|
133
133
|
? [
|
|
134
134
|
'flags:',
|
|
135
135
|
' - --url must be a public http/https app bundle zip URL',
|
|
136
|
-
' - --name
|
|
136
|
+
' - --name is accepted for compatibility; imported app name comes from the bundle source app',
|
|
137
137
|
'success:',
|
|
138
138
|
' - returns task_id; use app watch-import-task to wait for completion',
|
|
139
139
|
]
|
|
@@ -144,7 +144,7 @@ export function renderCommandHelp(scope, moduleName, commandName, env = process.
|
|
|
144
144
|
' - --task-id is returned by app create-from-bundle-url',
|
|
145
145
|
' - --ttl-seconds is a local wait limit and does not cancel the backend task',
|
|
146
146
|
'success:',
|
|
147
|
-
' - returns finished task status with app_id and warnings',
|
|
147
|
+
' - returns finished task status with app_id, name, and warnings',
|
|
148
148
|
]
|
|
149
149
|
: []),
|
|
150
150
|
...(scope === 'user' && command.commandPath[0] === 'row' && command.commandPath[1] === 'import-excel'
|
|
@@ -634,8 +634,8 @@ function buildAssignUsersValidationDetails(scope, command, requestType, path, me
|
|
|
634
634
|
commonMistakes: [
|
|
635
635
|
'do not use user_scope at top level',
|
|
636
636
|
'do not use users or allowedUsers',
|
|
637
|
-
'do not use
|
|
638
|
-
'id must be numeric
|
|
637
|
+
'do not use non-numeric arcubaseUserId as id',
|
|
638
|
+
'id must be the numeric arcubaseUserId',
|
|
639
639
|
],
|
|
640
640
|
};
|
|
641
641
|
}
|
|
@@ -906,7 +906,7 @@ function validateAccessRuleUserScope(scope, command, requestType, userScope, env
|
|
|
906
906
|
throwBodyValidationFailure('access-rule user_scope[].type must be "user", "department", or "actor"; do not use FieldVO type "member" here', requestType, `${pathPrefix}.${index}.type`, scope, command, env);
|
|
907
907
|
}
|
|
908
908
|
if (typeof item.id !== 'number' || !Number.isInteger(item.id) || item.id <= 0) {
|
|
909
|
-
throwBodyValidationFailure('access-rule user_scope[].id must be numeric
|
|
909
|
+
throwBodyValidationFailure('access-rule user_scope[].id must be numeric arcubaseUserId, department ID, or actor ID', requestType, `${pathPrefix}.${index}.id`, scope, command, env);
|
|
910
910
|
}
|
|
911
911
|
}
|
|
912
912
|
}
|
|
@@ -1001,7 +1001,7 @@ function validateActionSpecificBody(scope, command, flags, body, env) {
|
|
|
1001
1001
|
throwBodyValidationFailure('access-rule assign-users requires body.options.user_scope[].type to be "user"', command.requestType, `body.options.user_scope.${index}.type`, scope, command, env);
|
|
1002
1002
|
}
|
|
1003
1003
|
if (typeof item.id !== 'number' || !Number.isInteger(item.id) || item.id <= 0) {
|
|
1004
|
-
throwBodyValidationFailure('access-rule assign-users requires body.options.user_scope[].id to be numeric
|
|
1004
|
+
throwBodyValidationFailure('access-rule assign-users requires body.options.user_scope[].id to be numeric arcubaseUserId', command.requestType, `body.options.user_scope.${index}.id`, scope, command, env);
|
|
1005
1005
|
}
|
|
1006
1006
|
}
|
|
1007
1007
|
}
|
|
@@ -1714,7 +1714,7 @@ export async function executeCLI(scope, argv, env, fetchImpl = fetch) {
|
|
|
1714
1714
|
const message = parsedBody.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`).join('; ');
|
|
1715
1715
|
if (isAssignUsersCommand(scope, command)) {
|
|
1716
1716
|
const hasUserScopeIDIssue = parsedBody.error.issues.some((issue) => issue.path.join('.') === 'options.user_scope.0.id' || issue.path.join('.').startsWith('options.user_scope.'));
|
|
1717
|
-
throw new CLIError('BODY_VALIDATION_FAILED', hasUserScopeIDIssue ? 'access-rule assign-users requires body.options.user_scope[].id to be numeric
|
|
1717
|
+
throw new CLIError('BODY_VALIDATION_FAILED', hasUserScopeIDIssue ? 'access-rule assign-users requires body.options.user_scope[].id to be numeric arcubaseUserId' : message, 2, buildAssignUsersValidationDetails(scope, command, command.requestType, hasUserScopeIDIssue ? 'body.options.user_scope' : 'body', hasUserScopeIDIssue ? 'access-rule assign-users requires body.options.user_scope[].id to be numeric arcubaseUserId' : message, runtimeEnv));
|
|
1718
1718
|
}
|
|
1719
1719
|
throw new CLIError('BODY_VALIDATION_FAILED', message, 2, buildBodyValidationDetails(scope, command, command.requestType, parsedBody.error.issues.map((issue) => ({
|
|
1720
1720
|
path: issue.path.length > 0 ? `body.${issue.path.join('.')}` : 'body',
|
package/package.json
CHANGED
|
@@ -43,6 +43,8 @@ arcubase-admin table update-schema --app-id <app_id> --table-id <table_id> --bod
|
|
|
43
43
|
arcubase-admin access-rule assign-users --app-id <app_id> --table-id <table_id> --rule-id <rule_id> --body-json <json-string> | --body-file assign-users.json
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
+
`app create-from-bundle-url --name` is accepted for compatibility; imported app name comes from the bundle source app.
|
|
47
|
+
|
|
46
48
|
`--ttl-seconds` is a local wait limit. It does not cancel the backend import task.
|
|
47
49
|
|
|
48
50
|
Use `arcubase` for:
|
|
@@ -4,7 +4,7 @@ Use `arcubase-admin access-rule` for app/table access.
|
|
|
4
4
|
|
|
5
5
|
## One Path
|
|
6
6
|
|
|
7
|
-
1. Get the numeric `
|
|
7
|
+
1. Get the numeric `arcubaseUserId`.
|
|
8
8
|
2. Create an enabled rule with `options.policy`.
|
|
9
9
|
3. Assign users with `options.user_scope`.
|
|
10
10
|
4. Verify with `access-rule get`.
|
|
@@ -15,9 +15,9 @@ Use `arcubase-admin access-rule` for app/table access.
|
|
|
15
15
|
arcubase-admin get-digiemployee-users
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
Use the numeric `
|
|
18
|
+
Use the numeric `arcubaseUserId`.
|
|
19
19
|
|
|
20
|
-
Do not use
|
|
20
|
+
Do not use non-numeric Arcubase user ids in `user_scope[].id`.
|
|
21
21
|
Use `user_scope[].type:"user"` for a tenant user. Do not use FieldVO field type `member` in access rules.
|
|
22
22
|
|
|
23
23
|
## Body Input
|
|
@@ -107,8 +107,8 @@ Rules:
|
|
|
107
107
|
- `assign-users` preserves the existing policy.
|
|
108
108
|
- body must use `update:["user_scope"]`.
|
|
109
109
|
- body must use `options.user_scope`.
|
|
110
|
-
- `user_scope[].type` is `user` for
|
|
111
|
-
- `user_scope[].id` is numeric `
|
|
110
|
+
- `user_scope[].type` is `user` for Arcubase organization users.
|
|
111
|
+
- `user_scope[].id` is the numeric `arcubaseUserId`.
|
|
112
112
|
|
|
113
113
|
## Verify
|
|
114
114
|
|
package/src/runtime/execute.ts
CHANGED
|
@@ -140,9 +140,9 @@ export function renderCommandHelp(scope: CommandScope, moduleName: string, comma
|
|
|
140
140
|
' - {"update":["user_scope"],"options":{"user_scope":[{"type":"user","id":2188889901}]}}',
|
|
141
141
|
'success requires:',
|
|
142
142
|
' - result.enabled must be true',
|
|
143
|
-
' - result.options.user_scope must contain the assigned numeric
|
|
144
|
-
' - PermitUserScope.id must be numeric
|
|
145
|
-
' - Do not copy
|
|
143
|
+
' - result.options.user_scope must contain the assigned numeric arcubaseUserId values',
|
|
144
|
+
' - PermitUserScope.id must be the numeric arcubaseUserId',
|
|
145
|
+
' - Do not copy a non-numeric arcubaseUserId into PermitUserScope.id',
|
|
146
146
|
' - If result.enabled is false, enable the rule first and retry assign-users',
|
|
147
147
|
]
|
|
148
148
|
: []),
|
|
@@ -150,7 +150,7 @@ export function renderCommandHelp(scope: CommandScope, moduleName: string, comma
|
|
|
150
150
|
? [
|
|
151
151
|
'flags:',
|
|
152
152
|
' - --url must be a public http/https app bundle zip URL',
|
|
153
|
-
' - --name
|
|
153
|
+
' - --name is accepted for compatibility; imported app name comes from the bundle source app',
|
|
154
154
|
'success:',
|
|
155
155
|
' - returns task_id; use app watch-import-task to wait for completion',
|
|
156
156
|
]
|
|
@@ -161,7 +161,7 @@ export function renderCommandHelp(scope: CommandScope, moduleName: string, comma
|
|
|
161
161
|
' - --task-id is returned by app create-from-bundle-url',
|
|
162
162
|
' - --ttl-seconds is a local wait limit and does not cancel the backend task',
|
|
163
163
|
'success:',
|
|
164
|
-
' - returns finished task status with app_id and warnings',
|
|
164
|
+
' - returns finished task status with app_id, name, and warnings',
|
|
165
165
|
]
|
|
166
166
|
: []),
|
|
167
167
|
...(scope === 'user' && command.commandPath[0] === 'row' && command.commandPath[1] === 'import-excel'
|
|
@@ -703,8 +703,8 @@ function buildAssignUsersValidationDetails(
|
|
|
703
703
|
commonMistakes: [
|
|
704
704
|
'do not use user_scope at top level',
|
|
705
705
|
'do not use users or allowedUsers',
|
|
706
|
-
'do not use
|
|
707
|
-
'id must be numeric
|
|
706
|
+
'do not use non-numeric arcubaseUserId as id',
|
|
707
|
+
'id must be the numeric arcubaseUserId',
|
|
708
708
|
],
|
|
709
709
|
}
|
|
710
710
|
}
|
|
@@ -1036,7 +1036,7 @@ function validateAccessRuleUserScope(
|
|
|
1036
1036
|
}
|
|
1037
1037
|
if (typeof item.id !== 'number' || !Number.isInteger(item.id) || item.id <= 0) {
|
|
1038
1038
|
throwBodyValidationFailure(
|
|
1039
|
-
'access-rule user_scope[].id must be numeric
|
|
1039
|
+
'access-rule user_scope[].id must be numeric arcubaseUserId, department ID, or actor ID',
|
|
1040
1040
|
requestType,
|
|
1041
1041
|
`${pathPrefix}.${index}.id`,
|
|
1042
1042
|
scope,
|
|
@@ -1266,7 +1266,7 @@ function validateActionSpecificBody(
|
|
|
1266
1266
|
}
|
|
1267
1267
|
if (typeof item.id !== 'number' || !Number.isInteger(item.id) || item.id <= 0) {
|
|
1268
1268
|
throwBodyValidationFailure(
|
|
1269
|
-
'access-rule assign-users requires body.options.user_scope[].id to be numeric
|
|
1269
|
+
'access-rule assign-users requires body.options.user_scope[].id to be numeric arcubaseUserId',
|
|
1270
1270
|
command.requestType,
|
|
1271
1271
|
`body.options.user_scope.${index}.id`,
|
|
1272
1272
|
scope,
|
|
@@ -2110,14 +2110,14 @@ export async function executeCLI(scope: CommandScope, argv: string[], env?: Runt
|
|
|
2110
2110
|
const hasUserScopeIDIssue = parsedBody.error.issues.some((issue) => issue.path.join('.') === 'options.user_scope.0.id' || issue.path.join('.').startsWith('options.user_scope.'))
|
|
2111
2111
|
throw new CLIError(
|
|
2112
2112
|
'BODY_VALIDATION_FAILED',
|
|
2113
|
-
hasUserScopeIDIssue ? 'access-rule assign-users requires body.options.user_scope[].id to be numeric
|
|
2113
|
+
hasUserScopeIDIssue ? 'access-rule assign-users requires body.options.user_scope[].id to be numeric arcubaseUserId' : message,
|
|
2114
2114
|
2,
|
|
2115
2115
|
buildAssignUsersValidationDetails(
|
|
2116
2116
|
scope,
|
|
2117
2117
|
command,
|
|
2118
2118
|
command.requestType,
|
|
2119
2119
|
hasUserScopeIDIssue ? 'body.options.user_scope' : 'body',
|
|
2120
|
-
hasUserScopeIDIssue ? 'access-rule assign-users requires body.options.user_scope[].id to be numeric
|
|
2120
|
+
hasUserScopeIDIssue ? 'access-rule assign-users requires body.options.user_scope[].id to be numeric arcubaseUserId' : message,
|
|
2121
2121
|
runtimeEnv,
|
|
2122
2122
|
)
|
|
2123
2123
|
)
|
|
@@ -61,8 +61,8 @@ function assertAssignUsersGuidance(error: unknown, messagePattern?: RegExp): boo
|
|
|
61
61
|
assert.deepEqual(error.details?.commonMistakes, [
|
|
62
62
|
'do not use user_scope at top level',
|
|
63
63
|
'do not use users or allowedUsers',
|
|
64
|
-
'do not use
|
|
65
|
-
'id must be numeric
|
|
64
|
+
'do not use non-numeric arcubaseUserId as id',
|
|
65
|
+
'id must be the numeric arcubaseUserId',
|
|
66
66
|
])
|
|
67
67
|
assert.ok(error.details?.tsHints?.some((item) => item.symbol === 'AppIngressUpdateReqVO' && item.file === '/runtime/arcubase-sdk/types/ingress.ts'))
|
|
68
68
|
assert.ok(error.details?.tsHints?.some((item) => item.symbol === 'EntityIngressOptions' && item.file === '/runtime/arcubase-sdk/types/ingress.ts'))
|
|
@@ -229,7 +229,7 @@ test('app create-from-bundle-url rejects unsupported url scheme before request',
|
|
|
229
229
|
test('app watch-import-task polls until finished', async () => {
|
|
230
230
|
const statuses = [
|
|
231
231
|
{ data: { task_id: 'task-1', status: 'processing' } },
|
|
232
|
-
{ data: { task_id: 'task-1', status: 'finished', app_id: 2188889999 } },
|
|
232
|
+
{ data: { task_id: 'task-1', status: 'finished', app_id: 2188889999, name: '企业基础业务数据应用' } },
|
|
233
233
|
]
|
|
234
234
|
const calls: string[] = []
|
|
235
235
|
const out = await executeCLI(
|
|
@@ -243,6 +243,7 @@ test('app watch-import-task polls until finished', async () => {
|
|
|
243
243
|
)
|
|
244
244
|
assert.equal(calls.length, 2)
|
|
245
245
|
assert.equal((out as any).data.data.status, 'finished')
|
|
246
|
+
assert.equal((out as any).data.data.name, '企业基础业务数据应用')
|
|
246
247
|
})
|
|
247
248
|
|
|
248
249
|
test('app watch-import-task rejects finished status without app id', async () => {
|
|
@@ -1328,7 +1329,7 @@ test('access-rule assign-users rejects non-user member scope type', async () =>
|
|
|
1328
1329
|
}, (error: unknown) => assertAssignUsersGuidance(error, /type.*user/))
|
|
1329
1330
|
})
|
|
1330
1331
|
|
|
1331
|
-
test('access-rule assign-users rejects
|
|
1332
|
+
test('access-rule assign-users rejects non-numeric arcubaseUserId', async () => {
|
|
1332
1333
|
await assert.rejects(async () => {
|
|
1333
1334
|
await executeCLI(
|
|
1334
1335
|
'admin',
|
|
@@ -1336,7 +1337,7 @@ test('access-rule assign-users rejects hash tenant user id', async () => {
|
|
|
1336
1337
|
env as any,
|
|
1337
1338
|
async () => new Response('{}', { status: 200 }),
|
|
1338
1339
|
)
|
|
1339
|
-
}, (error: unknown) => assertAssignUsersGuidance(error, /numeric
|
|
1340
|
+
}, (error: unknown) => assertAssignUsersGuidance(error, /numeric arcubaseUserId/))
|
|
1340
1341
|
})
|
|
1341
1342
|
|
|
1342
1343
|
test('access-rule assign-users accepts canonical user_scope body', async () => {
|
package/src/tests/help.test.ts
CHANGED
|
@@ -121,11 +121,24 @@ test('admin access-rule help gives update whitelist and assign-users body-json e
|
|
|
121
121
|
assert.equal(assign.kind, 'help')
|
|
122
122
|
assert.match(assign.text, /"update":\["user_scope"\]/)
|
|
123
123
|
assert.match(assign.text, /\{"update":\["user_scope"\],"options":\{"user_scope":\[\{"type":"user","id":2188889901\}\]\}\}/)
|
|
124
|
+
assert.match(assign.text, /arcubaseUserId/)
|
|
125
|
+
assert.doesNotMatch(assign.text, forbiddenArcubaseUserTerms())
|
|
124
126
|
assert.doesNotMatch(assign.text, /"type":"member"/)
|
|
125
127
|
assert.doesNotMatch(assign.text, /"users"/)
|
|
126
128
|
assert.doesNotMatch(assign.text, /"allowedUsers"/)
|
|
127
129
|
})
|
|
128
130
|
|
|
131
|
+
test('admin assign-users help uses arcubaseUserId terminology', async () => {
|
|
132
|
+
const help = await executeCLI('admin', ['access-rule', 'assign-users', '--help'], env as any, async () => new Response('{}'))
|
|
133
|
+
assert.equal(help.kind, 'help')
|
|
134
|
+
assert.doesNotMatch(help.text, forbiddenArcubaseUserTerms())
|
|
135
|
+
assert.match(help.text, /arcubaseUserId/)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
function forbiddenArcubaseUserTerms(): RegExp {
|
|
139
|
+
return new RegExp(['tenant' + 'UserId', 'TenantUser' + String.raw`\.ID`, 'tenant user' + ' id'].join('|'), 'i')
|
|
140
|
+
}
|
|
141
|
+
|
|
129
142
|
test('every body command help exposes readable TypeScript type paths', async () => {
|
|
130
143
|
for (const scope of ['admin', 'user'] as const satisfies readonly CommandScope[]) {
|
|
131
144
|
for (const command of listCommands(scope).filter((item) => item.requestType)) {
|