openxiangda 1.0.127 → 1.0.128

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.
Files changed (29) hide show
  1. package/README.md +1 -1
  2. package/lib/cli.js +319 -28
  3. package/package.json +1 -1
  4. package/packages/sdk/dist/{ProcessPreview-Kexdosgu.d.mts → ProcessPreview-B2-umzSY.d.mts} +12 -6
  5. package/packages/sdk/dist/{ProcessPreview-Kexdosgu.d.ts → ProcessPreview-B2-umzSY.d.ts} +12 -6
  6. package/packages/sdk/dist/components/index.cjs +95 -16
  7. package/packages/sdk/dist/components/index.cjs.map +1 -1
  8. package/packages/sdk/dist/components/index.d.mts +4 -3
  9. package/packages/sdk/dist/components/index.d.ts +4 -3
  10. package/packages/sdk/dist/components/index.mjs +95 -16
  11. package/packages/sdk/dist/components/index.mjs.map +1 -1
  12. package/packages/sdk/dist/runtime/index.cjs +131 -16
  13. package/packages/sdk/dist/runtime/index.cjs.map +1 -1
  14. package/packages/sdk/dist/runtime/index.d.mts +2 -2
  15. package/packages/sdk/dist/runtime/index.d.ts +2 -2
  16. package/packages/sdk/dist/runtime/index.mjs +131 -16
  17. package/packages/sdk/dist/runtime/index.mjs.map +1 -1
  18. package/packages/sdk/dist/runtime/react.cjs +34 -0
  19. package/packages/sdk/dist/runtime/react.cjs.map +1 -1
  20. package/packages/sdk/dist/runtime/react.d.mts +63 -2
  21. package/packages/sdk/dist/runtime/react.d.ts +63 -2
  22. package/packages/sdk/dist/runtime/react.mjs +34 -0
  23. package/packages/sdk/dist/runtime/react.mjs.map +1 -1
  24. package/templates/openxiangda-react-spa/src/app/navigation.ts +8 -1
  25. package/templates/openxiangda-react-spa/src/app/router.tsx +6 -0
  26. package/templates/openxiangda-react-spa/src/pages/admin/LoginLogPage.tsx +425 -0
  27. package/templates/openxiangda-react-spa/src/resources/menus/menus.json +9 -0
  28. package/templates/openxiangda-react-spa/src/resources/permissions/page-groups/app-admin.json +3 -3
  29. package/templates/openxiangda-react-spa/src/resources/roles/roles.json +6 -0
package/README.md CHANGED
@@ -44,7 +44,7 @@ openxiangda app snapshot APP_XXXX --profile dev --json
44
44
 
45
45
  User tokens are stored in `~/.openxiangda/profiles.json` with `0600` permissions. Shared workspace environment values, including `APP_OSS_*`, can live in `~/.openxiangda/.env` and are inherited by new workspaces. Project `.env` files still work and override the global defaults. Project state is stored in `.openxiangda/state.json` and contains only profile-specific resource IDs.
46
46
 
47
- React SPA workspaces publish their frontend with `openxiangda runtime deploy`. The default upload mode is staged multipart: each `dist/` file is uploaded separately, then the CLI submits a release manifest and activates it unless `--no-activate` is passed. Upload progress, timeout, and `traceId` are written to stderr; `--json` stdout remains the final JSON result. Use `--upload-timeout-ms <ms>` or `OPENXIANGDA_RUNTIME_UPLOAD_TIMEOUT_MS` to tune runtime upload/finalize timeouts. Use `--upload-mode legacy-json` only as a compatibility fallback for older platforms.
47
+ React SPA workspaces publish their frontend with `openxiangda runtime deploy`. The default upload mode is `auto`: it tries staged multipart first, then falls back to built-in OSS direct upload if the staged file API returns HTTP 403. Use `--upload-mode oss-direct` to force built-in OSS direct upload, or `--upload-mode legacy-json` only as a compatibility fallback for older platforms. Upload progress, timeout, and `traceId` are written to stderr; `--json` stdout remains the final JSON result. Use `--upload-timeout-ms <ms>` or `OPENXIANGDA_RUNTIME_UPLOAD_TIMEOUT_MS` to tune runtime upload/finalize timeouts.
48
48
 
49
49
  React SPA templates include stable Vite manual chunk grouping for React, antd, ECharts, editor dependencies, and OpenXiangda runtime/component entrypoints. The SDK keeps large UI dependencies such as `antd-mobile` and `dayjs` external so the application bundler can split them by route. Applications should import from public package entrypoints such as `openxiangda`, `openxiangda/runtime`, and `openxiangda/runtime/react`; do not import `openxiangda/packages/sdk/dist/...` internals to chase bundle size.
50
50
 
package/lib/cli.js CHANGED
@@ -3863,6 +3863,7 @@ async function runtime(args) {
3863
3863
  ' openxiangda runtime releases --profile <name>',
3864
3864
  '说明:',
3865
3865
  ' - deploy 上传当前工作区 dist/ 并激活 React SPA runtime release。',
3866
+ ' - 默认 --upload-mode auto;multipart 上传遇到 403 时自动切换到阿里 OSS 直传。',
3866
3867
  ' - 如果平台服务较旧不支持分片上传,可临时使用 --upload-mode legacy-json。',
3867
3868
  ' - runtime 只发布前端产物;表单、流程、通知等资源仍走 resource publish。',
3868
3869
  ].join('\n'));
