@localazy/strapi-plugin 1.7.0 → 1.7.1

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.
@@ -9,4 +9,23 @@ export declare enum ShouldSetDownloadedPropertyReturnType {
9
9
  NO = "no",
10
10
  JSON = "json"
11
11
  }
12
+ /**
13
+ * Locate the field a downloaded key belongs to, using the Content Transfer Setup.
14
+ *
15
+ * - `YES`: the key is a plain field enabled for transfer (the field is the key's last segment).
16
+ * - `JSON`: the key is one leaf of an enabled `json` or `blocks` field, which the upload flattens
17
+ * into one key per leaf; `fieldSegmentIndex` is the index in `parsedKeyRest` of the segment
18
+ * naming that field. Everything before it is the path to the entry or component owning the
19
+ * field (dynamic zone `id;component` segments and component ids included); everything after it
20
+ * is the leaf's path inside the field's value, e.g. for
21
+ * `beats[3;about.timeline].stops[10].notes[0].children[0].text` the field is `notes` (index 4)
22
+ * of stop 10 of timeline 3, and for `tags[0]` or `years.2024` it is `tags` / `years` (index 0).
23
+ * - `NO`: anything else (field disabled or unknown, component gone, model not set up).
24
+ */
25
+ export declare const locateDownloadedField: (modelContentTransferSetup: ModelContentTransferSetup, parsedKeyRest: string[]) => {
26
+ type: ShouldSetDownloadedPropertyReturnType;
27
+ fieldSegmentIndex: number;
28
+ };
12
29
  export declare const shouldSetDownloadedProperty: (modelContentTransferSetup: ModelContentTransferSetup, parsedKeyRest: string[]) => ShouldSetDownloadedPropertyReturnType;
