Aller au contenu principal

Intervalles de Temps

Un attribut timeInterval est une règle de récurrence, pas une liste de créneaux : une date d'ancrage, des plages horaires quotidiennes et des indicateurs de répétition. Résolvez-le en paires concrètes [start, end] pour la fenêtre que vous rendez réellement avec les helpers de haut niveau expandAttributeTimeIntervals, expandTimeIntervals et le type guard isTimeIntervalAttribute.

import { expandAttributeTimeIntervals } from 'oneentry';

const slots = expandAttributeTimeIntervals(page.attributeValues.interval, {
from: '2025-04-01',
to: '2025-04-30',
});
// [['2025-04-14T09:00:00.000Z', '2025-04-14T10:00:00.000Z'], …]

Tous les trois helpers sont purs — ils ne modifient pas leur entrée et n'effectuent aucune requête.

Où vivent les horaires

L'API renvoie les horaires sous deux formes, et les deux sont acceptées par les helpers :

FormeOù la trouverContient
Entité (ITimeIntervalEntitySchedule)attributeValues[marker].value[].values[] sur les pages, produits, blocs et ensembles d'attributsune plage de dates avec des paires de times
Formulaire (ITimeIntervalSchedule)attributes[].localizeInfos.intervals[] sur les formulairesune range avec des intervals qui contiennent une période de créneau en minutes

expandAttributeTimeIntervals(attr, window)

Le chemin à un appel pour les attributs d'entité : il parcourt les groupes et les horaires de l'attribut, développe chacun d'eux et fusionne les résultats. La fusion est importante — la dé-duplication et l'ordre ne tiennent que dans un seul horaire, donc combiner des groupes à la main peut donner des créneaux en double ou non triés.

Tout ce qui n'est pas un attribut timeInterval renvoie un tableau vide, il est donc sûr de l'appeler sans vérifier d'abord le type.

import { expandAttributeTimeIntervals } from 'oneentry';

const page = await Pages.getPageByUrl('booking');

const slots = expandAttributeTimeIntervals(page.attributeValues.interval, {
from: '2025-04-01',
to: '2025-04-30',
});

expandTimeIntervals(schedule, window)

Résout un horaire unique. Utilisez-le lorsque vous en détenez déjà un — notamment sur les formulaires, dont les horaires sont déjà typés à localizeInfos.intervals :

import { expandTimeIntervals } from 'oneentry';

const form = await Forms.getFormByMarker('booking_form');
const field = form.attributes.find((a) => a.marker === 'schedule');

const slots = (field?.localizeInfos.intervals ?? []).flatMap((schedule) =>
expandTimeIntervals(schedule, { from: '2025-05-01', to: '2025-05-31' }),
);

isTimeIntervalAttribute(attr)

IAttributeValue.value est typé unknown, car sa forme dépend du type. Ce type guard réduit un attribut à ITimeIntervalAttributeValue, ce qui vous permet d'accéder aux horaires sans un cast :

import { isTimeIntervalAttribute } from 'oneentry';

const attr = page.attributeValues.interval;

if (isTimeIntervalAttribute(attr)) {
attr.value[0].values[0].dates; // fully typed
}

La fenêtre

const window = { from: '2025-04-01', to: '2025-04-30' };
  • from et to acceptent une Date, une chaîne ISO ou des millisecondes d'époque.
  • Les deux bornes sont inclusives et comparées à une granularité de jour UTC — la partie heure de from/to est ignorée.
  • La fenêtre est requise : un horaire est une règle de récurrence ouverte, et seul vous savez jusqu'où elle doit être résolue.