@@ -3921,24 +3922,56 @@ async function runtime(args) {
3921
3922
  printRuntimeProgress(
3922
3923
  `runtime release upload: mode=${uploadMode} traceId=${traceId} files=${files.length} size=${formatBytes(totalBytes)} timeout=${uploadTimeoutMs}ms`
3923
3924
  );
3924
- const releaseFiles =
3925
- uploadMode === 'legacy-json'
3926
- ? files.map(file => ({
3927
- path: file.path,
3928
- size: file.size,
3929
- sha256: file.sha256,
3930
- contentType: file.contentType,
3931
- contentBase64: file.buffer.toString('base64'),
3932
- }))
3933
- : await uploadRuntimeDistFilesStaged({
3934
- config,
3935
- profileName: target.profileName,
3936
- appType: target.appType,
3937
- buildId,
3938
- files,
3939
- traceId,
3940
- timeoutMs: uploadTimeoutMs,
3941
- });
3925
+ let effectiveUploadMode = uploadMode;
3926
+ let releaseFiles;
3927
+ if (uploadMode === 'legacy-json') {
3928
+ releaseFiles = files.map(file => ({
3929
+ path: file.path,
3930
+ size: file.size,
3931
+ sha256: file.sha256,
3932
+ contentType: file.contentType,
3933
+ contentBase64: file.buffer.toString('base64'),
3934
+ }));
3935
+ } else if (uploadMode === 'oss-direct') {
3936
+ releaseFiles = await uploadRuntimeDistFilesOssDirect({
3937
+ config,
3938
+ profileName: target.profileName,
3939
+ appType: target.appType,
3940
+ buildId,
3941
+ files,
3942
+ traceId,
3943
+ timeoutMs: uploadTimeoutMs,
3944
+ });
3945
+ } else {
3946
+ try {
3947
+ releaseFiles = await uploadRuntimeDistFilesStaged({
3948
+ config,
3949
+ profileName: target.profileName,
3950
+ appType: target.appType,
3951
+ buildId,
3952
+ files,
3953
+ traceId,
3954
+ timeoutMs: uploadTimeoutMs,
3955
+ });
3956
+ } catch (error) {
3957
+ if (uploadMode !== 'auto' || !isRuntimeStagedUploadBlocked(error)) {
3958
+ throw error;
3959
+ }
3960
+ effectiveUploadMode = 'oss-direct';
3961
+ printRuntimeProgress(
3962
+ `runtime staged upload blocked by HTTP 403; fallback to OSS direct upload traceId=${traceId}`
3963
+ );
3964
+ releaseFiles = await uploadRuntimeDistFilesOssDirect({
3965
+ config,
3966
+ profileName: target.profileName,
3967
+ appType: target.appType,
3968
+ buildId,
3969
+ files,
3970
+ traceId,
3971
+ timeoutMs: uploadTimeoutMs,
3972
+ });
3973
+ }
3974
+ }
3942
3975
  const data = await requestWithAuth(
3943
3976
  config,
3944
3977
  target.profileName,
@@ -3966,7 +3999,7 @@ async function runtime(args) {
3966
3999
  totalBytes,
3967
4000
  assetBaseUrl,
3968
4001
  activated: !flags['no-activate'],
3969
- uploadMode,
4002
+ uploadMode: effectiveUploadMode,
3970
4003
  traceId,
3971
4004
  };
3972
4005
  if (flags.json) return writeJson(result);
@@ -3975,7 +4008,7 @@ async function runtime(args) {
3975
4008
  `runtime release 已上传: ${target.appType}`,
3976
4009
  `build: ${buildId}`,
3977
4010
  `files: ${files.length} (${formatBytes(totalBytes)})`,
3978
- `upload: ${uploadMode}`,
4011
+ `upload: ${effectiveUploadMode}`,
3979
4012
  `traceId: ${traceId}`,
3980
4013
  `assetBase: ${assetBaseUrl}`,
3981
4014
  `active: ${result.activated ? 'yes' : 'no'}`,
@@ -4082,6 +4115,95 @@ async function uploadRuntimeDistFilesStaged(options) {
4082
4115
  }));
4083
4116
  }
4084
4117
 
