@interware/content-generator 0.7.2 → 0.8.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.
- package/dist/_chunks/{App-CTh6owSM.mjs → App-2eX-mcfo.mjs} +2 -2
- package/dist/_chunks/{App-ugsCmlsC.js → App-CvZirjX_.js} +2 -2
- package/dist/_chunks/{ImageStudioTabs-Umf3GODW.mjs → ImageStudioTabs-B6fkCK-o.mjs} +353 -21
- package/dist/_chunks/{ImageStudioTabs-BFEF9ggK.js → ImageStudioTabs-CNktoRax.js} +351 -19
- package/dist/_chunks/{Settings-Sk78JUBS.js → Settings-B-QPodCh.js} +169 -1
- package/dist/_chunks/{Settings-CdGW2O8h.mjs → Settings-CaGruvIm.mjs} +170 -2
- package/dist/_chunks/{StudioApp-DoC0z4eh.js → StudioApp-BDoB31L0.js} +2 -2
- package/dist/_chunks/{StudioApp-CrGn-9Gg.mjs → StudioApp-CF03znuL.mjs} +2 -2
- package/dist/_chunks/{index-D6UAvh53.mjs → index-DlemRDzs.mjs} +3 -3
- package/dist/_chunks/{index-C2s9Jhcc.js → index-DwHGS-BJ.js} +3 -3
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/components/settings/DriveSettings.d.ts +77 -0
- package/dist/admin/src/features/drive/DriveTab.d.ts +42 -0
- package/dist/admin/src/features/image-studio/ImageStudioTabs.d.ts +3 -0
- package/dist/admin/src/features/library/FileCard.d.ts +5 -2
- package/dist/admin/src/features/library/LibraryTab.d.ts +5 -0
- package/dist/admin/src/features/library/driveSync.d.ts +41 -0
- package/dist/admin/src/features/templates/export/templateOrigin.d.ts +10 -0
- package/dist/admin/src/lib/use-cases/drive/index.d.ts +3 -0
- package/dist/server/index.js +1411 -49
- package/dist/server/index.mjs +1409 -47
- package/dist/server/src/bootstrap.d.ts +2 -0
- package/dist/server/src/content-types/drive-link/index.d.ts +62 -0
- package/dist/server/src/content-types/drive-link/schema.d.ts +68 -0
- package/dist/server/src/content-types/drive-op/index.d.ts +46 -0
- package/dist/server/src/content-types/drive-op/schema.d.ts +49 -0
- package/dist/server/src/content-types/index.d.ts +106 -0
- package/dist/server/src/controllers/drive.d.ts +30 -0
- package/dist/server/src/controllers/index.d.ts +130 -0
- package/dist/server/src/drive/client.d.ts +32 -0
- package/dist/server/src/drive/clientConfig.d.ts +27 -0
- package/dist/server/src/drive/common.d.ts +6 -0
- package/dist/server/src/drive/fakes.d.ts +104 -0
- package/dist/server/src/drive/files.d.ts +136 -0
- package/dist/server/src/drive/lifecycles.d.ts +7 -0
- package/dist/server/src/drive/links.d.ts +23 -0
- package/dist/server/src/drive/model.d.ts +99 -0
- package/dist/server/src/drive/oauth.d.ts +47 -0
- package/dist/server/src/drive/pull.d.ts +23 -0
- package/dist/server/src/drive/strapiPorts.d.ts +10 -0
- package/dist/server/src/drive/sync.d.ts +40 -0
- package/dist/server/src/index.d.ts +294 -0
- package/dist/server/src/services/drive.d.ts +141 -0
- package/dist/server/src/services/index.d.ts +55 -0
- package/package.json +1 -1
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { DriveHttpClient } from './client';
|
|
2
|
+
export declare const DRIVE_ROOT = "root";
|
|
3
|
+
export declare const FOLDER_MIME = "application/vnd.google-apps.folder";
|
|
4
|
+
export interface DriveFile {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
mimeType: string;
|
|
8
|
+
}
|
|
9
|
+
type Http = Pick<DriveHttpClient, 'request'> & Partial<Pick<DriveHttpClient, 'download'>>;
|
|
10
|
+
/** Resultado de subir: el id y el `md5Checksum` con el que Drive identifica esta versión del contenido. */
|
|
11
|
+
export interface Uploaded {
|
|
12
|
+
id: string;
|
|
13
|
+
md5: string | null;
|
|
14
|
+
}
|
|
15
|
+
/** Un cambio de `changes.list` con los campos que usa la sincronización (S7.4). */
|
|
16
|
+
export interface DriveChange {
|
|
17
|
+
fileId: string;
|
|
18
|
+
removed: boolean;
|
|
19
|
+
file?: {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
mimeType: string;
|
|
23
|
+
parents?: string[];
|
|
24
|
+
trashed?: boolean;
|
|
25
|
+
md5Checksum?: string;
|
|
26
|
+
size?: string;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** Literal de cadena para `q`: Drive escapa `\` y `'` con barra invertida. */
|
|
30
|
+
export declare const quote: (value: string) => string;
|
|
31
|
+
/** El elemento llamado `name` dentro de `parentId` (sin papelera), o `null`. */
|
|
32
|
+
export declare const findChild: (http: Http, parentId: string, name: string) => Promise<DriveFile | null>;
|
|
33
|
+
export declare const createFolder: (http: Http, parentId: string, name: string) => Promise<string>;
|
|
34
|
+
/** Cuerpo `multipart/related` de Drive: metadatos JSON y contenido. */
|
|
35
|
+
export declare const multipart: (metadata: Record<string, unknown>, mime: string, content: Uint8Array) => {
|
|
36
|
+
body: Buffer;
|
|
37
|
+
contentType: string;
|
|
38
|
+
};
|
|
39
|
+
export interface UploadInput {
|
|
40
|
+
name: string;
|
|
41
|
+
mime: string;
|
|
42
|
+
content: Uint8Array;
|
|
43
|
+
description?: string;
|
|
44
|
+
}
|
|
45
|
+
export declare const uploadFile: (http: Http, parentId: string, file: UploadInput) => Promise<Uploaded>;
|
|
46
|
+
/** Contenido nuevo del mismo archivo de Drive: Drive guarda la versión anterior en su historial. */
|
|
47
|
+
export declare const updateContent: (http: Http, driveId: string, file: UploadInput) => Promise<Uploaded>;
|
|
48
|
+
/** Renombra y, si cambia `from` → `to`, mueve de carpeta. */
|
|
49
|
+
export declare const updateMeta: (http: Http, driveId: string, { name, from, to }: {
|
|
50
|
+
name?: string;
|
|
51
|
+
from?: string;
|
|
52
|
+
to?: string;
|
|
53
|
+
}) => Promise<void>;
|
|
54
|
+
/** Manda a la papelera de Drive (se recupera durante 30 días). Si ya no existe, no es error. */
|
|
55
|
+
export declare const trash: (http: Http, driveId: string) => Promise<void>;
|
|
56
|
+
/** Contenido de un archivo binario de Drive. */
|
|
57
|
+
export declare const download: (http: Http, driveId: string) => Promise<Uint8Array>;
|
|
58
|
+
/** Elemento de la vista de Drive (S7.2). */
|
|
59
|
+
export interface DriveEntry {
|
|
60
|
+
id: string;
|
|
61
|
+
name: string;
|
|
62
|
+
mimeType: string;
|
|
63
|
+
size: number | null;
|
|
64
|
+
modifiedTime: string | null;
|
|
65
|
+
webViewLink: string | null;
|
|
66
|
+
parents: string[];
|
|
67
|
+
}
|
|
68
|
+
/** Una página del contenido de una carpeta (sin papelera): carpetas primero, luego por nombre. */
|
|
69
|
+
export declare const listChildren: (http: Http, parentId: string, pageToken?: string) => Promise<{
|
|
70
|
+
items: DriveEntry[];
|
|
71
|
+
nextPageToken: string;
|
|
72
|
+
}>;
|
|
73
|
+
export declare const getFile: (http: Http, id: string) => Promise<DriveEntry>;
|
|
74
|
+
/** Cuántos archivos y carpetas hay dentro de una carpeta, recorriendo en vivo hasta `limit`. */
|
|
75
|
+
export declare const countTree: (http: Http, folderId: string, limit?: number) => Promise<{
|
|
76
|
+
files: number;
|
|
77
|
+
folders: number;
|
|
78
|
+
truncated: boolean;
|
|
79
|
+
}>;
|
|
80
|
+
/**
|
|
81
|
+
* Estado actual de un archivo con los campos de `changes.list`, para la revisión completa contra Drive
|
|
82
|
+
* (S7.4). `null` si ya no existe.
|
|
83
|
+
*/
|
|
84
|
+
export declare const getMeta: (http: Http, id: string) => Promise<DriveChange['file'] | null>;
|
|
85
|
+
/** Id real de «Mi unidad»: `changes.list` reporta los padres por id, no como `root`. */
|
|
86
|
+
export declare const rootId: (http: Http) => Promise<string>;
|
|
87
|
+
/** Token desde el que empezar a leer cambios: lo anterior no se procesa. */
|
|
88
|
+
export declare const startPageToken: (http: Http) => Promise<string>;
|
|
89
|
+
/** Una página de cambios del Drive desde `pageToken`. */
|
|
90
|
+
export declare const listChanges: (http: Http, pageToken: string) => Promise<{
|
|
91
|
+
changes?: DriveChange[];
|
|
92
|
+
nextPageToken?: string;
|
|
93
|
+
newStartPageToken?: string;
|
|
94
|
+
}>;
|
|
95
|
+
/** Las operaciones de este módulo atadas a un cliente: el puerto que usan vínculos y sincronización. */
|
|
96
|
+
export declare const driveOps: (http: Http) => {
|
|
97
|
+
findChild: (parentId: string, name: string) => Promise<DriveFile>;
|
|
98
|
+
createFolder: (parentId: string, name: string) => Promise<string>;
|
|
99
|
+
uploadFile: (parentId: string, file: UploadInput) => Promise<Uploaded>;
|
|
100
|
+
updateContent: (driveId: string, file: UploadInput) => Promise<Uploaded>;
|
|
101
|
+
updateMeta: (driveId: string, change: {
|
|
102
|
+
name?: string;
|
|
103
|
+
from?: string;
|
|
104
|
+
to?: string;
|
|
105
|
+
}) => Promise<void>;
|
|
106
|
+
trash: (driveId: string) => Promise<void>;
|
|
107
|
+
download: (driveId: string) => Promise<Uint8Array>;
|
|
108
|
+
startPageToken: () => Promise<string>;
|
|
109
|
+
rootId: () => Promise<string>;
|
|
110
|
+
listChildren: (parentId: string, pageToken?: string) => Promise<{
|
|
111
|
+
items: DriveEntry[];
|
|
112
|
+
nextPageToken: string;
|
|
113
|
+
}>;
|
|
114
|
+
getFile: (id: string) => Promise<DriveEntry>;
|
|
115
|
+
getMeta: (id: string) => Promise<{
|
|
116
|
+
id: string;
|
|
117
|
+
name: string;
|
|
118
|
+
mimeType: string;
|
|
119
|
+
parents?: string[];
|
|
120
|
+
trashed?: boolean;
|
|
121
|
+
md5Checksum?: string;
|
|
122
|
+
size?: string;
|
|
123
|
+
}>;
|
|
124
|
+
countTree: (folderId: string) => Promise<{
|
|
125
|
+
files: number;
|
|
126
|
+
folders: number;
|
|
127
|
+
truncated: boolean;
|
|
128
|
+
}>;
|
|
129
|
+
listChanges: (pageToken: string) => Promise<{
|
|
130
|
+
changes?: DriveChange[];
|
|
131
|
+
nextPageToken?: string;
|
|
132
|
+
newStartPageToken?: string;
|
|
133
|
+
}>;
|
|
134
|
+
};
|
|
135
|
+
export type DriveOps = ReturnType<typeof driveOps>;
|
|
136
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vía rápida de la sincronización (ADR-009): los lifecycles de upload avisan que algo cambió en la
|
|
3
|
+
* Biblioteca. Solo encolan; la revisión de cada ciclo cubre lo que no pasa por aquí (`bulk-move`).
|
|
4
|
+
*/
|
|
5
|
+
import type { Core } from '@strapi/strapi';
|
|
6
|
+
import type { CmsType } from './model';
|
|
7
|
+
export declare const subscribeUploadLifecycles: (strapi: Core.Strapi, onChange: (cmsType: CmsType, cmsId: number) => Promise<void>) => void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { DriveOps } from './files';
|
|
2
|
+
import type { Cms, CmsFolder, CmsType, LinkRepo, OpQueue } from './model';
|
|
3
|
+
export interface LinkDeps {
|
|
4
|
+
drive: DriveOps;
|
|
5
|
+
cms: Cms;
|
|
6
|
+
links: LinkRepo;
|
|
7
|
+
ops: OpQueue;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Carpetas entre «Generated» y el elemento, de arriba hacia abajo, sin incluir al elemento. `null` si no
|
|
11
|
+
* está dentro de «Generated».
|
|
12
|
+
*/
|
|
13
|
+
export declare const ancestorsOf: (cms: Cms, root: CmsFolder, path: string) => Promise<CmsFolder[] | null>;
|
|
14
|
+
export declare const mark: (deps: LinkDeps, cmsType: CmsType, cmsId: number) => Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Vínculos que siguen haciendo falta: los marcados, su contenido y los ancestros de cada marcado. Se calcula
|
|
17
|
+
* por rutas de Strapi (`path` / `folderPath`), sin recorrer el árbol.
|
|
18
|
+
*/
|
|
19
|
+
export declare const neededLinkIds: (deps: Pick<LinkDeps, 'cms' | 'links'>) => Promise<Set<number>>;
|
|
20
|
+
/** Deja de sincronizar el elemento y su contenido. No borra nada en Drive ni en el CMS. */
|
|
21
|
+
export declare const unmark: (deps: Pick<LinkDeps, 'cms' | 'links'>, cmsType: CmsType, cmsId: number) => Promise<void>;
|
|
22
|
+
/** ¿El elemento queda dentro de algo marcado (él mismo o una carpeta superior)? */
|
|
23
|
+
export declare const isSynced: (deps: Pick<LinkDeps, 'cms' | 'links'>, cmsType: CmsType, cmsId: number) => Promise<boolean>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tipos de la sincronización con Drive (S7.3) y los puertos hacia Strapi (Biblioteca, vínculos, cola). Los
|
|
3
|
+
* adaptadores reales viven en `strapiPorts.ts`; las pruebas usan versiones en memoria.
|
|
4
|
+
*/
|
|
5
|
+
export type CmsType = 'file' | 'folder';
|
|
6
|
+
export interface CmsFolder {
|
|
7
|
+
id: number;
|
|
8
|
+
pathId: number;
|
|
9
|
+
name: string;
|
|
10
|
+
/** Ruta de Strapi por `pathId`: `/44/45`. */
|
|
11
|
+
path: string;
|
|
12
|
+
parentId: number | null;
|
|
13
|
+
}
|
|
14
|
+
export interface CmsFile {
|
|
15
|
+
id: number;
|
|
16
|
+
name: string;
|
|
17
|
+
folderId: number | null;
|
|
18
|
+
/** `path` de su carpeta (`/44/45`), o `/` en la raíz. */
|
|
19
|
+
folderPath: string;
|
|
20
|
+
url: string;
|
|
21
|
+
/** KB, como lo guarda Strapi. */
|
|
22
|
+
size: number;
|
|
23
|
+
mime: string;
|
|
24
|
+
}
|
|
25
|
+
export type LinkStatus = 'synced' | 'pending' | 'error' | 'skipped';
|
|
26
|
+
export interface DriveLink {
|
|
27
|
+
id: number;
|
|
28
|
+
cmsType: CmsType;
|
|
29
|
+
cmsId: number;
|
|
30
|
+
driveId: string | null;
|
|
31
|
+
root: boolean;
|
|
32
|
+
name: string | null;
|
|
33
|
+
parentCmsId: number | null;
|
|
34
|
+
version: string | null;
|
|
35
|
+
/** `md5Checksum` de Drive de la última versión sincronizada (S7.4); vacío en carpetas. */
|
|
36
|
+
driveRev: string | null;
|
|
37
|
+
status: LinkStatus;
|
|
38
|
+
error: string | null;
|
|
39
|
+
}
|
|
40
|
+
export type NewLink = Omit<DriveLink, 'id'>;
|
|
41
|
+
export interface DriveOp {
|
|
42
|
+
id: number;
|
|
43
|
+
cmsType: CmsType;
|
|
44
|
+
cmsId: number;
|
|
45
|
+
attempts: number;
|
|
46
|
+
runAfter: number;
|
|
47
|
+
error: string | null;
|
|
48
|
+
}
|
|
49
|
+
/** La Biblioteca de Strapi (`plugin::upload.folder` y `plugin::upload.file`). */
|
|
50
|
+
export interface Cms {
|
|
51
|
+
generatedRoot(): Promise<CmsFolder | null>;
|
|
52
|
+
folder(id: number): Promise<CmsFolder | null>;
|
|
53
|
+
file(id: number): Promise<CmsFile | null>;
|
|
54
|
+
foldersByPathIds(pathIds: number[]): Promise<CmsFolder[]>;
|
|
55
|
+
childFolders(folderId: number): Promise<CmsFolder[]>;
|
|
56
|
+
childFiles(folderId: number): Promise<CmsFile[]>;
|
|
57
|
+
readFile(file: CmsFile): Promise<Uint8Array>;
|
|
58
|
+
}
|
|
59
|
+
/** Escrituras a la Biblioteca para lo que llega de Drive (S7.4). Se hacen dentro de `withoutEcho`. */
|
|
60
|
+
export interface CmsWriter {
|
|
61
|
+
uploadFile(folderId: number, name: string, mime: string, content: Uint8Array): Promise<CmsFile>;
|
|
62
|
+
replaceFile(id: number, name: string, mime: string, content: Uint8Array): Promise<CmsFile>;
|
|
63
|
+
updateFile(id: number, change: {
|
|
64
|
+
name?: string;
|
|
65
|
+
folderId?: number;
|
|
66
|
+
}): Promise<void>;
|
|
67
|
+
deleteFile(id: number): Promise<void>;
|
|
68
|
+
createFolder(name: string, parentId: number): Promise<CmsFolder>;
|
|
69
|
+
updateFolder(id: number, change: {
|
|
70
|
+
name?: string;
|
|
71
|
+
parentId?: number;
|
|
72
|
+
}): Promise<void>;
|
|
73
|
+
deleteFolder(id: number): Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
export interface LinkRepo {
|
|
76
|
+
all(): Promise<DriveLink[]>;
|
|
77
|
+
find(cmsType: CmsType, cmsId: number): Promise<DriveLink | null>;
|
|
78
|
+
findByDriveId(driveId: string): Promise<DriveLink | null>;
|
|
79
|
+
create(data: NewLink): Promise<DriveLink>;
|
|
80
|
+
update(id: number, data: Partial<NewLink>): Promise<DriveLink>;
|
|
81
|
+
remove(id: number): Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
export interface OpQueue {
|
|
84
|
+
/** Encola «revisa este elemento»; si ya está en cola, no duplica. */
|
|
85
|
+
push(cmsType: CmsType, cmsId: number): Promise<void>;
|
|
86
|
+
/** Hasta `limit` operaciones listas (`runAfter` vencido), las más viejas primero. */
|
|
87
|
+
ready(limit: number, now: number): Promise<DriveOp[]>;
|
|
88
|
+
done(op: DriveOp): Promise<void>;
|
|
89
|
+
retry(op: DriveOp, error: string, runAfter: number): Promise<void>;
|
|
90
|
+
count(): Promise<number>;
|
|
91
|
+
}
|
|
92
|
+
/** Entrada inválida o conflicto que el panel muestra tal cual. */
|
|
93
|
+
export declare class DriveSyncError extends Error {
|
|
94
|
+
readonly status: 400 | 409;
|
|
95
|
+
constructor(message: string, status?: 400 | 409);
|
|
96
|
+
}
|
|
97
|
+
export declare const collisionMessage: (name: string) => string;
|
|
98
|
+
/** Ids de carpeta (`pathId`) de una ruta de Strapi: `/44/45` → `[44, 45]`. */
|
|
99
|
+
export declare const pathIds: (path: string) => number[];
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import type { DriveClient } from './clientConfig';
|
|
3
|
+
export declare const DRIVE_SCOPE = "https://www.googleapis.com/auth/drive";
|
|
4
|
+
export declare const OAUTH_STATE_KEY = "DRIVE_OAUTH_STATE";
|
|
5
|
+
export type Fetch = typeof fetch;
|
|
6
|
+
/** Subconjunto del plugin store de Strapi que usa Drive. */
|
|
7
|
+
export interface Store {
|
|
8
|
+
get: (p: {
|
|
9
|
+
key: string;
|
|
10
|
+
}) => Promise<unknown>;
|
|
11
|
+
set: (p: {
|
|
12
|
+
key: string;
|
|
13
|
+
value: unknown;
|
|
14
|
+
}) => Promise<void>;
|
|
15
|
+
delete: (p: {
|
|
16
|
+
key: string;
|
|
17
|
+
}) => Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
/** Google rechazó las credenciales: código inválido, acceso revocado o token vencido. */
|
|
20
|
+
export declare class DriveAuthError extends Error {
|
|
21
|
+
constructor(message: string);
|
|
22
|
+
}
|
|
23
|
+
export declare const authUrl: (client: DriveClient, redirectUri: string, state: string) => string;
|
|
24
|
+
/** Emite un `state` de un solo uso que caduca en 10 minutos. */
|
|
25
|
+
export declare const newState: (store: Store, now?: number) => Promise<string>;
|
|
26
|
+
/** Verdadero si `state` es el último emitido y no ha caducado. Siempre lo consume. */
|
|
27
|
+
export declare const checkState: (store: Store, state: unknown, now?: number) => Promise<boolean>;
|
|
28
|
+
export declare const exchangeCode: ({ client, code, redirectUri, fetch: fetchFn, }: {
|
|
29
|
+
client: DriveClient;
|
|
30
|
+
code: string;
|
|
31
|
+
redirectUri: string;
|
|
32
|
+
fetch: Fetch;
|
|
33
|
+
}) => Promise<{
|
|
34
|
+
accessToken: string;
|
|
35
|
+
expiresIn: number;
|
|
36
|
+
refreshToken: string;
|
|
37
|
+
}>;
|
|
38
|
+
export declare const refreshAccessToken: ({ client, refreshToken, fetch: fetchFn, }: {
|
|
39
|
+
client: DriveClient;
|
|
40
|
+
refreshToken: string;
|
|
41
|
+
fetch: Fetch;
|
|
42
|
+
}) => Promise<{
|
|
43
|
+
accessToken: string;
|
|
44
|
+
expiresIn: number;
|
|
45
|
+
}>;
|
|
46
|
+
/** Revoca el token en Google. Un token ya inválido no es error: el resultado es el mismo. */
|
|
47
|
+
export declare const revokeToken: (token: string, fetchFn: Fetch) => Promise<void>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { DriveChange } from './files';
|
|
2
|
+
import type { CmsWriter } from './model';
|
|
3
|
+
import type { SyncDeps } from './sync';
|
|
4
|
+
export declare const PAGE_TOKEN_KEY = "DRIVE_PAGE_TOKEN";
|
|
5
|
+
export declare const ROOT_ID_KEY = "DRIVE_ROOT_ID";
|
|
6
|
+
/** Se hizo la revisión completa contra Drive desde el último punto de partida. */
|
|
7
|
+
export declare const FULL_CHECK_KEY = "DRIVE_FULL_CHECK";
|
|
8
|
+
export interface PullDeps extends SyncDeps {
|
|
9
|
+
writer: CmsWriter;
|
|
10
|
+
}
|
|
11
|
+
/** Aplica un cambio de Drive (tabla del diseño de S7.4). */
|
|
12
|
+
/** Aplica un cambio de Drive. Verdadero si cambió algo (en el CMS o en los vínculos). */
|
|
13
|
+
export declare const applyChange: (deps: PullDeps, change: DriveChange, rootId: string) => Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Lee y aplica los cambios pendientes de Drive. Sin punto de partida, lo guarda y hace una revisión completa
|
|
16
|
+
* de lo vinculado, para no perder lo que cambió antes.
|
|
17
|
+
*/
|
|
18
|
+
export declare const pullChanges: (deps: PullDeps, { full }?: {
|
|
19
|
+
full?: boolean;
|
|
20
|
+
}) => Promise<{
|
|
21
|
+
applied: number;
|
|
22
|
+
errors: number;
|
|
23
|
+
}>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import type { Core } from '@strapi/strapi';
|
|
3
|
+
import type { Cms, CmsWriter, LinkRepo, OpQueue } from './model';
|
|
4
|
+
export declare const LINK_UID = "plugin::strapi-content-generator-gemini.drive-link";
|
|
5
|
+
export declare const OP_UID = "plugin::strapi-content-generator-gemini.drive-op";
|
|
6
|
+
export declare const strapiCms: (strapi: Core.Strapi, fetchFn?: typeof fetch) => Cms;
|
|
7
|
+
/** Escrituras con los servicios de `@strapi/upload`, para que rutas, formatos y proveedor (S3) sean los de Strapi. */
|
|
8
|
+
export declare const strapiCmsWriter: (strapi: Core.Strapi) => CmsWriter;
|
|
9
|
+
export declare const strapiLinks: (strapi: Core.Strapi) => LinkRepo;
|
|
10
|
+
export declare const strapiOps: (strapi: Core.Strapi) => OpQueue;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export { MAX_FILE_BYTES, isEcho, versionOf, withoutEcho } from './common';
|
|
2
|
+
import type { LinkDeps } from './links';
|
|
3
|
+
import type { CmsFile, CmsType, CmsWriter } from './model';
|
|
4
|
+
import type { Store } from './oauth';
|
|
5
|
+
export declare const LOCK_KEY = "DRIVE_LOCK";
|
|
6
|
+
export declare const LAST_RUN_KEY = "DRIVE_LAST_RUN";
|
|
7
|
+
export interface SyncDeps extends LinkDeps {
|
|
8
|
+
/** Lo que llega de Drive se escribe con esto (S7.4); sin él, el ciclo solo sube del CMS a Drive. */
|
|
9
|
+
writer?: CmsWriter;
|
|
10
|
+
store: Store;
|
|
11
|
+
now?: () => number;
|
|
12
|
+
/** Descripción del archivo en Drive (por ejemplo, el template de origen), si tiene. */
|
|
13
|
+
describe?: (file: CmsFile) => Promise<string | undefined>;
|
|
14
|
+
log?: {
|
|
15
|
+
warn: (msg: string) => void;
|
|
16
|
+
info?: (msg: string) => void;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export interface SyncSummary {
|
|
20
|
+
skipped: boolean;
|
|
21
|
+
/** Cambios de Drive aplicados al CMS (S7.4). */
|
|
22
|
+
pulled: number;
|
|
23
|
+
processed: number;
|
|
24
|
+
errors: number;
|
|
25
|
+
pending: number;
|
|
26
|
+
}
|
|
27
|
+
/** Decide y aplica lo que corresponde a un elemento (tabla del diseño de S7.3). */
|
|
28
|
+
export declare const processItem: (deps: SyncDeps, cmsType: CmsType, cmsId: number, depth?: number) => Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Compara lo vinculado con el CMS y encola lo que cambió, lo que se borró y lo que llegó a una carpeta
|
|
31
|
+
* sincronizada sin pasar por un lifecycle (`bulk-move`).
|
|
32
|
+
*/
|
|
33
|
+
export declare const reconcile: (deps: SyncDeps) => Promise<void>;
|
|
34
|
+
/** Un ciclo completo: revisión y cola por tandas, con un solo proceso a la vez. */
|
|
35
|
+
export declare const runSync: (deps: SyncDeps, { budgetMs, full }?: {
|
|
36
|
+
budgetMs?: number;
|
|
37
|
+
full?: boolean;
|
|
38
|
+
}) => Promise<SyncSummary>;
|
|
39
|
+
/** Programa un ciclo `delayMs` después de la última llamada (los lifecycles llegan en ráfagas). */
|
|
40
|
+
export declare const debounce: (run: () => Promise<unknown>, delayMs?: number, onError?: (err: unknown) => void) => () => void;
|