30
+ /** Index of the `json`/`blocks` field's own segment in `parsedKeyRest`, or -1 (see `locateDownloadedField`). */
31
+ export declare const getJsonFieldSegmentIndex: (modelContentTransferSetup: ModelContentTransferSetup, parsedKeyRest: string[]) => number;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Downloaded values are positioned by the source-locale entry: the n-th repeatable component or
3
+ * dynamic zone item of the source goes to the n-th item of the localization. That holds only while
4
+ * both lists have the same layout. When the source list was changed (items added or removed,
5
+ * dynamic zone components replaced or reordered), the localized list is rebuilt from the source
6
+ * items instead of merging translations into unrelated items.
7
+ *
8
+ * Only lists that receive downloaded values (present in `downloadedEntry`) are aligned; other
9
+ * localized values are kept as they are.
10
+ */
11
+ export declare const alignLocalizedEntryToSource: (models: any, localizedEntry: any, sourceEntry: any, model: any, downloadedEntry: any) => any;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Data for creating a new localization of `baseEntry` (the source-locale entry) from the
3
+ * translated model downloaded from Localazy: the source entry with the translated values put in
4
+ * place. Items positioning is done by `parsedLocalazyEntryToCreateEntry`, so the two can be merged.
5
+ */
6
+ export declare const buildLocalizedCreateEntry: (models: any, translatedModel: any, baseEntry: any, uid: any, isoStrapi: string) => Record<string, any>;
@@ -0,0 +1,44 @@
1
+ export type DownloadedLocalazyKey = {
2
+ id: string;
3
+ key: string[];
4
+ value: unknown;
5
+ event?: number;
6
+ };
7
+ export type DownloadedKeySource = {
8
+ lang: string;
9
+ id: string;
10
+ event: number | undefined;
11
+ };
12
+ /** `{ [isoStrapi]: { [uid]: { [documentId]: translatedModel } } }` */
13
+ export type ParsedLocalazyContent = Record<string, Record<string, Record<string, any>>>;
14
+ type ParseLocalazyKey = (key: string) => {
15
+ uid: string;
16
+ id: string;
17
+ rest: string[];
18
+ };
19
+ /**
20
+ * Turns the keys downloaded from Localazy into one translated model per Strapi entry and locale,
21
+ * and records which keys changed for each entry (so they can be marked processed once the entry
22
+ * is written).
23
+ *
24
+ * With a sync cursor (`processedKeys`), only entries with at least one key changed since it was
25
+ * last processed are taken, but each of them with all of its keys: an incremental download
26
+ * rewrites a changed entry exactly as a full sync would. Applying the changed keys alone is not
27
+ * enough, because a json/blocks field is rebuilt from all of its leaves and list items are placed
28
+ * by the source entry, so a partial set of keys would put source-language text or wrong items into
29
+ * everything that did not change.
30
+ */
31
+ export declare const collectDownloadedContent: ({ languages, processedKeys, contentTransferSetup, models, parseLocalazyKey, }: {
32
+ languages: Array<{
33
+ isoStrapi: string;
34
+ keys: DownloadedLocalazyKey[];
35
+ }>;
36
+ processedKeys: Record<string, Record<string, number>>;
37
+ contentTransferSetup: any;
38
+ models: any[];
39
+ parseLocalazyKey: ParseLocalazyKey;
40
+ }) => {
41
+ parsedLocalazyContent: ParsedLocalazyContent;
42
+ entryKeySourceMap: Record<string, DownloadedKeySource[]>;
43
+ };
44
+ export {};
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Collects the downloaded keys of `json` and `blocks` fields. On upload such a field is flattened
3
+ * into one Localazy key per leaf; on download the leaves are put back together into one value per
4
+ * field, which is then written into the parsed Localazy content at the field's own path.
5
+ *
6
+ * A field is identified by its full path (owner path + field name), so two json/blocks fields of
7
+ * the same entry or component (e.g. a component's `title` and `line`) never share one value, and
8
+ * a field inside a nested component is written at its own level instead of replacing the
9
+ * component it lives in.
10
+ */
11
+ export declare const createJsonFieldsDownloadAccumulator: () => {
12
+ /**
13
+ * @param fieldKey path to the field in the parsed content: `[iso, uid, documentId, ...ownerPath, fieldName]`
14
+ * @param valuePath path of this leaf inside the field's value
15
+ */
16
+ add(fieldKey: string[], valuePath: string[], value: unknown): void;
17
+ /** Write every collected field value into `parsedContent` at its own path. */
18
+ applyTo(parsedContent: Record<string, any>): void;
19
+ };
@@ -4,5 +4,6 @@ declare const isDynamicZone: (attributeObj: any) => boolean;
4
4
  declare const isRepeatable: (attributeObj: any) => boolean;
5
5
  declare const isRelation: (attributeObj: any) => boolean;
6
6
  declare const isBlocks: (attributeObj: any) => boolean;
7
+ declare const isJson: (attributeObj: any) => boolean;
7
8
  declare const findModel: (models: any, uid: any) => any;
8
- export { getAttribute, isComponent, isDynamicZone, isRepeatable, isRelation, isBlocks, findModel };
9
+ export { getAttribute, isComponent, isDynamicZone, isRepeatable, isRelation, isBlocks, isJson, findModel };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Download side of a `json` field. On upload, every leaf of the source-locale value becomes one
3
+ * Localazy key (see `flattenObject`); `translated` is those leaves put back together by key path.
4
+ * The result is a copy of the source value with each string leaf replaced by its translation, so
5
+ * its shape (objects vs arrays, numeric keys, non-string values) always matches the source, leaves
6
+ * that are no longer in the source are ignored, and untranslated leaves keep the source text.
7
+ *
8
+ * Returns `undefined` when there is no source value to overlay onto.
9
+ */
10
+ export declare const overlayJsonTranslation: (sourceValue: any, translated: any) => any;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Split a Localazy key produced by the upload (`flattenObject`) into the content type uid, the
3
+ * document id and the remaining path segments, e.g.
4
+ * `api::page.page[doc].sections[3;sections.timeline].stops[11].label` →
5
+ * `{ uid: 'api::page.page', id: 'doc', rest: ['sections', '3;sections.timeline', 'stops', '11', 'label'] }`.
6
+ */
7
+ export declare const parseLocalazyKey: (key: string) => {
8
+ uid: string;
9
+ id: string;
10
+ rest: string[];
11
+ };
@@ -1,7 +1,15 @@
1
1
  /**
2
- * Items positioning is done by the `toCreateEntry` function
2
+ * Items positioning is done by the `toCreateEntry` function: repeatable component and dynamic
3
+ * zone items are placed at their position in `baseEntry` (the source-locale entry), so arrays may
4
+ * have holes for items without downloaded values. They are not compacted, because callers merge
5
+ * the result onto a complete entry (the source entry, or the current localization), and shifting
6
+ * items would put translations into the wrong item.
7
+ *
8
+ * `rebuiltFieldPaths` lists where blocks and json fields were written; each holds a complete value
9
+ * rebuilt from the source value (see `overlayBlocksTranslation`, `overlayJsonTranslation`).
3
10
  */
4
11
  export declare const parsedLocalazyEntryToCreateEntry: (models: any, parsedLocalazyEntry: any, baseEntry: any, uid: string, locale?: string) => {
5
12
  createEntry: Record<string, any>;
6
13
  dynamicZoneComponentKeys: any[];
14
+ rebuiltFieldPaths: string[];
7
15
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@localazy/strapi-plugin",
3
- "version": "1.7.0",
3
+ "version": "1.7.1",
4
4
  "description": "The official Strapi Plugin by Localazy.",
5
5
  "keywords": [
6
6
  "strapi",
@@ -1 +0,0 @@
1
- export declare const resetArrayKeysDeep: (object: Record<string, any>, keysToFilter: string[]) => void;