@fieldia/core 0.21.0 → 0.22.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.
- package/README.md +116 -1
- package/package.json +1 -1
- package/schema/page.schema.json +149 -1
- package/src/index.d.mts +2 -2
- package/src/index.d.ts +2 -2
- package/src/index.js +3 -1
- package/src/index.js.map +1 -1
- package/src/index.mjs +2 -2
- package/src/index.mjs.map +1 -1
- package/src/lib/format/check-page.d.mts +3 -2
- package/src/lib/format/check-page.d.ts +3 -2
- package/src/lib/format/check-page.js +9 -4
- package/src/lib/format/check-page.js.map +1 -1
- package/src/lib/format/check-page.mjs +10 -5
- package/src/lib/format/check-page.mjs.map +1 -1
- package/src/lib/format/field.d.mts +85 -0
- package/src/lib/format/field.d.ts +85 -0
- package/src/lib/format/field.js +14 -1
- package/src/lib/format/field.js.map +1 -1
- package/src/lib/format/field.mjs +13 -0
- package/src/lib/format/field.mjs.map +1 -1
- package/src/lib/format/layout.d.mts +142 -17
- package/src/lib/format/layout.d.ts +142 -17
- package/src/lib/format/layout.js +18 -1
- package/src/lib/format/layout.js.map +1 -1
- package/src/lib/format/layout.mjs +17 -0
- package/src/lib/format/layout.mjs.map +1 -1
- package/src/lib/format/layout.types.d.mts +6 -2
- package/src/lib/format/layout.types.d.ts +6 -2
- package/src/lib/format/page.d.mts +69 -10
- package/src/lib/format/page.d.ts +69 -10
- package/src/lib/format/page.js +4 -1
- package/src/lib/format/page.js.map +1 -1
- package/src/lib/format/page.mjs +5 -2
- package/src/lib/format/page.mjs.map +1 -1
- package/src/lib/format/references.d.mts +7 -0
- package/src/lib/format/references.d.ts +7 -0
- package/src/lib/format/references.js +46 -0
- package/src/lib/format/references.js.map +1 -1
- package/src/lib/format/references.mjs +46 -0
- package/src/lib/format/references.mjs.map +1 -1
- package/src/lib/format/translate.js +3 -2
- package/src/lib/format/translate.js.map +1 -1
- package/src/lib/format/translate.mjs +3 -2
- package/src/lib/format/translate.mjs.map +1 -1
- package/src/lib/format/upgrade.d.mts +41 -0
- package/src/lib/format/upgrade.d.ts +41 -0
- package/src/lib/format/upgrade.js +41 -0
- package/src/lib/format/upgrade.js.map +1 -0
- package/src/lib/format/upgrade.mjs +37 -0
- package/src/lib/format/upgrade.mjs.map +1 -0
- package/src/lib/format/validate.d.mts +2 -1
- package/src/lib/format/validate.d.ts +2 -1
- package/src/lib/format/validate.js +4 -2
- package/src/lib/format/validate.js.map +1 -1
- package/src/lib/format/validate.mjs +4 -2
- package/src/lib/format/validate.mjs.map +1 -1
- package/src/lib/format/version.d.mts +16 -1
- package/src/lib/format/version.d.ts +16 -1
- package/src/lib/format/version.js +39 -2
- package/src/lib/format/version.js.map +1 -1
- package/src/lib/format/version.mjs +36 -1
- package/src/lib/format/version.mjs.map +1 -1
- package/src/lib/record/data-source.d.mts +224 -10
- package/src/lib/record/data-source.d.ts +224 -10
- package/src/lib/record/data-source.js +29 -0
- package/src/lib/record/data-source.js.map +1 -1
- package/src/lib/record/data-source.mjs +25 -0
- package/src/lib/record/data-source.mjs.map +1 -1
- package/src/lib/record/form.d.mts +144 -5
- package/src/lib/record/form.d.ts +144 -5
- package/src/lib/record/form.js +792 -42
- package/src/lib/record/form.js.map +1 -1
- package/src/lib/record/form.mjs +791 -43
- package/src/lib/record/form.mjs.map +1 -1
- package/src/lib/record/locales/ar.js +10 -0
- package/src/lib/record/locales/ar.js.map +1 -1
- package/src/lib/record/locales/ar.mjs +10 -0
- package/src/lib/record/locales/ar.mjs.map +1 -1
- package/src/lib/record/locales/de.js +10 -0
- package/src/lib/record/locales/de.js.map +1 -1
- package/src/lib/record/locales/de.mjs +10 -0
- package/src/lib/record/locales/de.mjs.map +1 -1
- package/src/lib/record/locales/fr.js +10 -0
- package/src/lib/record/locales/fr.js.map +1 -1
- package/src/lib/record/locales/fr.mjs +10 -0
- package/src/lib/record/locales/fr.mjs.map +1 -1
- package/src/lib/record/memory-data-source.d.mts +40 -3
- package/src/lib/record/memory-data-source.d.ts +40 -3
- package/src/lib/record/memory-data-source.js +164 -20
- package/src/lib/record/memory-data-source.js.map +1 -1
- package/src/lib/record/memory-data-source.mjs +164 -20
- package/src/lib/record/memory-data-source.mjs.map +1 -1
- package/src/lib/record/messages.d.mts +21 -0
- package/src/lib/record/messages.d.ts +21 -0
- package/src/lib/record/messages.js +10 -0
- package/src/lib/record/messages.js.map +1 -1
- package/src/lib/record/messages.mjs +10 -0
- package/src/lib/record/messages.mjs.map +1 -1
- package/src/lib/record/run.d.mts +50 -7
- package/src/lib/record/run.d.ts +50 -7
- package/src/lib/record/run.js +67 -20
- package/src/lib/record/run.js.map +1 -1
- package/src/lib/record/run.mjs +67 -20
- package/src/lib/record/run.mjs.map +1 -1
- package/src/lib/record/upload-to.d.mts +50 -0
- package/src/lib/record/upload-to.d.ts +50 -0
- package/src/lib/record/upload-to.js +117 -0
- package/src/lib/record/upload-to.js.map +1 -0
- package/src/lib/record/upload-to.mjs +114 -0
- package/src/lib/record/upload-to.mjs.map +1 -0
- package/src/lib/record/uploads.d.mts +152 -0
- package/src/lib/record/uploads.d.ts +152 -0
- package/src/lib/record/uploads.js +345 -0
- package/src/lib/record/uploads.js.map +1 -0
- package/src/lib/record/uploads.mjs +337 -0
- package/src/lib/record/uploads.mjs.map +1 -0
- package/src/lib/record/values.d.mts +6 -0
- package/src/lib/record/values.d.ts +6 -0
- package/src/lib/record/values.js.map +1 -1
- package/src/lib/record/values.mjs.map +1 -1
- package/src/runtime.d.mts +10 -6
- package/src/runtime.d.ts +10 -6
- package/src/runtime.js +19 -2
- package/src/runtime.js.map +1 -1
- package/src/runtime.mjs +7 -3
- package/src/runtime.mjs.map +1 -1
|
@@ -35,6 +35,9 @@ exports.de = {
|
|
|
35
35
|
fileType: '{label} muss eine {types}-Datei sein',
|
|
36
36
|
minFiles: 'Fügen Sie {label} mindestens {min} Dateien hinzu',
|
|
37
37
|
maxFiles: 'Zu viele Dateien für {label}: höchstens {max}',
|
|
38
|
+
notUploaded: '{name} wurde nicht hochgeladen: erneut versuchen oder entfernen',
|
|
39
|
+
notUploadedMany: '{n} Dateien wurden nicht hochgeladen: erneut versuchen oder entfernen',
|
|
40
|
+
fileRefused: '{name} wurde nicht angenommen: {reason}',
|
|
38
41
|
minLength: '{label} muss mindestens {min} Zeichen haben',
|
|
39
42
|
endsWith: '{label} muss auf {ending} enden',
|
|
40
43
|
atLeast: 'Wählen Sie bei {label} mindestens {min} aus',
|
|
@@ -57,6 +60,13 @@ exports.de = {
|
|
|
57
60
|
addressParts: 'Straße und Hausnummer|Adresszeile 2|Ort|Bundesland oder Region|Postleitzahl|Land',
|
|
58
61
|
archiveConfirm: 'Möchten Sie diesen Datensatz wirklich archivieren?',
|
|
59
62
|
deleteConfirm: 'Möchten Sie diesen Datensatz wirklich löschen?',
|
|
63
|
+
mayNotEdit: 'Sie können diesen Datensatz lesen, aber nicht ändern.',
|
|
64
|
+
mayNotArchive: 'Sie können diesen Datensatz nicht archivieren.',
|
|
65
|
+
mayNotDuplicate: 'Sie können diesen Datensatz nicht duplizieren.',
|
|
66
|
+
mayNotDelete: 'Sie können diesen Datensatz nicht löschen.',
|
|
67
|
+
theirsUnread: 'Die andere Fassung konnte nicht gelesen werden, darum wurde Ihre nicht darüber gespeichert. Versuchen Sie Meine behalten erneut, oder Neu laden.',
|
|
68
|
+
discardChanges: 'Ihre Änderungen verwerfen?',
|
|
69
|
+
recordReplaced: 'Jetzt wird ein anderer Datensatz angezeigt: die übrigen Schritte wurden nicht ausgeführt.',
|
|
60
70
|
overBy: '{label} ist {over} Zeichen zu lang (höchstens {max}); kürzen Sie es zum Speichern',
|
|
61
71
|
overByOne: '{label} ist 1 Zeichen zu lang (höchstens {max}); kürzen Sie es zum Speichern',
|
|
62
72
|
postcode: '{label}: Postleitzahl für {country} mit {n} Ziffern, z. B. {example}',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"de.js","sourceRoot":"","sources":["../../../../../../../libs/core/src/lib/record/locales/de.ts"],"names":[],"mappings":";;;AAEA,yCAAyC;AAC5B,QAAA,EAAE,GAAa;IAC1B,QAAQ,EAAE,0BAA0B;IACpC,SAAS,EAAE,qCAAqC;IAChD,OAAO,EAAE,wCAAwC;IACjD,IAAI,EAAE,wBAAwB;IAC9B,MAAM,EAAE,6BAA6B;IACrC,OAAO,EAAE,mCAAmC;IAC5C,GAAG,EAAE,oCAAoC;IACzC,GAAG,EAAE,mCAAmC;IACxC,QAAQ,EAAE,iDAAiD;IAC3D,WAAW,EAAE,4CAA4C;IACzD,WAAW,EAAE,iDAAiD;IAC9D,YAAY,EAAE,iDAAiD;IAC/D,MAAM,EAAE,mCAAmC;IAC3C,OAAO,EAAE,gCAAgC;IACzC,UAAU,EAAE,+CAA+C;IAC3D,WAAW,EAAE,yCAAyC;IACtD,cAAc,EAAE,kEAAkE;IAClF,eAAe,EAAE,yCAAyC;IAC1D,MAAM,EAAE,kCAAkC;IAC1C,aAAa,EAAE,6DAA6D;IAC5E,MAAM,EAAE,uCAAuC;IAC/C,SAAS,EAAE,yBAAyB;IACpC,UAAU,EAAE,wCAAwC;IACpD,OAAO,EAAE,2CAA2C;IACpD,MAAM,EAAE,iCAAiC;IACzC,OAAO,EAAE,8CAA8C;IACvD,SAAS,EAAE,qCAAqC;IAChD,IAAI,EAAE,8BAA8B;IACpC,QAAQ,EAAE,+BAA+B;IACzC,QAAQ,EAAE,sCAAsC;IAChD,QAAQ,EAAE,kDAAkD;IAC5D,QAAQ,EAAE,+CAA+C;IACzD,SAAS,EAAE,6CAA6C;IACxD,QAAQ,EAAE,iCAAiC;IAC3C,OAAO,EAAE,6CAA6C;IACtD,MAAM,EAAE,4CAA4C;IACpD,QAAQ,EAAE,0CAA0C;IACpD,UAAU,EAAE,oCAAoC;IAChD,KAAK,EAAE,8CAA8C;IACrD,QAAQ,EAAE,6DAA6D;IACvE,EAAE,EAAE,MAAM;IACV,IAAI,EAAE,iDAAiD;IACvD,KAAK,EAAE,2DAA2D;IAClE,GAAG,EAAE,kDAAkD;IACvD,KAAK,EAAE,0DAA0D;IACjE,IAAI,EAAE,yCAAyC;IAC/C,MAAM,EAAE,2BAA2B;IACnC,KAAK,EAAE,2BAA2B;IAClC,OAAO,EAAE,4CAA4C;IACrD,QAAQ,EAAE,0CAA0C;IACpD,QAAQ,EAAE,sCAAsC;IAChD,YAAY,EAAE,kFAAkF;IAChG,cAAc,EAAE,oDAAoD;IACpE,aAAa,EAAE,gDAAgD;IAC/D,MAAM,EAAE,mFAAmF;IAC3F,SAAS,EAAE,8EAA8E;IACzF,QAAQ,EAAE,sEAAsE;IAChF,SAAS,EAAE,wDAAwD;IACnE,cAAc,EAAE,qCAAqC;IACrD,QAAQ,EAAE,iFAAiF;IAC3F,aAAa,EAAE,gDAAgD;IAC/D,MAAM,EAAE,IAAI;CACb,CAAC"}
|
|
1
|
+
{"version":3,"file":"de.js","sourceRoot":"","sources":["../../../../../../../libs/core/src/lib/record/locales/de.ts"],"names":[],"mappings":";;;AAEA,yCAAyC;AAC5B,QAAA,EAAE,GAAa;IAC1B,QAAQ,EAAE,0BAA0B;IACpC,SAAS,EAAE,qCAAqC;IAChD,OAAO,EAAE,wCAAwC;IACjD,IAAI,EAAE,wBAAwB;IAC9B,MAAM,EAAE,6BAA6B;IACrC,OAAO,EAAE,mCAAmC;IAC5C,GAAG,EAAE,oCAAoC;IACzC,GAAG,EAAE,mCAAmC;IACxC,QAAQ,EAAE,iDAAiD;IAC3D,WAAW,EAAE,4CAA4C;IACzD,WAAW,EAAE,iDAAiD;IAC9D,YAAY,EAAE,iDAAiD;IAC/D,MAAM,EAAE,mCAAmC;IAC3C,OAAO,EAAE,gCAAgC;IACzC,UAAU,EAAE,+CAA+C;IAC3D,WAAW,EAAE,yCAAyC;IACtD,cAAc,EAAE,kEAAkE;IAClF,eAAe,EAAE,yCAAyC;IAC1D,MAAM,EAAE,kCAAkC;IAC1C,aAAa,EAAE,6DAA6D;IAC5E,MAAM,EAAE,uCAAuC;IAC/C,SAAS,EAAE,yBAAyB;IACpC,UAAU,EAAE,wCAAwC;IACpD,OAAO,EAAE,2CAA2C;IACpD,MAAM,EAAE,iCAAiC;IACzC,OAAO,EAAE,8CAA8C;IACvD,SAAS,EAAE,qCAAqC;IAChD,IAAI,EAAE,8BAA8B;IACpC,QAAQ,EAAE,+BAA+B;IACzC,QAAQ,EAAE,sCAAsC;IAChD,QAAQ,EAAE,kDAAkD;IAC5D,QAAQ,EAAE,+CAA+C;IACzD,WAAW,EAAE,iEAAiE;IAC9E,eAAe,EAAE,uEAAuE;IACxF,WAAW,EAAE,yCAAyC;IACtD,SAAS,EAAE,6CAA6C;IACxD,QAAQ,EAAE,iCAAiC;IAC3C,OAAO,EAAE,6CAA6C;IACtD,MAAM,EAAE,4CAA4C;IACpD,QAAQ,EAAE,0CAA0C;IACpD,UAAU,EAAE,oCAAoC;IAChD,KAAK,EAAE,8CAA8C;IACrD,QAAQ,EAAE,6DAA6D;IACvE,EAAE,EAAE,MAAM;IACV,IAAI,EAAE,iDAAiD;IACvD,KAAK,EAAE,2DAA2D;IAClE,GAAG,EAAE,kDAAkD;IACvD,KAAK,EAAE,0DAA0D;IACjE,IAAI,EAAE,yCAAyC;IAC/C,MAAM,EAAE,2BAA2B;IACnC,KAAK,EAAE,2BAA2B;IAClC,OAAO,EAAE,4CAA4C;IACrD,QAAQ,EAAE,0CAA0C;IACpD,QAAQ,EAAE,sCAAsC;IAChD,YAAY,EAAE,kFAAkF;IAChG,cAAc,EAAE,oDAAoD;IACpE,aAAa,EAAE,gDAAgD;IAC/D,UAAU,EAAE,uDAAuD;IACnE,aAAa,EAAE,gDAAgD;IAC/D,eAAe,EAAE,gDAAgD;IACjE,YAAY,EAAE,4CAA4C;IAC1D,YAAY,EAAE,kJAAkJ;IAChK,cAAc,EAAE,4BAA4B;IAC5C,cAAc,EAAE,2FAA2F;IAC3G,MAAM,EAAE,mFAAmF;IAC3F,SAAS,EAAE,8EAA8E;IACzF,QAAQ,EAAE,sEAAsE;IAChF,SAAS,EAAE,wDAAwD;IACnE,cAAc,EAAE,qCAAqC;IACrD,QAAQ,EAAE,iFAAiF;IAC3F,aAAa,EAAE,gDAAgD;IAC/D,MAAM,EAAE,IAAI;CACb,CAAC"}
|
|
@@ -32,6 +32,9 @@ export const de = {
|
|
|
32
32
|
fileType: '{label} muss eine {types}-Datei sein',
|
|
33
33
|
minFiles: 'Fügen Sie {label} mindestens {min} Dateien hinzu',
|
|
34
34
|
maxFiles: 'Zu viele Dateien für {label}: höchstens {max}',
|
|
35
|
+
notUploaded: '{name} wurde nicht hochgeladen: erneut versuchen oder entfernen',
|
|
36
|
+
notUploadedMany: '{n} Dateien wurden nicht hochgeladen: erneut versuchen oder entfernen',
|
|
37
|
+
fileRefused: '{name} wurde nicht angenommen: {reason}',
|
|
35
38
|
minLength: '{label} muss mindestens {min} Zeichen haben',
|
|
36
39
|
endsWith: '{label} muss auf {ending} enden',
|
|
37
40
|
atLeast: 'Wählen Sie bei {label} mindestens {min} aus',
|
|
@@ -54,6 +57,13 @@ export const de = {
|
|
|
54
57
|
addressParts: 'Straße und Hausnummer|Adresszeile 2|Ort|Bundesland oder Region|Postleitzahl|Land',
|
|
55
58
|
archiveConfirm: 'Möchten Sie diesen Datensatz wirklich archivieren?',
|
|
56
59
|
deleteConfirm: 'Möchten Sie diesen Datensatz wirklich löschen?',
|
|
60
|
+
mayNotEdit: 'Sie können diesen Datensatz lesen, aber nicht ändern.',
|
|
61
|
+
mayNotArchive: 'Sie können diesen Datensatz nicht archivieren.',
|
|
62
|
+
mayNotDuplicate: 'Sie können diesen Datensatz nicht duplizieren.',
|
|
63
|
+
mayNotDelete: 'Sie können diesen Datensatz nicht löschen.',
|
|
64
|
+
theirsUnread: 'Die andere Fassung konnte nicht gelesen werden, darum wurde Ihre nicht darüber gespeichert. Versuchen Sie Meine behalten erneut, oder Neu laden.',
|
|
65
|
+
discardChanges: 'Ihre Änderungen verwerfen?',
|
|
66
|
+
recordReplaced: 'Jetzt wird ein anderer Datensatz angezeigt: die übrigen Schritte wurden nicht ausgeführt.',
|
|
57
67
|
overBy: '{label} ist {over} Zeichen zu lang (höchstens {max}); kürzen Sie es zum Speichern',
|
|
58
68
|
overByOne: '{label} ist 1 Zeichen zu lang (höchstens {max}); kürzen Sie es zum Speichern',
|
|
59
69
|
postcode: '{label}: Postleitzahl für {country} mit {n} Ziffern, z. B. {example}',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"de.mjs","sourceRoot":"","sources":["../../../../../../../libs/core/src/lib/record/locales/de.ts"],"names":[],"mappings":"AAEA,yCAAyC;AACzC,MAAM,CAAC,MAAM,EAAE,GAAa;IAC1B,QAAQ,EAAE,0BAA0B;IACpC,SAAS,EAAE,qCAAqC;IAChD,OAAO,EAAE,wCAAwC;IACjD,IAAI,EAAE,wBAAwB;IAC9B,MAAM,EAAE,6BAA6B;IACrC,OAAO,EAAE,mCAAmC;IAC5C,GAAG,EAAE,oCAAoC;IACzC,GAAG,EAAE,mCAAmC;IACxC,QAAQ,EAAE,iDAAiD;IAC3D,WAAW,EAAE,4CAA4C;IACzD,WAAW,EAAE,iDAAiD;IAC9D,YAAY,EAAE,iDAAiD;IAC/D,MAAM,EAAE,mCAAmC;IAC3C,OAAO,EAAE,gCAAgC;IACzC,UAAU,EAAE,+CAA+C;IAC3D,WAAW,EAAE,yCAAyC;IACtD,cAAc,EAAE,kEAAkE;IAClF,eAAe,EAAE,yCAAyC;IAC1D,MAAM,EAAE,kCAAkC;IAC1C,aAAa,EAAE,6DAA6D;IAC5E,MAAM,EAAE,uCAAuC;IAC/C,SAAS,EAAE,yBAAyB;IACpC,UAAU,EAAE,wCAAwC;IACpD,OAAO,EAAE,2CAA2C;IACpD,MAAM,EAAE,iCAAiC;IACzC,OAAO,EAAE,8CAA8C;IACvD,SAAS,EAAE,qCAAqC;IAChD,IAAI,EAAE,8BAA8B;IACpC,QAAQ,EAAE,+BAA+B;IACzC,QAAQ,EAAE,sCAAsC;IAChD,QAAQ,EAAE,kDAAkD;IAC5D,QAAQ,EAAE,+CAA+C;IACzD,SAAS,EAAE,6CAA6C;IACxD,QAAQ,EAAE,iCAAiC;IAC3C,OAAO,EAAE,6CAA6C;IACtD,MAAM,EAAE,4CAA4C;IACpD,QAAQ,EAAE,0CAA0C;IACpD,UAAU,EAAE,oCAAoC;IAChD,KAAK,EAAE,8CAA8C;IACrD,QAAQ,EAAE,6DAA6D;IACvE,EAAE,EAAE,MAAM;IACV,IAAI,EAAE,iDAAiD;IACvD,KAAK,EAAE,2DAA2D;IAClE,GAAG,EAAE,kDAAkD;IACvD,KAAK,EAAE,0DAA0D;IACjE,IAAI,EAAE,yCAAyC;IAC/C,MAAM,EAAE,2BAA2B;IACnC,KAAK,EAAE,2BAA2B;IAClC,OAAO,EAAE,4CAA4C;IACrD,QAAQ,EAAE,0CAA0C;IACpD,QAAQ,EAAE,sCAAsC;IAChD,YAAY,EAAE,kFAAkF;IAChG,cAAc,EAAE,oDAAoD;IACpE,aAAa,EAAE,gDAAgD;IAC/D,MAAM,EAAE,mFAAmF;IAC3F,SAAS,EAAE,8EAA8E;IACzF,QAAQ,EAAE,sEAAsE;IAChF,SAAS,EAAE,wDAAwD;IACnE,cAAc,EAAE,qCAAqC;IACrD,QAAQ,EAAE,iFAAiF;IAC3F,aAAa,EAAE,gDAAgD;IAC/D,MAAM,EAAE,IAAI;CACb,CAAC"}
|
|
1
|
+
{"version":3,"file":"de.mjs","sourceRoot":"","sources":["../../../../../../../libs/core/src/lib/record/locales/de.ts"],"names":[],"mappings":"AAEA,yCAAyC;AACzC,MAAM,CAAC,MAAM,EAAE,GAAa;IAC1B,QAAQ,EAAE,0BAA0B;IACpC,SAAS,EAAE,qCAAqC;IAChD,OAAO,EAAE,wCAAwC;IACjD,IAAI,EAAE,wBAAwB;IAC9B,MAAM,EAAE,6BAA6B;IACrC,OAAO,EAAE,mCAAmC;IAC5C,GAAG,EAAE,oCAAoC;IACzC,GAAG,EAAE,mCAAmC;IACxC,QAAQ,EAAE,iDAAiD;IAC3D,WAAW,EAAE,4CAA4C;IACzD,WAAW,EAAE,iDAAiD;IAC9D,YAAY,EAAE,iDAAiD;IAC/D,MAAM,EAAE,mCAAmC;IAC3C,OAAO,EAAE,gCAAgC;IACzC,UAAU,EAAE,+CAA+C;IAC3D,WAAW,EAAE,yCAAyC;IACtD,cAAc,EAAE,kEAAkE;IAClF,eAAe,EAAE,yCAAyC;IAC1D,MAAM,EAAE,kCAAkC;IAC1C,aAAa,EAAE,6DAA6D;IAC5E,MAAM,EAAE,uCAAuC;IAC/C,SAAS,EAAE,yBAAyB;IACpC,UAAU,EAAE,wCAAwC;IACpD,OAAO,EAAE,2CAA2C;IACpD,MAAM,EAAE,iCAAiC;IACzC,OAAO,EAAE,8CAA8C;IACvD,SAAS,EAAE,qCAAqC;IAChD,IAAI,EAAE,8BAA8B;IACpC,QAAQ,EAAE,+BAA+B;IACzC,QAAQ,EAAE,sCAAsC;IAChD,QAAQ,EAAE,kDAAkD;IAC5D,QAAQ,EAAE,+CAA+C;IACzD,WAAW,EAAE,iEAAiE;IAC9E,eAAe,EAAE,uEAAuE;IACxF,WAAW,EAAE,yCAAyC;IACtD,SAAS,EAAE,6CAA6C;IACxD,QAAQ,EAAE,iCAAiC;IAC3C,OAAO,EAAE,6CAA6C;IACtD,MAAM,EAAE,4CAA4C;IACpD,QAAQ,EAAE,0CAA0C;IACpD,UAAU,EAAE,oCAAoC;IAChD,KAAK,EAAE,8CAA8C;IACrD,QAAQ,EAAE,6DAA6D;IACvE,EAAE,EAAE,MAAM;IACV,IAAI,EAAE,iDAAiD;IACvD,KAAK,EAAE,2DAA2D;IAClE,GAAG,EAAE,kDAAkD;IACvD,KAAK,EAAE,0DAA0D;IACjE,IAAI,EAAE,yCAAyC;IAC/C,MAAM,EAAE,2BAA2B;IACnC,KAAK,EAAE,2BAA2B;IAClC,OAAO,EAAE,4CAA4C;IACrD,QAAQ,EAAE,0CAA0C;IACpD,QAAQ,EAAE,sCAAsC;IAChD,YAAY,EAAE,kFAAkF;IAChG,cAAc,EAAE,oDAAoD;IACpE,aAAa,EAAE,gDAAgD;IAC/D,UAAU,EAAE,uDAAuD;IACnE,aAAa,EAAE,gDAAgD;IAC/D,eAAe,EAAE,gDAAgD;IACjE,YAAY,EAAE,4CAA4C;IAC1D,YAAY,EAAE,kJAAkJ;IAChK,cAAc,EAAE,4BAA4B;IAC5C,cAAc,EAAE,2FAA2F;IAC3G,MAAM,EAAE,mFAAmF;IAC3F,SAAS,EAAE,8EAA8E;IACzF,QAAQ,EAAE,sEAAsE;IAChF,SAAS,EAAE,wDAAwD;IACnE,cAAc,EAAE,qCAAqC;IACrD,QAAQ,EAAE,iFAAiF;IAC3F,aAAa,EAAE,gDAAgD;IAC/D,MAAM,EAAE,IAAI;CACb,CAAC"}
|
|
@@ -35,6 +35,9 @@ exports.fr = {
|
|
|
35
35
|
fileType: '{label} doit être un fichier {types}',
|
|
36
36
|
minFiles: 'Ajoutez au moins {min} fichiers à {label}',
|
|
37
37
|
maxFiles: 'Trop de fichiers pour {label} : {max} au plus',
|
|
38
|
+
notUploaded: '{name} n’a pas été envoyé : réessayez, ou retirez-le',
|
|
39
|
+
notUploadedMany: '{n} fichiers n’ont pas été envoyés : réessayez, ou retirez-les',
|
|
40
|
+
fileRefused: '{name} n’a pas été accepté : {reason}',
|
|
38
41
|
minLength: '{label} doit comporter au moins {min} caractères',
|
|
39
42
|
endsWith: '{label} doit se terminer par {ending}',
|
|
40
43
|
atLeast: 'Choisissez au moins {min} pour {label}',
|
|
@@ -57,6 +60,13 @@ exports.fr = {
|
|
|
57
60
|
addressParts: 'Adresse|Complément d’adresse|Ville|État ou région|Code postal|Pays',
|
|
58
61
|
archiveConfirm: 'Voulez-vous vraiment archiver cet enregistrement ?',
|
|
59
62
|
deleteConfirm: 'Voulez-vous vraiment supprimer cet enregistrement ?',
|
|
63
|
+
mayNotEdit: 'Vous pouvez lire cet enregistrement, mais pas le modifier.',
|
|
64
|
+
mayNotArchive: 'Vous ne pouvez pas archiver cet enregistrement.',
|
|
65
|
+
mayNotDuplicate: 'Vous ne pouvez pas dupliquer cet enregistrement.',
|
|
66
|
+
mayNotDelete: 'Vous ne pouvez pas supprimer cet enregistrement.',
|
|
67
|
+
theirsUnread: 'Leur version n’a pas pu être lue : la vôtre n’a donc pas été enregistrée par-dessus. Réessayez Garder les miennes, ou Recharger.',
|
|
68
|
+
discardChanges: 'Abandonner vos modifications ?',
|
|
69
|
+
recordReplaced: 'Un autre enregistrement est affiché : le reste de ces étapes n’a pas été exécuté.',
|
|
60
70
|
overBy: '{label} dépasse de {over} caractères la limite de {max} : raccourcissez-le pour enregistrer',
|
|
61
71
|
overByOne: '{label} dépasse d’un caractère la limite de {max} : raccourcissez-le pour enregistrer',
|
|
62
72
|
postcode: '{label} : code postal de {n} chiffres attendu pour {country}, par exemple {example}',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fr.js","sourceRoot":"","sources":["../../../../../../../libs/core/src/lib/record/locales/fr.ts"],"names":[],"mappings":";;;AAEA,yCAAyC;AAC5B,QAAA,EAAE,GAAa;IAC1B,QAAQ,EAAE,yBAAyB;IACnC,SAAS,EAAE,0CAA0C;IACrD,OAAO,EAAE,mCAAmC;IAC5C,IAAI,EAAE,4BAA4B;IAClC,MAAM,EAAE,6BAA6B;IACrC,OAAO,EAAE,oCAAoC;IAC7C,GAAG,EAAE,kCAAkC;IACvC,GAAG,EAAE,iCAAiC;IACtC,QAAQ,EAAE,4CAA4C;IACtD,WAAW,EAAE,sCAAsC;IACnD,WAAW,EAAE,4CAA4C;IACzD,YAAY,EAAE,4CAA4C;IAC1D,MAAM,EAAE,sCAAsC;IAC9C,OAAO,EAAE,8BAA8B;IACvC,UAAU,EAAE,8CAA8C;IAC1D,WAAW,EAAE,6CAA6C;IAC1D,cAAc,EAAE,gEAAgE;IAChF,eAAe,EAAE,wBAAwB;IACzC,MAAM,EAAE,6BAA6B;IACrC,aAAa,EAAE,mDAAmD;IAClE,MAAM,EAAE,sCAAsC;IAC9C,SAAS,EAAE,0BAA0B;IACrC,UAAU,EAAE,oCAAoC;IAChD,OAAO,EAAE,sCAAsC;IAC/C,MAAM,EAAE,qCAAqC;IAC7C,OAAO,EAAE,+CAA+C;IACxD,SAAS,EAAE,oCAAoC;IAC/C,IAAI,EAAE,8BAA8B;IACpC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,sCAAsC;IAChD,QAAQ,EAAE,2CAA2C;IACrD,QAAQ,EAAE,+CAA+C;IACzD,SAAS,EAAE,kDAAkD;IAC7D,QAAQ,EAAE,uCAAuC;IACjD,OAAO,EAAE,wCAAwC;IACjD,MAAM,EAAE,uCAAuC;IAC/C,QAAQ,EAAE,iCAAiC;IAC3C,UAAU,EAAE,iCAAiC;IAC7C,KAAK,EAAE,kDAAkD;IACzD,QAAQ,EAAE,2DAA2D;IACrE,EAAE,EAAE,IAAI;IACR,IAAI,EAAE,kCAAkC;IACxC,KAAK,EAAE,2DAA2D;IAClE,GAAG,EAAE,oDAAoD;IACzD,KAAK,EAAE,iEAAiE;IACxE,IAAI,EAAE,wCAAwC;IAC9C,MAAM,EAAE,6BAA6B;IACrC,KAAK,EAAE,8BAA8B;IACrC,OAAO,EAAE,sCAAsC;IAC/C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,8CAA8C;IACxD,YAAY,EAAE,oEAAoE;IAClF,cAAc,EAAE,oDAAoD;IACpE,aAAa,EAAE,qDAAqD;IACpE,MAAM,EAAE,6FAA6F;IACrG,SAAS,EAAE,uFAAuF;IAClG,QAAQ,EAAE,qFAAqF;IAC/F,SAAS,EAAE,wDAAwD;IACnE,cAAc,EAAE,oCAAoC;IACpD,QAAQ,EAAE,sFAAsF;IAChG,aAAa,EAAE,kDAAkD;IACjE,MAAM,EAAE,IAAI;CACb,CAAC"}
|
|
1
|
+
{"version":3,"file":"fr.js","sourceRoot":"","sources":["../../../../../../../libs/core/src/lib/record/locales/fr.ts"],"names":[],"mappings":";;;AAEA,yCAAyC;AAC5B,QAAA,EAAE,GAAa;IAC1B,QAAQ,EAAE,yBAAyB;IACnC,SAAS,EAAE,0CAA0C;IACrD,OAAO,EAAE,mCAAmC;IAC5C,IAAI,EAAE,4BAA4B;IAClC,MAAM,EAAE,6BAA6B;IACrC,OAAO,EAAE,oCAAoC;IAC7C,GAAG,EAAE,kCAAkC;IACvC,GAAG,EAAE,iCAAiC;IACtC,QAAQ,EAAE,4CAA4C;IACtD,WAAW,EAAE,sCAAsC;IACnD,WAAW,EAAE,4CAA4C;IACzD,YAAY,EAAE,4CAA4C;IAC1D,MAAM,EAAE,sCAAsC;IAC9C,OAAO,EAAE,8BAA8B;IACvC,UAAU,EAAE,8CAA8C;IAC1D,WAAW,EAAE,6CAA6C;IAC1D,cAAc,EAAE,gEAAgE;IAChF,eAAe,EAAE,wBAAwB;IACzC,MAAM,EAAE,6BAA6B;IACrC,aAAa,EAAE,mDAAmD;IAClE,MAAM,EAAE,sCAAsC;IAC9C,SAAS,EAAE,0BAA0B;IACrC,UAAU,EAAE,oCAAoC;IAChD,OAAO,EAAE,sCAAsC;IAC/C,MAAM,EAAE,qCAAqC;IAC7C,OAAO,EAAE,+CAA+C;IACxD,SAAS,EAAE,oCAAoC;IAC/C,IAAI,EAAE,8BAA8B;IACpC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,sCAAsC;IAChD,QAAQ,EAAE,2CAA2C;IACrD,QAAQ,EAAE,+CAA+C;IACzD,WAAW,EAAE,sDAAsD;IACnE,eAAe,EAAE,gEAAgE;IACjF,WAAW,EAAE,uCAAuC;IACpD,SAAS,EAAE,kDAAkD;IAC7D,QAAQ,EAAE,uCAAuC;IACjD,OAAO,EAAE,wCAAwC;IACjD,MAAM,EAAE,uCAAuC;IAC/C,QAAQ,EAAE,iCAAiC;IAC3C,UAAU,EAAE,iCAAiC;IAC7C,KAAK,EAAE,kDAAkD;IACzD,QAAQ,EAAE,2DAA2D;IACrE,EAAE,EAAE,IAAI;IACR,IAAI,EAAE,kCAAkC;IACxC,KAAK,EAAE,2DAA2D;IAClE,GAAG,EAAE,oDAAoD;IACzD,KAAK,EAAE,iEAAiE;IACxE,IAAI,EAAE,wCAAwC;IAC9C,MAAM,EAAE,6BAA6B;IACrC,KAAK,EAAE,8BAA8B;IACrC,OAAO,EAAE,sCAAsC;IAC/C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,8CAA8C;IACxD,YAAY,EAAE,oEAAoE;IAClF,cAAc,EAAE,oDAAoD;IACpE,aAAa,EAAE,qDAAqD;IACpE,UAAU,EAAE,4DAA4D;IACxE,aAAa,EAAE,iDAAiD;IAChE,eAAe,EAAE,kDAAkD;IACnE,YAAY,EAAE,kDAAkD;IAChE,YAAY,EAAE,kIAAkI;IAChJ,cAAc,EAAE,gCAAgC;IAChD,cAAc,EAAE,mFAAmF;IACnG,MAAM,EAAE,6FAA6F;IACrG,SAAS,EAAE,uFAAuF;IAClG,QAAQ,EAAE,qFAAqF;IAC/F,SAAS,EAAE,wDAAwD;IACnE,cAAc,EAAE,oCAAoC;IACpD,QAAQ,EAAE,sFAAsF;IAChG,aAAa,EAAE,kDAAkD;IACjE,MAAM,EAAE,IAAI;CACb,CAAC"}
|
|
@@ -32,6 +32,9 @@ export const fr = {
|
|
|
32
32
|
fileType: '{label} doit être un fichier {types}',
|
|
33
33
|
minFiles: 'Ajoutez au moins {min} fichiers à {label}',
|
|
34
34
|
maxFiles: 'Trop de fichiers pour {label} : {max} au plus',
|
|
35
|
+
notUploaded: '{name} n’a pas été envoyé : réessayez, ou retirez-le',
|
|
36
|
+
notUploadedMany: '{n} fichiers n’ont pas été envoyés : réessayez, ou retirez-les',
|
|
37
|
+
fileRefused: '{name} n’a pas été accepté : {reason}',
|
|
35
38
|
minLength: '{label} doit comporter au moins {min} caractères',
|
|
36
39
|
endsWith: '{label} doit se terminer par {ending}',
|
|
37
40
|
atLeast: 'Choisissez au moins {min} pour {label}',
|
|
@@ -54,6 +57,13 @@ export const fr = {
|
|
|
54
57
|
addressParts: 'Adresse|Complément d’adresse|Ville|État ou région|Code postal|Pays',
|
|
55
58
|
archiveConfirm: 'Voulez-vous vraiment archiver cet enregistrement ?',
|
|
56
59
|
deleteConfirm: 'Voulez-vous vraiment supprimer cet enregistrement ?',
|
|
60
|
+
mayNotEdit: 'Vous pouvez lire cet enregistrement, mais pas le modifier.',
|
|
61
|
+
mayNotArchive: 'Vous ne pouvez pas archiver cet enregistrement.',
|
|
62
|
+
mayNotDuplicate: 'Vous ne pouvez pas dupliquer cet enregistrement.',
|
|
63
|
+
mayNotDelete: 'Vous ne pouvez pas supprimer cet enregistrement.',
|
|
64
|
+
theirsUnread: 'Leur version n’a pas pu être lue : la vôtre n’a donc pas été enregistrée par-dessus. Réessayez Garder les miennes, ou Recharger.',
|
|
65
|
+
discardChanges: 'Abandonner vos modifications ?',
|
|
66
|
+
recordReplaced: 'Un autre enregistrement est affiché : le reste de ces étapes n’a pas été exécuté.',
|
|
57
67
|
overBy: '{label} dépasse de {over} caractères la limite de {max} : raccourcissez-le pour enregistrer',
|
|
58
68
|
overByOne: '{label} dépasse d’un caractère la limite de {max} : raccourcissez-le pour enregistrer',
|
|
59
69
|
postcode: '{label} : code postal de {n} chiffres attendu pour {country}, par exemple {example}',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fr.mjs","sourceRoot":"","sources":["../../../../../../../libs/core/src/lib/record/locales/fr.ts"],"names":[],"mappings":"AAEA,yCAAyC;AACzC,MAAM,CAAC,MAAM,EAAE,GAAa;IAC1B,QAAQ,EAAE,yBAAyB;IACnC,SAAS,EAAE,0CAA0C;IACrD,OAAO,EAAE,mCAAmC;IAC5C,IAAI,EAAE,4BAA4B;IAClC,MAAM,EAAE,6BAA6B;IACrC,OAAO,EAAE,oCAAoC;IAC7C,GAAG,EAAE,kCAAkC;IACvC,GAAG,EAAE,iCAAiC;IACtC,QAAQ,EAAE,4CAA4C;IACtD,WAAW,EAAE,sCAAsC;IACnD,WAAW,EAAE,4CAA4C;IACzD,YAAY,EAAE,4CAA4C;IAC1D,MAAM,EAAE,sCAAsC;IAC9C,OAAO,EAAE,8BAA8B;IACvC,UAAU,EAAE,8CAA8C;IAC1D,WAAW,EAAE,6CAA6C;IAC1D,cAAc,EAAE,gEAAgE;IAChF,eAAe,EAAE,wBAAwB;IACzC,MAAM,EAAE,6BAA6B;IACrC,aAAa,EAAE,mDAAmD;IAClE,MAAM,EAAE,sCAAsC;IAC9C,SAAS,EAAE,0BAA0B;IACrC,UAAU,EAAE,oCAAoC;IAChD,OAAO,EAAE,sCAAsC;IAC/C,MAAM,EAAE,qCAAqC;IAC7C,OAAO,EAAE,+CAA+C;IACxD,SAAS,EAAE,oCAAoC;IAC/C,IAAI,EAAE,8BAA8B;IACpC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,sCAAsC;IAChD,QAAQ,EAAE,2CAA2C;IACrD,QAAQ,EAAE,+CAA+C;IACzD,SAAS,EAAE,kDAAkD;IAC7D,QAAQ,EAAE,uCAAuC;IACjD,OAAO,EAAE,wCAAwC;IACjD,MAAM,EAAE,uCAAuC;IAC/C,QAAQ,EAAE,iCAAiC;IAC3C,UAAU,EAAE,iCAAiC;IAC7C,KAAK,EAAE,kDAAkD;IACzD,QAAQ,EAAE,2DAA2D;IACrE,EAAE,EAAE,IAAI;IACR,IAAI,EAAE,kCAAkC;IACxC,KAAK,EAAE,2DAA2D;IAClE,GAAG,EAAE,oDAAoD;IACzD,KAAK,EAAE,iEAAiE;IACxE,IAAI,EAAE,wCAAwC;IAC9C,MAAM,EAAE,6BAA6B;IACrC,KAAK,EAAE,8BAA8B;IACrC,OAAO,EAAE,sCAAsC;IAC/C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,8CAA8C;IACxD,YAAY,EAAE,oEAAoE;IAClF,cAAc,EAAE,oDAAoD;IACpE,aAAa,EAAE,qDAAqD;IACpE,MAAM,EAAE,6FAA6F;IACrG,SAAS,EAAE,uFAAuF;IAClG,QAAQ,EAAE,qFAAqF;IAC/F,SAAS,EAAE,wDAAwD;IACnE,cAAc,EAAE,oCAAoC;IACpD,QAAQ,EAAE,sFAAsF;IAChG,aAAa,EAAE,kDAAkD;IACjE,MAAM,EAAE,IAAI;CACb,CAAC"}
|
|
1
|
+
{"version":3,"file":"fr.mjs","sourceRoot":"","sources":["../../../../../../../libs/core/src/lib/record/locales/fr.ts"],"names":[],"mappings":"AAEA,yCAAyC;AACzC,MAAM,CAAC,MAAM,EAAE,GAAa;IAC1B,QAAQ,EAAE,yBAAyB;IACnC,SAAS,EAAE,0CAA0C;IACrD,OAAO,EAAE,mCAAmC;IAC5C,IAAI,EAAE,4BAA4B;IAClC,MAAM,EAAE,6BAA6B;IACrC,OAAO,EAAE,oCAAoC;IAC7C,GAAG,EAAE,kCAAkC;IACvC,GAAG,EAAE,iCAAiC;IACtC,QAAQ,EAAE,4CAA4C;IACtD,WAAW,EAAE,sCAAsC;IACnD,WAAW,EAAE,4CAA4C;IACzD,YAAY,EAAE,4CAA4C;IAC1D,MAAM,EAAE,sCAAsC;IAC9C,OAAO,EAAE,8BAA8B;IACvC,UAAU,EAAE,8CAA8C;IAC1D,WAAW,EAAE,6CAA6C;IAC1D,cAAc,EAAE,gEAAgE;IAChF,eAAe,EAAE,wBAAwB;IACzC,MAAM,EAAE,6BAA6B;IACrC,aAAa,EAAE,mDAAmD;IAClE,MAAM,EAAE,sCAAsC;IAC9C,SAAS,EAAE,0BAA0B;IACrC,UAAU,EAAE,oCAAoC;IAChD,OAAO,EAAE,sCAAsC;IAC/C,MAAM,EAAE,qCAAqC;IAC7C,OAAO,EAAE,+CAA+C;IACxD,SAAS,EAAE,oCAAoC;IAC/C,IAAI,EAAE,8BAA8B;IACpC,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,sCAAsC;IAChD,QAAQ,EAAE,2CAA2C;IACrD,QAAQ,EAAE,+CAA+C;IACzD,WAAW,EAAE,sDAAsD;IACnE,eAAe,EAAE,gEAAgE;IACjF,WAAW,EAAE,uCAAuC;IACpD,SAAS,EAAE,kDAAkD;IAC7D,QAAQ,EAAE,uCAAuC;IACjD,OAAO,EAAE,wCAAwC;IACjD,MAAM,EAAE,uCAAuC;IAC/C,QAAQ,EAAE,iCAAiC;IAC3C,UAAU,EAAE,iCAAiC;IAC7C,KAAK,EAAE,kDAAkD;IACzD,QAAQ,EAAE,2DAA2D;IACrE,EAAE,EAAE,IAAI;IACR,IAAI,EAAE,kCAAkC;IACxC,KAAK,EAAE,2DAA2D;IAClE,GAAG,EAAE,oDAAoD;IACzD,KAAK,EAAE,iEAAiE;IACxE,IAAI,EAAE,wCAAwC;IAC9C,MAAM,EAAE,6BAA6B;IACrC,KAAK,EAAE,8BAA8B;IACrC,OAAO,EAAE,sCAAsC;IAC/C,QAAQ,EAAE,kCAAkC;IAC5C,QAAQ,EAAE,8CAA8C;IACxD,YAAY,EAAE,oEAAoE;IAClF,cAAc,EAAE,oDAAoD;IACpE,aAAa,EAAE,qDAAqD;IACpE,UAAU,EAAE,4DAA4D;IACxE,aAAa,EAAE,iDAAiD;IAChE,eAAe,EAAE,kDAAkD;IACnE,YAAY,EAAE,kDAAkD;IAChE,YAAY,EAAE,kIAAkI;IAChJ,cAAc,EAAE,gCAAgC;IAChD,cAAc,EAAE,mFAAmF;IACnG,MAAM,EAAE,6FAA6F;IACrG,SAAS,EAAE,uFAAuF;IAClG,QAAQ,EAAE,qFAAqF;IAC/F,SAAS,EAAE,wDAAwD;IACnE,cAAc,EAAE,oCAAoC;IACpD,QAAQ,EAAE,sFAAsF;IAChG,aAAa,EAAE,kDAAkD;IACjE,MAAM,EAAE,IAAI;CACb,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Option, PropertyDefinition } from '../format/field.mjs';
|
|
2
|
-
import type { DataSource, SubmitRequest } from './data-source.mjs';
|
|
2
|
+
import type { DataSource, SubmitRequest, RecordPermissions, RecordVersion, UploadFile } from './data-source.mjs';
|
|
3
3
|
import { type Scheduler } from './scheduler.mjs';
|
|
4
|
-
import { type FileValue, type Values } from './values.mjs';
|
|
4
|
+
import { type FileValue, type RecordId, type Values } from './values.mjs';
|
|
5
5
|
export interface MemoryDataSourceOptions {
|
|
6
6
|
/** Records by model, then by id. */
|
|
7
7
|
records?: Record<string, Record<string, Values>>;
|
|
@@ -44,7 +44,35 @@ export interface MemoryDataSourceOptions {
|
|
|
44
44
|
attachments?: Record<string, FileValue[]>;
|
|
45
45
|
/** The words after a copy's name, as a backend's copy adds them: " (copy)" unless said. */
|
|
46
46
|
copySuffix?: string;
|
|
47
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Keep a version of each record, moved on by each save: a load gives it
|
|
49
|
+
* (with `loadedRecord`), and a save that carries an older one is refused
|
|
50
|
+
* with a `ConflictError`. `by` names whoever saves through this source;
|
|
51
|
+
* `changeElsewhere` changes a record as someone else would.
|
|
52
|
+
*/
|
|
53
|
+
versions?: boolean | {
|
|
54
|
+
by?: string;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* What the person may do with each record, by model: given with its load
|
|
58
|
+
* and its row in a list, and kept to as a backend would — a save, a
|
|
59
|
+
* delete, an archive or a copy it does not allow is refused, and hidden
|
|
60
|
+
* fields' values are left out.
|
|
61
|
+
*/
|
|
62
|
+
can?: Record<string, (values: Values, id: RecordId) => RecordPermissions | undefined>;
|
|
63
|
+
/**
|
|
64
|
+
* A store as slow, or as unreliable, as a real one, for demos and tests of
|
|
65
|
+
* files stored as they are picked: `bytesPerSecond` paces each upload, its
|
|
66
|
+
* progress told every tenth of a second; `fails` says which tries fail —
|
|
67
|
+
* true for a failure partway that Retry may mend, words for the store
|
|
68
|
+
* refusing the file as it is (its kind, its size). Each file's tries are
|
|
69
|
+
* counted by its name and size, from 1.
|
|
70
|
+
*/
|
|
71
|
+
storage?: {
|
|
72
|
+
bytesPerSecond?: number;
|
|
73
|
+
fails?: (file: UploadFile, attempt: number) => boolean | string | undefined;
|
|
74
|
+
};
|
|
75
|
+
/** Answer after this long, so a demo shows its loading states (an upload's progress, in four steps). */
|
|
48
76
|
delayMs?: number;
|
|
49
77
|
scheduler?: Scheduler;
|
|
50
78
|
}
|
|
@@ -55,6 +83,15 @@ export interface MemoryDataSource extends Required<DataSource> {
|
|
|
55
83
|
method: keyof DataSource;
|
|
56
84
|
request: unknown;
|
|
57
85
|
}[];
|
|
86
|
+
/**
|
|
87
|
+
* Change a stored record as someone else would, from another screen: its
|
|
88
|
+
* version moves on, named for them, so a page that opened it before is
|
|
89
|
+
* told of a conflict when it saves. Gives the new version.
|
|
90
|
+
*/
|
|
91
|
+
changeElsewhere(model: string, id: RecordId, values: Values, who: {
|
|
92
|
+
by: string;
|
|
93
|
+
at?: string;
|
|
94
|
+
}): RecordVersion;
|
|
58
95
|
}
|
|
59
96
|
/**
|
|
60
97
|
* A data source that keeps everything in memory. It implements the whole
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Option, PropertyDefinition } from '../format/field';
|
|
2
|
-
import type { DataSource, SubmitRequest } from './data-source';
|
|
2
|
+
import type { DataSource, SubmitRequest, RecordPermissions, RecordVersion, UploadFile } from './data-source';
|
|
3
3
|
import { type Scheduler } from './scheduler';
|
|
4
|
-
import { type FileValue, type Values } from './values';
|
|
4
|
+
import { type FileValue, type RecordId, type Values } from './values';
|
|
5
5
|
export interface MemoryDataSourceOptions {
|
|
6
6
|
/** Records by model, then by id. */
|
|
7
7
|
records?: Record<string, Record<string, Values>>;
|
|
@@ -44,7 +44,35 @@ export interface MemoryDataSourceOptions {
|
|
|
44
44
|
attachments?: Record<string, FileValue[]>;
|
|
45
45
|
/** The words after a copy's name, as a backend's copy adds them: " (copy)" unless said. */
|
|
46
46
|
copySuffix?: string;
|
|
47
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Keep a version of each record, moved on by each save: a load gives it
|
|
49
|
+
* (with `loadedRecord`), and a save that carries an older one is refused
|
|
50
|
+
* with a `ConflictError`. `by` names whoever saves through this source;
|
|
51
|
+
* `changeElsewhere` changes a record as someone else would.
|
|
52
|
+
*/
|
|
53
|
+
versions?: boolean | {
|
|
54
|
+
by?: string;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* What the person may do with each record, by model: given with its load
|
|
58
|
+
* and its row in a list, and kept to as a backend would — a save, a
|
|
59
|
+
* delete, an archive or a copy it does not allow is refused, and hidden
|
|
60
|
+
* fields' values are left out.
|
|
61
|
+
*/
|
|
62
|
+
can?: Record<string, (values: Values, id: RecordId) => RecordPermissions | undefined>;
|
|
63
|
+
/**
|
|
64
|
+
* A store as slow, or as unreliable, as a real one, for demos and tests of
|
|
65
|
+
* files stored as they are picked: `bytesPerSecond` paces each upload, its
|
|
66
|
+
* progress told every tenth of a second; `fails` says which tries fail —
|
|
67
|
+
* true for a failure partway that Retry may mend, words for the store
|
|
68
|
+
* refusing the file as it is (its kind, its size). Each file's tries are
|
|
69
|
+
* counted by its name and size, from 1.
|
|
70
|
+
*/
|
|
71
|
+
storage?: {
|
|
72
|
+
bytesPerSecond?: number;
|
|
73
|
+
fails?: (file: UploadFile, attempt: number) => boolean | string | undefined;
|
|
74
|
+
};
|
|
75
|
+
/** Answer after this long, so a demo shows its loading states (an upload's progress, in four steps). */
|
|
48
76
|
delayMs?: number;
|
|
49
77
|
scheduler?: Scheduler;
|
|
50
78
|
}
|
|
@@ -55,6 +83,15 @@ export interface MemoryDataSource extends Required<DataSource> {
|
|
|
55
83
|
method: keyof DataSource;
|
|
56
84
|
request: unknown;
|
|
57
85
|
}[];
|
|
86
|
+
/**
|
|
87
|
+
* Change a stored record as someone else would, from another screen: its
|
|
88
|
+
* version moves on, named for them, so a page that opened it before is
|
|
89
|
+
* told of a conflict when it saves. Gives the new version.
|
|
90
|
+
*/
|
|
91
|
+
changeElsewhere(model: string, id: RecordId, values: Values, who: {
|
|
92
|
+
by: string;
|
|
93
|
+
at?: string;
|
|
94
|
+
}): RecordVersion;
|
|
58
95
|
}
|
|
59
96
|
/**
|
|
60
97
|
* A data source that keeps everything in memory. It implements the whole
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createMemoryDataSource = createMemoryDataSource;
|
|
4
4
|
const input_rules_1 = require("./input-rules");
|
|
5
|
+
const data_source_1 = require("./data-source");
|
|
5
6
|
const filter_1 = require("./filter");
|
|
6
7
|
const scheduler_1 = require("./scheduler");
|
|
7
8
|
const values_1 = require("./values");
|
|
@@ -17,6 +18,43 @@ function createMemoryDataSource(options = {}) {
|
|
|
17
18
|
/** Properties added in place, by the list and the definitions the app gave for the record they were added to. */
|
|
18
19
|
const addedDefinitions = new Map();
|
|
19
20
|
let lineIds = 1000;
|
|
21
|
+
let fileIds = 0;
|
|
22
|
+
/** Each file's tries at the store, by its name and size: what `storage.fails` is told. */
|
|
23
|
+
const tries = new Map();
|
|
24
|
+
/** Each record's version, by `model:id`, given when first asked. */
|
|
25
|
+
const versions = new Map();
|
|
26
|
+
let stamps = 0;
|
|
27
|
+
const versionOf = (model, id) => {
|
|
28
|
+
if (!options.versions)
|
|
29
|
+
return undefined;
|
|
30
|
+
const key = `${model}:${id}`;
|
|
31
|
+
if (!versions.has(key))
|
|
32
|
+
versions.set(key, { token: String(++stamps) });
|
|
33
|
+
return versions.get(key);
|
|
34
|
+
};
|
|
35
|
+
const moveOn = (model, id, by, at = new Date().toISOString()) => {
|
|
36
|
+
const version = { token: String(++stamps), ...(by ? { by } : {}), at };
|
|
37
|
+
versions.set(`${model}:${id}`, version);
|
|
38
|
+
return version;
|
|
39
|
+
};
|
|
40
|
+
const me = typeof options.versions === 'object' ? options.versions.by : undefined;
|
|
41
|
+
const permissions = (model, id) => {
|
|
42
|
+
const stored = table(model)[String(id)];
|
|
43
|
+
return stored ? options.can?.[model]?.((0, values_1.structuredCopy)(stored), id) : undefined;
|
|
44
|
+
};
|
|
45
|
+
/** A record as this person may read it: without the fields hidden from them. */
|
|
46
|
+
const readable = (values, can) => {
|
|
47
|
+
for (const name of can?.hiddenFields ?? [])
|
|
48
|
+
delete values[name];
|
|
49
|
+
return values;
|
|
50
|
+
};
|
|
51
|
+
/** Refused, as a backend refuses what the person may not do. */
|
|
52
|
+
const allowed = (can, what) => {
|
|
53
|
+
if (can?.[what] === false)
|
|
54
|
+
throw (0, data_source_1.saveRefused)({ kind: 'rule', message: can.reason ?? `You may not ${what} this record` });
|
|
55
|
+
};
|
|
56
|
+
/** A version and permissions, where this source keeps them. */
|
|
57
|
+
const told = (version, can) => ({ ...(version ? { version } : {}), ...(can ? { can } : {}) });
|
|
20
58
|
const pause = () => (options.delayMs ? (0, scheduler_1.wait)(options.delayMs, options.scheduler) : Promise.resolve());
|
|
21
59
|
const table = (model) => (records[model] ??= {});
|
|
22
60
|
const labelOf = (model, id) => {
|
|
@@ -56,6 +94,8 @@ function createMemoryDataSource(options = {}) {
|
|
|
56
94
|
const asId = (key) => (Number.isFinite(Number(key)) ? Number(key) : key);
|
|
57
95
|
/** A record as a filter reads it: its values and its own `id`, which a field of its own named id comes before. */
|
|
58
96
|
const withId = (key, values) => ({ id: asId(key), ...values });
|
|
97
|
+
/** The stored records a filter keeps. */
|
|
98
|
+
const matchingRows = (model, filter) => Object.entries(table(model)).filter(([key, values]) => (0, filter_1.matchesFilter)(withId(key, values), filter)).map(([, values]) => values);
|
|
59
99
|
function applyLines(current, ops) {
|
|
60
100
|
let lines = [...current];
|
|
61
101
|
for (const op of ops) {
|
|
@@ -91,13 +131,22 @@ function createMemoryDataSource(options = {}) {
|
|
|
91
131
|
records,
|
|
92
132
|
responses,
|
|
93
133
|
calls,
|
|
134
|
+
changeElsewhere(model, id, values, who) {
|
|
135
|
+
const stored = table(model)[String(id)];
|
|
136
|
+
if (!stored)
|
|
137
|
+
throw new Error(`No ${model} record with id ${id}`);
|
|
138
|
+
Object.assign(stored, (0, values_1.structuredCopy)(values));
|
|
139
|
+
return moveOn(model, id, who.by, who.at);
|
|
140
|
+
},
|
|
94
141
|
async load(request) {
|
|
95
142
|
calls.push({ method: 'load', request });
|
|
96
143
|
await pause();
|
|
97
144
|
const stored = table(request.model)[String(request.id)];
|
|
98
145
|
if (!stored)
|
|
99
146
|
throw new Error(`No ${request.model} record with id ${request.id}`);
|
|
100
|
-
const
|
|
147
|
+
const can = permissions(request.model, request.id);
|
|
148
|
+
const version = versionOf(request.model, request.id);
|
|
149
|
+
const values = readable((0, values_1.structuredCopy)(stored), can);
|
|
101
150
|
// Its links, with what their models show besides their names.
|
|
102
151
|
if (options.shows) {
|
|
103
152
|
for (const [name, def] of Object.entries(request.fields)) {
|
|
@@ -108,11 +157,24 @@ function createMemoryDataSource(options = {}) {
|
|
|
108
157
|
values[name] = value.map((record) => shown(def.relation, record));
|
|
109
158
|
}
|
|
110
159
|
}
|
|
111
|
-
|
|
160
|
+
// Bare values, as ever, from a source that keeps no versions and no permissions.
|
|
161
|
+
return version || can ? (0, data_source_1.loadedRecord)(values, told(version, can)) : values;
|
|
112
162
|
},
|
|
113
163
|
async save(request) {
|
|
114
164
|
calls.push({ method: 'save', request });
|
|
115
165
|
await pause();
|
|
166
|
+
if (request.id !== null && table(request.model)[String(request.id)]) {
|
|
167
|
+
const can = permissions(request.model, request.id);
|
|
168
|
+
allowed(can, 'edit');
|
|
169
|
+
const locked = Object.keys(request.changes.values).filter((name) => can?.readonlyFields?.includes(name) || can?.hiddenFields?.includes(name));
|
|
170
|
+
if (locked.length)
|
|
171
|
+
throw (0, data_source_1.saveRefused)({ kind: 'fields', message: 'You may not change these fields', fields: Object.fromEntries(locked.map((name) => [name, 'You may not change this field'])) });
|
|
172
|
+
const now = versionOf(request.model, request.id);
|
|
173
|
+
// A save that says which version it was opened at is checked; one that says none is not.
|
|
174
|
+
if (now && request.version && request.version.token !== now.token) {
|
|
175
|
+
throw new data_source_1.ConflictError({ version: now, theirs: readable((0, values_1.structuredCopy)(table(request.model)[String(request.id)]), can) });
|
|
176
|
+
}
|
|
177
|
+
}
|
|
116
178
|
const id = request.id ?? nextId(request.model);
|
|
117
179
|
const stored = { ...(table(request.model)[String(id)] ?? {}), ...(0, values_1.structuredCopy)(request.changes.values) };
|
|
118
180
|
for (const [name, ops] of Object.entries(request.changes.lines)) {
|
|
@@ -122,7 +184,9 @@ function createMemoryDataSource(options = {}) {
|
|
|
122
184
|
stored[name] = applyLinks(stored[name] ?? [], ops, relationOf(request.fields, name));
|
|
123
185
|
}
|
|
124
186
|
table(request.model)[String(id)] = stored;
|
|
125
|
-
|
|
187
|
+
const version = options.versions ? moveOn(request.model, id, me) : undefined;
|
|
188
|
+
const can = permissions(request.model, id);
|
|
189
|
+
return { id, values: readable((0, values_1.structuredCopy)(stored), can), ...told(version, can) };
|
|
126
190
|
},
|
|
127
191
|
async onchange(request) {
|
|
128
192
|
calls.push({ method: 'onchange', request });
|
|
@@ -168,28 +232,64 @@ function createMemoryDataSource(options = {}) {
|
|
|
168
232
|
});
|
|
169
233
|
return {
|
|
170
234
|
total: matching.length,
|
|
171
|
-
records: matching.slice(request.offset, request.offset + request.limit).map(({ id, values }) =>
|
|
172
|
-
id
|
|
173
|
-
|
|
174
|
-
|
|
235
|
+
records: matching.slice(request.offset, request.offset + request.limit).map(({ id, values }) => {
|
|
236
|
+
const can = permissions(request.model, id);
|
|
237
|
+
const shownValues = readable(Object.fromEntries(request.fields.map((field) => [field, (0, values_1.structuredCopy)(values[field] ?? null)])), can);
|
|
238
|
+
return { id, values: shownValues, ...told(versionOf(request.model, id), can) };
|
|
239
|
+
}),
|
|
240
|
+
...(request.allIds ? { allIds: matching.map(({ id }) => id) } : {}),
|
|
175
241
|
};
|
|
176
242
|
},
|
|
177
243
|
async groups(request) {
|
|
178
244
|
calls.push({ method: 'groups', request });
|
|
179
245
|
await pause();
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
246
|
+
return groupRows(matchingRows(request.model, request.filter), request.field).map(({ rows: _rows, ...group }) => group);
|
|
247
|
+
},
|
|
248
|
+
async totals(request) {
|
|
249
|
+
calls.push({ method: 'totals', request });
|
|
250
|
+
await pause();
|
|
251
|
+
const rows = matchingRows(request.model, request.filter);
|
|
252
|
+
const result = { count: rows.length, totals: totalsOver(rows, request.totals) };
|
|
253
|
+
if (request.groupBy)
|
|
254
|
+
result.groups = groupRows(rows, request.groupBy).map(({ rows: under, ...group }) => ({ ...group, totals: totalsOver(under, request.totals) }));
|
|
255
|
+
return result;
|
|
256
|
+
},
|
|
257
|
+
async upload(file, request) {
|
|
258
|
+
calls.push({ method: 'upload', request: { ...request, file } });
|
|
259
|
+
const stopped = () => Object.assign(new Error('The upload was stopped'), { name: 'AbortError' });
|
|
260
|
+
// A store slow or failing as `storage` says: a refusal at once, a failure partway, the bytes paced as they go.
|
|
261
|
+
const tried = `${file.name}:${file.size}`;
|
|
262
|
+
tries.set(tried, (tries.get(tried) ?? 0) + 1);
|
|
263
|
+
const failure = options.storage?.fails?.(file, tries.get(tried));
|
|
264
|
+
if (typeof failure === 'string')
|
|
265
|
+
throw (0, data_source_1.saveRefused)({ kind: 'rule', message: failure });
|
|
266
|
+
const pace = options.storage?.bytesPerSecond;
|
|
267
|
+
if (pace) {
|
|
268
|
+
const each = Math.max(1, Math.round(pace / 10));
|
|
269
|
+
for (let sent = 0; sent < file.size;) {
|
|
270
|
+
await (0, scheduler_1.wait)(100, options.scheduler);
|
|
271
|
+
if (request.signal?.aborted)
|
|
272
|
+
throw stopped();
|
|
273
|
+
sent = Math.min(file.size, sent + each);
|
|
274
|
+
if (failure && sent >= file.size / 2)
|
|
275
|
+
throw new Error('The store stopped answering: the upload failed partway');
|
|
276
|
+
request.onProgress?.(sent, file.size);
|
|
277
|
+
}
|
|
191
278
|
}
|
|
192
|
-
|
|
279
|
+
// In four steps when it is slowed for a demo, so its progress shows.
|
|
280
|
+
const steps = options.delayMs && !pace ? 4 : 1;
|
|
281
|
+
for (let step = 1; step <= steps && !pace; step++) {
|
|
282
|
+
if (options.delayMs)
|
|
283
|
+
await (0, scheduler_1.wait)(options.delayMs / steps, options.scheduler);
|
|
284
|
+
if (request.signal?.aborted)
|
|
285
|
+
throw stopped();
|
|
286
|
+
request.onProgress?.(Math.round((file.size * step) / steps), file.size);
|
|
287
|
+
}
|
|
288
|
+
if (failure)
|
|
289
|
+
throw new Error('The store stopped answering: the upload failed');
|
|
290
|
+
// Kept as a data address, so a preview needs nothing else.
|
|
291
|
+
const type = file.type || 'application/octet-stream';
|
|
292
|
+
return { fileId: ++fileIds, url: `data:${type};base64,${base64(new Uint8Array(await file.arrayBuffer()))}`, name: file.name, size: file.size, type };
|
|
193
293
|
},
|
|
194
294
|
async create(request) {
|
|
195
295
|
calls.push({ method: 'create', request });
|
|
@@ -211,6 +311,7 @@ function createMemoryDataSource(options = {}) {
|
|
|
211
311
|
const stored = table(request.model)[String(request.id)];
|
|
212
312
|
if (!stored)
|
|
213
313
|
throw new Error(`No ${request.model} record with id ${request.id}`);
|
|
314
|
+
allowed(permissions(request.model, request.id), 'archive');
|
|
214
315
|
stored['active'] = !request.archive;
|
|
215
316
|
},
|
|
216
317
|
async copy(request) {
|
|
@@ -219,6 +320,7 @@ function createMemoryDataSource(options = {}) {
|
|
|
219
320
|
const stored = table(request.model)[String(request.id)];
|
|
220
321
|
if (!stored)
|
|
221
322
|
throw new Error(`No ${request.model} record with id ${request.id}`);
|
|
323
|
+
allowed(permissions(request.model, request.id), 'duplicate');
|
|
222
324
|
const id = nextId(request.model);
|
|
223
325
|
const copy = (0, values_1.structuredCopy)(stored);
|
|
224
326
|
const name = options.labelField?.[request.model] ?? 'name';
|
|
@@ -231,13 +333,15 @@ function createMemoryDataSource(options = {}) {
|
|
|
231
333
|
}
|
|
232
334
|
}
|
|
233
335
|
table(request.model)[String(id)] = copy;
|
|
234
|
-
|
|
336
|
+
const can = permissions(request.model, id);
|
|
337
|
+
return { id, values: readable((0, values_1.structuredCopy)(copy), can), ...told(versionOf(request.model, id), can) };
|
|
235
338
|
},
|
|
236
339
|
async delete(request) {
|
|
237
340
|
calls.push({ method: 'delete', request });
|
|
238
341
|
await pause();
|
|
239
342
|
if (!table(request.model)[String(request.id)])
|
|
240
343
|
throw new Error(`No ${request.model} record with id ${request.id}`);
|
|
344
|
+
allowed(permissions(request.model, request.id), 'delete');
|
|
241
345
|
delete table(request.model)[String(request.id)];
|
|
242
346
|
},
|
|
243
347
|
async attachments(request) {
|
|
@@ -291,4 +395,44 @@ function compareValues(a, b) {
|
|
|
291
395
|
return { result: x - y, empty: false };
|
|
292
396
|
return { result: String(x).localeCompare(String(y)), empty: false };
|
|
293
397
|
}
|
|
398
|
+
/** Records under each value of a field: a link's by its record, nothing as its own group, last; the rest by their labels. */
|
|
399
|
+
function groupRows(rows, field) {
|
|
400
|
+
const grouped = new Map();
|
|
401
|
+
for (const values of rows) {
|
|
402
|
+
const raw = values[field] ?? null;
|
|
403
|
+
const link = raw !== null && typeof raw === 'object' && !Array.isArray(raw) && 'id' in raw ? raw : null;
|
|
404
|
+
const value = (link ? link.id : raw);
|
|
405
|
+
const key = JSON.stringify(value);
|
|
406
|
+
const group = grouped.get(key) ?? { value, label: link ? link.label : raw === null || raw === '' ? '' : String(raw), count: 0, rows: [] };
|
|
407
|
+
group.count++;
|
|
408
|
+
group.rows.push(values);
|
|
409
|
+
grouped.set(key, group);
|
|
410
|
+
}
|
|
411
|
+
return [...grouped.values()].sort((a, b) => (a.value === null) === (b.value === null) ? a.label.localeCompare(b.label) : a.value === null ? 1 : -1);
|
|
412
|
+
}
|
|
413
|
+
/** Each field's totals over these records: of its numbers, and a count of those holding any value. */
|
|
414
|
+
function totalsOver(rows, asked) {
|
|
415
|
+
const totals = {};
|
|
416
|
+
for (const [field, kinds] of Object.entries(asked)) {
|
|
417
|
+
const numbers = rows.map((values) => values[field]).filter((v) => typeof v === 'number' && Number.isFinite(v));
|
|
418
|
+
const sum = numbers.reduce((a, b) => a + b, 0);
|
|
419
|
+
const of = {
|
|
420
|
+
sum,
|
|
421
|
+
avg: numbers.length ? sum / numbers.length : null,
|
|
422
|
+
min: numbers.length ? numbers.reduce((a, b) => Math.min(a, b)) : null,
|
|
423
|
+
max: numbers.length ? numbers.reduce((a, b) => Math.max(a, b)) : null,
|
|
424
|
+
count: rows.filter((values) => !blankValue(values[field])).length,
|
|
425
|
+
};
|
|
426
|
+
totals[field] = Object.fromEntries(kinds.map((kind) => [kind, of[kind]]));
|
|
427
|
+
}
|
|
428
|
+
return totals;
|
|
429
|
+
}
|
|
430
|
+
const blankValue = (v) => v === null || v === undefined || v === '' || (Array.isArray(v) && v.length === 0);
|
|
431
|
+
/** Bytes as base64, by the host's `btoa` (a browser's, or Node's). */
|
|
432
|
+
function base64(bytes) {
|
|
433
|
+
let text = '';
|
|
434
|
+
for (let at = 0; at < bytes.length; at += 0x8000)
|
|
435
|
+
text += String.fromCharCode(...bytes.subarray(at, at + 0x8000));
|
|
436
|
+
return globalThis.btoa(text);
|
|
437
|
+
}
|
|
294
438
|
//# sourceMappingURL=memory-data-source.js.map
|