openyida 2026.7.18 → 2026.7.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -2
- package/bin/yida.js +113 -18
- package/docs/capabilities.md +202 -0
- package/lib/agent-center/agent-center.js +2 -3
- package/lib/app/app-list.js +3 -4
- package/lib/app/build-page.js +13 -6
- package/lib/app/check-page.js +16 -6
- package/lib/app/compile.js +17 -7
- package/lib/app/create-app.js +14 -2
- package/lib/app/create-form/api-path.js +25 -0
- package/lib/app/create-form/args.js +13 -0
- package/lib/app/create-form/commands.js +4 -0
- package/lib/app/create-form/definition-reader.js +23 -23
- package/lib/app/create-form/field-normalizers.js +26 -7
- package/lib/app/create-form/schema-patch.js +4 -1
- package/lib/app/create-form.js +155 -68
- package/lib/app/create-page.js +47 -10
- package/lib/app/generate-page.js +20 -1
- package/lib/app/get-form-config.js +2 -1
- package/lib/app/get-schema.js +67 -15
- package/lib/app/import-app.js +94 -42
- package/lib/app/list-forms.js +4 -8
- package/lib/app/page-ir.js +140 -0
- package/lib/app/publish.js +289 -556
- package/lib/app/schema-field-resolution.js +370 -0
- package/lib/app/services/app-reader.js +85 -0
- package/lib/app/services/app-service.js +235 -0
- package/lib/app/services/canvas-page-compiler.js +91 -0
- package/lib/app/services/canvas-page-schema-builder.js +149 -0
- package/lib/app/services/field-bindings.js +68 -0
- package/lib/app/services/form-compiler.js +1922 -0
- package/lib/app/services/form-mode-service.js +182 -0
- package/lib/app/services/form-schema-patcher.js +333 -0
- package/lib/app/services/form-schema-reader.js +59 -0
- package/lib/app/services/form-service.js +379 -0
- package/lib/app/services/form-validation.js +562 -0
- package/lib/app/services/native-page-compiler.js +92 -0
- package/lib/app/services/native-page-schema-builder.js +428 -0
- package/lib/app/services/page-resource-service.js +185 -0
- package/lib/app/update-app.js +22 -9
- package/lib/app/update-form-config.js +4 -2
- package/lib/asset/asset-cmd.js +19 -6
- package/lib/auth/oauth-loopback.js +376 -15
- package/lib/auth/token-auth.js +34 -3
- package/lib/auth/token-store.js +22 -4
- package/lib/basic-info/basic-info.js +2 -1
- package/lib/bridge/bridge.js +43 -18
- package/lib/core/agent-capabilities.js +5 -3
- package/lib/core/command-errors.js +38 -0
- package/lib/core/command-manifest.js +59 -1
- package/lib/core/copy.js +12 -0
- package/lib/core/doctor.js +15 -4
- package/lib/core/env-cmd.js +1 -1
- package/lib/core/env.js +7 -6
- package/lib/core/i18n.js +66 -8
- package/lib/core/legacy-schema-guard.js +408 -0
- package/lib/core/locales/en.js +38 -46
- package/lib/core/locales/zh.js +30 -46
- package/lib/core/sample.js +12 -2
- package/lib/core/utils.js +334 -66
- package/lib/core/yida-client.js +108 -5
- package/lib/corp-efficiency/corp-efficiency.js +2 -2
- package/lib/corp-manager/corp-manager.js +3 -3
- package/lib/formula/evaluate.js +11 -68
- package/lib/formula/field-refs.js +83 -0
- package/lib/i18n-management/i18n-management.js +2 -3
- package/lib/process/configure-process.js +44 -1992
- package/lib/process/create-process.js +54 -87
- package/lib/process/preview-process.js +20 -8
- package/lib/process/services/process-compiler.js +2056 -0
- package/lib/process/services/process-reader.js +232 -0
- package/lib/process/services/process-resource-service.js +571 -0
- package/lib/process/services/process-service.js +122 -0
- package/lib/process/services/process-stage-checkpoint.js +246 -0
- package/lib/report/append.js +7 -26
- package/lib/report/http.js +31 -5
- package/lib/report/index.js +10 -2
- package/lib/samples/yida-canvas-custom-page/business-list.canvas.jsx +63 -14
- package/lib/samples/yida-canvas-custom-page/dashboard-overview.canvas.jsx +176 -32
- package/lib/samples/yida-canvas-custom-page/dashboard-starter.canvas.jsx +5 -2
- package/lib/samples/yida-canvas-custom-page/data-management.canvas.jsx +228 -14
- package/lib/samples/yida-canvas-custom-page/portal-shell-home.canvas.jsx +2 -2
- package/lib/samples/yida-canvas-custom-page/split-pane-detail.canvas.jsx +206 -10
- package/lib/samples/yida-custom-page/data-management.oyd.jsx +14 -3
- package/lib/samples/yida-custom-page/design-tokens.js +2 -2
- package/lib/samples/yida-custom-page/detail-profile.oyd.jsx +1 -1
- package/lib/samples/yida-custom-page/portal-shell-home.oyd.jsx +7 -2
- package/lib/samples/yida-custom-page/split-pane-detail.oyd.jsx +2 -1
- package/lib/schema/adapters/app-adapter.js +210 -0
- package/lib/schema/adapters/form-adapter.js +1362 -0
- package/lib/schema/adapters/keys.js +19 -0
- package/lib/schema/adapters/page-adapter.js +566 -0
- package/lib/schema/adapters/process-adapter.js +519 -0
- package/lib/schema/applier.js +1878 -0
- package/lib/schema/apply-store.js +1083 -0
- package/lib/schema/command.js +645 -0
- package/lib/schema/dependency-graph.js +83 -0
- package/lib/schema/errors.js +481 -0
- package/lib/schema/hash.js +9 -0
- package/lib/schema/manifest-limits.js +177 -0
- package/lib/schema/manifest-loader.js +309 -0
- package/lib/schema/manifest-schema-v1.json +193 -0
- package/lib/schema/normalize-manifest.js +281 -0
- package/lib/schema/page-canvas-foundation.js +447 -0
- package/lib/schema/page-data-source-builder.js +561 -0
- package/lib/schema/page-foundation.js +556 -0
- package/lib/schema/page-source-loader.js +314 -0
- package/lib/schema/planner.js +691 -0
- package/lib/schema/remote-dispatch-boundary.js +39 -0
- package/lib/schema/remote-missing.js +21 -0
- package/lib/schema/remote-reader.js +189 -0
- package/lib/schema/resource-registry.js +157 -0
- package/lib/schema/server-revision.js +71 -0
- package/lib/schema/sort.js +28 -0
- package/lib/schema/state-store.js +589 -0
- package/package.json +10 -8
- package/scripts/check-release-risks.js +254 -0
- package/scripts/generate-command-docs.js +6 -1
- package/scripts/i18n-baseline.json +11 -11
- package/scripts/postinstall.js +8 -12
- package/scripts/validate-ci.sh +15 -11
- package/scripts/validate-i18n.js +30 -9
- package/scripts/validate-package-size.js +5 -2
- package/scripts/validate-skills.js +4 -0
- package/scripts/validate-structure.js +15 -0
- package/yida-skills/SKILL.md +117 -30
- package/yida-skills/references/schema-as-code-phase1.md +99 -0
- package/yida-skills/references/setup-and-env.md +59 -59
- package/yida-skills/references/task-retrospective.md +6 -6
- package/yida-skills/skills/yida-app/SKILL.md +78 -17
- package/yida-skills/skills/yida-canvas-custom-page/SKILL.md +18 -7
- package/yida-skills/skills/yida-canvas-custom-page/references/data-bridge-guide.md +3 -3
- package/yida-skills/skills/yida-canvas-custom-page/references/page-generation-guide.md +15 -0
- package/yida-skills/skills/yida-create-app/SKILL.md +21 -3
- package/yida-skills/skills/yida-create-form-page/SKILL.md +19 -1
- package/yida-skills/skills/yida-create-page/SKILL.md +16 -3
- package/yida-skills/skills/yida-create-process/SKILL.md +100 -4
- package/yida-skills/skills/yida-custom-page/SKILL.md +19 -4
- package/yida-skills/skills/yida-dashboard/SKILL.md +1 -1
- package/yida-skills/skills/yida-dashboard/references/pitfalls.md +1 -1
- package/yida-skills/skills/yida-get-schema/SKILL.md +49 -5
- package/yida-skills/skills/yida-i18n/SKILL.md +1 -1
- package/yida-skills/skills/yida-integration/SKILL.md +7 -1
- package/yida-skills/skills/yida-login/SKILL.md +50 -99
- package/yida-skills/skills/yida-page-config/SKILL.md +7 -1
- package/yida-skills/skills/yida-page-uiux/references/app/blueprint.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/app/navigation-patterns.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/app/role-journey.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/dashboard/app-blueprint.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/dashboard/chart-contracts.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/dashboard/component-contracts.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/dashboard/layout-patterns.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/dashboard/theme-recipes.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/detail/object-narrative.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/detail/section-patterns.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/detail/timeline-and-related.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/landing/assets-workflow.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/landing/industry-playbooks.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/landing/research-levels.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/landing/section-patterns.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/list/drawer-detail.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/list/empty-loading-error.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/list/filter-patterns.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/list/table-patterns.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/scenes/screen.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/workbench/entry-patterns.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/workbench/portal-layouts.md +0 -1
- package/yida-skills/skills/yida-page-uiux/references/workbench/task-feed.md +0 -1
- package/yida-skills/skills/yida-page-uiux/workflow/output-decision-block.md +1 -1
- package/yida-skills/skills/yida-process-rule/SKILL.md +35 -1
- package/yida-skills/skills/yida-publish-page/SKILL.md +46 -4
- package/yida-skills/skills/yida-report/SKILL.md +9 -235
- package/yida-skills/skills/yida-report/references/schema-builder-details.md +239 -0
- package/yida-skills/skills/yida-skill-evaluator/SKILL.md +170 -0
- package/yida-skills/skills-index.json +238 -54
- package/lib/core/locales/ar.js +0 -834
- package/lib/core/locales/de.js +0 -834
- package/lib/core/locales/es.js +0 -834
- package/lib/core/locales/fr.js +0 -834
- package/lib/core/locales/hi.js +0 -834
- package/lib/core/locales/ja.js +0 -1227
- package/lib/core/locales/ko.js +0 -836
- package/lib/core/locales/pt.js +0 -834
- package/lib/core/locales/vi.js +0 -834
- package/lib/core/locales/zh-HK.js +0 -1263
- package/project/pages/src/demo-birthday-game.oyd.jsx +0 -832
- package/project/pages/src/demo-chip-insight.oyd.jsx +0 -983
- package/project/pages/src/demo-compat-smoke.oyd.jsx +0 -58
- package/project/pages/src/demo-crm-batch-entry.oyd.jsx +0 -805
- package/project/pages/src/demo-crm-dashboard.oyd.jsx +0 -677
- package/project/pages/src/demo-future-vision-2026.oyd.jsx +0 -1102
- package/project/pages/src/demo-ppt.oyd.jsx +0 -1192
- package/project/pages/src/demo-salary-calculator.oyd.jsx +0 -904
- package/project/pages/src/openyida-knowledge-doc.oyd.jsx +0 -1714
- package/yida-skills/skills/large-file-write/SKILL.md +0 -93
- package/yida-skills/skills/large-file-write/references/write-patterns.md +0 -147
- package/yida-skills/skills/large-file-write/scripts/write.js +0 -157
- package/yida-skills/skills/sls-log-workbench/SKILL.md +0 -134
- package/yida-skills/skills/sls-log-workbench/references/workbench-reference.md +0 -130
- package/yida-skills/skills/sls-log-workbench/sls-query.js +0 -295
package/lib/core/yida-client.js
CHANGED
|
@@ -16,7 +16,7 @@ function buildCommonParams(auth, extra = {}) {
|
|
|
16
16
|
_api: 'nattyFetch',
|
|
17
17
|
_mock: 'false',
|
|
18
18
|
_csrf_token: auth && auth.csrfToken,
|
|
19
|
-
_locale_time_zone_offset:
|
|
19
|
+
_locale_time_zone_offset: '28800000',
|
|
20
20
|
_stamp: Date.now(),
|
|
21
21
|
...extra,
|
|
22
22
|
};
|
|
@@ -31,7 +31,9 @@ function unwrapYidaResponse(response, options = {}) {
|
|
|
31
31
|
const detail = response && (response.errorMsg || response.message);
|
|
32
32
|
throw new Error(detail || failMessage || `${action} failed`);
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
// 部分宜搭接口成功时不返回 content 字段(也可能不返回 success),
|
|
35
|
+
// 沿用项目中的兵底约定(content 缺失时回退为整个响应),避免静默返回 undefined。
|
|
36
|
+
return response.content !== undefined ? response.content : response;
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
function isUsableAuthData(authData) {
|
|
@@ -41,7 +43,9 @@ function isUsableAuthData(authData) {
|
|
|
41
43
|
if (authData.auth_mode === 'token' || authData.authMode === 'token') {
|
|
42
44
|
return true;
|
|
43
45
|
}
|
|
44
|
-
|
|
46
|
+
const cookies = Array.isArray(authData.cookies) ? authData.cookies : [];
|
|
47
|
+
const csrfToken = authData.csrf_token || authData.csrfToken || authData._csrf_token;
|
|
48
|
+
return cookies.length > 0 && typeof csrfToken === 'string' && csrfToken.length > 0;
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
function createAuthRef(authData) {
|
|
@@ -51,7 +55,7 @@ function createAuthRef(authData) {
|
|
|
51
55
|
: triggerLogin();
|
|
52
56
|
const safeAuthData = loadedAuthData || {};
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
const authRef = {
|
|
55
59
|
baseUrl: resolveBaseUrl(safeAuthData),
|
|
56
60
|
authData: safeAuthData,
|
|
57
61
|
authMode: safeAuthData.auth_mode || safeAuthData.authMode || '',
|
|
@@ -59,6 +63,12 @@ function createAuthRef(authData) {
|
|
|
59
63
|
corpId: safeAuthData.corp_id || '',
|
|
60
64
|
userId: safeAuthData.user_id || '',
|
|
61
65
|
};
|
|
66
|
+
if (Array.isArray(safeAuthData.cookies)) {
|
|
67
|
+
authRef.cookieData = safeAuthData;
|
|
68
|
+
authRef.cookies = safeAuthData.cookies;
|
|
69
|
+
authRef.csrfToken = safeAuthData.csrf_token || safeAuthData.csrfToken || safeAuthData._csrf_token || '';
|
|
70
|
+
}
|
|
71
|
+
return authRef;
|
|
62
72
|
}
|
|
63
73
|
|
|
64
74
|
function isTokenAuthRef(authRef) {
|
|
@@ -78,6 +88,22 @@ function isTokenAuthRef(authRef) {
|
|
|
78
88
|
return authMode === 'token' || authSource === 'token';
|
|
79
89
|
}
|
|
80
90
|
|
|
91
|
+
function isCookieAuthRef(authRef) {
|
|
92
|
+
if (!authRef) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
const authData = authRef.authData || authRef.cookieData || {};
|
|
96
|
+
const authMode = authRef.authMode || authRef.auth_mode || authData.auth_mode || authData.authMode;
|
|
97
|
+
const authSource = authRef.authSource || authRef.auth_source || authData.auth_source || authData.authSource;
|
|
98
|
+
return (
|
|
99
|
+
authMode === 'env' ||
|
|
100
|
+
authMode === 'cookie' ||
|
|
101
|
+
authSource === 'env' ||
|
|
102
|
+
authSource === 'cookie' ||
|
|
103
|
+
Array.isArray(authRef.cookies)
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
81
107
|
function isAuthRefReady(authRef) {
|
|
82
108
|
if (!authRef) {
|
|
83
109
|
return false;
|
|
@@ -85,7 +111,14 @@ function isAuthRefReady(authRef) {
|
|
|
85
111
|
if (isTokenAuthRef(authRef)) {
|
|
86
112
|
return true;
|
|
87
113
|
}
|
|
88
|
-
return
|
|
114
|
+
return (
|
|
115
|
+
isCookieAuthRef(authRef) &&
|
|
116
|
+
typeof authRef.baseUrl === 'string' &&
|
|
117
|
+
authRef.baseUrl.length > 0 &&
|
|
118
|
+
typeof authRef.csrfToken === 'string' &&
|
|
119
|
+
authRef.csrfToken.length > 0 &&
|
|
120
|
+
Array.isArray(authRef.cookies)
|
|
121
|
+
);
|
|
89
122
|
}
|
|
90
123
|
|
|
91
124
|
class YidaClient {
|
|
@@ -115,6 +148,20 @@ class YidaClient {
|
|
|
115
148
|
);
|
|
116
149
|
}
|
|
117
150
|
|
|
151
|
+
async getOnce(requestPath, queryParams, options) {
|
|
152
|
+
const ref = requireReadAuth(this.authRef);
|
|
153
|
+
const resolvedRequestPath = typeof requestPath === 'function'
|
|
154
|
+
? requestPath(ref)
|
|
155
|
+
: requestPath;
|
|
156
|
+
const resolvedQueryParams = typeof queryParams === 'function'
|
|
157
|
+
? queryParams(ref)
|
|
158
|
+
: queryParams;
|
|
159
|
+
if (options === undefined) {
|
|
160
|
+
return httpGet(ref.baseUrl, resolvedRequestPath, resolvedQueryParams || null, ref.cookies);
|
|
161
|
+
}
|
|
162
|
+
return httpGet(ref.baseUrl, resolvedRequestPath, resolvedQueryParams || null, ref.cookies, options);
|
|
163
|
+
}
|
|
164
|
+
|
|
118
165
|
async postForm(requestPath, bodyParams, options) {
|
|
119
166
|
return requestWithAutoLogin(
|
|
120
167
|
(ref) => {
|
|
@@ -136,6 +183,23 @@ class YidaClient {
|
|
|
136
183
|
);
|
|
137
184
|
}
|
|
138
185
|
|
|
186
|
+
async postFormOnce(requestPath, bodyParams, options) {
|
|
187
|
+
const ref = requireOneShotAuth(this.authRef);
|
|
188
|
+
const resolvedRequestPath = typeof requestPath === 'function'
|
|
189
|
+
? requestPath(ref)
|
|
190
|
+
: requestPath;
|
|
191
|
+
const resolvedBodyParams = typeof bodyParams === 'function'
|
|
192
|
+
? bodyParams(ref)
|
|
193
|
+
: bodyParams;
|
|
194
|
+
const postData = typeof resolvedBodyParams === 'string'
|
|
195
|
+
? resolvedBodyParams
|
|
196
|
+
: querystring.stringify(resolvedBodyParams || {});
|
|
197
|
+
if (options === undefined) {
|
|
198
|
+
return httpPost(ref.baseUrl, resolvedRequestPath, postData, ref.cookies);
|
|
199
|
+
}
|
|
200
|
+
return httpPost(ref.baseUrl, resolvedRequestPath, postData, ref.cookies, options);
|
|
201
|
+
}
|
|
202
|
+
|
|
139
203
|
async postJson(requestPath, bodyParams, options) {
|
|
140
204
|
return requestWithAutoLogin(
|
|
141
205
|
(ref) => {
|
|
@@ -176,6 +240,44 @@ class YidaClient {
|
|
|
176
240
|
}
|
|
177
241
|
}
|
|
178
242
|
|
|
243
|
+
function requireOneShotAuth(authRef) {
|
|
244
|
+
if (!authRef || typeof authRef.baseUrl !== 'string' || authRef.baseUrl.length === 0) {
|
|
245
|
+
const error = new Error('Schema write authentication is not ready.');
|
|
246
|
+
error.code = 'YIDA_WRITE_AUTH_NOT_READY';
|
|
247
|
+
throw error;
|
|
248
|
+
}
|
|
249
|
+
if (isTokenAuthRef(authRef)) {
|
|
250
|
+
return authRef;
|
|
251
|
+
}
|
|
252
|
+
if (
|
|
253
|
+
typeof authRef.csrfToken !== 'string' ||
|
|
254
|
+
authRef.csrfToken.length === 0 ||
|
|
255
|
+
!Array.isArray(authRef.cookies)
|
|
256
|
+
) {
|
|
257
|
+
const error = new Error('Schema write authentication is not ready.');
|
|
258
|
+
error.code = 'YIDA_WRITE_AUTH_NOT_READY';
|
|
259
|
+
throw error;
|
|
260
|
+
}
|
|
261
|
+
return authRef;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function requireReadAuth(authRef) {
|
|
265
|
+
if (!authRef || typeof authRef.baseUrl !== 'string' || authRef.baseUrl.length === 0) {
|
|
266
|
+
const error = new Error('Yida read authentication is not ready.');
|
|
267
|
+
error.code = 'YIDA_READ_AUTH_NOT_READY';
|
|
268
|
+
throw error;
|
|
269
|
+
}
|
|
270
|
+
if (isTokenAuthRef(authRef)) {
|
|
271
|
+
return authRef;
|
|
272
|
+
}
|
|
273
|
+
if (!Array.isArray(authRef.cookies)) {
|
|
274
|
+
const error = new Error('Yida read authentication is not ready.');
|
|
275
|
+
error.code = 'YIDA_READ_AUTH_NOT_READY';
|
|
276
|
+
throw error;
|
|
277
|
+
}
|
|
278
|
+
return authRef;
|
|
279
|
+
}
|
|
280
|
+
|
|
179
281
|
function createYidaClient(options = {}) {
|
|
180
282
|
return new YidaClient(options);
|
|
181
283
|
}
|
|
@@ -186,6 +288,7 @@ module.exports = {
|
|
|
186
288
|
createAuthRef,
|
|
187
289
|
createYidaClient,
|
|
188
290
|
isAuthRefReady,
|
|
291
|
+
isCookieAuthRef,
|
|
189
292
|
isTokenAuthRef,
|
|
190
293
|
unwrapYidaResponse,
|
|
191
294
|
};
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
const { createAuthRef: createCoreAuthRef, createYidaClient, isAuthRefReady } = require('../core/yida-client');
|
|
17
17
|
const { c, success, listItem } = require('../core/chalk');
|
|
18
18
|
const { parseOpenOption, withBrowserHandoff } = require('../core/browser-handoff');
|
|
19
|
+
const { throwCommandError } = require('../core/command-errors');
|
|
19
20
|
|
|
20
21
|
const API = {
|
|
21
22
|
corpInfoManageCard: '/query/corpadmin/getCorpInfoManageCard.json',
|
|
@@ -619,8 +620,7 @@ async function run(args = []) {
|
|
|
619
620
|
throw new Error(`未知的 corp-efficiency 子命令: ${subCommand}`);
|
|
620
621
|
}
|
|
621
622
|
} catch (err) {
|
|
622
|
-
|
|
623
|
-
process.exit(1);
|
|
623
|
+
throwCommandError(`企业效能命令失败:${err.message}`);
|
|
624
624
|
}
|
|
625
625
|
}
|
|
626
626
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const { throwUsage } = require('../core/command-errors');
|
|
4
|
+
|
|
3
5
|
const {
|
|
4
6
|
buildSubAdminConfig,
|
|
5
7
|
listAdmins,
|
|
@@ -27,9 +29,7 @@ Examples:
|
|
|
27
29
|
`;
|
|
28
30
|
|
|
29
31
|
function fail(message) {
|
|
30
|
-
|
|
31
|
-
console.error(USAGE);
|
|
32
|
-
process.exit(1);
|
|
32
|
+
throwUsage(message, USAGE);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
function parseCliOptions(tokens) {
|
package/lib/formula/evaluate.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
|
+
const { throwCommandError, throwUsage } = require('../core/command-errors');
|
|
4
5
|
const path = require('path');
|
|
6
|
+
const {
|
|
7
|
+
normalizeFormulaFieldRefs,
|
|
8
|
+
normalizeSubtableFieldId,
|
|
9
|
+
stripSubtableFieldPrefix,
|
|
10
|
+
} = require('./field-refs');
|
|
5
11
|
|
|
6
12
|
const KNOWN_FUNCTIONS = new Set([
|
|
7
13
|
'ABS',
|
|
@@ -48,12 +54,6 @@ const KNOWN_FUNCTIONS = new Set([
|
|
|
48
54
|
'YEAR',
|
|
49
55
|
]);
|
|
50
56
|
|
|
51
|
-
// Subtable child fields are stored flat in the schema (get-schema / save never
|
|
52
|
-
// emit a "tableField_xxx.xxx" form), and Yida formulas reference them by their
|
|
53
|
-
// plain fieldId. A "tableField_xxx." prefix inside #{...} is therefore always
|
|
54
|
-
// an invalid reference that the web platform cannot resolve.
|
|
55
|
-
const SUBTABLE_FIELD_PREFIX_PATTERN = /^tableField_[A-Za-z0-9]+\./;
|
|
56
|
-
|
|
57
57
|
const CHINESE_PUNCTUATION = {
|
|
58
58
|
',': ',',
|
|
59
59
|
';': ',',
|
|
@@ -163,64 +163,6 @@ function collectSchemaFieldIds(value) {
|
|
|
163
163
|
return fieldIds;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
// Rewrite every `#{tableField_xxx.field}` reference inside a string to the
|
|
167
|
-
// canonical `#{field}` form. Returns the corrected string plus how many refs
|
|
168
|
-
// were fixed. Only the exact `#{tableField_<alnum>.<rest>}` shape is touched,
|
|
169
|
-
// so unrelated text (e.g. a JS regex like `#{1,3}`) is left untouched.
|
|
170
|
-
function stripSubtableFieldPrefix(str) {
|
|
171
|
-
if (typeof str !== 'string' || str.indexOf('#{') === -1) {
|
|
172
|
-
return { value: str, count: 0 };
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
let count = 0;
|
|
176
|
-
const value = str.replace(/#\{([^}]*)\}/g, (whole, inner) => {
|
|
177
|
-
const trimmed = inner.trim();
|
|
178
|
-
if (SUBTABLE_FIELD_PREFIX_PATTERN.test(trimmed)) {
|
|
179
|
-
count += 1;
|
|
180
|
-
return `#{${trimmed.replace(SUBTABLE_FIELD_PREFIX_PATTERN, '')}}`;
|
|
181
|
-
}
|
|
182
|
-
return whole;
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
return { value, count };
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Recursively walk any schema node (object/array) and normalize subtable
|
|
189
|
-
// prefixes in every string value in place. Returns the total number of refs
|
|
190
|
-
// fixed. Covers formula, complexValue.formula, expression, linkage, and any
|
|
191
|
-
// other string-valued property uniformly.
|
|
192
|
-
function normalizeFormulaFieldRefs(node) {
|
|
193
|
-
let total = 0;
|
|
194
|
-
|
|
195
|
-
function visit(parent, key) {
|
|
196
|
-
const current = parent[key];
|
|
197
|
-
if (typeof current === 'string') {
|
|
198
|
-
const { value, count } = stripSubtableFieldPrefix(current);
|
|
199
|
-
if (count > 0) {
|
|
200
|
-
parent[key] = value;
|
|
201
|
-
total += count;
|
|
202
|
-
}
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
if (Array.isArray(current)) {
|
|
206
|
-
for (let i = 0; i < current.length; i++) {
|
|
207
|
-
visit(current, i);
|
|
208
|
-
}
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
if (current && typeof current === 'object') {
|
|
212
|
-
for (const childKey of Object.keys(current)) {
|
|
213
|
-
visit(current, childKey);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (node && typeof node === 'object') {
|
|
219
|
-
visit({ root: node }, 'root');
|
|
220
|
-
}
|
|
221
|
-
return total;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
166
|
function scanOutsideStrings(formula, callback) {
|
|
225
167
|
let quote = '';
|
|
226
168
|
let escaped = false;
|
|
@@ -354,8 +296,9 @@ function collectFieldRefs(formula, diagnostics) {
|
|
|
354
296
|
{ fieldId, index }
|
|
355
297
|
));
|
|
356
298
|
}
|
|
357
|
-
|
|
358
|
-
|
|
299
|
+
const normalizedFieldId = normalizeSubtableFieldId(fieldId);
|
|
300
|
+
if (normalizedFieldId.changed) {
|
|
301
|
+
const suggestion = normalizedFieldId.value;
|
|
359
302
|
diagnostics.push(createDiagnostic(
|
|
360
303
|
'error',
|
|
361
304
|
'field_ref_subtable_prefix',
|
|
@@ -646,7 +589,7 @@ async function run(args) {
|
|
|
646
589
|
if (parsed.help || !parsed.formulaInput) {
|
|
647
590
|
console.log(usage());
|
|
648
591
|
if (!parsed.help) {
|
|
649
|
-
|
|
592
|
+
throwUsage('Missing formula input', usage());
|
|
650
593
|
}
|
|
651
594
|
return;
|
|
652
595
|
}
|
|
@@ -662,7 +605,7 @@ async function run(args) {
|
|
|
662
605
|
}
|
|
663
606
|
|
|
664
607
|
if (parsed.strict && !result.ok) {
|
|
665
|
-
|
|
608
|
+
throwCommandError('Formula validation failed', { code: 'CLI_FORMULA_INVALID' });
|
|
666
609
|
}
|
|
667
610
|
}
|
|
668
611
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Subtable child fields are stored flat in the schema (get-schema / save never
|
|
4
|
+
// emit a "tableField_xxx.xxx" form), and Yida formulas reference them by their
|
|
5
|
+
// plain fieldId. A "tableField_xxx." prefix inside #{...} is therefore always
|
|
6
|
+
// an invalid reference that the web platform cannot resolve.
|
|
7
|
+
const SUBTABLE_FIELD_PREFIX_PATTERN = /^tableField_[A-Za-z0-9]+\./;
|
|
8
|
+
|
|
9
|
+
function normalizeSubtableFieldId(fieldId) {
|
|
10
|
+
const value = String(fieldId || '');
|
|
11
|
+
if (!SUBTABLE_FIELD_PREFIX_PATTERN.test(value)) {
|
|
12
|
+
return { value, changed: false };
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
value: value.replace(SUBTABLE_FIELD_PREFIX_PATTERN, ''),
|
|
16
|
+
changed: true,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Rewrite every `#{tableField_xxx.field}` reference inside a string to the
|
|
21
|
+
// canonical `#{field}` form. Returns the corrected string plus how many refs
|
|
22
|
+
// were fixed. Only the exact `#{tableField_<alnum>.<rest>}` shape is touched,
|
|
23
|
+
// so unrelated text (e.g. a JS regex like `#{1,3}`) is left untouched.
|
|
24
|
+
function stripSubtableFieldPrefix(str) {
|
|
25
|
+
if (typeof str !== 'string' || str.indexOf('#{') === -1) {
|
|
26
|
+
return { value: str, count: 0 };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let count = 0;
|
|
30
|
+
const value = str.replace(/#\{([^}]*)\}/g, (whole, inner) => {
|
|
31
|
+
const trimmed = inner.trim();
|
|
32
|
+
const normalized = normalizeSubtableFieldId(trimmed);
|
|
33
|
+
if (normalized.changed) {
|
|
34
|
+
count += 1;
|
|
35
|
+
return `#{${normalized.value}}`;
|
|
36
|
+
}
|
|
37
|
+
return whole;
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
return { value, count };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Recursively walk any schema node (object/array) and normalize subtable
|
|
44
|
+
// prefixes in every string value in place. Returns the total number of refs
|
|
45
|
+
// fixed. Covers formula, complexValue.formula, expression, linkage, and any
|
|
46
|
+
// other string-valued property uniformly.
|
|
47
|
+
function normalizeFormulaFieldRefs(node) {
|
|
48
|
+
let total = 0;
|
|
49
|
+
|
|
50
|
+
function visit(parent, key) {
|
|
51
|
+
const current = parent[key];
|
|
52
|
+
if (typeof current === 'string') {
|
|
53
|
+
const { value, count } = stripSubtableFieldPrefix(current);
|
|
54
|
+
if (count > 0) {
|
|
55
|
+
parent[key] = value;
|
|
56
|
+
total += count;
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (Array.isArray(current)) {
|
|
61
|
+
for (let i = 0; i < current.length; i++) {
|
|
62
|
+
visit(current, i);
|
|
63
|
+
}
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (current && typeof current === 'object') {
|
|
67
|
+
for (const childKey of Object.keys(current)) {
|
|
68
|
+
visit(current, childKey);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (node && typeof node === 'object') {
|
|
74
|
+
visit({ root: node }, 'root');
|
|
75
|
+
}
|
|
76
|
+
return total;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
module.exports = {
|
|
80
|
+
normalizeFormulaFieldRefs,
|
|
81
|
+
normalizeSubtableFieldId,
|
|
82
|
+
stripSubtableFieldPrefix,
|
|
83
|
+
};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { createAuthRef: createCoreAuthRef, createYidaClient, isAuthRefReady } = require('../core/yida-client');
|
|
4
4
|
const { normalizeYidaLocale } = require('../core/yida-i18n');
|
|
5
|
+
const { throwUsage } = require('../core/command-errors');
|
|
5
6
|
|
|
6
7
|
const SYSTEM_LANGUAGES = {
|
|
7
8
|
zh_CN: { languageTag: 'zh_CN', languageName: '简体中文', autonym: '简体中文', support: 'full' },
|
|
@@ -43,9 +44,7 @@ Examples:
|
|
|
43
44
|
`;
|
|
44
45
|
|
|
45
46
|
function fail(message) {
|
|
46
|
-
|
|
47
|
-
console.error(USAGE);
|
|
48
|
-
process.exit(1);
|
|
47
|
+
throwUsage(message, USAGE);
|
|
49
48
|
}
|
|
50
49
|
|
|
51
50
|
function printJson(payload) {
|