Sémantique de récurrence

  • dates[0] / range[0] est à la fois la phase de récurrence et le premier jour valide — rien d'antérieur n'est émis, quelle que soit l'amplitude de la fenêtre.
  • dates[1] / range[1] met fin à la validité. Lorsqu'il ne s'étend pas au-delà du début, l'horaire est ancré à ce jour unique ; avec un indicateur de récurrence activé, la récurrence est alors ouverte et la fenêtre seule limite le résultat.
  • inEveryWeek se répète tous les 7 jours à partir de l'ancre.
  • inEveryMonth se répète le même jour du mois, en sautant les mois qui sont trop courts.
  • Avec les deux indicateurs activés, la règle hebdomadaire s'applique — ce qu'elle a toujours signifié en pratique.
  • Avec aucun indicateur, l'horaire est une simple plage de dates : chaque jour produit des créneaux.
  • Le résultat est dé-duplicé et trié par début, puis par fin.
  • Tous les calculs sont en UTC, donc le résultat ne dépend pas du fuseau horaire de la machine.

Migration depuis le champ timeIntervals

Les versions antérieures du SDK injectaient un tableau timeIntervals calculé dans chaque valeur d'attribut timeInterval. Ce champ n'existe plus. Il matérialisait une année complète de créneaux, peu importe ce dont l'appelant avait besoin — un seul attribut avec des créneaux horaires s'étendait à environ 2 000 lignes de JSON, et des périodes de créneaux plus fines atteignaient des mégaoctets, suffisamment pour dépasser les limites de cache de données du framework. Il n'a jamais été déclaré dans aucune interface ou schéma non plus, donc les consommateurs TypeScript ne pouvaient y accéder que par un cast.

// before — read the pre-computed field
const slots = page.attributeValues.interval.value[0].values[0].timeIntervals;

// now — expand the window you actually render
import { expandAttributeTimeIntervals } from 'oneentry';

const slots = expandAttributeTimeIntervals(page.attributeValues.interval, {
from: '2025-04-01',
to: '2025-04-30',
});

Les données sources étant étendues (dates/range, times/intervals, inEveryWeek, inEveryMonth) restent inchangées et toujours présentes sur chaque horaire — rien n'est perdu, il est simplement résolu à la demande au lieu d'être de manière anticipée, et la règle compacte est ce qui est mis en cache.

Les méthodes _addTimeIntervalsToSchedules et _addTimeIntervalsToFormSchedules ont également été supprimées de chaque module (malgré le préfixe _, elles étaient appelables, par exemple Pages._addTimeIntervalsToSchedules). Utilisez expandTimeIntervals à la place.

Types

Tous ces types sont exportés depuis la racine du package et depuis oneentry/types (voir Importation de Types) :

TypeDécrit
ITimeIntervalAttributeValueUn IAttributeValue réduit à type: 'timeInterval', dont la value est un tableau de groupes
ITimeIntervalGroupUne entrée de la value de l'attribut — horaires partageant un intervalId
ITimeIntervalEntityScheduleUn horaire d'entité : dates, times, inEveryWeek, inEveryMonth
ITimeIntervalScheduleUn horaire de formulaire : range, intervals, inEveryWeek, inEveryMonth
ITimeIntervalRangeUne plage quotidienne avec start, end et une période de créneau en minutes (null lorsqu'elle n'est pas découpée)
ITimeIntervalPointUn point dans une journée - { hours, minutes }
ITimeIntervalWindowLa fenêtre d'expansion - { from, to }
TimeIntervalPairUn créneau résolu - [start, end], deux chaînes ISO 8601 UTC

Exemple : rendu d'un mois de créneaux

import { expandAttributeTimeIntervals } from 'oneentry';

const page = await Pages.getPageByUrl('booking');

if ('statusCode' in page) {
throw new Error(page.message);
}

const slots = expandAttributeTimeIntervals(page.attributeValues.interval, {
from: '2025-04-01',
to: '2025-04-30',
});

// Group the slots by day for a calendar view
const byDay = slots.reduce((acc, [start, end]) => {
const day = start.slice(0, 10);
(acc[day] ??= []).push([start, end]);
return acc;
}, {});

🔗 Documentation Connexe