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 :
| Forme | Où la trouver | Contient |
|---|---|---|
Entité (ITimeIntervalEntitySchedule) | attributeValues[marker].value[].values[] sur les pages, produits, blocs et ensembles d'attributs | une plage de dates avec des paires de times |
Formulaire (ITimeIntervalSchedule) | attributes[].localizeInfos.intervals[] sur les formulaires | une 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' };
fromettoacceptent uneDate, 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/toest 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.inEveryWeekse répète tous les 7 jours à partir de l'ancre.inEveryMonthse 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) :
| Type | Décrit |
|---|---|
ITimeIntervalAttributeValue | Un IAttributeValue réduit à type: 'timeInterval', dont la value est un tableau de groupes |
ITimeIntervalGroup | Une entrée de la value de l'attribut — horaires partageant un intervalId |
ITimeIntervalEntitySchedule | Un horaire d'entité : dates, times, inEveryWeek, inEveryMonth |
ITimeIntervalSchedule | Un horaire de formulaire : range, intervals, inEveryWeek, inEveryMonth |
ITimeIntervalRange | Une plage quotidienne avec start, end et une période de créneau en minutes (null lorsqu'elle n'est pas découpée) |
ITimeIntervalPoint | Un point dans une journée - { hours, minutes } |
ITimeIntervalWindow | La fenêtre d'expansion - { from, to } |
TimeIntervalPair | Un 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
- Valeurs d'Attributs - la forme normalisée de chaque valeur d'attribut
- Importation de Types - importation de
ITimeIntervalWindowet amis - Module Formulaires - attributs de formulaire portant
localizeInfos.intervals