@coffer-org/plugin-documents 1.4.1 → 2.0.0

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.
@@ -12,6 +12,7 @@ nationality — ISO alpha-2. variants — given/family name per language (field.
12
12
  field.keyed({
13
13
  key: 'variants',
14
14
  label: 'documents.person_identity.fields.variants',
15
+ icon: 'lucide:languages',
15
16
  by: field.select({ key: 'lang', label: 'documents.person_identity.variants.lang', options: 'languages' }),
16
17
  fields: [
17
18
  field.string({ key: 'name', label: 'documents.person_identity.variants.name' }),
@@ -6,7 +6,7 @@ export default defineShelf({
6
6
  label: 'documents.personal_document.label',
7
7
  icon: 'lucide:id-card',
8
8
  views: {
9
- table: ['owner', 'type', 'surname', 'expires'],
9
+ list: { fields: ['owner', 'type', 'surname', 'expires'] },
10
10
  },
11
11
  fields: [
12
12
  field.title({ key: 'name', label: 'core.fields.name' }),
package/dist/schema.js CHANGED
@@ -5887,7 +5887,7 @@ function group(o) {
5887
5887
  required: o.required,
5888
5888
  unique: r.unique,
5889
5889
  label: o.label,
5890
- icon: v.icon,
5890
+ icon: o.icon,
5891
5891
  display: v.display ?? "wrap",
5892
5892
  kind: v.kind,
5893
5893
  fixed: r.fixed,
@@ -5898,11 +5898,9 @@ function group(o) {
5898
5898
  function row(o) {
5899
5899
  return group({
5900
5900
  label: o.label,
5901
+ icon: o.icon,
5901
5902
  fields: o.fields,
5902
- view: {
5903
- ...o.view,
5904
- display: "scroll"
5905
- }
5903
+ view: { display: "scroll" }
5906
5904
  });
5907
5905
  }
5908
5906
  /** Tabular collection (array of rows → <table>, aligned by columns). Sugar. */
@@ -5910,14 +5908,12 @@ function table(o) {
5910
5908
  return group({
5911
5909
  key: o.key,
5912
5910
  label: o.label,
5911
+ icon: o.icon,
5913
5912
  fields: o.fields,
5914
5913
  multiple: true,
5915
5914
  required: o.required,
5916
5915
  rules: o.rules,
5917
- view: {
5918
- ...o.view,
5919
- display: "table"
5920
- }
5916
+ view: { display: "table" }
5921
5917
  });
5922
5918
  }
5923
5919
  /**
@@ -5933,11 +5929,9 @@ function sheet(o) {
5933
5929
  });
5934
5930
  return group({
5935
5931
  label: o.label,
5932
+ icon: o.icon,
5936
5933
  fields: flat,
5937
- view: {
5938
- ...o.view,
5939
- display: "sheet"
5940
- }
5934
+ view: { display: "sheet" }
5941
5935
  });
5942
5936
  }
5943
5937
  /**
@@ -5969,8 +5963,8 @@ function keyed(o) {
5969
5963
  return {
5970
5964
  ...(o.container ?? group)({
5971
5965
  label: o.label,
5972
- fields: [o.by, ...o.fields],
5973
- view: o.view
5966
+ icon: o.icon,
5967
+ fields: [o.by, ...o.fields]
5974
5968
  }),
5975
5969
  key: o.key,
5976
5970
  multiple: true,
@@ -6407,7 +6401,7 @@ function relation(raw) {
6407
6401
  },
6408
6402
  relation: {
6409
6403
  library: raw.options.library,
6410
- type: raw.options.shelf
6404
+ shelf: raw.options.shelf
6411
6405
  },
6412
6406
  ...multi && { json: true },
6413
6407
  zod: optionalize(s, required)
@@ -6787,15 +6781,44 @@ function period(raw) {
6787
6781
  zod: optionalize(s, required)
6788
6782
  });
6789
6783
  }
6784
+ /** Keys a file entry may carry. Everything else is rejected — see fileEntryIssue. */
6785
+ var FILE_KEYS = /* @__PURE__ */ new Set([
6786
+ "name",
6787
+ "mime",
6788
+ "size"
6789
+ ]);
6790
+ /** Keys that mean "the author pasted a remote address" — the one mistake worth naming. */
6791
+ var FILE_URL_KEYS = [
6792
+ "url",
6793
+ "src",
6794
+ "href",
6795
+ "link"
6796
+ ];
6797
+ /**
6798
+ * A file entry points at a file already uploaded to the server: `{ name }`, where
6799
+ * name is the bare filename returned by POST /api/upload. Anything else — a remote
6800
+ * URL, an extra key, a path — is refused here, so a record can never hold a
6801
+ * reference the server cannot serve. `mime`/`size` are accepted (legacy payloads
6802
+ * and the web uploader send them) but the server overwrites them from disk.
6803
+ * Returns a vmsg code, or null when the entry is well-formed.
6804
+ */
6805
+ function fileEntryIssue(it) {
6806
+ if (typeof it !== "object" || it === null || Array.isArray(it)) return "file_structure";
6807
+ const rec = it;
6808
+ if (FILE_URL_KEYS.some((k) => k in rec)) return "file_remote_url";
6809
+ const name = rec["name"];
6810
+ if (typeof name !== "string" || name === "") return "file_structure";
6811
+ if (name.includes("://") || name.startsWith("//")) return "file_remote_url";
6812
+ if (/[\\/]/.test(name) || name.includes("..")) return "file_name";
6813
+ for (const k of Object.keys(rec)) if (!FILE_KEYS.has(k)) return "file_unknown_key";
6814
+ if (rec["mime"] !== void 0 && typeof rec["mime"] !== "string") return "file_structure";
6815
+ if (rec["size"] !== void 0 && typeof rec["size"] !== "number") return "file_structure";
6816
+ return null;
6817
+ }
6790
6818
  function makeFile(kind, raw) {
6791
6819
  const o = normalizeOpts(raw);
6792
6820
  const required = o.required ?? false;
6793
6821
  const multiple = o.multiple ?? false;
6794
- const rowSchema = object({
6795
- name: string$1().min(1),
6796
- mime: string$1().optional(),
6797
- size: number$1().optional()
6798
- });
6799
6822
  const s = unknown().superRefine((raw, ctx) => {
6800
6823
  if (typeof raw === "string") try {
6801
6824
  JSON.parse(raw);
@@ -6808,12 +6831,15 @@ function makeFile(kind, raw) {
6808
6831
  }
6809
6832
  const parsed = jsonValue(raw);
6810
6833
  const items = Array.isArray(parsed) ? parsed : [parsed];
6811
- for (const it of items) if (!rowSchema.safeParse(it).success) {
6812
- ctx.addIssue({
6813
- code: ZodIssueCode.custom,
6814
- message: vmsg("file_structure")
6815
- });
6816
- return;
6834
+ for (const it of items) {
6835
+ const code = fileEntryIssue(it);
6836
+ if (code) {
6837
+ ctx.addIssue({
6838
+ code: ZodIssueCode.custom,
6839
+ message: vmsg(code)
6840
+ });
6841
+ return;
6842
+ }
6817
6843
  }
6818
6844
  });
6819
6845
  return wrapKey(o, {
@@ -7744,7 +7770,7 @@ function defineShelf(m) {
7744
7770
  const keys = fieldEntries(m.fields).map(([k]) => k);
7745
7771
  const dup = keys.find((k, i) => keys.indexOf(k) !== i);
7746
7772
  if (dup) throw new Error(`[shelf] ${m.library}/${m.shelf}: duplicate key '${dup}'`);
7747
- if (m.standalone !== false && !m.views?.table?.length) console.warn(`[shelf] ${m.library}/${m.shelf}: standalone shelf without an explicit views.table`);
7773
+ if (m.standalone !== false && !m.views?.list?.fields?.length) console.warn(`[shelf] ${m.library}/${m.shelf}: standalone shelf without an explicit views.list`);
7748
7774
  return m;
7749
7775
  }
7750
7776
  //#endregion
@@ -7754,12 +7780,12 @@ var personal_document_default = defineShelf({
7754
7780
  library: "documents",
7755
7781
  label: "documents.personal_document.label",
7756
7782
  icon: "lucide:id-card",
7757
- views: { table: [
7783
+ views: { list: { fields: [
7758
7784
  "owner",
7759
7785
  "type",
7760
7786
  "surname",
7761
7787
  "expires"
7762
- ] },
7788
+ ] } },
7763
7789
  fields: [
7764
7790
  field.title({
7765
7791
  key: "name",
@@ -7936,6 +7962,7 @@ nationality — ISO alpha-2. variants — given/family name per language (field.
7936
7962
  }), field.keyed({
7937
7963
  key: "variants",
7938
7964
  label: "documents.person_identity.fields.variants",
7965
+ icon: "lucide:languages",
7939
7966
  by: field.select({
7940
7967
  key: "lang",
7941
7968
  label: "documents.person_identity.variants.lang",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coffer-org/plugin-documents",
3
- "version": "1.4.1",
3
+ "version": "2.0.0",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=24"
@@ -25,9 +25,9 @@
25
25
  "postpack": "node ../../scripts/swap-exports.mjs src"
26
26
  },
27
27
  "dependencies": {
28
- "@coffer-org/plugin-people": "^1.4.0",
29
- "@coffer-org/sdk": "^1.5.0",
30
- "@coffer-org/server": "^1.8.0"
28
+ "@coffer-org/plugin-people": "^2.0.0",
29
+ "@coffer-org/sdk": "^2.0.0",
30
+ "@coffer-org/server": "^2.0.1"
31
31
  },
32
32
  "coffer": {
33
33
  "schema": "dist/schema.js"