@craftguild/jscalendar 0.1.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/LICENSE.md +7 -0
- package/README.md +295 -0
- package/dist/__tests__/calendar-extra.test.d.ts +1 -0
- package/dist/__tests__/calendar-extra.test.js +185 -0
- package/dist/__tests__/calendar.test.d.ts +1 -0
- package/dist/__tests__/calendar.test.js +104 -0
- package/dist/__tests__/ical-extra.test.d.ts +1 -0
- package/dist/__tests__/ical-extra.test.js +87 -0
- package/dist/__tests__/ical.test.d.ts +1 -0
- package/dist/__tests__/ical.test.js +72 -0
- package/dist/__tests__/index.test.d.ts +1 -0
- package/dist/__tests__/index.test.js +9 -0
- package/dist/__tests__/patch.test.d.ts +1 -0
- package/dist/__tests__/patch.test.js +47 -0
- package/dist/__tests__/recurrence.test.d.ts +1 -0
- package/dist/__tests__/recurrence.test.js +498 -0
- package/dist/__tests__/search.test.d.ts +1 -0
- package/dist/__tests__/search.test.js +237 -0
- package/dist/__tests__/timezones.test.d.ts +1 -0
- package/dist/__tests__/timezones.test.js +12 -0
- package/dist/__tests__/utils.test.d.ts +1 -0
- package/dist/__tests__/utils.test.js +116 -0
- package/dist/__tests__/validation.test.d.ts +1 -0
- package/dist/__tests__/validation.test.js +91 -0
- package/dist/ical.d.ts +7 -0
- package/dist/ical.js +202 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/jscal.d.ts +129 -0
- package/dist/jscal.js +504 -0
- package/dist/patch.d.ts +5 -0
- package/dist/patch.js +91 -0
- package/dist/recurrence.d.ts +15 -0
- package/dist/recurrence.js +674 -0
- package/dist/search.d.ts +14 -0
- package/dist/search.js +208 -0
- package/dist/timezones.d.ts +4 -0
- package/dist/timezones.js +441 -0
- package/dist/types.d.ts +219 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +80 -0
- package/dist/validate.d.ts +6 -0
- package/dist/validate.js +745 -0
- package/package.json +33 -0
package/dist/patch.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { deepClone } from "./utils.js";
|
|
2
|
+
export class PatchError extends Error {
|
|
3
|
+
constructor(message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "PatchError";
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
function unescapePointer(segment) {
|
|
9
|
+
return segment.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
10
|
+
}
|
|
11
|
+
function normalizePointer(pointer) {
|
|
12
|
+
return pointer.startsWith("/") ? pointer : `/${pointer}`;
|
|
13
|
+
}
|
|
14
|
+
function splitPointer(pointer) {
|
|
15
|
+
const normalized = normalizePointer(pointer);
|
|
16
|
+
if (normalized === "/")
|
|
17
|
+
return [];
|
|
18
|
+
return normalized
|
|
19
|
+
.split("/")
|
|
20
|
+
.slice(1)
|
|
21
|
+
.map(unescapePointer);
|
|
22
|
+
}
|
|
23
|
+
function validatePrefixConflicts(pointers) {
|
|
24
|
+
const normalized = pointers.map(normalizePointer).sort();
|
|
25
|
+
for (let i = 0; i < normalized.length; i += 1) {
|
|
26
|
+
const current = normalized[i];
|
|
27
|
+
for (let j = i + 1; j < normalized.length; j += 1) {
|
|
28
|
+
const other = normalized[j];
|
|
29
|
+
if (other && other.startsWith(`${current}/`)) {
|
|
30
|
+
throw new PatchError(`Patch pointer conflict: ${current} is prefix of ${other}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function assertNotArray(value, pointer) {
|
|
36
|
+
if (Array.isArray(value)) {
|
|
37
|
+
throw new PatchError(`Patch pointer references into array: ${pointer}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function assertObject(value, pointer) {
|
|
41
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
42
|
+
throw new PatchError(`Patch pointer references missing or non-object path: ${pointer}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function assertRecord(value, pointer) {
|
|
46
|
+
if (value === null || Array.isArray(value)) {
|
|
47
|
+
throw new PatchError(`Patch pointer references missing or non-object path: ${pointer}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export function applyPatch(input, patch) {
|
|
51
|
+
const pointers = Object.keys(patch);
|
|
52
|
+
validatePrefixConflicts(pointers);
|
|
53
|
+
const target = deepClone(input);
|
|
54
|
+
assertRecord(target, "/");
|
|
55
|
+
for (const [rawPointer, value] of Object.entries(patch)) {
|
|
56
|
+
const pointer = normalizePointer(rawPointer);
|
|
57
|
+
const segments = splitPointer(pointer);
|
|
58
|
+
let current = target;
|
|
59
|
+
for (let i = 0; i < segments.length; i += 1) {
|
|
60
|
+
const segment = segments[i];
|
|
61
|
+
if (segment === undefined) {
|
|
62
|
+
throw new PatchError(`Patch pointer missing segment: ${pointer}`);
|
|
63
|
+
}
|
|
64
|
+
const isLast = i === segments.length - 1;
|
|
65
|
+
assertNotArray(current, pointer);
|
|
66
|
+
assertRecord(current, pointer);
|
|
67
|
+
if (isLast) {
|
|
68
|
+
if (value === null) {
|
|
69
|
+
if (Object.prototype.hasOwnProperty.call(current, segment)) {
|
|
70
|
+
delete current[segment];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
current[segment] = value;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
if (!Object.prototype.hasOwnProperty.call(current, segment)) {
|
|
79
|
+
throw new PatchError(`Patch pointer missing path: ${pointer}`);
|
|
80
|
+
}
|
|
81
|
+
const next = current[segment];
|
|
82
|
+
if (next === undefined) {
|
|
83
|
+
throw new PatchError(`Patch pointer missing path: ${pointer}`);
|
|
84
|
+
}
|
|
85
|
+
assertObject(next, pointer);
|
|
86
|
+
current = next;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return target;
|
|
91
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { JSCalendarObject } from "./types.js";
|
|
2
|
+
export type RecurrenceRange = {
|
|
3
|
+
from: Date;
|
|
4
|
+
to: Date;
|
|
5
|
+
};
|
|
6
|
+
export type RecurrencePage = {
|
|
7
|
+
items: JSCalendarObject[];
|
|
8
|
+
nextCursor?: string;
|
|
9
|
+
};
|
|
10
|
+
export type RecurrencePageOptions = {
|
|
11
|
+
limit: number;
|
|
12
|
+
cursor?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function expandRecurrence(items: JSCalendarObject[], range: RecurrenceRange): Generator<JSCalendarObject>;
|
|
15
|
+
export declare function expandRecurrencePaged(items: JSCalendarObject[], range: RecurrenceRange, options: RecurrencePageOptions): RecurrencePage;
|