diff --git a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj
index be53181a..1d0eca76 100644
--- a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj
+++ b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj
@@ -42,6 +42,7 @@
+
diff --git a/EnvelopeGenerator.Web/Handler/FileHandler.cs b/EnvelopeGenerator.Web/Handler/FileHandler.cs
index 36228c97..f5be8167 100644
--- a/EnvelopeGenerator.Web/Handler/FileHandler.cs
+++ b/EnvelopeGenerator.Web/Handler/FileHandler.cs
@@ -2,14 +2,15 @@
using EnvelopeGenerator.Common.My.Resources;
using EnvelopeGenerator.Web.Services;
using Microsoft.Extensions.Primitives;
+using System.IO.Pipelines;
namespace EnvelopeGenerator.Web.Handler
{
public class FileHandler
{
- public async static Task HandleFile(HttpContext ctx, DatabaseService database, LoggingService logging)
+ public async static Task HandleFileDownload(HttpContext ctx, DatabaseService database, LoggingService logging)
{
-
+
var logger = logging.LogConfig.GetLogger("FileHandler");
string envelopeKey = (string)ctx.Request.RouteValues["envelopeKey"];
@@ -39,8 +40,44 @@ namespace EnvelopeGenerator.Web.Handler
{
logger.Error(e);
return Results.Problem();
-
- }
+
+ }
+ }
+
+ public async static Task HandleFileUpload(HttpContext ctx, DatabaseService database, LoggingService logging)
+ {
+ var logger = logging.LogConfig.GetLogger("FileHandler");
+ string envelopeKey = (string)ctx.Request.RouteValues["envelopeKey"];
+ int documentId = int.Parse((string)ctx.Request.RouteValues["documentId"]);
+
+ logger.Info("Uploading file with EnvelopeKey [{0}]", envelopeKey);
+
+ Tuple result = Helpers.DecodeEnvelopeReceiverId(envelopeKey);
+ logger.Info("EnvelopeUUID: [{0}]", result.Item1);
+ logger.Info("ReceiverSignature: [{0}]", result.Item2);
+
+ EnvelopeResponse response = database.LoadEnvelope(envelopeKey);
+ var envelope = response.Envelope;
+ logger.Info("Envelope [{0}] loaded", envelope.Id);
+ logger.Info("Contains [{0}] documents", envelope.Documents.Count);
+ logger.Info("Contains [{0}] receivers", envelope.Receivers.Count);
+
+ var document = envelope.Documents.Where(d => d.Id == documentId).FirstOrDefault();
+
+ if (document != null)
+ {
+ var path = document.Filepath;
+
+ using FileStream fs = new(path, FileMode.Open);
+ await ctx.Request.Body.CopyToAsync(fs);
+ fs.Flush();
+
+ return Results.Ok();
+ }
+ else
+ {
+ return Results.Problem();
+ }
}
private static int getDocumentIndex(HttpContext ctx)
@@ -90,7 +127,7 @@ namespace EnvelopeGenerator.Web.Handler
logger.Info("Contains [{0}] documents", envelope.Documents.Count);
logger.Info("Contains [{0}] receivers", envelope.Receivers.Count);
-
+
return Task.FromResult(Results.Json(response));
}
diff --git a/EnvelopeGenerator.Web/Program.cs b/EnvelopeGenerator.Web/Program.cs
index 8bba466c..84080bed 100644
--- a/EnvelopeGenerator.Web/Program.cs
+++ b/EnvelopeGenerator.Web/Program.cs
@@ -35,7 +35,8 @@ app.UseStaticFiles();
app.UseRouting();
// Add file download endpoint
-app.MapGet("/api/download/{envelopeKey}", FileHandler.HandleFile);
+app.MapGet("/api/download/{envelopeKey}", FileHandler.HandleFileDownload);
+app.MapPost("/api/upload/{envelopeKey}/{documentId}", FileHandler.HandleFileUpload);
app.MapGet("/api/get-data/{envelopeKey}", FileHandler.HandleGetData);
// Blazor plumbing
diff --git a/EnvelopeGenerator.Web/Scripts/app.ts b/EnvelopeGenerator.Web/Scripts/app.ts
index 87f73ffe..4c0ba4a6 100644
--- a/EnvelopeGenerator.Web/Scripts/app.ts
+++ b/EnvelopeGenerator.Web/Scripts/app.ts
@@ -1,6 +1,6 @@
-import PSPDFKitType, { AnnotationsUnion } from "./index";
+import PSPDFKitType, { AnnotationsUnion, SignatureFormField as SignatureFormFieldType } from "./index";
import { Instance, WidgetAnnotation, ToolbarItem } from "./index";
-import { EnvelopeResponse, Envelope, User, Element, Document } from "./interfaces";
+import { EnvelopeResponse, Envelope, User, Element, Document, IFunction } from "./interfaces";
declare const PSPDFKit: typeof PSPDFKitType
@@ -10,34 +10,27 @@ const { SignatureFormField } = PSPDFKit.FormFields;
const { DRAW, TYPE } = PSPDFKit.ElectronicSignatureCreationMode;
const { DISABLED } = PSPDFKit.AutoSaveMode;
-const allowedToolbarItems: string[] = [
- "sidebar-thumbnails",
- "sidebar-document-ouline",
- "sidebar-bookmarks",
- "pager",
- "pan",
- "zoom-out",
- "zoom-in",
- "zoom-mode",
- "spacer",
- "search"
-]
-
export class App {
public static Instance: Instance;
- public static currentDocument
+ public static currentDocument: Document;
+ public static envelopeKey: string;
+
+ public static ui: UI;
// This function will be called in the ShowEnvelope.razor page
// and will trigger loading of the Editor Interface
- public static async loadPDFFromUrl (container: string, envelopeKey: string) {
+ public static async loadPDFFromUrl(container: string, envelopeKey: string) {
+ App.ui = new UI();
+
console.debug("Loading PSPDFKit..");
const envelopeObject: EnvelopeResponse = await App.loadData(`/api/get-data/${envelopeKey}`);
- const document: Document = envelopeObject.envelope.documents[0];
+ App.envelopeKey = envelopeKey;
+ App.currentDocument = envelopeObject.envelope.documents[0];
let arrayBuffer
try {
- arrayBuffer = await App.loadDocument(`/api/download/${envelopeKey}?id=${document.id}`);
+ arrayBuffer = await App.loadDocument(`/api/download/${envelopeKey}?id=${App.currentDocument.id}`);
} catch (e) {
console.error(e)
}
@@ -50,29 +43,21 @@ export class App {
const annotations: any[] = [];
- document.elements.forEach(function (element: Element) {
- console.log("Loading element")
- console.debug("Page", element.page)
- console.debug("Width / Height", element.width, element.height)
- console.debug("Top / Left", element.top, element.left)
-
- const id = PSPDFKit.generateInstantId()
- const annotation: WidgetAnnotation = App.createSignatureAnnotation(id, element.width, element.height, element.top, element.left, element.page)
-
- const formField = new SignatureFormField({
- name: id,
- annotationIds: List([annotation.id])
- })
+ App.currentDocument.elements.forEach(function (element: Element) {
+ console.log("Creating annotation for element", element.id)
+ const [annotation, formField] = App.createAnnotationFromElement(element)
annotations.push(annotation);
annotations.push(formField);
+ })
- console.debug("Annotation created.")
- })
+ const createdAnnotations = await App.Instance.create(annotations)
- const [createdAnnotation] = await App.Instance.create(annotations)
+ console.debug(createdAnnotations)
+ }
- console.debug(createdAnnotation)
+ private static inchToPoint(inch: number): number {
+ return inch * 72;
}
// Makes a call to the supplied url and fetches the binary response as an array buffer
@@ -87,22 +72,26 @@ export class App {
.then(res => res.json());
}
+ private static postDocument(url: string, buffer: ArrayBuffer): Promise {
+ return fetch(url, { credentials: "include", method: "POST", body: buffer })
+ .then(res => res.json());
+ }
+
// Load the PSPDFKit UI by setting a target element as the container to render in
// and a arraybuffer which represents the document that should be displayed.
private static loadPSPDFKit(arrayBuffer: ArrayBuffer, container: string): Promise {
- const annotationPresets = PSPDFKit.defaultAnnotationPresets;
- console.log(annotationPresets)
- annotationPresets.ink = {
- lineWidth: 10
- };
-
return PSPDFKit.load({
container: container,
document: arrayBuffer,
autoSaveMode: DISABLED,
- annotationPresets,
- electronicSignatures: {
- creationModes: [DRAW]
+ annotationPresets: App.ui.getPresets(),
+ electronicSignatures: {
+ creationModes: [DRAW, TYPE]
+ },
+ isEditableAnnotation: function (annotation: WidgetAnnotation) {
+ // Check if the annotation is a signature
+ // This will allow new signatures, but not allow edits.
+ return !annotation.isSignature;
}
})
}
@@ -116,35 +105,57 @@ export class App {
console.log("annotations changed")
})
- instance.addEventListener("annotations.create", (createdAnnotations) => {
- const annotation: AnnotationsUnion = createdAnnotations[0];
- console.log("annotations created", createdAnnotations.toJS());
+ instance.addEventListener("annotations.create", async (createdAnnotations) => {
+ console.log("annotations created", createdAnnotations.toJS());
})
const filteredItems: Array = instance.toolbarItems
- .filter((item) => allowedToolbarItems.includes(item.type))
+ .filter((item) => App.ui.allowedToolbarItems.includes(item.type))
-
- const customItems: ToolbarItem[] = [
- {
- type: "custom",
- id: "button-finish",
- title: "Abschließen",
- icon: ``,
- onPress: this.handleFinish
- }
- ]
-
- instance.setToolbarItems(filteredItems.concat(customItems))
+ instance.setToolbarItems(filteredItems.concat(App.ui.getToolbarItems(App.handleClick)))
}
- private static async handleFinish(event: any) {
- await App.Instance.applyOperations([{ type: "flattenAnnotations" }])
+ public static async handleClick(eventType: string) {
+ switch (eventType) {
+ case "RESET":
+ await App.handleReset(null)
+ break;
+ case "FINISH":
+ await App.handleFinish(null)
+ break;
+ }
+ }
- //await downloadDocument();
+ public static async handleFinish(event: any) {
+ await App.Instance.save();
+ const json = await App.Instance.exportInstantJSON()
+
+ console.log(json);
+
+ const buffer = await App.Instance.exportPDF({ flatten: true });
+ await App.uploadDocument(buffer, App.envelopeKey, App.currentDocument.id);
+
+ alert("Signatur wird gespeichert!")
+ }
+
+ public static async handleReset(event: any) {
+ if (confirm("Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?")) {
+ for (let i = 0; i < App.Instance.totalPageCount; i++) {
+ const annotations = await App.Instance.getAnnotations(i)
+ annotations.forEach((annotation) => {
+ //console.log(annotation)
+ // TODO: Delete only create signatures
+ //App.Instance.delete(annotation.id)
+ })
+ }
+ }
+ }
+
+ private static async uploadDocument(buffer: ArrayBuffer, envelopeKey: string, documentId: number) {
+
+ const result = await App.postDocument(`/api/upload/${envelopeKey}/${documentId}`, buffer);
+
+ console.log(result)
}
private static async downloadDocument() {
@@ -176,6 +187,27 @@ export class App {
}
}
+ private static createAnnotationFromElement(element: Element): [annotation: WidgetAnnotation, formField: SignatureFormFieldType] {
+ const id = PSPDFKit.generateInstantId()
+ console.log("Creating Annotation", id)
+
+ const width = App.inchToPoint(element.width)
+ const height = App.inchToPoint(element.height)
+ const top = App.inchToPoint(element.top) - (height / 2)
+ const left = App.inchToPoint(element.left) - (width / 2)
+ const page = element.page - 1
+ const annotation: WidgetAnnotation = App.createSignatureAnnotation(id, width, height, top, left, page)
+ console.log(annotation)
+
+ const formField = new SignatureFormField({
+ name: id,
+ annotationIds: List([annotation.id])
+ })
+ console.log(formField)
+
+ return [annotation, formField]
+ }
+
private static createSignatureAnnotation(id: string, width: number, height: number, top: number, left: number, pageIndex: number): WidgetAnnotation {
const annotation = new PSPDFKit.Annotations.WidgetAnnotation({
@@ -190,3 +222,65 @@ export class App {
}
+
+class UI {
+ constructor() {
+
+ }
+
+ public allowedToolbarItems: string[] = [
+ "sidebar-thumbnails",
+ "sidebar-document-ouline",
+ "sidebar-bookmarks",
+ "pager",
+ "pan",
+ "zoom-out",
+ "zoom-in",
+ "zoom-mode",
+ "spacer",
+ "search"
+ ]
+
+ public getToolbarItems = function (callback: any) {
+ const customItems: ToolbarItem[] = [
+ {
+ type: "custom",
+ id: "button-reset",
+ title: "Zurücksetzen",
+ onPress() {
+ callback("RESET")
+ },
+ icon: ``
+ },
+ {
+ type: "custom",
+ id: "button-finish",
+ title: "Abschließen",
+ onPress() {
+ callback("FINISH")
+ },
+ icon: ``
+ }
+ ]
+ return customItems
+ }
+
+ public getPresets() {
+ const annotationPresets = PSPDFKit.defaultAnnotationPresets;
+ annotationPresets.ink = {
+ lineWidth: 10
+ };
+
+ annotationPresets.widget = {
+ readOnly: true
+ }
+
+ return annotationPresets;
+ }
+}
\ No newline at end of file
diff --git a/EnvelopeGenerator.Web/Scripts/index.d.ts b/EnvelopeGenerator.Web/Scripts/index.d.ts
index ff64ee04..b2be715a 100644
--- a/EnvelopeGenerator.Web/Scripts/index.d.ts
+++ b/EnvelopeGenerator.Web/Scripts/index.d.ts
@@ -1,4 +1,4 @@
-declare const SignatureSaveMode: {
+declare const SignatureSaveMode: {
readonly ALWAYS: "ALWAYS";
readonly NEVER: "NEVER";
readonly USING_UI: "USING_UI";
@@ -106,21 +106,21 @@ type ISignatureSaveMode = (typeof SignatureSaveMode)[keyof typeof SignatureSaveM
-/**
- * Lists are ordered indexed dense collections, much like a JavaScript
- * Array.
- *
- * Lists are immutable and fully persistent with O(log32 N) gets and sets,
- * and O(1) push and pop.
- *
- * Lists implement Deque, with efficient addition and removal from both the
- * end (`push`, `pop`) and beginning (`unshift`, `shift`).
- *
- * Unlike a JavaScript Array, there is no distinction between an
- * "unset" index and an index set to `undefined`. `List#forEach` visits all
- * indices from 0 to size, regardless of whether they were explicitly defined.
- */
-declare module List {
+ /**
+ * Lists are ordered indexed dense collections, much like a JavaScript
+ * Array.
+ *
+ * Lists are immutable and fully persistent with O(log32 N) gets and sets,
+ * and O(1) push and pop.
+ *
+ * Lists implement Deque, with efficient addition and removal from both the
+ * end (`push`, `pop`) and beginning (`unshift`, `shift`).
+ *
+ * Unlike a JavaScript Array, there is no distinction between an
+ * "unset" index and an index set to `undefined`. `List#forEach` visits all
+ * indices from 0 to size, regardless of whether they were explicitly defined.
+ */
+ declare module List {
/**
* True if the provided value is a List
@@ -154,44 +154,44 @@ declare module List {
* ```
*/
function of(...values: Array): List;
-}
+ }
-/**
- * Create a new immutable List containing the values of the provided
- * collection-like.
- *
- * Note: `List` is a factory function and not a class, and does not use the
- * `new` keyword during construction.
- *
- *
- * ```js
- * const { List, Set } = require('immutable')
- *
- * const emptyList = List()
- * // List []
- *
- * const plainArray = [ 1, 2, 3, 4 ]
- * const listFromPlainArray = List(plainArray)
- * // List [ 1, 2, 3, 4 ]
- *
- * const plainSet = Set([ 1, 2, 3, 4 ])
- * const listFromPlainSet = List(plainSet)
- * // List [ 1, 2, 3, 4 ]
- *
- * const arrayIterator = plainArray[Symbol.iterator]()
- * const listFromCollectionArray = List(arrayIterator)
- * // List [ 1, 2, 3, 4 ]
- *
- * listFromPlainArray.equals(listFromCollectionArray) // true
- * listFromPlainSet.equals(listFromCollectionArray) // true
- * listFromPlainSet.equals(listFromPlainArray) // true
- * ```
- */
-declare function List(): List;
-declare function List(): List;
-declare function List(collection: Iterable): List;
+ /**
+ * Create a new immutable List containing the values of the provided
+ * collection-like.
+ *
+ * Note: `List` is a factory function and not a class, and does not use the
+ * `new` keyword during construction.
+ *
+ *
+ * ```js
+ * const { List, Set } = require('immutable')
+ *
+ * const emptyList = List()
+ * // List []
+ *
+ * const plainArray = [ 1, 2, 3, 4 ]
+ * const listFromPlainArray = List(plainArray)
+ * // List [ 1, 2, 3, 4 ]
+ *
+ * const plainSet = Set([ 1, 2, 3, 4 ])
+ * const listFromPlainSet = List(plainSet)
+ * // List [ 1, 2, 3, 4 ]
+ *
+ * const arrayIterator = plainArray[Symbol.iterator]()
+ * const listFromCollectionArray = List(arrayIterator)
+ * // List [ 1, 2, 3, 4 ]
+ *
+ * listFromPlainArray.equals(listFromCollectionArray) // true
+ * listFromPlainSet.equals(listFromCollectionArray) // true
+ * listFromPlainSet.equals(listFromPlainArray) // true
+ * ```
+ */
+ declare function List(): List;
+ declare function List(): List;
+ declare function List(collection: Iterable): List;
-interface List extends Collection.Indexed {
+ interface List extends Collection.Indexed {
/**
* The number of items in this List.
@@ -568,8 +568,8 @@ interface List extends Collection.Indexed {
* ```
*/
map(
- mapper: (value: T, key: number, iter: this) => M,
- context?: any
+ mapper: (value: T, key: number, iter: this) => M,
+ context?: any
): List;
/**
@@ -578,8 +578,8 @@ interface List extends Collection.Indexed {
* Similar to `list.map(...).flatten(true)`.
*/
flatMap(
- mapper: (value: T, key: number, iter: this) => Iterable,
- context?: any
+ mapper: (value: T, key: number, iter: this) => Iterable,
+ context?: any
): List;
/**
@@ -590,12 +590,12 @@ interface List extends Collection.Indexed {
* not filtering out any values.
*/
filter(
- predicate: (value: T, index: number, iter: this) => value is F,
- context?: any
+ predicate: (value: T, index: number, iter: this) => value is F,
+ context?: any
): List;
filter(
- predicate: (value: T, index: number, iter: this) => any,
- context?: any
+ predicate: (value: T, index: number, iter: this) => any,
+ context?: any
): this;
/**
@@ -612,8 +612,8 @@ interface List extends Collection.Indexed {
* const c = a.zip(b); // List [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]
* ```
*/
- zip(other: Collection): List<[T, U]>;
- zip(other: Collection, other2: Collection): List<[T, U, V]>;
+ zip(other: Collection): List<[T,U]>;
+ zip(other: Collection, other2: Collection): List<[T,U,V]>;
zip(...collections: Array>): List;
/**
@@ -635,8 +635,8 @@ interface List extends Collection.Indexed {
* input, some results may contain undefined values. TypeScript cannot
* account for these without cases (as of v2.5).
*/
- zipAll(other: Collection): List<[T, U]>;
- zipAll(other: Collection, other2: Collection): List<[T, U, V]>;
+ zipAll(other: Collection): List<[T,U]>;
+ zipAll(other: Collection, other2: Collection): List<[T,U,V]>;
zipAll(...collections: Array>): List;
/**
@@ -654,49 +654,49 @@ interface List extends Collection.Indexed {
* ```
*/
zipWith(
- zipper: (value: T, otherValue: U) => Z,
- otherCollection: Collection
+ zipper: (value: T, otherValue: U) => Z,
+ otherCollection: Collection
): List;
zipWith(
- zipper: (value: T, otherValue: U, thirdValue: V) => Z,
- otherCollection: Collection,
- thirdCollection: Collection
+ zipper: (value: T, otherValue: U, thirdValue: V) => Z,
+ otherCollection: Collection,
+ thirdCollection: Collection
): List;
zipWith(
- zipper: (...any: Array) => Z,
- ...collections: Array>
+ zipper: (...any: Array) => Z,
+ ...collections: Array>
): List;
-}
+ }
-/**
- * Immutable Map is an unordered Collection.Keyed of (key, value) pairs with
- * `O(log32 N)` gets and `O(log32 N)` persistent sets.
- *
- * Iteration order of a Map is undefined, however is stable. Multiple
- * iterations of the same Map will iterate in the same order.
- *
- * Map's keys can be of any type, and use `Immutable.is` to determine key
- * equality. This allows the use of any value (including NaN) as a key.
- *
- * Because `Immutable.is` returns equality based on value semantics, and
- * Immutable collections are treated as values, any Immutable collection may
- * be used as a key.
- *
- *
- * ```js
- * const { Map, List } = require('immutable');
- * Map().set(List([ 1 ]), 'listofone').get(List([ 1 ]));
- * // 'listofone'
- * ```
- *
- * Any JavaScript object may be used as a key, however strict identity is used
- * to evaluate key equality. Two similar looking objects will represent two
- * different keys.
- *
- * Implemented by a hash-array mapped trie.
- */
-declare module Map {
+ /**
+ * Immutable Map is an unordered Collection.Keyed of (key, value) pairs with
+ * `O(log32 N)` gets and `O(log32 N)` persistent sets.
+ *
+ * Iteration order of a Map is undefined, however is stable. Multiple
+ * iterations of the same Map will iterate in the same order.
+ *
+ * Map's keys can be of any type, and use `Immutable.is` to determine key
+ * equality. This allows the use of any value (including NaN) as a key.
+ *
+ * Because `Immutable.is` returns equality based on value semantics, and
+ * Immutable collections are treated as values, any Immutable collection may
+ * be used as a key.
+ *
+ *
+ * ```js
+ * const { Map, List } = require('immutable');
+ * Map().set(List([ 1 ]), 'listofone').get(List([ 1 ]));
+ * // 'listofone'
+ * ```
+ *
+ * Any JavaScript object may be used as a key, however strict identity is used
+ * to evaluate key equality. Two similar looking objects will represent two
+ * different keys.
+ *
+ * Implemented by a hash-array mapped trie.
+ */
+ declare module Map {
/**
* True if the provided value is a Map
@@ -727,51 +727,51 @@ declare module Map {
* @deprecated Use Map([ [ 'k', 'v' ] ]) or Map({ k: 'v' })
*/
function of(...keyValues: Array): Map;
-}
+ }
-/**
- * Creates a new Immutable Map.
- *
- * Created with the same key value pairs as the provided Collection.Keyed or
- * JavaScript Object or expects a Collection of [K, V] tuple entries.
- *
- * Note: `Map` is a factory function and not a class, and does not use the
- * `new` keyword during construction.
- *
- *
- * ```js
- * const { Map } = require('immutable')
- * Map({ key: "value" })
- * Map([ [ "key", "value" ] ])
- * ```
- *
- * Keep in mind, when using JS objects to construct Immutable Maps, that
- * JavaScript Object properties are always strings, even if written in a
- * quote-less shorthand, while Immutable Maps accept keys of any type.
- *
- *
- * ```js
- * let obj = { 1: "one" }
- * Object.keys(obj) // [ "1" ]
- * assert.equal(obj["1"], obj[1]) // "one" === "one"
- *
- * let map = Map(obj)
- * assert.notEqual(map.get("1"), map.get(1)) // "one" !== undefined
- * ```
- *
- * Property access for JavaScript Objects first converts the key to a string,
- * but since Immutable Map keys can be of any type the argument to `get()` is
- * not altered.
- */
-declare function Map(collection: Iterable<[K, V]>): Map;
-declare function Map(collection: Iterable>): Map;
-declare function Map(obj: { [key: string]: V }): Map;
-declare function Map(): Map;
-declare function Map(): Map;
+ /**
+ * Creates a new Immutable Map.
+ *
+ * Created with the same key value pairs as the provided Collection.Keyed or
+ * JavaScript Object or expects a Collection of [K, V] tuple entries.
+ *
+ * Note: `Map` is a factory function and not a class, and does not use the
+ * `new` keyword during construction.
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * Map({ key: "value" })
+ * Map([ [ "key", "value" ] ])
+ * ```
+ *
+ * Keep in mind, when using JS objects to construct Immutable Maps, that
+ * JavaScript Object properties are always strings, even if written in a
+ * quote-less shorthand, while Immutable Maps accept keys of any type.
+ *
+ *
+ * ```js
+ * let obj = { 1: "one" }
+ * Object.keys(obj) // [ "1" ]
+ * assert.equal(obj["1"], obj[1]) // "one" === "one"
+ *
+ * let map = Map(obj)
+ * assert.notEqual(map.get("1"), map.get(1)) // "one" !== undefined
+ * ```
+ *
+ * Property access for JavaScript Objects first converts the key to a string,
+ * but since Immutable Map keys can be of any type the argument to `get()` is
+ * not altered.
+ */
+ declare function Map(collection: Iterable<[K, V]>): Map;
+ declare function Map(collection: Iterable>): Map;
+ declare function Map(obj: {[key: string]: V}): Map;
+ declare function Map(): Map;
+ declare function Map(): Map;
-interface Map extends Collection.Keyed {
+ interface Map extends Collection.Keyed {
/**
* The number of entries in this Map.
@@ -988,9 +988,9 @@ interface Map extends Collection.Keyed {
* @alias concat
*/
merge(...collections: Array>): Map;
- merge(...collections: Array<{ [key: string]: C }>): Map;
+ merge(...collections: Array<{[key: string]: C}>): Map;
concat(...collections: Array>): Map;
- concat(...collections: Array<{ [key: string]: C }>): Map;
+ concat(...collections: Array<{[key: string]: C}>): Map;
/**
* Like `merge()`, `mergeWith()` returns a new Map resulting from merging
@@ -1011,8 +1011,8 @@ interface Map extends Collection.Keyed {
* Note: `mergeWith` can be used in `withMutations`.
*/
mergeWith(
- merger: (oldVal: V, newVal: V, key: K) => V,
- ...collections: Array | { [key: string]: V }>
+ merger: (oldVal: V, newVal: V, key: K) => V,
+ ...collections: Array | {[key: string]: V}>
): this;
/**
@@ -1038,7 +1038,7 @@ interface Map extends Collection.Keyed {
*
* Note: `mergeDeep` can be used in `withMutations`.
*/
- mergeDeep(...collections: Array | { [key: string]: V }>): this;
+ mergeDeep(...collections: Array | {[key: string]: V}>): this;
/**
* Like `mergeDeep()`, but when two non-Collections conflict, it uses the
@@ -1060,8 +1060,8 @@ interface Map extends Collection.Keyed {
* Note: `mergeDeepWith` can be used in `withMutations`.
*/
mergeDeepWith(
- merger: (oldVal: any, newVal: any, key: any) => any,
- ...collections: Array | { [key: string]: V }>
+ merger: (oldVal: any, newVal: any, key: any) => any,
+ ...collections: Array | {[key: string]: V}>
): this;
@@ -1337,24 +1337,24 @@ interface Map extends Collection.Keyed {
* // Map { a: 10, b: 20 }
*/
map(
- mapper: (value: V, key: K, iter: this) => M,
- context?: any
+ mapper: (value: V, key: K, iter: this) => M,
+ context?: any
): Map;
/**
* @see Collection.Keyed.mapKeys
*/
mapKeys(
- mapper: (key: K, value: V, iter: this) => M,
- context?: any
+ mapper: (key: K, value: V, iter: this) => M,
+ context?: any
): Map;
/**
* @see Collection.Keyed.mapEntries
*/
mapEntries(
- mapper: (entry: [K, V], index: number, iter: this) => [KM, VM],
- context?: any
+ mapper: (entry: [K, V], index: number, iter: this) => [KM, VM],
+ context?: any
): Map;
/**
@@ -1363,8 +1363,8 @@ interface Map extends Collection.Keyed {
* Similar to `data.map(...).flatten(true)`.
*/
flatMap(
- mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>,
- context?: any
+ mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>,
+ context?: any
): Map;
/**
@@ -1375,63 +1375,63 @@ interface Map extends Collection.Keyed {
* not filtering out any values.
*/
filter(
- predicate: (value: V, key: K, iter: this) => value is F,
- context?: any
+ predicate: (value: V, key: K, iter: this) => value is F,
+ context?: any
): Map;
filter(
- predicate: (value: V, key: K, iter: this) => any,
- context?: any
+ predicate: (value: V, key: K, iter: this) => any,
+ context?: any
): this;
/**
* @see Collection.Keyed.flip
*/
flip(): Map;
-}
+ }
-/**
- * A type of Map that has the additional guarantee that the iteration order of
- * entries will be the order in which they were set().
- *
- * The iteration behavior of OrderedMap is the same as native ES6 Map and
- * JavaScript Object.
- *
- * Note that `OrderedMap` are more expensive than non-ordered `Map` and may
- * consume more memory. `OrderedMap#set` is amortized O(log32 N), but not
- * stable.
- */
+ /**
+ * A type of Map that has the additional guarantee that the iteration order of
+ * entries will be the order in which they were set().
+ *
+ * The iteration behavior of OrderedMap is the same as native ES6 Map and
+ * JavaScript Object.
+ *
+ * Note that `OrderedMap` are more expensive than non-ordered `Map` and may
+ * consume more memory. `OrderedMap#set` is amortized O(log32 N), but not
+ * stable.
+ */
-declare module OrderedMap {
+ declare module OrderedMap {
/**
* True if the provided value is an OrderedMap.
*/
function isOrderedMap(maybeOrderedMap: any): maybeOrderedMap is OrderedMap;
-}
+ }
-/**
- * Creates a new Immutable OrderedMap.
- *
- * Created with the same key value pairs as the provided Collection.Keyed or
- * JavaScript Object or expects a Collection of [K, V] tuple entries.
- *
- * The iteration order of key-value pairs provided to this constructor will
- * be preserved in the OrderedMap.
- *
- * let newOrderedMap = OrderedMap({key: "value"})
- * let newOrderedMap = OrderedMap([["key", "value"]])
- *
- * Note: `OrderedMap` is a factory function and not a class, and does not use
- * the `new` keyword during construction.
- */
-declare function OrderedMap(collection: Iterable<[K, V]>): OrderedMap;
-declare function OrderedMap(collection: Iterable>): OrderedMap;
-declare function OrderedMap(obj: { [key: string]: V }): OrderedMap;
-declare function OrderedMap(): OrderedMap;
-declare function OrderedMap(): OrderedMap;
+ /**
+ * Creates a new Immutable OrderedMap.
+ *
+ * Created with the same key value pairs as the provided Collection.Keyed or
+ * JavaScript Object or expects a Collection of [K, V] tuple entries.
+ *
+ * The iteration order of key-value pairs provided to this constructor will
+ * be preserved in the OrderedMap.
+ *
+ * let newOrderedMap = OrderedMap({key: "value"})
+ * let newOrderedMap = OrderedMap([["key", "value"]])
+ *
+ * Note: `OrderedMap` is a factory function and not a class, and does not use
+ * the `new` keyword during construction.
+ */
+ declare function OrderedMap(collection: Iterable<[K, V]>): OrderedMap;
+ declare function OrderedMap(collection: Iterable>): OrderedMap;
+ declare function OrderedMap(obj: {[key: string]: V}): OrderedMap;
+ declare function OrderedMap(): OrderedMap;
+ declare function OrderedMap(): OrderedMap;
-interface OrderedMap extends Map {
+ interface OrderedMap extends Map {
/**
* The number of entries in this OrderedMap.
@@ -1481,9 +1481,9 @@ interface OrderedMap extends Map {
* @alias concat
*/
merge(...collections: Array>): OrderedMap;
- merge(...collections: Array<{ [key: string]: C }>): OrderedMap;
+ merge(...collections: Array<{[key: string]: C}>): OrderedMap;
concat(...collections: Array>): OrderedMap;
- concat(...collections: Array<{ [key: string]: C }>): OrderedMap;
+ concat(...collections: Array<{[key: string]: C}>): OrderedMap;
// Sequence algorithms
@@ -1498,24 +1498,24 @@ interface OrderedMap extends Map {
* value at every step.
*/
map(
- mapper: (value: V, key: K, iter: this) => M,
- context?: any
+ mapper: (value: V, key: K, iter: this) => M,
+ context?: any
): OrderedMap;
/**
* @see Collection.Keyed.mapKeys
*/
mapKeys(
- mapper: (key: K, value: V, iter: this) => M,
- context?: any
+ mapper: (key: K, value: V, iter: this) => M,
+ context?: any
): OrderedMap;
/**
* @see Collection.Keyed.mapEntries
*/
mapEntries(
- mapper: (entry: [K, V], index: number, iter: this) => [KM, VM],
- context?: any
+ mapper: (entry: [K, V], index: number, iter: this) => [KM, VM],
+ context?: any
): OrderedMap;
/**
@@ -1524,8 +1524,8 @@ interface OrderedMap extends Map {
* Similar to `data.map(...).flatten(true)`.
*/
flatMap(
- mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>,
- context?: any
+ mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>,
+ context?: any
): OrderedMap;
/**
@@ -1536,33 +1536,33 @@ interface OrderedMap extends Map {
* not filtering out any values.
*/
filter(
- predicate: (value: V, key: K, iter: this) => value is F,
- context?: any
+ predicate: (value: V, key: K, iter: this) => value is F,
+ context?: any
): OrderedMap;
filter(
- predicate: (value: V, key: K, iter: this) => any,
- context?: any
+ predicate: (value: V, key: K, iter: this) => any,
+ context?: any
): this;
/**
* @see Collection.Keyed.flip
*/
flip(): OrderedMap;
-}
+ }
-/**
- * A Collection of unique values with `O(log32 N)` adds and has.
- *
- * When iterating a Set, the entries will be (value, value) pairs. Iteration
- * order of a Set is undefined, however is stable. Multiple iterations of the
- * same Set will iterate in the same order.
- *
- * Set values, like Map keys, may be of any type. Equality is determined using
- * `Immutable.is`, enabling Sets to uniquely include other Immutable
- * collections, custom value types, and NaN.
- */
-declare module Set {
+ /**
+ * A Collection of unique values with `O(log32 N)` adds and has.
+ *
+ * When iterating a Set, the entries will be (value, value) pairs. Iteration
+ * order of a Set is undefined, however is stable. Multiple iterations of the
+ * same Set will iterate in the same order.
+ *
+ * Set values, like Map keys, may be of any type. Equality is determined using
+ * `Immutable.is`, enabling Sets to uniquely include other Immutable
+ * collections, custom value types, and NaN.
+ */
+ declare module Set {
/**
* True if the provided value is a Set
@@ -1579,7 +1579,7 @@ declare module Set {
* this Collection or JavaScript Object.
*/
function fromKeys(iter: Collection): Set;
- function fromKeys(obj: { [key: string]: any }): Set;
+ function fromKeys(obj: {[key: string]: any}): Set;
/**
* `Set.intersect()` creates a new immutable Set that is the intersection of
@@ -1610,20 +1610,20 @@ declare module Set {
* ```
*/
function union(sets: Iterable>): Set;
-}
+ }
-/**
- * Create a new immutable Set containing the values of the provided
- * collection-like.
- *
- * Note: `Set` is a factory function and not a class, and does not use the
- * `new` keyword during construction.
- */
-declare function Set(): Set;
-declare function Set(): Set;
-declare function Set(collection: Iterable): Set;
+ /**
+ * Create a new immutable Set containing the values of the provided
+ * collection-like.
+ *
+ * Note: `Set` is a factory function and not a class, and does not use the
+ * `new` keyword during construction.
+ */
+ declare function Set(): Set;
+ declare function Set(): Set;
+ declare function Set(collection: Iterable): Set;
-interface Set extends Collection.Set {
+ interface Set extends Collection.Set {
/**
* The number of items in this Set.
@@ -1734,8 +1734,8 @@ interface Set extends Collection.Set {
* // Set [10,20]
*/
map(
- mapper: (value: T, key: T, iter: this) => M,
- context?: any
+ mapper: (value: T, key: T, iter: this) => M,
+ context?: any
): Set;
/**
@@ -1744,8 +1744,8 @@ interface Set extends Collection.Set {
* Similar to `set.map(...).flatten(true)`.
*/
flatMap(
- mapper: (value: T, key: T, iter: this) => Iterable,
- context?: any
+ mapper: (value: T, key: T, iter: this) => Iterable,
+ context?: any
): Set;
/**
@@ -1756,27 +1756,27 @@ interface Set extends Collection.Set {
* not filtering out any values.
*/
filter(
- predicate: (value: T, key: T, iter: this) => value is F,
- context?: any
+ predicate: (value: T, key: T, iter: this) => value is F,
+ context?: any
): Set;
filter(
- predicate: (value: T, key: T, iter: this) => any,
- context?: any
+ predicate: (value: T, key: T, iter: this) => any,
+ context?: any
): this;
-}
+ }
-/**
- * A type of Set that has the additional guarantee that the iteration order of
- * values will be the order in which they were `add`ed.
- *
- * The iteration behavior of OrderedSet is the same as native ES6 Set.
- *
- * Note that `OrderedSet` are more expensive than non-ordered `Set` and may
- * consume more memory. `OrderedSet#add` is amortized O(log32 N), but not
- * stable.
- */
-declare module OrderedSet {
+ /**
+ * A type of Set that has the additional guarantee that the iteration order of
+ * values will be the order in which they were `add`ed.
+ *
+ * The iteration behavior of OrderedSet is the same as native ES6 Set.
+ *
+ * Note that `OrderedSet` are more expensive than non-ordered `Set` and may
+ * consume more memory. `OrderedSet#add` is amortized O(log32 N), but not
+ * stable.
+ */
+ declare module OrderedSet {
/**
* True if the provided value is an OrderedSet.
@@ -1793,21 +1793,21 @@ declare module OrderedSet {
* the keys from this Collection or JavaScript Object.
*/
function fromKeys(iter: Collection