openxiangda 1.0.102 → 1.0.104

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 CHANGED
@@ -224,6 +224,18 @@ React SPA 新应用的无需登录访问统一使用 `/view/:appType/public/*`
224
224
 
225
225
  旧 `?publicAccess=guest` 和表单 `settings/forms/*.json` 里的 `publicAccess` 只用于旧 `sy-lowcode-view` 兼容。新 React SPA 应用不要再设计或生成这种链接。
226
226
 
227
+ 公开页面里的图片和附件分两类处理。真正可以对公网长期公开的资产,例如仪器封面图、公开说明书、门户 banner,应上传到平台公开文件区,默认 bucket 为 `public-assets`,上传后保存的 `url` / `previewUrl` / `downloadUrl` 会是 `/file/public/...`,未登录浏览器可以直接读取并被浏览器/CDN 缓存。仍可能包含隐私、审批材料、订单报告、结算单、维保现场照片的附件不要放入公开区,应继续保存在私有 bucket,并通过登录态或受控文件票据访问。
228
+
229
+ ```ts
230
+ import { createFormRuntimeApi } from "openxiangda"
231
+
232
+ const api = createFormRuntimeApi({ baseUrl: "/service" })
233
+ const file = await api.uploadPublicFile(imageFile, "public-assets")
234
+
235
+ // file.url === "/service/file/public/public-assets/..."
236
+ // file.visibility === "public"
237
+ ```
238
+
227
239
  ```json
228
240
  {
229
241
  "code": "public_register",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openxiangda",
3
- "version": "1.0.102",
3
+ "version": "1.0.104",
4
4
  "description": "OpenXiangda CLI, workspace build tools, runtime SDK, and form components.",
5
5
  "private": false,
6
6
  "bin": {
@@ -39122,6 +39122,7 @@ async function validateAllFields(formData, fieldRules) {
39122
39122
  init_cjs_shims();
39123
39123
  var DEFAULT_CHUNK_SIZE = 5 * 1024 * 1024;
39124
39124
  var CHUNK_UPLOAD_THRESHOLD = 10 * 1024 * 1024;
39125
+ var DEFAULT_PUBLIC_FILE_BUCKET = "public-assets";
39125
39126
  var trimTrailingSlash = (value) => String(value || "").replace(/\/$/, "");
39126
39127
  var getDefaultBaseUrl = () => {
39127
39128
  const globalEnv = globalThis.process?.env;
@@ -39168,6 +39169,7 @@ var normalizeFilePayloadUrls = (baseUrl, payload) => {
39168
39169
  ...payload,
39169
39170
  url: normalizeRuntimeFileUrl(baseUrl, payload.url),
39170
39171
  downloadUrl: normalizeRuntimeFileUrl(baseUrl, payload.downloadUrl),
39172
+ publicUrl: normalizeRuntimeFileUrl(baseUrl, payload.publicUrl),
39171
39173
  relayUrl: normalizeRuntimeFileUrl(baseUrl, payload.relayUrl),
39172
39174
  previewUrl: normalizeRuntimeFileUrl(baseUrl, payload.previewUrl),
39173
39175
  metadataUrl: normalizeRuntimeFileUrl(baseUrl, payload.metadataUrl),
@@ -39263,6 +39265,8 @@ var normalizeUploadData = (data, file, bucketName, baseUrl = "") => {
39263
39265
  url: normalizeRuntimeFileUrl(baseUrl, item?.url) || "",
39264
39266
  downloadUrl: normalizeRuntimeFileUrl(baseUrl, item?.downloadUrl),
39265
39267
  previewUrl: normalizeRuntimeFileUrl(baseUrl, item?.previewUrl),
39268
+ publicUrl: normalizeRuntimeFileUrl(baseUrl, item?.publicUrl),
39269
+ visibility: item?.visibility,
39266
39270
  status: "done",
39267
39271
  size: item?.size ?? file.size,
39268
39272
  objectName,
@@ -39271,7 +39275,7 @@ var normalizeUploadData = (data, file, bucketName, baseUrl = "") => {
39271
39275
  mimeType: item?.contentType || file.type
39272
39276
  };
39273
39277
  };
39274
- var uploadWithXhr = (baseUrl, file, bucketName, onProgress) => new Promise((resolve, reject) => {
39278
+ var uploadWithXhr = (baseUrl, file, bucketName, onProgress, options = {}) => new Promise((resolve, reject) => {
39275
39279
  if (globalThis.process?.env?.VITEST) {
39276
39280
  onProgress?.(100);
39277
39281
  resolve({
@@ -39282,14 +39286,24 @@ var uploadWithXhr = (baseUrl, file, bucketName, onProgress) => new Promise((reso
39282
39286
  status: "done",
39283
39287
  size: file.size,
39284
39288
  bucketName,
39285
- contentType: file.type
39289
+ contentType: file.type,
39290
+ visibility: options.visibility
39286
39291
  });
39287
39292
  return;
39288
39293
  }
39289
39294
  const xhr = new XMLHttpRequest();
39290
39295
  const formData = new FormData();
39291
39296
  formData.append("files", file);
39292
- xhr.open("POST", joinUrl(baseUrl, `/file/upload?bucketName=${encodeURIComponent(bucketName)}`));
39297
+ xhr.open(
39298
+ "POST",
39299
+ joinUrl(
39300
+ baseUrl,
39301
+ appendQuery("/file/upload", {
39302
+ bucketName,
39303
+ visibility: options.visibility
39304
+ })
39305
+ )
39306
+ );
39293
39307
  xhr.withCredentials = true;
39294
39308
  const token = typeof window !== "undefined" ? window.localStorage?.getItem("token") : void 0;
39295
39309
  if (token) xhr.setRequestHeader("authorization", token);
@@ -39313,7 +39327,7 @@ var uploadWithXhr = (baseUrl, file, bucketName, onProgress) => new Promise((reso
39313
39327
  xhr.onerror = () => reject(new Error("\u4E0A\u4F20\u5931\u8D25"));
39314
39328
  xhr.send(formData);
39315
39329
  });
39316
- async function uploadChunkedFile(request, file, bucketName, baseUrl, onProgress) {
39330
+ async function uploadChunkedFile(request, file, bucketName, baseUrl, onProgress, options = {}) {
39317
39331
  const initiate = await request({
39318
39332
  url: "/file/multipart/initiate",
39319
39333
  method: "post",
@@ -39321,7 +39335,8 @@ async function uploadChunkedFile(request, file, bucketName, baseUrl, onProgress)
39321
39335
  fileName: file.name,
39322
39336
  fileSize: file.size,
39323
39337
  chunkSize: DEFAULT_CHUNK_SIZE,
39324
- bucketName
39338
+ bucketName,
39339
+ visibility: options.visibility
39325
39340
  }
39326
39341
  });
39327
39342
  const uploadInfo = initiate.data || initiate.result;
@@ -39382,6 +39397,16 @@ function createFormRuntimeApi(config3) {
39382
39397
  }
39383
39398
  return uploadWithXhr(baseUrl, file, bucketName, onProgress);
39384
39399
  },
39400
+ uploadPublicFile: async (file, bucketName = DEFAULT_PUBLIC_FILE_BUCKET, onProgress) => {
39401
+ if (file.size > CHUNK_UPLOAD_THRESHOLD) {
39402
+ return uploadChunkedFile(request, file, bucketName, baseUrl, onProgress, {
39403
+ visibility: "public"
39404
+ });
39405
+ }
39406
+ return uploadWithXhr(baseUrl, file, bucketName, onProgress, {
39407
+ visibility: "public"
39408
+ });
39409
+ },
39385
39410
  deleteFile: async (objectName, bucketName = "files") => {
39386
39411
  await request({ url: "/file/delete", method: "post", data: { bucketName, objectName } });
39387
39412
  return { success: true };