// SPDX-FileCopyrightText: 2026 Kerstin Humm // // SPDX-License-Identifier: AGPL-3.0-or-later import { Rule } from "../types.js"; import { buildReference } from "../utils.js"; export default { name: "startTime attribute", validate: (self) => { const rfc3339 = /^[1-9]\d{3}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?(Z|\+\d{2}:\d{2})$/; // const result: AnnotatedJson = { annotations: [], object: {} }; if (!("startTime" in self || "previousStartTime" in self)) { return { annotations: [], object: { "startTime": { kind: "Violation", id: "NoStartTime", text: "The startTime field does not exist while there is also no previousStartTime field.", reference: buildReference({ anchor: "object-type-event", text: "The startTime is not REQUIRED in case an event is postponed and a https://w3id.org/fep/8a8e/previousStartTime is set instead.", }), }, }, }; } if (typeof self["startTime"] !== "string") { return { annotations: [], object: { "startTime": { kind: "Violation", id: "StartTimeNotAString", text: `The startTime field with value ${ self["startTime"] } is not a String.`, reference: buildReference({ anchor: "object-type-event", text: "The date and time when the event ends or is scheduled to end in the format as specified in the Activity Stream 2.0 specification.", }), }, }, }; } else if (!rfc3339.test(self["startTime"])) { return { annotations: [], object: { "startTime": { kind: "Violation", id: "StartTimeNotRfc3339Compliant", text: `The startTime field with value ${ self["startTime"] } is not compliant with RFC3339.`, reference: buildReference({ anchor: "object-type-event", text: "The date and time when the event ends or is scheduled to end in the format as specified in the Activity Stream 2.0 specification.", }), }, }, }; } return { annotations: [], object: { "startTime": { kind: "Correct", text: "Correct startTime", }, }, }; }, tests: [ { value: {}, result: { annotations: ["NoStartTime"], object: {} }, }, { value: { "startTime": "2014-12-31T23:00:00Z" }, result: { annotations: [], object: { "startTime": "Correct" } }, }, // All properties with date and time values MUST conform to the "date-time" production in [RFC3339] with the one exception that seconds MAY be omitted. // https://www.w3.org/TR/activitystreams-core/#dates { value: { "startTime": "2014-12-31T23:00Z" }, result: { annotations: [], object: { "startTime": "Correct" } }, }, { value: { "startTime": "invalid" }, result: { annotations: [], object: { "startTime": "StartTimeNotRfc3339Compliant" }, }, }, { value: { "startTime": "2014-12-31T23:00:00Z", "previousStartTime": "2014-12-31T23:00:00Z", }, result: { annotations: [], object: { "startTime": "Correct" } }, }, { value: { "startTime": "2025-06-11T20:15:00+02:00", }, result: { annotations: [], object: { "startTime": "Correct" } }, }, ], } satisfies Rule;