4118
+ async function uploadRuntimeDistFilesOssDirect(options) {
4119
+ const files = options.files || [];
4120
+ const plan = await requestWithAuth(
4121
+ options.config,
4122
+ options.profileName,
4123
+ `/openxiangda-api/v1/apps/${encodeURIComponent(options.appType)}/runtime/releases/oss-upload-plan`,
4124
+ {
4125
+ method: 'POST',
4126
+ timeoutMs: options.timeoutMs,
4127
+ headers: { 'x-openxiangda-trace-id': options.traceId },
4128
+ body: {
4129
+ buildId: options.buildId,
4130
+ files: files.map(file => ({
4131
+ path: file.path,
4132
+ size: file.size,
4133
+ sha256: file.sha256,
4134
+ contentType: file.contentType,
4135
+ })),
4136
+ },
4137
+ }
4138
+ );
4139
+ const uploadFiles = Array.isArray(plan?.files) ? plan.files : [];
4140
+ const uploadByPath = new Map(uploadFiles.map(file => [file.path, file]));
4141
+ let completed = 0;
4142
+ const results = await runWithConcurrency(
4143
+ files,
4144
+ RUNTIME_UPLOAD_CONCURRENCY,
4145
+ async file => {
4146
+ const uploadInfo = uploadByPath.get(file.path);
4147
+ if (!uploadInfo?.uploadUrl) {
4148
+ fail(`runtime OSS 上传计划缺少文件: ${file.path}`);
4149
+ }
4150
+ const uploaded = await uploadRuntimeDistFileToSignedUrl(options, file, uploadInfo);
4151
+ completed += 1;
4152
+ printRuntimeProgress(
4153
+ `runtime OSS file uploaded [${completed}/${files.length}] ${file.path} ${formatBytes(file.size)} traceId=${options.traceId}`
4154
+ );
4155
+ return uploaded;
4156
+ }
4157
+ );
4158
+ return results.map(file => ({
4159
+ path: file.path,
4160
+ size: file.size,
4161
+ sha256: file.sha256,
4162
+ contentType: file.contentType,
4163
+ storageProvider: 'oss',
4164
+ objectName: file.objectName,
4165
+ bucketName: file.bucketName,
4166
+ }));
4167
+ }
4168
+
4169
+ async function uploadRuntimeDistFileToSignedUrl(options, file, uploadInfo) {
4170
+ const timeoutMs = normalizeRuntimeUploadTimeoutMs(options.timeoutMs);
4171
+ const controller = new AbortController();
4172
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
4173
+ let response;
4174
+ try {
4175
+ response = await fetch(uploadInfo.uploadUrl, {
4176
+ method: String(uploadInfo.uploadMethod || 'PUT').toUpperCase(),
4177
+ headers: uploadInfo.headers || {},
4178
+ body: file.buffer,
4179
+ signal: controller.signal,
4180
+ });
4181
+ } catch (error) {
4182
+ if (isAbortError(error)) {
4183
+ throw new Error(`runtime OSS 文件上传超时: ${file.path}, timeout=${timeoutMs}ms`);
4184
+ }
4185
+ throw new Error(formatFetchError(error, `runtime OSS upload ${file.path}`));
4186
+ } finally {
4187
+ clearTimeout(timer);
4188
+ }
4189
+ if (!response.ok) {
4190
+ const text = await response.text().catch(() => '');
4191
+ throw new Error(
4192
+ `runtime OSS 文件上传失败: ${file.path}, HTTP ${response.status}: ${
4193
+ text || response.statusText || 'request failed'
4194
+ }`
4195
+ );
4196
+ }
4197
+ return {
4198
+ path: file.path,
4199
+ size: file.size,
4200
+ sha256: file.sha256,
4201
+ contentType: file.contentType,
4202
+ objectName: uploadInfo.objectName,
4203
+ bucketName: uploadInfo.bucketName,
4204
+ };
4205
+ }
4206
+
4085
4207
  async function uploadRuntimeDistFile(options, file) {
4086
4208
  const apiPath = apiPathWithQuery(
4087
4209
  `/openxiangda-api/v1/apps/${encodeURIComponent(options.appType)}/runtime/releases/files`,
@@ -4137,9 +4259,20 @@ async function runWithConcurrency(items, concurrency, worker) {
4137
4259
  }
4138
4260
 
4139
4261
  function normalizeRuntimeUploadMode(value) {
4140
- const normalized = String(value || 'staged').trim().toLowerCase();
4141
- if (normalized === 'staged' || normalized === 'legacy-json') return normalized;
4142
- fail(`--upload-mode 只支持 staged 或 legacy-json,当前: ${value}`);
4262
+ const normalized = String(value || 'auto').trim().toLowerCase();
4263
+ if (
4264
+ normalized === 'auto' ||
4265
+ normalized === 'staged' ||
4266
+ normalized === 'oss-direct' ||
4267
+ normalized === 'legacy-json'
4268
+ ) {
4269
+ return normalized;
4270
+ }
4271
+ fail(`--upload-mode 只支持 auto、staged、oss-direct 或 legacy-json,当前: ${value}`);
4272
+ }
4273
+
4274
+ function isRuntimeStagedUploadBlocked(error) {
4275
+ return /^HTTP 403\b/.test(String(error?.message || ''));
4143
4276
  }
4144
4277
 
4145
4278
  function normalizeRuntimeUploadTimeoutMs(value) {
@@ -5764,7 +5897,21 @@ function validateResourceItem(kind, item, errors, warnings) {
5764
5897
  return;
5765
5898
  }
5766
5899
 
5767
- if (kind === 'roles' && !item.name) errors.push(`${label}: 缺少 name`);
5900
+ if (kind === 'roles') {
5901
+ if (!item.name) errors.push(`${label}: 缺少 name`);
5902
+ if (
5903
+ item.apiPermissionCodes !== undefined &&
5904
+ !Array.isArray(item.apiPermissionCodes)
5905
+ ) {
5906
+ errors.push(`${label}: apiPermissionCodes 必须是数组`);
5907
+ }
5908
+ if (
5909
+ item.apiPermissionMode !== undefined &&
5910
+ !['merge', 'replace'].includes(String(item.apiPermissionMode))
5911
+ ) {
5912
+ errors.push(`${label}: apiPermissionMode 只能是 merge 或 replace`);
5913
+ }
5914
+ }
5768
5915
  if (kind === 'menus' && !item.name) errors.push(`${label}: 缺少 name`);
5769
5916
  if (kind === 'workflows') {
5770
5917
  if (!item.formCode && !item.formUuid) errors.push(`${label}: 缺少 formCode 或 formUuid`);
@@ -6421,6 +6568,12 @@ async function fetchExistingResourceMaps(config, target, manifest) {
6421
6568
  })
6422
6569
  );
6423
6570
  indexByCode(maps.roles, normalizeItems(data), item => item.code);
6571
+ await hydrateRoleApiPermissions(
6572
+ config,
6573
+ target,
6574
+ maps.roles,
6575
+ manifest.roles || []
6576
+ );
6424
6577
  }
6425
6578
  if ((manifest.menus || []).length > 0) {
6426
6579
  const data = await requestWithAuth(
@@ -6640,6 +6793,118 @@ async function fetchExistingResourceMaps(config, target, manifest) {
6640
6793
  return maps;
6641
6794
  }
6642
6795
 
6796
+ function roleDeclaresApiPermissions(role) {
6797
+ if (!Array.isArray(role?.apiPermissionCodes)) return false;
6798
+ if (normalizePermissionCodeArray(role.apiPermissionCodes).length > 0) {
6799
+ return true;
6800
+ }
6801
+ return String(role?.apiPermissionMode || '').trim().toLowerCase() === 'replace';
6802
+ }
6803
+
6804
+ function normalizeApiPermissionMode(role) {
6805
+ const mode = String(role?.apiPermissionMode || 'merge').trim().toLowerCase();
6806
+ if (mode === 'merge' || mode === 'replace') return mode;
6807
+ fail(`${resourceLabel('role', role)}: apiPermissionMode 只能是 merge 或 replace`);
6808
+ }
6809
+
6810
+ function sameStringSet(left, right) {
6811
+ const a = normalizePermissionCodeArray(left);
6812
+ const b = normalizePermissionCodeArray(right);
6813
+ if (a.length !== b.length) return false;
6814
+ const bSet = new Set(b);
6815
+ return a.every(item => bSet.has(item));
6816
+ }
6817
+
6818
+ function isSubsetStringSet(subset, source) {
6819
+ const sourceSet = new Set(normalizePermissionCodeArray(source));
6820
+ return normalizePermissionCodeArray(subset).every(item => sourceSet.has(item));
6821
+ }
6822
+
6823
+ function normalizeApiPermissionRecords(data) {
6824
+ return flattenItems(normalizeItems(data)).filter(item => item?.code);
6825
+ }
6826
+
6827
+ async function fetchRoleApiPermissions(config, target, roleId) {
6828
+ if (!roleId) return [];
6829
+ const data = await requestWithAuth(
6830
+ config,
6831
+ target.profileName,
6832
+ `/permission/api/role/${encodeURIComponent(roleId)}`
6833
+ );
6834
+ return normalizeApiPermissionRecords(data);
6835
+ }
6836
+
6837
+ async function hydrateRoleApiPermissions(config, target, roleMap, desiredRoles) {
6838
+ const roles = (desiredRoles || []).filter(roleDeclaresApiPermissions);
6839
+ if (roles.length === 0) return;
6840
+ for (const role of roles) {
6841
+ const code = role.code || role.resourceCode;
6842
+ const existing = roleMap.get(code);
6843
+ if (!existing?.id) continue;
6844
+ const permissions = await fetchRoleApiPermissions(config, target, existing.id);
6845
+ roleMap.set(code, {
6846
+ ...existing,
6847
+ apiPermissionCodes: normalizePermissionCodeArray(
6848
+ permissions.map(item => item.code)
6849
+ ),
6850
+ });
6851
+ }
6852
+ }
6853
+
6854
+ async function fetchAppApiPermissionMap(config, target) {
6855
+ const data = await requestWithAuth(
6856
+ config,
6857
+ target.profileName,
6858
+ apiPathWithQuery('/permission/api', {
6859
+ scope: 'app',
6860
+ appType: target.appType,
6861
+ page: 1,
6862
+ limit: 1000,
6863
+ })
6864
+ );
6865
+ const map = new Map();
6866
+ for (const item of normalizeApiPermissionRecords(data)) {
6867
+ map.set(String(item.code), item);
6868
+ }
6869
+ return map;
6870
+ }
6871
+
6872
+ async function syncRoleApiPermissions(config, target, role, roleId) {
6873
+ if (!roleDeclaresApiPermissions(role) || !roleId) return null;
6874
+ const desiredCodes = normalizePermissionCodeArray(role.apiPermissionCodes);
6875
+ const mode = normalizeApiPermissionMode(role);
6876
+ const currentPermissions = await fetchRoleApiPermissions(config, target, roleId);
6877
+ const currentCodes = normalizePermissionCodeArray(
6878
+ currentPermissions.map(item => item.code)
6879
+ );
6880
+ const nextCodes =
6881
+ mode === 'replace' ? desiredCodes : unique([...currentCodes, ...desiredCodes]);
6882
+ if (sameStringSet(currentCodes, nextCodes)) {
6883
+ return { action: 'noop', mode, codes: desiredCodes };
6884
+ }
6885
+
6886
+ const permissionMap = await fetchAppApiPermissionMap(config, target);
6887
+ const currentByCode = new Map(
6888
+ currentPermissions.map(item => [String(item.code), item])
6889
+ );
6890
+ const permissionIds = nextCodes.map(code => {
6891
+ const permission = currentByCode.get(code) || permissionMap.get(code);
6892
+ if (!permission?.id) {
6893
+ fail(
6894
+ `${resourceLabel('role', role)}: 未找到接口权限点 ${code},请确认平台已 seed 该权限`
6895
+ );
6896
+ }
6897
+ return permission.id;
6898
+ });
6899
+
6900
+ await requestWithAuth(config, target.profileName, '/permission/api/assign', {
6901
+ method: 'POST',
6902
+ body: { roleId, permissionIds },
6903
+ });
6904
+
6905
+ return { action: 'update', mode, codes: desiredCodes };
6906
+ }
6907
+
6643
6908
  function addPlanActions(actions, kind, desiredItems = [], existingMap, equals) {
6644
6909
  for (const item of desiredItems) {
6645
6910
  const code = item.code || item.resourceCode || item.methodName;
@@ -6821,7 +7086,19 @@ async function publishRoleResources(config, target, roles, result, options = {})
6821
7086
  { method: 'POST', body: { userIds: role.userIds } }
6822
7087
  );
6823
7088
  }
6824
- result.published.push({ kind: 'role', code: role.code, action: existing ? 'update' : 'create', id: data?.id });
7089
+ const apiPermissions = await syncRoleApiPermissions(
7090
+ config,
7091
+ target,
7092
+ role,
7093
+ data?.id
7094
+ );
7095
+ result.published.push({
7096
+ kind: 'role',
7097
+ code: role.code,
7098
+ action: existing ? 'update' : 'create',
7099
+ id: data?.id,
7100
+ ...(apiPermissions ? { apiPermissions } : {}),
7101
+ });
6825
7102
  }
6826
7103
  }
6827
7104
 
@@ -8124,10 +8401,17 @@ async function pullResources(config, target) {
8124
8401
  );
8125
8402
  for (const role of normalizeItems(roles)) {
8126
8403
  const filePath = path.join(baseDir, 'roles', `${role.code}.json`);
8404
+ const apiPermissions = role.id
8405
+ ? await fetchRoleApiPermissions(config, target, role.id)
8406
+ : [];
8407
+ const apiPermissionCodes = normalizePermissionCodeArray(
8408
+ apiPermissions.map(item => item.code)
8409
+ );
8127
8410
  writeResourceJsonFile(filePath, {
8128
8411
  code: role.code,
8129
8412
  name: role.name,
8130
8413
  description: role.description || '',
8414
+ ...(apiPermissionCodes.length > 0 ? { apiPermissionCodes } : {}),
8131
8415
  });
8132
8416
  written.push(path.relative(process.cwd(), filePath));
8133
8417
  }
@@ -9313,10 +9597,17 @@ function withoutResourceMeta(value) {
9313
9597
  }
9314
9598
 
9315
9599
  function roleEquals(desired, existing) {
9316
- return (
9600
+ const metadataEquals =
9317
9601
  String(existing.name || '') === String(desired.name || desired.code || '') &&
9318
- String(existing.description || '') === String(desired.description || '')
9319
- );
9602
+ String(existing.description || '') === String(desired.description || '');
9603
+ if (!metadataEquals) return false;
9604
+ if (!roleDeclaresApiPermissions(desired)) return true;
9605
+
9606
+ const desiredCodes = normalizePermissionCodeArray(desired.apiPermissionCodes);
9607
+ const existingCodes = normalizePermissionCodeArray(existing.apiPermissionCodes);
9608
+ return normalizeApiPermissionMode(desired) === 'replace'
9609
+ ? sameStringSet(desiredCodes, existingCodes)
9610
+ : isSubsetStringSet(desiredCodes, existingCodes);
9320
9611
  }
9321
9612
 
9322
9613
  function menuEquals(bound, desired, existing) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openxiangda",
3
- "version": "1.0.127",
3
+ "version": "1.0.128",
4
4
  "description": "OpenXiangda CLI, workspace build tools, runtime SDK, and form components.",
5
5
  "private": false,
6
6
  "bin": {
@@ -252,10 +252,13 @@ interface RuntimeRequestConfig {
252
252
  headers?: Record<string, string>;
253
253
  responseType?: 'json' | 'blob';
254
254
  }
255
+ type RuntimeUploadProvider = 'platform' | 'oss' | 'builtin-oss';
255
256
  interface RuntimeUploadOptions {
256
- uploadProvider?: 'platform' | 'oss';
257
+ uploadProvider?: RuntimeUploadProvider;
258
+ storageScope?: 'app' | 'platform';
257
259
  storageCode?: string;
258
260
  appType?: string;
261
+ uploadPurpose?: 'attachment' | 'image';
259
262
  imageCompression?: ImageCompressionConfig;
260
263
  }
261
264
  interface FormRuntimeApi {
@@ -297,6 +300,7 @@ interface FormEngineConfig {
297
300
  mode: FormEngineMode;
298
301
  formUuid: string;
299
302
  appType: string;
303
+ defaultUploadProvider?: RuntimeUploadProvider;
300
304
  formInstanceId?: string;
301
305
  submitBehavior?: FormSubmitBehavior;
302
306
  permissions?: {
@@ -592,6 +596,8 @@ interface AttachmentItem {
592
596
  uid?: string;
593
597
  status?: 'uploading' | 'done' | 'error';
594
598
  provider?: 'platform' | 'oss';
599
+ uploadProvider?: RuntimeUploadProvider;
600
+ storageScope?: 'app' | 'platform';
595
601
  storageCode?: string;
596
602
  appType?: string;
597
603
  objectName?: string;
@@ -642,8 +648,8 @@ interface AttachmentFieldProps extends BaseFieldProps {
642
648
  maxSize?: number;
643
649
  uploadAction?: string;
644
650
  bucketName?: string;
645
- /** 自定义上传提供方;设置为 oss 时需同时配置 storageCode。 */
646
- uploadProvider?: 'platform' | 'oss';
651
+ /** 自定义上传提供方;oss 需配置 storageCode,builtin-oss 使用平台内置 OSS。 */
652
+ uploadProvider?: RuntimeUploadProvider;
647
653
  /** src/resources/storage/<code>.json 中声明的存储 code。 */
648
654
  storageCode?: string;
649
655
  multiple?: boolean;
@@ -664,8 +670,8 @@ interface ImageFieldProps extends BaseFieldProps {
664
670
  accept?: string;
665
671
  uploadAction?: string;
666
672
  bucketName?: string;
667
- /** 自定义上传提供方;设置为 oss 时需同时配置 storageCode。 */
668
- uploadProvider?: 'platform' | 'oss';
673
+ /** 自定义上传提供方;oss 需配置 storageCode,builtin-oss 使用平台内置 OSS。 */
674
+ uploadProvider?: RuntimeUploadProvider;
669
675
  /** src/resources/storage/<code>.json 中声明的存储 code。 */
670
676
  storageCode?: string;
671
677
  multiple?: boolean;
@@ -1156,4 +1162,4 @@ interface ProcessPreviewProps {
1156
1162
  }
1157
1163
  declare const ProcessPreview: React__default.FC<ProcessPreviewProps>;
1158
1164
 
1159
- export { type FormRuntimeApiConfig as $, type AddressFieldProps as A, type BaseFieldProps as B, type CascadeDateFieldProps as C, type DataFilter as D, type DepartmentSelectFieldProps as E, type DepartmentTreeNode as F, type DigitalSignatureFieldProps as G, type DigitalSignatureValue as H, type EditorChoiceOption as I, type EditorFieldProps as J, type EditorToolbarAction as K, type FieldBehavior as L, type FieldDefinition as M, type FieldLayoutNode as N, type FieldValueSyncConfig as O, type FormAppearanceConfig as P, type FormDataDeleteParams as Q, type FormDataQueryParams as R, type FormEffect as S, type FormEffectAction as T, type FormEffectCondition as U, type FormEffectConditionOperator as V, type FormEngineConfig as W, type FormEngineMode as X, type FormInstanceData as Y, type FormLayoutNode as Z, type FormRuntimeApi as _, type AddressValue as a, type SubFormFieldProps as a$, type FormRuntimeConfig as a0, type FormSchema as a1, FormSection as a2, type FormSectionProps as a3, type FormSubmitBehavior as a4, type FormTemplateConfig as a5, type GridLayoutCell as a6, type GridLayoutNode as a7, type ImageCompressionConfig as a8, type ImageCompressionVariantConfig as a9, type ProcessNodeType as aA, ProcessPreview as aB, type ProcessPreviewProps as aC, type ProcessRoute as aD, type ProcessStatus as aE, type ProcessTask as aF, type RadioFieldProps as aG, type ResubmitParams as aH, type ReturnParams as aI, type ReturnPolicy as aJ, type ReturnableNode as aK, type ReturnableNodeResult as aL, type RuntimeDataQueryParams as aM, type RuntimeDataQueryResult as aN, type RuntimeRequestConfig as aO, type RuntimeResponse as aP, type RuntimeUploadOptions as aQ, type SaveTaskParams as aR, type SectionLayoutNode as aS, type SelectFieldProps as aT, type SerialNumberFieldProps as aU, type SignaturePoint as aV, type StandardFormPageMode as aW, type StatusMeta as aX, type StepLayoutItem as aY, type StepsLayoutNode as aZ, type SubFormColumn as a_, type ImageFieldProps as aa, type ImageVariant as ab, type InitiatorSelectCandidate as ac, type InitiatorSelectRequirement as ad, type InitiatorSelectScope as ae, type InitiatorSelectedApprovers as af, type JSONFieldProps as ag, type LayoutVisibleWhen as ah, type LinkedFormOptionConfig as ai, type LocationFieldProps as aj, type LocationValue as ak, type LowcodePageMeta as al, type LowcodePageNode as am, type LowcodePageNodeType as an, type LowcodePageSchema as ao, type MultiSelectFieldProps as ap, type NumberFieldProps as aq, type OptionItem as ar, type OptionSourceConfig as as, type OptionSourceType as at, type PeopleShortcutConfig as au, type PeopleShortcutType as av, type PreviewParams as aw, type ProcessAction as ax, type ProcessBasicInfo as ay, type ProcessDefinition as az, type ApprovalActionType as b, type TabLayoutItem as b0, type TabsLayoutNode as b1, type TaskStatus as b2, type TextAreaFieldProps as b3, type TextFieldProps as b4, type TextShortcutConfig as b5, type TextShortcutType as b6, type TransferParams as b7, type UserDisplayFormat as b8, type UserItem as b9, type UserSelectFieldProps as ba, type ValidationPreset as bb, type ValidationRule as bc, type ViewPermissionQueryParams as bd, type ViewPermissionSummary as be, type WithdrawParams as bf, type ApprovalPermission as c, ApprovalTimeline as d, type ApprovalTimelineProps as e, type ApproveParams as f, type AssociationFormConfig as g, type AssociationFormFieldProps as h, type AssociationValue as i, type AttachmentFieldProps as j, type AttachmentImageVariants as k, type AttachmentItem as l, type BaseLayoutNode as m, type CascadeSelectFieldProps as n, type ChangeRecord as o, type ChangeRecordListResponse as p, type ChangeRecordQueryParams as q, type CheckboxFieldProps as r, type DataLinkageCondition as s, type DataLinkageConfig as t, type DateFieldProps as u, type DateRangeRestriction as v, type DateRestrictionConfig as w, type DateShortcutConfig as x, type DateShortcutType as y, type DefaultValueLinkageConfig as z };
1165
+ export { type FormRuntimeApiConfig as $, type AddressFieldProps as A, type BaseFieldProps as B, type CascadeDateFieldProps as C, type DataFilter as D, type DepartmentSelectFieldProps as E, type DepartmentTreeNode as F, type DigitalSignatureFieldProps as G, type DigitalSignatureValue as H, type EditorChoiceOption as I, type EditorFieldProps as J, type EditorToolbarAction as K, type FieldBehavior as L, type FieldDefinition as M, type FieldLayoutNode as N, type FieldValueSyncConfig as O, type FormAppearanceConfig as P, type FormDataDeleteParams as Q, type FormDataQueryParams as R, type FormEffect as S, type FormEffectAction as T, type FormEffectCondition as U, type FormEffectConditionOperator as V, type FormEngineConfig as W, type FormEngineMode as X, type FormInstanceData as Y, type FormLayoutNode as Z, type FormRuntimeApi as _, type AddressValue as a, type SubFormColumn as a$, type FormRuntimeConfig as a0, type FormSchema as a1, FormSection as a2, type FormSectionProps as a3, type FormSubmitBehavior as a4, type FormTemplateConfig as a5, type GridLayoutCell as a6, type GridLayoutNode as a7, type ImageCompressionConfig as a8, type ImageCompressionVariantConfig as a9, type ProcessNodeType as aA, ProcessPreview as aB, type ProcessPreviewProps as aC, type ProcessRoute as aD, type ProcessStatus as aE, type ProcessTask as aF, type RadioFieldProps as aG, type ResubmitParams as aH, type ReturnParams as aI, type ReturnPolicy as aJ, type ReturnableNode as aK, type ReturnableNodeResult as aL, type RuntimeDataQueryParams as aM, type RuntimeDataQueryResult as aN, type RuntimeRequestConfig as aO, type RuntimeResponse as aP, type RuntimeUploadOptions as aQ, type RuntimeUploadProvider as aR, type SaveTaskParams as aS, type SectionLayoutNode as aT, type SelectFieldProps as aU, type SerialNumberFieldProps as aV, type SignaturePoint as aW, type StandardFormPageMode as aX, type StatusMeta as aY, type StepLayoutItem as aZ, type StepsLayoutNode as a_, type ImageFieldProps as aa, type ImageVariant as ab, type InitiatorSelectCandidate as ac, type InitiatorSelectRequirement as ad, type InitiatorSelectScope as ae, type InitiatorSelectedApprovers as af, type JSONFieldProps as ag, type LayoutVisibleWhen as ah, type LinkedFormOptionConfig as ai, type LocationFieldProps as aj, type LocationValue as ak, type LowcodePageMeta as al, type LowcodePageNode as am, type LowcodePageNodeType as an, type LowcodePageSchema as ao, type MultiSelectFieldProps as ap, type NumberFieldProps as aq, type OptionItem as ar, type OptionSourceConfig as as, type OptionSourceType as at, type PeopleShortcutConfig as au, type PeopleShortcutType as av, type PreviewParams as aw, type ProcessAction as ax, type ProcessBasicInfo as ay, type ProcessDefinition as az, type ApprovalActionType as b, type SubFormFieldProps as b0, type TabLayoutItem as b1, type TabsLayoutNode as b2, type TaskStatus as b3, type TextAreaFieldProps as b4, type TextFieldProps as b5, type TextShortcutConfig as b6, type TextShortcutType as b7, type TransferParams as b8, type UserDisplayFormat as b9, type UserItem as ba, type UserSelectFieldProps as bb, type ValidationPreset as bc, type ValidationRule as bd, type ViewPermissionQueryParams as be, type ViewPermissionSummary as bf, type WithdrawParams as bg, type ApprovalPermission as c, ApprovalTimeline as d, type ApprovalTimelineProps as e, type ApproveParams as f, type AssociationFormConfig as g, type AssociationFormFieldProps as h, type AssociationValue as i, type AttachmentFieldProps as j, type AttachmentImageVariants as k, type AttachmentItem as l, type BaseLayoutNode as m, type CascadeSelectFieldProps as n, type ChangeRecord as o, type ChangeRecordListResponse as p, type ChangeRecordQueryParams as q, type CheckboxFieldProps as r, type DataLinkageCondition as s, type DataLinkageConfig as t, type DateFieldProps as u, type DateRangeRestriction as v, type DateRestrictionConfig as w, type DateShortcutConfig as x, type DateShortcutType as y, type DefaultValueLinkageConfig as z };
@@ -252,10 +252,13 @@ interface RuntimeRequestConfig {
252
252
  headers?: Record<string, string>;
253
253
  responseType?: 'json' | 'blob';
254
254
  }
255
+ type RuntimeUploadProvider = 'platform' | 'oss' | 'builtin-oss';
255
256
  interface RuntimeUploadOptions {
256
- uploadProvider?: 'platform' | 'oss';
257
+ uploadProvider?: RuntimeUploadProvider;
258
+ storageScope?: 'app' | 'platform';
257
259
  storageCode?: string;
258
260
  appType?: string;
261
+ uploadPurpose?: 'attachment' | 'image';
259
262
  imageCompression?: ImageCompressionConfig;
260
263
  }
261
264
  interface FormRuntimeApi {
@@ -297,6 +300,7 @@ interface FormEngineConfig {
297
300
  mode: FormEngineMode;
298
301
  formUuid: string;
299
302
  appType: string;
303
+ defaultUploadProvider?: RuntimeUploadProvider;
300
304
  formInstanceId?: string;
301
305
  submitBehavior?: FormSubmitBehavior;
302
306
  permissions?: {
@@ -592,6 +596,8 @@ interface AttachmentItem {
592
596
  uid?: string;
593
597
  status?: 'uploading' | 'done' | 'error';
594
598
  provider?: 'platform' | 'oss';
599
+ uploadProvider?: RuntimeUploadProvider;
600
+ storageScope?: 'app' | 'platform';
595
601
  storageCode?: string;
596
602
  appType?: string;
597
603
  objectName?: string;
@@ -642,8 +648,8 @@ interface AttachmentFieldProps extends BaseFieldProps {
642
648
  maxSize?: number;
643
649
  uploadAction?: string;
644
650
  bucketName?: string;
645
- /** 自定义上传提供方;设置为 oss 时需同时配置 storageCode。 */
646
- uploadProvider?: 'platform' | 'oss';
651
+ /** 自定义上传提供方;oss 需配置 storageCode,builtin-oss 使用平台内置 OSS。 */
652
+ uploadProvider?: RuntimeUploadProvider;
647
653
  /** src/resources/storage/<code>.json 中声明的存储 code。 */
648
654
  storageCode?: string;
649
655
  multiple?: boolean;
@@ -664,8 +670,8 @@ interface ImageFieldProps extends BaseFieldProps {
664
670
  accept?: string;
665
671
  uploadAction?: string;
666
672
  bucketName?: string;
667
- /** 自定义上传提供方;设置为 oss 时需同时配置 storageCode。 */
668
- uploadProvider?: 'platform' | 'oss';
673
+ /** 自定义上传提供方;oss 需配置 storageCode,builtin-oss 使用平台内置 OSS。 */
674
+ uploadProvider?: RuntimeUploadProvider;
669
675
  /** src/resources/storage/<code>.json 中声明的存储 code。 */
670
676
  storageCode?: string;
671
677
  multiple?: boolean;
@@ -1156,4 +1162,4 @@ interface ProcessPreviewProps {
1156
1162
  }
1157
1163
  declare const ProcessPreview: React__default.FC<ProcessPreviewProps>;
1158
1164
 
1159
- export { type FormRuntimeApiConfig as $, type AddressFieldProps as A, type BaseFieldProps as B, type CascadeDateFieldProps as C, type DataFilter as D, type DepartmentSelectFieldProps as E, type DepartmentTreeNode as F, type DigitalSignatureFieldProps as G, type DigitalSignatureValue as H, type EditorChoiceOption as I, type EditorFieldProps as J, type EditorToolbarAction as K, type FieldBehavior as L, type FieldDefinition as M, type FieldLayoutNode as N, type FieldValueSyncConfig as O, type FormAppearanceConfig as P, type FormDataDeleteParams as Q, type FormDataQueryParams as R, type FormEffect as S, type FormEffectAction as T, type FormEffectCondition as U, type FormEffectConditionOperator as V, type FormEngineConfig as W, type FormEngineMode as X, type FormInstanceData as Y, type FormLayoutNode as Z, type FormRuntimeApi as _, type AddressValue as a, type SubFormFieldProps as a$, type FormRuntimeConfig as a0, type FormSchema as a1, FormSection as a2, type FormSectionProps as a3, type FormSubmitBehavior as a4, type FormTemplateConfig as a5, type GridLayoutCell as a6, type GridLayoutNode as a7, type ImageCompressionConfig as a8, type ImageCompressionVariantConfig as a9, type ProcessNodeType as aA, ProcessPreview as aB, type ProcessPreviewProps as aC, type ProcessRoute as aD, type ProcessStatus as aE, type ProcessTask as aF, type RadioFieldProps as aG, type ResubmitParams as aH, type ReturnParams as aI, type ReturnPolicy as aJ, type ReturnableNode as aK, type ReturnableNodeResult as aL, type RuntimeDataQueryParams as aM, type RuntimeDataQueryResult as aN, type RuntimeRequestConfig as aO, type RuntimeResponse as aP, type RuntimeUploadOptions as aQ, type SaveTaskParams as aR, type SectionLayoutNode as aS, type SelectFieldProps as aT, type SerialNumberFieldProps as aU, type SignaturePoint as aV, type StandardFormPageMode as aW, type StatusMeta as aX, type StepLayoutItem as aY, type StepsLayoutNode as aZ, type SubFormColumn as a_, type ImageFieldProps as aa, type ImageVariant as ab, type InitiatorSelectCandidate as ac, type InitiatorSelectRequirement as ad, type InitiatorSelectScope as ae, type InitiatorSelectedApprovers as af, type JSONFieldProps as ag, type LayoutVisibleWhen as ah, type LinkedFormOptionConfig as ai, type LocationFieldProps as aj, type LocationValue as ak, type LowcodePageMeta as al, type LowcodePageNode as am, type LowcodePageNodeType as an, type LowcodePageSchema as ao, type MultiSelectFieldProps as ap, type NumberFieldProps as aq, type OptionItem as ar, type OptionSourceConfig as as, type OptionSourceType as at, type PeopleShortcutConfig as au, type PeopleShortcutType as av, type PreviewParams as aw, type ProcessAction as ax, type ProcessBasicInfo as ay, type ProcessDefinition as az, type ApprovalActionType as b, type TabLayoutItem as b0, type TabsLayoutNode as b1, type TaskStatus as b2, type TextAreaFieldProps as b3, type TextFieldProps as b4, type TextShortcutConfig as b5, type TextShortcutType as b6, type TransferParams as b7, type UserDisplayFormat as b8, type UserItem as b9, type UserSelectFieldProps as ba, type ValidationPreset as bb, type ValidationRule as bc, type ViewPermissionQueryParams as bd, type ViewPermissionSummary as be, type WithdrawParams as bf, type ApprovalPermission as c, ApprovalTimeline as d, type ApprovalTimelineProps as e, type ApproveParams as f, type AssociationFormConfig as g, type AssociationFormFieldProps as h, type AssociationValue as i, type AttachmentFieldProps as j, type AttachmentImageVariants as k, type AttachmentItem as l, type BaseLayoutNode as m, type CascadeSelectFieldProps as n, type ChangeRecord as o, type ChangeRecordListResponse as p, type ChangeRecordQueryParams as q, type CheckboxFieldProps as r, type DataLinkageCondition as s, type DataLinkageConfig as t, type DateFieldProps as u, type DateRangeRestriction as v, type DateRestrictionConfig as w, type DateShortcutConfig as x, type DateShortcutType as y, type DefaultValueLinkageConfig as z };
1165
+ export { type FormRuntimeApiConfig as $, type AddressFieldProps as A, type BaseFieldProps as B, type CascadeDateFieldProps as C, type DataFilter as D, type DepartmentSelectFieldProps as E, type DepartmentTreeNode as F, type DigitalSignatureFieldProps as G, type DigitalSignatureValue as H, type EditorChoiceOption as I, type EditorFieldProps as J, type EditorToolbarAction as K, type FieldBehavior as L, type FieldDefinition as M, type FieldLayoutNode as N, type FieldValueSyncConfig as O, type FormAppearanceConfig as P, type FormDataDeleteParams as Q, type FormDataQueryParams as R, type FormEffect as S, type FormEffectAction as T, type FormEffectCondition as U, type FormEffectConditionOperator as V, type FormEngineConfig as W, type FormEngineMode as X, type FormInstanceData as Y, type FormLayoutNode as Z, type FormRuntimeApi as _, type AddressValue as a, type SubFormColumn as a$, type FormRuntimeConfig as a0, type FormSchema as a1, FormSection as a2, type FormSectionProps as a3, type FormSubmitBehavior as a4, type FormTemplateConfig as a5, type GridLayoutCell as a6, type GridLayoutNode as a7, type ImageCompressionConfig as a8, type ImageCompressionVariantConfig as a9, type ProcessNodeType as aA, ProcessPreview as aB, type ProcessPreviewProps as aC, type ProcessRoute as aD, type ProcessStatus as aE, type ProcessTask as aF, type RadioFieldProps as aG, type ResubmitParams as aH, type ReturnParams as aI, type ReturnPolicy as aJ, type ReturnableNode as aK, type ReturnableNodeResult as aL, type RuntimeDataQueryParams as aM, type RuntimeDataQueryResult as aN, type RuntimeRequestConfig as aO, type RuntimeResponse as aP, type RuntimeUploadOptions as aQ, type RuntimeUploadProvider as aR, type SaveTaskParams as aS, type SectionLayoutNode as aT, type SelectFieldProps as aU, type SerialNumberFieldProps as aV, type SignaturePoint as aW, type StandardFormPageMode as aX, type StatusMeta as aY, type StepLayoutItem as aZ, type StepsLayoutNode as a_, type ImageFieldProps as aa, type ImageVariant as ab, type InitiatorSelectCandidate as ac, type InitiatorSelectRequirement as ad, type InitiatorSelectScope as ae, type InitiatorSelectedApprovers as af, type JSONFieldProps as ag, type LayoutVisibleWhen as ah, type LinkedFormOptionConfig as ai, type LocationFieldProps as aj, type LocationValue as ak, type LowcodePageMeta as al, type LowcodePageNode as am, type LowcodePageNodeType as an, type LowcodePageSchema as ao, type MultiSelectFieldProps as ap, type NumberFieldProps as aq, type OptionItem as ar, type OptionSourceConfig as as, type OptionSourceType as at, type PeopleShortcutConfig as au, type PeopleShortcutType as av, type PreviewParams as aw, type ProcessAction as ax, type ProcessBasicInfo as ay, type ProcessDefinition as az, type ApprovalActionType as b, type SubFormFieldProps as b0, type TabLayoutItem as b1, type TabsLayoutNode as b2, type TaskStatus as b3, type TextAreaFieldProps as b4, type TextFieldProps as b5, type TextShortcutConfig as b6, type TextShortcutType as b7, type TransferParams as b8, type UserDisplayFormat as b9, type UserItem as ba, type UserSelectFieldProps as bb, type ValidationPreset as bc, type ValidationRule as bd, type ViewPermissionQueryParams as be, type ViewPermissionSummary as bf, type WithdrawParams as bg, type ApprovalPermission as c, ApprovalTimeline as d, type ApprovalTimelineProps as e, type ApproveParams as f, type AssociationFormConfig as g, type AssociationFormFieldProps as h, type AssociationValue as i, type AttachmentFieldProps as j, type AttachmentImageVariants as k, type AttachmentItem as l, type BaseLayoutNode as m, type CascadeSelectFieldProps as n, type ChangeRecord as o, type ChangeRecordListResponse as p, type ChangeRecordQueryParams as q, type CheckboxFieldProps as r, type DataLinkageCondition as s, type DataLinkageConfig as t, type DateFieldProps as u, type DateRangeRestriction as v, type DateRestrictionConfig as w, type DateShortcutConfig as x, type DateShortcutType as y, type DefaultValueLinkageConfig as z };