@ai-matrx/office 0.3.1 → 0.4.0
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/CHANGELOG.md +13 -4
- package/dist/chunk-5T2M6LSI.js +529 -0
- package/dist/chunk-5T2M6LSI.js.map +1 -0
- package/dist/chunk-QZE7HBZB.cjs +529 -0
- package/dist/chunk-QZE7HBZB.cjs.map +1 -0
- package/dist/chunk-WKBWRG7N.js +209 -0
- package/dist/chunk-WKBWRG7N.js.map +1 -0
- package/dist/chunk-ZDZCCOUB.cjs +209 -0
- package/dist/chunk-ZDZCCOUB.cjs.map +1 -0
- package/dist/core.d.cts +5 -1
- package/dist/core.d.ts +5 -1
- package/dist/matrxImagePorts-JDFYE4QI.cjs +59 -0
- package/dist/matrxImagePorts-JDFYE4QI.cjs.map +1 -0
- package/dist/matrxImagePorts-VPBBUADM.js +59 -0
- package/dist/matrxImagePorts-VPBBUADM.js.map +1 -0
- package/dist/sheets-xlsx.cjs +525 -0
- package/dist/sheets-xlsx.cjs.map +1 -0
- package/dist/sheets-xlsx.d.cts +153 -0
- package/dist/sheets-xlsx.d.ts +153 -0
- package/dist/sheets-xlsx.js +525 -0
- package/dist/sheets-xlsx.js.map +1 -0
- package/dist/sheets.cjs +921 -0
- package/dist/sheets.cjs.map +1 -0
- package/dist/sheets.d.cts +605 -0
- package/dist/sheets.d.ts +605 -0
- package/dist/sheets.js +921 -0
- package/dist/sheets.js.map +1 -0
- package/dist/univer-collab.cjs +1 -77
- package/dist/univer-collab.cjs.map +1 -1
- package/dist/univer-collab.d.cts +1 -15
- package/dist/univer-collab.d.ts +1 -15
- package/dist/univer-collab.js +1 -77
- package/dist/univer-collab.js.map +1 -1
- package/dist/univer-realtime.cjs +102 -0
- package/dist/univer-realtime.cjs.map +1 -0
- package/dist/univer-realtime.d.cts +15 -0
- package/dist/univer-realtime.d.ts +15 -0
- package/dist/univer-realtime.js +80 -0
- package/dist/univer-realtime.js.map +1 -0
- package/dist/xlsx-to-univer-AQAXU3TC.cjs +7 -0
- package/dist/xlsx-to-univer-AQAXU3TC.cjs.map +1 -0
- package/dist/xlsx-to-univer-OPMMBWEW.js +7 -0
- package/dist/xlsx-to-univer-OPMMBWEW.js.map +1 -0
- package/package.json +41 -4
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// src/sheets/ports.ts
|
|
2
|
+
var SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.office.sheets-host");
|
|
3
|
+
var slot = () => {
|
|
4
|
+
const g = globalThis;
|
|
5
|
+
return g[SLOT] ??= {};
|
|
6
|
+
};
|
|
7
|
+
function configureSheetsHost(ports) {
|
|
8
|
+
slot().ports = ports;
|
|
9
|
+
}
|
|
10
|
+
function getSheetsHost() {
|
|
11
|
+
const ports = slot().ports;
|
|
12
|
+
if (!ports) throw new Error("@ai-matrx/office/sheets: configureSheetsHost(ports) was not called before the workbook service ran.");
|
|
13
|
+
return ports;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// src/sheets/workbook-service.ts
|
|
17
|
+
import { requireOrganizationContext } from "@ai-matrx/api";
|
|
18
|
+
import { getClaimsUser } from "@ai-matrx/auth";
|
|
19
|
+
import { tryWriteOne, writeOneRow } from "@ai-matrx/data/db";
|
|
20
|
+
var db = () => getSheetsHost().getSupabase();
|
|
21
|
+
var WORKBOOK_SOURCE_LABELS = {
|
|
22
|
+
created: "Created",
|
|
23
|
+
imported_xlsx: "Imported Excel",
|
|
24
|
+
imported_gsheet: "Imported from Google Sheets",
|
|
25
|
+
imported_csv: "Imported CSV",
|
|
26
|
+
linked_gsheet: "Imported from Google Sheets"
|
|
27
|
+
};
|
|
28
|
+
function workbookSourceLabel(source) {
|
|
29
|
+
return WORKBOOK_SOURCE_LABELS[source] ?? source.replace(/_/g, " ");
|
|
30
|
+
}
|
|
31
|
+
async function createWorkbook(args) {
|
|
32
|
+
let organizationId;
|
|
33
|
+
try {
|
|
34
|
+
organizationId = requireOrganizationContext(void 0, args.organizationId);
|
|
35
|
+
} catch (error2) {
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
error: error2 instanceof Error ? error2.message : "Select an organization before creating a workbook."
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const { data: userData, error: userErr } = await getClaimsUser(db());
|
|
42
|
+
if (userErr || !userData?.user) {
|
|
43
|
+
return {
|
|
44
|
+
success: false,
|
|
45
|
+
error: userErr?.message ?? "not authenticated"
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const { data, error } = await db().schema("workbench").from("udt_workbooks").insert({
|
|
49
|
+
workbook_name: args.name,
|
|
50
|
+
description: args.description ?? null,
|
|
51
|
+
source: args.source ?? "created",
|
|
52
|
+
organization_id: organizationId,
|
|
53
|
+
project_id: args.projectId ?? null,
|
|
54
|
+
task_id: args.taskId ?? null,
|
|
55
|
+
original_file_id: args.originalFileId ?? null,
|
|
56
|
+
// CANONICAL columns (workbench_udt_canonical_step1). `visibility` is the
|
|
57
|
+
// source of truth; legacy `is_public` is derived from it by the
|
|
58
|
+
// workbench._bridge_legacy_owner trigger. A new workbook defaults to
|
|
59
|
+
// `internal` — org work product, not an individual's private thing
|
|
60
|
+
// (db-rules §6) — unless the caller explicitly asked for public.
|
|
61
|
+
created_by: userData.user.id,
|
|
62
|
+
visibility: args.isPublic ? "public" : "internal"
|
|
63
|
+
}).select("*").single();
|
|
64
|
+
if (error) return { success: false, error: error.message };
|
|
65
|
+
return { success: true, data };
|
|
66
|
+
}
|
|
67
|
+
async function listAccessibleWorkbooks() {
|
|
68
|
+
const { data, error } = await db().schema("workbench").from("udt_workbooks").select("*").is("deleted_at", null).order("updated_at", { ascending: false });
|
|
69
|
+
if (error) return { success: false, error: error.message };
|
|
70
|
+
return { success: true, data: data ?? [] };
|
|
71
|
+
}
|
|
72
|
+
async function getWorkbook(workbookId) {
|
|
73
|
+
const { data, error } = await db().schema("workbench").from("udt_workbooks").select("*").eq("id", workbookId).is("deleted_at", null).single();
|
|
74
|
+
if (error) return { success: false, error: error.message };
|
|
75
|
+
return { success: true, data };
|
|
76
|
+
}
|
|
77
|
+
async function renameWorkbook(workbookId, name) {
|
|
78
|
+
const { data, error } = await writeOneRow(
|
|
79
|
+
db().schema("workbench").from("udt_workbooks").update({ workbook_name: name, updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", workbookId).select("*"),
|
|
80
|
+
{ action: "update", noun: "workbook" }
|
|
81
|
+
);
|
|
82
|
+
if (error) return { success: false, error: error.message };
|
|
83
|
+
return { success: true, data };
|
|
84
|
+
}
|
|
85
|
+
async function moveWorkbook(workbookId, projectId) {
|
|
86
|
+
const { data, error } = await writeOneRow(
|
|
87
|
+
db().schema("workbench").from("udt_workbooks").update({ project_id: projectId, updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", workbookId).select("*"),
|
|
88
|
+
{ action: "update", noun: "workbook" }
|
|
89
|
+
);
|
|
90
|
+
if (error) return { success: false, error: error.message };
|
|
91
|
+
return { success: true, data };
|
|
92
|
+
}
|
|
93
|
+
async function updateWorkbookDescription(workbookId, description) {
|
|
94
|
+
const { data, error } = await writeOneRow(
|
|
95
|
+
db().schema("workbench").from("udt_workbooks").update({
|
|
96
|
+
description: description && description.length > 0 ? description : null,
|
|
97
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
98
|
+
}).eq("id", workbookId).select("*"),
|
|
99
|
+
{ action: "update", noun: "workbook" }
|
|
100
|
+
);
|
|
101
|
+
if (error) return { success: false, error: error.message };
|
|
102
|
+
return { success: true, data };
|
|
103
|
+
}
|
|
104
|
+
async function deleteWorkbook(workbookId) {
|
|
105
|
+
const { error } = await tryWriteOne(
|
|
106
|
+
db().schema("workbench").from("udt_workbooks").update({ deleted_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", workbookId).select("id"),
|
|
107
|
+
{ action: "delete", noun: "workbook" }
|
|
108
|
+
);
|
|
109
|
+
if (error) return { success: false, error: error.message };
|
|
110
|
+
return { success: true, data: true };
|
|
111
|
+
}
|
|
112
|
+
async function discardFailedWorkbook(workbookId) {
|
|
113
|
+
const { error } = await tryWriteOne(
|
|
114
|
+
db().schema("workbench").from("udt_workbooks").update({ deleted_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", workbookId).select("id"),
|
|
115
|
+
{ action: "archive", noun: "workbook" }
|
|
116
|
+
);
|
|
117
|
+
if (error) return { success: false, error: error.message };
|
|
118
|
+
return { success: true, data: true };
|
|
119
|
+
}
|
|
120
|
+
async function restoreWorkbook(workbookId) {
|
|
121
|
+
const { error } = await tryWriteOne(
|
|
122
|
+
db().schema("workbench").from("udt_workbooks").update({ deleted_at: null }).eq("id", workbookId).select("id"),
|
|
123
|
+
{ action: "restore", noun: "workbook" }
|
|
124
|
+
);
|
|
125
|
+
if (error) return { success: false, error: error.message };
|
|
126
|
+
return { success: true, data: true };
|
|
127
|
+
}
|
|
128
|
+
async function listTrashedWorkbooks() {
|
|
129
|
+
const { data, error } = await db().schema("workbench").from("udt_workbooks").select("*").not("deleted_at", "is", null).order("deleted_at", { ascending: false });
|
|
130
|
+
if (error) return { success: false, error: error.message };
|
|
131
|
+
return { success: true, data: data ?? [] };
|
|
132
|
+
}
|
|
133
|
+
async function copyWorkbook(workbookId, name) {
|
|
134
|
+
const original = await getWorkbook(workbookId);
|
|
135
|
+
if (!original.success) return original;
|
|
136
|
+
const row = original.data;
|
|
137
|
+
if (!row.organization_id) {
|
|
138
|
+
return {
|
|
139
|
+
success: false,
|
|
140
|
+
error: "This workbook has no organization and cannot be copied."
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const created = await createWorkbook({
|
|
144
|
+
name: name ?? `Copy of ${row.workbook_name}`,
|
|
145
|
+
description: row.description ?? null,
|
|
146
|
+
organizationId: row.organization_id,
|
|
147
|
+
projectId: row.project_id ?? null
|
|
148
|
+
});
|
|
149
|
+
if (!created.success) return created;
|
|
150
|
+
const latest = await getLatestSnapshot(workbookId);
|
|
151
|
+
if (!latest.success) return latest;
|
|
152
|
+
if (latest.data) {
|
|
153
|
+
const saved = await saveSnapshot({
|
|
154
|
+
workbookId: created.data.id,
|
|
155
|
+
snapshot: latest.data.snapshot,
|
|
156
|
+
label: latest.data.label,
|
|
157
|
+
origin: "autosave"
|
|
158
|
+
});
|
|
159
|
+
if (!saved.success) return saved;
|
|
160
|
+
}
|
|
161
|
+
return created;
|
|
162
|
+
}
|
|
163
|
+
async function getLatestSnapshot(workbookId) {
|
|
164
|
+
const { data, error } = await db().schema("workbench").from("udt_workbook_snapshots").select("*").eq("workbook_id", workbookId).order("created_at", { ascending: false }).limit(1).maybeSingle();
|
|
165
|
+
if (error) return { success: false, error: error.message };
|
|
166
|
+
return { success: true, data: data ?? null };
|
|
167
|
+
}
|
|
168
|
+
async function saveSnapshot(args) {
|
|
169
|
+
const { data: userData } = await getClaimsUser(db());
|
|
170
|
+
const { data: workbook, error: workbookError } = await db().schema("workbench").from("udt_workbooks").select("organization_id").eq("id", args.workbookId).single();
|
|
171
|
+
if (workbookError) return { success: false, error: workbookError.message };
|
|
172
|
+
const { data, error } = await db().schema("workbench").from("udt_workbook_snapshots").insert({
|
|
173
|
+
organization_id: workbook.organization_id,
|
|
174
|
+
workbook_id: args.workbookId,
|
|
175
|
+
snapshot: args.snapshot,
|
|
176
|
+
label: args.label ?? null,
|
|
177
|
+
origin: args.origin ?? "autosave",
|
|
178
|
+
created_by: userData?.user?.id ?? null
|
|
179
|
+
}).select("*").single();
|
|
180
|
+
if (error) return { success: false, error: error.message };
|
|
181
|
+
await db().schema("workbench").from("udt_workbooks").update({ updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", args.workbookId);
|
|
182
|
+
return { success: true, data };
|
|
183
|
+
}
|
|
184
|
+
async function listSnapshots(workbookId, limit = 50) {
|
|
185
|
+
const { data, error } = await db().schema("workbench").from("udt_workbook_snapshots").select("id, workbook_id, label, origin, created_by, created_at").eq("workbook_id", workbookId).order("created_at", { ascending: false }).limit(limit);
|
|
186
|
+
if (error) return { success: false, error: error.message };
|
|
187
|
+
return { success: true, data: data ?? [] };
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export {
|
|
191
|
+
configureSheetsHost,
|
|
192
|
+
getSheetsHost,
|
|
193
|
+
workbookSourceLabel,
|
|
194
|
+
createWorkbook,
|
|
195
|
+
listAccessibleWorkbooks,
|
|
196
|
+
getWorkbook,
|
|
197
|
+
renameWorkbook,
|
|
198
|
+
moveWorkbook,
|
|
199
|
+
updateWorkbookDescription,
|
|
200
|
+
deleteWorkbook,
|
|
201
|
+
discardFailedWorkbook,
|
|
202
|
+
restoreWorkbook,
|
|
203
|
+
listTrashedWorkbooks,
|
|
204
|
+
copyWorkbook,
|
|
205
|
+
getLatestSnapshot,
|
|
206
|
+
saveSnapshot,
|
|
207
|
+
listSnapshots
|
|
208
|
+
};
|
|
209
|
+
//# sourceMappingURL=chunk-WKBWRG7N.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sheets/ports.ts","../src/sheets/workbook-service.ts"],"sourcesContent":["/**\n * The host ports of the Sheets model and io.\n *\n * The package owns the workbook service, the page-setup store and the import flow, but three things\n * belong to the app that mounts them: the database client (a package owns no client), the\n * organization a write acts in (the active-organization ladder is app state) and the file store that\n * keeps a lossless copy of an imported file. The host states them once at start-up with\n * `configureSheetsHost`. State sits on a `globalThis` slot so a dual-bundled copy of the package\n * still sees one host. An unconfigured port THROWS naming itself (nothing fails silently).\n */\nimport type { SupabaseClient } from \"@supabase/supabase-js\";\n\n/** A Supabase client over any schema: the package cannot import the app's generated database types. */\nexport type SheetsSupabase = SupabaseClient<any, any, any>;\n\nexport interface SheetsHostPorts {\n /** The app's database client (signed in as the person). */\n getSupabase(): SheetsSupabase;\n /** The organization a write acts in: the record's own when given, otherwise the active one. */\n ensureOrgId(organizationId: string | null): Promise<string>;\n /** Keep the original of an imported spreadsheet in the file store, in `folderPath`. */\n uploadOriginalFile(file: File, options: { folderPath: string }): Promise<{ fileId: string }>;\n}\n\nconst SLOT = Symbol.for(\"ai-matrx.office.sheets-host\");\ntype Slot = { ports?: SheetsHostPorts };\nconst slot = (): Slot => {\n const g = globalThis as Record<symbol, Slot | undefined>;\n return (g[SLOT] ??= {});\n};\n\nexport function configureSheetsHost(ports: SheetsHostPorts): void {\n slot().ports = ports;\n}\n\nexport function getSheetsHost(): SheetsHostPorts {\n const ports = slot().ports;\n if (!ports) throw new Error(\"@ai-matrx/office/sheets: configureSheetsHost(ports) was not called before the workbook service ran.\");\n return ports;\n}\n","/**\n * Workbook service — typed wrappers for `udt_workbooks` + `udt_workbook_snapshots`.\n *\n * Workbooks are the lossless-spreadsheet surface (P4): metadata in\n * `udt_workbooks`, content state in append-only `udt_workbook_snapshots`. The\n * editor (Univer or equivalent) hydrates from the LATEST snapshot and writes\n * a new snapshot per save (debounced on the client — see WorkbookEditor).\n *\n * What lives elsewhere:\n * - Sharing / permissions: features/sharing/ + `has_permission(...)` RLS\n * - Realtime: @ai-matrx/office/univer/collab useWorkbookRealtime\n * - Component: the Sheets editor\n */\nimport { requireOrganizationContext } from \"@ai-matrx/api\";\nimport { getClaimsUser } from \"@ai-matrx/auth\";\nimport { tryWriteOne, writeOneRow } from \"@ai-matrx/data/db\";\nimport type { ServiceResult } from \"@ai-matrx/records/core\";\n\nimport type { Workbook, WorkbookSnapshot, WorkbookSnapshotOrigin } from \"../core/types\";\nimport { getSheetsHost } from \"./ports\";\n\n/** The app's database client, read through the host port at call time. */\nconst db = () => getSheetsHost().getSupabase();\n\n// ─── workbooks ────────────────────────────────────────────────────────────────\n\nconst WORKBOOK_SOURCE_LABELS: Record<string, string> = {\n created: \"Created\",\n imported_xlsx: \"Imported Excel\",\n imported_gsheet: \"Imported from Google Sheets\",\n imported_csv: \"Imported CSV\",\n linked_gsheet: \"Imported from Google Sheets\",\n};\n\n/** Honest, human label for `udt_workbooks.source`. */\nexport function workbookSourceLabel(source: string): string {\n return WORKBOOK_SOURCE_LABELS[source] ?? source.replace(/_/g, \" \");\n}\n\nexport type CreateWorkbookArgs = {\n name: string;\n description?: string | null;\n /** Origin label for the workbook itself, mirrors `udt_workbooks.source`. */\n source?:\n | \"created\"\n | \"imported_xlsx\"\n | \"imported_gsheet\"\n | \"imported_csv\"\n | \"linked_gsheet\";\n organizationId: string;\n projectId?: string | null;\n taskId?: string | null;\n isPublic?: boolean;\n /**\n * cld_files.id of the source upload (XLSX / CSV blob). Set on the import\n * flow so the lossless original is recoverable; FK is ON DELETE SET NULL,\n * so deleting the file just nulls the link — the workbook survives.\n */\n originalFileId?: string | null;\n};\n\nexport async function createWorkbook(\n args: CreateWorkbookArgs,\n): Promise<ServiceResult<Workbook>> {\n let organizationId: string;\n try {\n organizationId = requireOrganizationContext(undefined, args.organizationId);\n } catch (error) {\n return {\n success: false,\n error:\n error instanceof Error\n ? error.message\n : \"Select an organization before creating a workbook.\",\n };\n }\n\n const { data: userData, error: userErr } = await getClaimsUser(db());\n if (userErr || !userData?.user) {\n return {\n success: false,\n error: userErr?.message ?? \"not authenticated\",\n };\n }\n\n const { data, error } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .insert({\n workbook_name: args.name,\n description: args.description ?? null,\n source: args.source ?? \"created\",\n organization_id: organizationId,\n project_id: args.projectId ?? null,\n task_id: args.taskId ?? null,\n original_file_id: args.originalFileId ?? null,\n // CANONICAL columns (workbench_udt_canonical_step1). `visibility` is the\n // source of truth; legacy `is_public` is derived from it by the\n // workbench._bridge_legacy_owner trigger. A new workbook defaults to\n // `internal` — org work product, not an individual's private thing\n // (db-rules §6) — unless the caller explicitly asked for public.\n created_by: userData.user.id,\n visibility: args.isPublic ? \"public\" : \"internal\",\n })\n .select(\"*\")\n .single();\n if (error) return { success: false, error: error.message };\n return { success: true, data: data as Workbook };\n}\n\nexport async function listAccessibleWorkbooks(): Promise<\n ServiceResult<Workbook[]>\n> {\n // RLS handles owner / published-to-the-web / shared access.\n const { data, error } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .select(\"*\")\n .is(\"deleted_at\", null)\n .order(\"updated_at\", { ascending: false });\n if (error) return { success: false, error: error.message };\n return { success: true, data: (data ?? []) as Workbook[] };\n}\n\nexport async function getWorkbook(\n workbookId: string,\n): Promise<ServiceResult<Workbook>> {\n const { data, error } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .select(\"*\")\n .eq(\"id\", workbookId)\n .is(\"deleted_at\", null)\n .single();\n if (error) return { success: false, error: error.message };\n return { success: true, data: data as Workbook };\n}\n\nexport async function renameWorkbook(\n workbookId: string,\n name: string,\n): Promise<ServiceResult<Workbook>> {\n const { data, error } = await writeOneRow(\n db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .update({ workbook_name: name, updated_at: new Date().toISOString() })\n .eq(\"id\", workbookId)\n .select(\"*\"),\n { action: \"update\", noun: \"workbook\" },\n );\n if (error) return { success: false, error: error.message };\n return { success: true, data: data as Workbook };\n}\n\n/**\n * Move the workbook into a project (or out of one with `null`). Sibling of\n * `renameWorkbook`: the one named setter for `project_id`.\n */\nexport async function moveWorkbook(\n workbookId: string,\n projectId: string | null,\n): Promise<ServiceResult<Workbook>> {\n const { data, error } = await writeOneRow(\n db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .update({ project_id: projectId, updated_at: new Date().toISOString() })\n .eq(\"id\", workbookId)\n .select(\"*\"),\n { action: \"update\", noun: \"workbook\" },\n );\n if (error) return { success: false, error: error.message };\n return { success: true, data: data as Workbook };\n}\n\n/**\n * Rewrite the workbook's description. Sibling of `renameWorkbook` — the two\n * human-authored fields on `udt_workbooks` each get a named setter so callers\n * never hand-roll a `.from(\"udt_workbooks\").update(...)`. Pass `null` (or an\n * empty string) to clear it.\n *\n * Written by the import flow at creation (\"Imported from <file>\") and, since\n * the workbooks surface became agent-writable, by the `workbook_description`\n * write target on `/workbooks/[id]`.\n */\nexport async function updateWorkbookDescription(\n workbookId: string,\n description: string | null,\n): Promise<ServiceResult<Workbook>> {\n const { data, error } = await writeOneRow(\n db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .update({\n description: description && description.length > 0 ? description : null,\n updated_at: new Date().toISOString(),\n })\n .eq(\"id\", workbookId)\n .select(\"*\"),\n { action: \"update\", noun: \"workbook\" },\n );\n if (error) return { success: false, error: error.message };\n return { success: true, data: data as Workbook };\n}\n\n/**\n * Soft delete — the workbook is tombstoned, not destroyed, and its snapshots stay\n * with it. Every read path filters `deleted_at is null`. Pair with\n * restoreWorkbook for undo.\n */\nexport async function deleteWorkbook(\n workbookId: string,\n): Promise<ServiceResult<true>> {\n const { error } = await tryWriteOne(\n db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .update({ deleted_at: new Date().toISOString() })\n .eq(\"id\", workbookId)\n .select(\"id\"),\n { action: \"delete\", noun: \"workbook\" },\n );\n if (error) return { success: false, error: error.message };\n return { success: true, data: true };\n}\n\n/**\n * Archive (delete means archive: never a hard delete) — only for rolling back a workbook this very flow just created and\n * failed to populate (see the import path in app/(core)/workbooks/page.tsx).\n * Never use this for a user-initiated delete: that is deleteWorkbook, which\n * tombstones and stays recoverable.\n */\nexport async function discardFailedWorkbook(\n workbookId: string,\n): Promise<ServiceResult<true>> {\n const { error } = await tryWriteOne(\n db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .update({ deleted_at: new Date().toISOString() })\n .eq(\"id\", workbookId)\n .select(\"id\"),\n { action: \"archive\", noun: \"workbook\" },\n );\n if (error) return { success: false, error: error.message };\n return { success: true, data: true };\n}\n\nexport async function restoreWorkbook(\n workbookId: string,\n): Promise<ServiceResult<true>> {\n const { error } = await tryWriteOne(\n db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .update({ deleted_at: null })\n .eq(\"id\", workbookId)\n .select(\"id\"),\n { action: \"restore\", noun: \"workbook\" },\n );\n if (error) return { success: false, error: error.message };\n return { success: true, data: true };\n}\n\n/** Trash view: the caller's own archived workbooks (RLS decides what is readable). */\nexport async function listTrashedWorkbooks(): Promise<\n ServiceResult<Workbook[]>\n> {\n const { data, error } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .select(\"*\")\n .not(\"deleted_at\", \"is\", null)\n .order(\"deleted_at\", { ascending: false });\n if (error) return { success: false, error: error.message };\n return { success: true, data: (data ?? []) as Workbook[] };\n}\n\n/**\n * An independent copy of a workbook: its own row in the original's organization\n * and project, with the latest snapshot copied over. Editing the copy never\n * touches the original.\n */\nexport async function copyWorkbook(\n workbookId: string,\n name?: string,\n): Promise<ServiceResult<Workbook>> {\n const original = await getWorkbook(workbookId);\n if (!original.success) return original;\n const row = original.data;\n if (!row.organization_id) {\n return {\n success: false,\n error: \"This workbook has no organization and cannot be copied.\",\n };\n }\n const created = await createWorkbook({\n name: name ?? `Copy of ${row.workbook_name}`,\n description: row.description ?? null,\n organizationId: row.organization_id,\n projectId: row.project_id ?? null,\n });\n if (!created.success) return created;\n const latest = await getLatestSnapshot(workbookId);\n if (!latest.success) return latest;\n if (latest.data) {\n const saved = await saveSnapshot({\n workbookId: created.data.id,\n snapshot: latest.data.snapshot,\n label: latest.data.label,\n origin: \"autosave\",\n });\n if (!saved.success) return saved;\n }\n return created;\n}\n\n// ─── snapshots (workbook content) ────────────────────────────────────────────\n\n/**\n * Latest-snapshot fetch — what an opened workbook hydrates from. Returns\n * `data: null` (success path) when the workbook has no snapshots yet (newly\n * created, never saved). Distinguish \"no snapshot\" from \"load error\" by\n * checking `result.data === null`.\n */\nexport async function getLatestSnapshot(\n workbookId: string,\n): Promise<ServiceResult<WorkbookSnapshot | null>> {\n const { data, error } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbook_snapshots\")\n .select(\"*\")\n .eq(\"workbook_id\", workbookId)\n .order(\"created_at\", { ascending: false })\n .limit(1)\n .maybeSingle();\n if (error) return { success: false, error: error.message };\n return { success: true, data: (data ?? null) as WorkbookSnapshot | null };\n}\n\nexport type SaveSnapshotArgs = {\n workbookId: string;\n snapshot: unknown; // opaque to us — editor library decides the shape\n label?: string | null;\n origin?: WorkbookSnapshotOrigin;\n};\n\nexport async function saveSnapshot(\n args: SaveSnapshotArgs,\n): Promise<ServiceResult<WorkbookSnapshot>> {\n const { data: userData } = await getClaimsUser(db());\n // A snapshot is a component of its workbook and carries the workbook's organization.\n const { data: workbook, error: workbookError } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .select(\"organization_id\")\n .eq(\"id\", args.workbookId)\n .single();\n if (workbookError) return { success: false, error: workbookError.message };\n const { data, error } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbook_snapshots\")\n .insert({\n organization_id: workbook.organization_id,\n workbook_id: args.workbookId,\n snapshot: args.snapshot as never,\n label: args.label ?? null,\n origin: args.origin ?? \"autosave\",\n created_by: userData?.user?.id ?? null,\n })\n .select(\"*\")\n .single();\n if (error) return { success: false, error: error.message };\n\n // Touch the parent workbook's updated_at so list views can sort by recency\n // without scanning snapshots. Best-effort — failure here is harmless.\n // write-lands-exempt: best-effort recency stamp on the parent workbook; the snapshot insert above is the real write\n await db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .update({ updated_at: new Date().toISOString() })\n .eq(\"id\", args.workbookId);\n\n return { success: true, data: data as WorkbookSnapshot };\n}\n\nexport async function listSnapshots(\n workbookId: string,\n limit = 50,\n): Promise<ServiceResult<WorkbookSnapshot[]>> {\n const { data, error } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbook_snapshots\")\n // component-created-by-ok: append-only snapshot with NO updated_by column and NO parent-rewrite trigger — created_by is the author the client wrote at insert (the only person field this table has)\n .select(\"id, workbook_id, label, origin, created_by, created_at\")\n .eq(\"workbook_id\", workbookId)\n .order(\"created_at\", { ascending: false })\n .limit(limit);\n if (error) return { success: false, error: error.message };\n return { success: true, data: (data ?? []) as WorkbookSnapshot[] };\n}\n"],"mappings":"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","names":["error"]}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/sheets/ports.ts
|
|
2
|
+
var SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.office.sheets-host");
|
|
3
|
+
var slot = () => {
|
|
4
|
+
const g = globalThis;
|
|
5
|
+
return g[SLOT] ??= {};
|
|
6
|
+
};
|
|
7
|
+
function configureSheetsHost(ports) {
|
|
8
|
+
slot().ports = ports;
|
|
9
|
+
}
|
|
10
|
+
function getSheetsHost() {
|
|
11
|
+
const ports = slot().ports;
|
|
12
|
+
if (!ports) throw new Error("@ai-matrx/office/sheets: configureSheetsHost(ports) was not called before the workbook service ran.");
|
|
13
|
+
return ports;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// src/sheets/workbook-service.ts
|
|
17
|
+
var _api = require('@ai-matrx/api');
|
|
18
|
+
var _auth = require('@ai-matrx/auth');
|
|
19
|
+
var _db = require('@ai-matrx/data/db');
|
|
20
|
+
var db = () => getSheetsHost().getSupabase();
|
|
21
|
+
var WORKBOOK_SOURCE_LABELS = {
|
|
22
|
+
created: "Created",
|
|
23
|
+
imported_xlsx: "Imported Excel",
|
|
24
|
+
imported_gsheet: "Imported from Google Sheets",
|
|
25
|
+
imported_csv: "Imported CSV",
|
|
26
|
+
linked_gsheet: "Imported from Google Sheets"
|
|
27
|
+
};
|
|
28
|
+
function workbookSourceLabel(source) {
|
|
29
|
+
return _nullishCoalesce(WORKBOOK_SOURCE_LABELS[source], () => ( source.replace(/_/g, " ")));
|
|
30
|
+
}
|
|
31
|
+
async function createWorkbook(args) {
|
|
32
|
+
let organizationId;
|
|
33
|
+
try {
|
|
34
|
+
organizationId = _api.requireOrganizationContext.call(void 0, void 0, args.organizationId);
|
|
35
|
+
} catch (error2) {
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
error: error2 instanceof Error ? error2.message : "Select an organization before creating a workbook."
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const { data: userData, error: userErr } = await _auth.getClaimsUser.call(void 0, db());
|
|
42
|
+
if (userErr || !_optionalChain([userData, 'optionalAccess', _ => _.user])) {
|
|
43
|
+
return {
|
|
44
|
+
success: false,
|
|
45
|
+
error: _nullishCoalesce(_optionalChain([userErr, 'optionalAccess', _2 => _2.message]), () => ( "not authenticated"))
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const { data, error } = await db().schema("workbench").from("udt_workbooks").insert({
|
|
49
|
+
workbook_name: args.name,
|
|
50
|
+
description: _nullishCoalesce(args.description, () => ( null)),
|
|
51
|
+
source: _nullishCoalesce(args.source, () => ( "created")),
|
|
52
|
+
organization_id: organizationId,
|
|
53
|
+
project_id: _nullishCoalesce(args.projectId, () => ( null)),
|
|
54
|
+
task_id: _nullishCoalesce(args.taskId, () => ( null)),
|
|
55
|
+
original_file_id: _nullishCoalesce(args.originalFileId, () => ( null)),
|
|
56
|
+
// CANONICAL columns (workbench_udt_canonical_step1). `visibility` is the
|
|
57
|
+
// source of truth; legacy `is_public` is derived from it by the
|
|
58
|
+
// workbench._bridge_legacy_owner trigger. A new workbook defaults to
|
|
59
|
+
// `internal` — org work product, not an individual's private thing
|
|
60
|
+
// (db-rules §6) — unless the caller explicitly asked for public.
|
|
61
|
+
created_by: userData.user.id,
|
|
62
|
+
visibility: args.isPublic ? "public" : "internal"
|
|
63
|
+
}).select("*").single();
|
|
64
|
+
if (error) return { success: false, error: error.message };
|
|
65
|
+
return { success: true, data };
|
|
66
|
+
}
|
|
67
|
+
async function listAccessibleWorkbooks() {
|
|
68
|
+
const { data, error } = await db().schema("workbench").from("udt_workbooks").select("*").is("deleted_at", null).order("updated_at", { ascending: false });
|
|
69
|
+
if (error) return { success: false, error: error.message };
|
|
70
|
+
return { success: true, data: _nullishCoalesce(data, () => ( [])) };
|
|
71
|
+
}
|
|
72
|
+
async function getWorkbook(workbookId) {
|
|
73
|
+
const { data, error } = await db().schema("workbench").from("udt_workbooks").select("*").eq("id", workbookId).is("deleted_at", null).single();
|
|
74
|
+
if (error) return { success: false, error: error.message };
|
|
75
|
+
return { success: true, data };
|
|
76
|
+
}
|
|
77
|
+
async function renameWorkbook(workbookId, name) {
|
|
78
|
+
const { data, error } = await _db.writeOneRow.call(void 0,
|
|
79
|
+
db().schema("workbench").from("udt_workbooks").update({ workbook_name: name, updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", workbookId).select("*"),
|
|
80
|
+
{ action: "update", noun: "workbook" }
|
|
81
|
+
);
|
|
82
|
+
if (error) return { success: false, error: error.message };
|
|
83
|
+
return { success: true, data };
|
|
84
|
+
}
|
|
85
|
+
async function moveWorkbook(workbookId, projectId) {
|
|
86
|
+
const { data, error } = await _db.writeOneRow.call(void 0,
|
|
87
|
+
db().schema("workbench").from("udt_workbooks").update({ project_id: projectId, updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", workbookId).select("*"),
|
|
88
|
+
{ action: "update", noun: "workbook" }
|
|
89
|
+
);
|
|
90
|
+
if (error) return { success: false, error: error.message };
|
|
91
|
+
return { success: true, data };
|
|
92
|
+
}
|
|
93
|
+
async function updateWorkbookDescription(workbookId, description) {
|
|
94
|
+
const { data, error } = await _db.writeOneRow.call(void 0,
|
|
95
|
+
db().schema("workbench").from("udt_workbooks").update({
|
|
96
|
+
description: description && description.length > 0 ? description : null,
|
|
97
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
98
|
+
}).eq("id", workbookId).select("*"),
|
|
99
|
+
{ action: "update", noun: "workbook" }
|
|
100
|
+
);
|
|
101
|
+
if (error) return { success: false, error: error.message };
|
|
102
|
+
return { success: true, data };
|
|
103
|
+
}
|
|
104
|
+
async function deleteWorkbook(workbookId) {
|
|
105
|
+
const { error } = await _db.tryWriteOne.call(void 0,
|
|
106
|
+
db().schema("workbench").from("udt_workbooks").update({ deleted_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", workbookId).select("id"),
|
|
107
|
+
{ action: "delete", noun: "workbook" }
|
|
108
|
+
);
|
|
109
|
+
if (error) return { success: false, error: error.message };
|
|
110
|
+
return { success: true, data: true };
|
|
111
|
+
}
|
|
112
|
+
async function discardFailedWorkbook(workbookId) {
|
|
113
|
+
const { error } = await _db.tryWriteOne.call(void 0,
|
|
114
|
+
db().schema("workbench").from("udt_workbooks").update({ deleted_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", workbookId).select("id"),
|
|
115
|
+
{ action: "archive", noun: "workbook" }
|
|
116
|
+
);
|
|
117
|
+
if (error) return { success: false, error: error.message };
|
|
118
|
+
return { success: true, data: true };
|
|
119
|
+
}
|
|
120
|
+
async function restoreWorkbook(workbookId) {
|
|
121
|
+
const { error } = await _db.tryWriteOne.call(void 0,
|
|
122
|
+
db().schema("workbench").from("udt_workbooks").update({ deleted_at: null }).eq("id", workbookId).select("id"),
|
|
123
|
+
{ action: "restore", noun: "workbook" }
|
|
124
|
+
);
|
|
125
|
+
if (error) return { success: false, error: error.message };
|
|
126
|
+
return { success: true, data: true };
|
|
127
|
+
}
|
|
128
|
+
async function listTrashedWorkbooks() {
|
|
129
|
+
const { data, error } = await db().schema("workbench").from("udt_workbooks").select("*").not("deleted_at", "is", null).order("deleted_at", { ascending: false });
|
|
130
|
+
if (error) return { success: false, error: error.message };
|
|
131
|
+
return { success: true, data: _nullishCoalesce(data, () => ( [])) };
|
|
132
|
+
}
|
|
133
|
+
async function copyWorkbook(workbookId, name) {
|
|
134
|
+
const original = await getWorkbook(workbookId);
|
|
135
|
+
if (!original.success) return original;
|
|
136
|
+
const row = original.data;
|
|
137
|
+
if (!row.organization_id) {
|
|
138
|
+
return {
|
|
139
|
+
success: false,
|
|
140
|
+
error: "This workbook has no organization and cannot be copied."
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const created = await createWorkbook({
|
|
144
|
+
name: _nullishCoalesce(name, () => ( `Copy of ${row.workbook_name}`)),
|
|
145
|
+
description: _nullishCoalesce(row.description, () => ( null)),
|
|
146
|
+
organizationId: row.organization_id,
|
|
147
|
+
projectId: _nullishCoalesce(row.project_id, () => ( null))
|
|
148
|
+
});
|
|
149
|
+
if (!created.success) return created;
|
|
150
|
+
const latest = await getLatestSnapshot(workbookId);
|
|
151
|
+
if (!latest.success) return latest;
|
|
152
|
+
if (latest.data) {
|
|
153
|
+
const saved = await saveSnapshot({
|
|
154
|
+
workbookId: created.data.id,
|
|
155
|
+
snapshot: latest.data.snapshot,
|
|
156
|
+
label: latest.data.label,
|
|
157
|
+
origin: "autosave"
|
|
158
|
+
});
|
|
159
|
+
if (!saved.success) return saved;
|
|
160
|
+
}
|
|
161
|
+
return created;
|
|
162
|
+
}
|
|
163
|
+
async function getLatestSnapshot(workbookId) {
|
|
164
|
+
const { data, error } = await db().schema("workbench").from("udt_workbook_snapshots").select("*").eq("workbook_id", workbookId).order("created_at", { ascending: false }).limit(1).maybeSingle();
|
|
165
|
+
if (error) return { success: false, error: error.message };
|
|
166
|
+
return { success: true, data: _nullishCoalesce(data, () => ( null)) };
|
|
167
|
+
}
|
|
168
|
+
async function saveSnapshot(args) {
|
|
169
|
+
const { data: userData } = await _auth.getClaimsUser.call(void 0, db());
|
|
170
|
+
const { data: workbook, error: workbookError } = await db().schema("workbench").from("udt_workbooks").select("organization_id").eq("id", args.workbookId).single();
|
|
171
|
+
if (workbookError) return { success: false, error: workbookError.message };
|
|
172
|
+
const { data, error } = await db().schema("workbench").from("udt_workbook_snapshots").insert({
|
|
173
|
+
organization_id: workbook.organization_id,
|
|
174
|
+
workbook_id: args.workbookId,
|
|
175
|
+
snapshot: args.snapshot,
|
|
176
|
+
label: _nullishCoalesce(args.label, () => ( null)),
|
|
177
|
+
origin: _nullishCoalesce(args.origin, () => ( "autosave")),
|
|
178
|
+
created_by: _nullishCoalesce(_optionalChain([userData, 'optionalAccess', _3 => _3.user, 'optionalAccess', _4 => _4.id]), () => ( null))
|
|
179
|
+
}).select("*").single();
|
|
180
|
+
if (error) return { success: false, error: error.message };
|
|
181
|
+
await db().schema("workbench").from("udt_workbooks").update({ updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", args.workbookId);
|
|
182
|
+
return { success: true, data };
|
|
183
|
+
}
|
|
184
|
+
async function listSnapshots(workbookId, limit = 50) {
|
|
185
|
+
const { data, error } = await db().schema("workbench").from("udt_workbook_snapshots").select("id, workbook_id, label, origin, created_by, created_at").eq("workbook_id", workbookId).order("created_at", { ascending: false }).limit(limit);
|
|
186
|
+
if (error) return { success: false, error: error.message };
|
|
187
|
+
return { success: true, data: _nullishCoalesce(data, () => ( [])) };
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
exports.configureSheetsHost = configureSheetsHost; exports.getSheetsHost = getSheetsHost; exports.workbookSourceLabel = workbookSourceLabel; exports.createWorkbook = createWorkbook; exports.listAccessibleWorkbooks = listAccessibleWorkbooks; exports.getWorkbook = getWorkbook; exports.renameWorkbook = renameWorkbook; exports.moveWorkbook = moveWorkbook; exports.updateWorkbookDescription = updateWorkbookDescription; exports.deleteWorkbook = deleteWorkbook; exports.discardFailedWorkbook = discardFailedWorkbook; exports.restoreWorkbook = restoreWorkbook; exports.listTrashedWorkbooks = listTrashedWorkbooks; exports.copyWorkbook = copyWorkbook; exports.getLatestSnapshot = getLatestSnapshot; exports.saveSnapshot = saveSnapshot; exports.listSnapshots = listSnapshots;
|
|
209
|
+
//# sourceMappingURL=chunk-ZDZCCOUB.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/aidream/aidream/apps/shared/office/dist/chunk-ZDZCCOUB.cjs","../src/sheets/ports.ts","../src/sheets/workbook-service.ts"],"names":["error"],"mappings":"AAAA;ACwBA,IAAM,KAAA,kBAAO,MAAA,CAAO,GAAA,CAAI,6BAA6B,CAAA;AAErD,IAAM,KAAA,EAAO,CAAA,EAAA,GAAY;AACvB,EAAA,MAAM,EAAA,EAAI,UAAA;AACV,EAAA,OAAQ,CAAA,CAAE,IAAI,EAAA,IAAM,CAAC,CAAA;AACvB,CAAA;AAEO,SAAS,mBAAA,CAAoB,KAAA,EAA8B;AAChE,EAAA,IAAA,CAAK,CAAA,CAAE,MAAA,EAAQ,KAAA;AACjB;AAEO,SAAS,aAAA,CAAA,EAAiC;AAC/C,EAAA,MAAM,MAAA,EAAQ,IAAA,CAAK,CAAA,CAAE,KAAA;AACrB,EAAA,GAAA,CAAI,CAAC,KAAA,EAAO,MAAM,IAAI,KAAA,CAAM,qGAAqG,CAAA;AACjI,EAAA,OAAO,KAAA;AACT;ADzBA;AACA;AEFA,oCAA2C;AAC3C,sCAA8B;AAC9B,uCAAyC;AAOzC,IAAM,GAAA,EAAK,CAAA,EAAA,GAAM,aAAA,CAAc,CAAA,CAAE,WAAA,CAAY,CAAA;AAI7C,IAAM,uBAAA,EAAiD;AAAA,EACrD,OAAA,EAAS,SAAA;AAAA,EACT,aAAA,EAAe,gBAAA;AAAA,EACf,eAAA,EAAiB,6BAAA;AAAA,EACjB,YAAA,EAAc,cAAA;AAAA,EACd,aAAA,EAAe;AACjB,CAAA;AAGO,SAAS,mBAAA,CAAoB,MAAA,EAAwB;AAC1D,EAAA,wBAAO,sBAAA,CAAuB,MAAM,CAAA,UAAK,MAAA,CAAO,OAAA,CAAQ,IAAA,EAAM,GAAG,GAAA;AACnE;AAwBA,MAAA,SAAsB,cAAA,CACpB,IAAA,EACkC;AAClC,EAAA,IAAI,cAAA;AACJ,EAAA,IAAI;AACF,IAAA,eAAA,EAAiB,6CAAA,KAA2B,CAAA,EAAW,IAAA,CAAK,cAAc,CAAA;AAAA,EAC5E,EAAA,MAAA,CAASA,MAAAA,EAAO;AACd,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EACEA,OAAAA,WAAiB,MAAA,EACbA,MAAAA,CAAM,QAAA,EACN;AAAA,IACR,CAAA;AAAA,EACF;AAEA,EAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,QAAQ,EAAA,EAAI,MAAM,iCAAA,EAAc,CAAG,CAAC,CAAA;AACnE,EAAA,GAAA,CAAI,QAAA,GAAW,iBAAC,QAAA,2BAAU,MAAA,EAAM;AAC9B,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,mCAAO,OAAA,6BAAS,SAAA,UAAW;AAAA,IAC7B,CAAA;AAAA,EACF;AAEA,EAAA,MAAM,EAAE,IAAA,EAAM,MAAM,EAAA,EAAI,MAAM,EAAA,CAAG,CAAA,CAC9B,MAAA,CAAO,WAAW,CAAA,CAClB,IAAA,CAAK,eAAe,CAAA,CACpB,MAAA,CAAO;AAAA,IACN,aAAA,EAAe,IAAA,CAAK,IAAA;AAAA,IACpB,WAAA,mBAAa,IAAA,CAAK,WAAA,UAAe,MAAA;AAAA,IACjC,MAAA,mBAAQ,IAAA,CAAK,MAAA,UAAU,WAAA;AAAA,IACvB,eAAA,EAAiB,cAAA;AAAA,IACjB,UAAA,mBAAY,IAAA,CAAK,SAAA,UAAa,MAAA;AAAA,IAC9B,OAAA,mBAAS,IAAA,CAAK,MAAA,UAAU,MAAA;AAAA,IACxB,gBAAA,mBAAkB,IAAA,CAAK,cAAA,UAAkB,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMzC,UAAA,EAAY,QAAA,CAAS,IAAA,CAAK,EAAA;AAAA,IAC1B,UAAA,EAAY,IAAA,CAAK,SAAA,EAAW,SAAA,EAAW;AAAA,EACzC,CAAC,CAAA,CACA,MAAA,CAAO,GAAG,CAAA,CACV,MAAA,CAAO,CAAA;AACV,EAAA,GAAA,CAAI,KAAA,EAAO,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,QAAQ,CAAA;AACzD,EAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,KAAuB,CAAA;AACjD;AAEA,MAAA,SAAsB,uBAAA,CAAA,EAEpB;AAEA,EAAA,MAAM,EAAE,IAAA,EAAM,MAAM,EAAA,EAAI,MAAM,EAAA,CAAG,CAAA,CAC9B,MAAA,CAAO,WAAW,CAAA,CAClB,IAAA,CAAK,eAAe,CAAA,CACpB,MAAA,CAAO,GAAG,CAAA,CACV,EAAA,CAAG,YAAA,EAAc,IAAI,CAAA,CACrB,KAAA,CAAM,YAAA,EAAc,EAAE,SAAA,EAAW,MAAM,CAAC,CAAA;AAC3C,EAAA,GAAA,CAAI,KAAA,EAAO,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,QAAQ,CAAA;AACzD,EAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,IAAA,mBAAO,IAAA,UAAQ,CAAC,IAAiB,CAAA;AAC3D;AAEA,MAAA,SAAsB,WAAA,CACpB,UAAA,EACkC;AAClC,EAAA,MAAM,EAAE,IAAA,EAAM,MAAM,EAAA,EAAI,MAAM,EAAA,CAAG,CAAA,CAC9B,MAAA,CAAO,WAAW,CAAA,CAClB,IAAA,CAAK,eAAe,CAAA,CACpB,MAAA,CAAO,GAAG,CAAA,CACV,EAAA,CAAG,IAAA,EAAM,UAAU,CAAA,CACnB,EAAA,CAAG,YAAA,EAAc,IAAI,CAAA,CACrB,MAAA,CAAO,CAAA;AACV,EAAA,GAAA,CAAI,KAAA,EAAO,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,QAAQ,CAAA;AACzD,EAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,KAAuB,CAAA;AACjD;AAEA,MAAA,SAAsB,cAAA,CACpB,UAAA,EACA,IAAA,EACkC;AAClC,EAAA,MAAM,EAAE,IAAA,EAAM,MAAM,EAAA,EAAI,MAAM,6BAAA;AAAA,IAC5B,EAAA,CAAG,CAAA,CACA,MAAA,CAAO,WAAW,CAAA,CAClB,IAAA,CAAK,eAAe,CAAA,CACpB,MAAA,CAAO,EAAE,aAAA,EAAe,IAAA,EAAM,UAAA,EAAA,iBAAY,IAAI,IAAA,CAAK,CAAA,CAAA,CAAE,WAAA,CAAY,EAAE,CAAC,CAAA,CACpE,EAAA,CAAG,IAAA,EAAM,UAAU,CAAA,CACnB,MAAA,CAAO,GAAG,CAAA;AAAA,IACb,EAAE,MAAA,EAAQ,QAAA,EAAU,IAAA,EAAM,WAAW;AAAA,EACvC,CAAA;AACA,EAAA,GAAA,CAAI,KAAA,EAAO,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,QAAQ,CAAA;AACzD,EAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,KAAuB,CAAA;AACjD;AAMA,MAAA,SAAsB,YAAA,CACpB,UAAA,EACA,SAAA,EACkC;AAClC,EAAA,MAAM,EAAE,IAAA,EAAM,MAAM,EAAA,EAAI,MAAM,6BAAA;AAAA,IAC5B,EAAA,CAAG,CAAA,CACA,MAAA,CAAO,WAAW,CAAA,CAClB,IAAA,CAAK,eAAe,CAAA,CACpB,MAAA,CAAO,EAAE,UAAA,EAAY,SAAA,EAAW,UAAA,EAAA,iBAAY,IAAI,IAAA,CAAK,CAAA,CAAA,CAAE,WAAA,CAAY,EAAE,CAAC,CAAA,CACtE,EAAA,CAAG,IAAA,EAAM,UAAU,CAAA,CACnB,MAAA,CAAO,GAAG,CAAA;AAAA,IACb,EAAE,MAAA,EAAQ,QAAA,EAAU,IAAA,EAAM,WAAW;AAAA,EACvC,CAAA;AACA,EAAA,GAAA,CAAI,KAAA,EAAO,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,QAAQ,CAAA;AACzD,EAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,KAAuB,CAAA;AACjD;AAYA,MAAA,SAAsB,yBAAA,CACpB,UAAA,EACA,WAAA,EACkC;AAClC,EAAA,MAAM,EAAE,IAAA,EAAM,MAAM,EAAA,EAAI,MAAM,6BAAA;AAAA,IAC5B,EAAA,CAAG,CAAA,CACA,MAAA,CAAO,WAAW,CAAA,CAClB,IAAA,CAAK,eAAe,CAAA,CACpB,MAAA,CAAO;AAAA,MACN,WAAA,EAAa,YAAA,GAAe,WAAA,CAAY,OAAA,EAAS,EAAA,EAAI,YAAA,EAAc,IAAA;AAAA,MACnE,UAAA,EAAA,iBAAY,IAAI,IAAA,CAAK,CAAA,CAAA,CAAE,WAAA,CAAY;AAAA,IACrC,CAAC,CAAA,CACA,EAAA,CAAG,IAAA,EAAM,UAAU,CAAA,CACnB,MAAA,CAAO,GAAG,CAAA;AAAA,IACb,EAAE,MAAA,EAAQ,QAAA,EAAU,IAAA,EAAM,WAAW;AAAA,EACvC,CAAA;AACA,EAAA,GAAA,CAAI,KAAA,EAAO,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,QAAQ,CAAA;AACzD,EAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,KAAuB,CAAA;AACjD;AAOA,MAAA,SAAsB,cAAA,CACpB,UAAA,EAC8B;AAC9B,EAAA,MAAM,EAAE,MAAM,EAAA,EAAI,MAAM,6BAAA;AAAA,IACtB,EAAA,CAAG,CAAA,CACA,MAAA,CAAO,WAAW,CAAA,CAClB,IAAA,CAAK,eAAe,CAAA,CACpB,MAAA,CAAO,EAAE,UAAA,EAAA,iBAAY,IAAI,IAAA,CAAK,CAAA,CAAA,CAAE,WAAA,CAAY,EAAE,CAAC,CAAA,CAC/C,EAAA,CAAG,IAAA,EAAM,UAAU,CAAA,CACnB,MAAA,CAAO,IAAI,CAAA;AAAA,IACd,EAAE,MAAA,EAAQ,QAAA,EAAU,IAAA,EAAM,WAAW;AAAA,EACvC,CAAA;AACA,EAAA,GAAA,CAAI,KAAA,EAAO,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,QAAQ,CAAA;AACzD,EAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,IAAA,EAAM,KAAK,CAAA;AACrC;AAQA,MAAA,SAAsB,qBAAA,CACpB,UAAA,EAC8B;AAC9B,EAAA,MAAM,EAAE,MAAM,EAAA,EAAI,MAAM,6BAAA;AAAA,IACtB,EAAA,CAAG,CAAA,CACA,MAAA,CAAO,WAAW,CAAA,CAClB,IAAA,CAAK,eAAe,CAAA,CACpB,MAAA,CAAO,EAAE,UAAA,EAAA,iBAAY,IAAI,IAAA,CAAK,CAAA,CAAA,CAAE,WAAA,CAAY,EAAE,CAAC,CAAA,CAC/C,EAAA,CAAG,IAAA,EAAM,UAAU,CAAA,CACnB,MAAA,CAAO,IAAI,CAAA;AAAA,IACd,EAAE,MAAA,EAAQ,SAAA,EAAW,IAAA,EAAM,WAAW;AAAA,EACxC,CAAA;AACA,EAAA,GAAA,CAAI,KAAA,EAAO,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,QAAQ,CAAA;AACzD,EAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,IAAA,EAAM,KAAK,CAAA;AACrC;AAEA,MAAA,SAAsB,eAAA,CACpB,UAAA,EAC8B;AAC9B,EAAA,MAAM,EAAE,MAAM,EAAA,EAAI,MAAM,6BAAA;AAAA,IACtB,EAAA,CAAG,CAAA,CACA,MAAA,CAAO,WAAW,CAAA,CAClB,IAAA,CAAK,eAAe,CAAA,CACpB,MAAA,CAAO,EAAE,UAAA,EAAY,KAAK,CAAC,CAAA,CAC3B,EAAA,CAAG,IAAA,EAAM,UAAU,CAAA,CACnB,MAAA,CAAO,IAAI,CAAA;AAAA,IACd,EAAE,MAAA,EAAQ,SAAA,EAAW,IAAA,EAAM,WAAW;AAAA,EACxC,CAAA;AACA,EAAA,GAAA,CAAI,KAAA,EAAO,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,QAAQ,CAAA;AACzD,EAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,IAAA,EAAM,KAAK,CAAA;AACrC;AAGA,MAAA,SAAsB,oBAAA,CAAA,EAEpB;AACA,EAAA,MAAM,EAAE,IAAA,EAAM,MAAM,EAAA,EAAI,MAAM,EAAA,CAAG,CAAA,CAC9B,MAAA,CAAO,WAAW,CAAA,CAClB,IAAA,CAAK,eAAe,CAAA,CACpB,MAAA,CAAO,GAAG,CAAA,CACV,GAAA,CAAI,YAAA,EAAc,IAAA,EAAM,IAAI,CAAA,CAC5B,KAAA,CAAM,YAAA,EAAc,EAAE,SAAA,EAAW,MAAM,CAAC,CAAA;AAC3C,EAAA,GAAA,CAAI,KAAA,EAAO,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,QAAQ,CAAA;AACzD,EAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,IAAA,mBAAO,IAAA,UAAQ,CAAC,IAAiB,CAAA;AAC3D;AAOA,MAAA,SAAsB,YAAA,CACpB,UAAA,EACA,IAAA,EACkC;AAClC,EAAA,MAAM,SAAA,EAAW,MAAM,WAAA,CAAY,UAAU,CAAA;AAC7C,EAAA,GAAA,CAAI,CAAC,QAAA,CAAS,OAAA,EAAS,OAAO,QAAA;AAC9B,EAAA,MAAM,IAAA,EAAM,QAAA,CAAS,IAAA;AACrB,EAAA,GAAA,CAAI,CAAC,GAAA,CAAI,eAAA,EAAiB;AACxB,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO;AAAA,IACT,CAAA;AAAA,EACF;AACA,EAAA,MAAM,QAAA,EAAU,MAAM,cAAA,CAAe;AAAA,IACnC,IAAA,mBAAM,IAAA,UAAQ,CAAA,QAAA,EAAW,GAAA,CAAI,aAAa,CAAA,GAAA;AACV,IAAA;AACZ,IAAA;AACS,IAAA;AAC9B,EAAA;AAC4B,EAAA;AACU,EAAA;AACX,EAAA;AACX,EAAA;AACkB,IAAA;AACN,MAAA;AACH,MAAA;AACH,MAAA;AACX,MAAA;AACT,IAAA;AAC0B,IAAA;AAC7B,EAAA;AACO,EAAA;AACT;AAYmD;AAEvC,EAAA;AAOiC,EAAA;AAC6B,EAAA;AAC1E;AAW4C;AACT,EAAA;AAEY,EAAA;AAMD,EAAA;AAElC,EAAA;AAGoB,IAAA;AACR,IAAA;AACH,IAAA;AACM,IAAA;AACE,IAAA;AACW,IAAA;AAG5B,EAAA;AACiC,EAAA;AAOnC,EAAA;AAI+C,EAAA;AACzD;AAIE;AAGU,EAAA;AAOiC,EAAA;AACsB,EAAA;AACnE;AFrN+C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/aidream/aidream/apps/shared/office/dist/chunk-ZDZCCOUB.cjs","sourcesContent":[null,"/**\n * The host ports of the Sheets model and io.\n *\n * The package owns the workbook service, the page-setup store and the import flow, but three things\n * belong to the app that mounts them: the database client (a package owns no client), the\n * organization a write acts in (the active-organization ladder is app state) and the file store that\n * keeps a lossless copy of an imported file. The host states them once at start-up with\n * `configureSheetsHost`. State sits on a `globalThis` slot so a dual-bundled copy of the package\n * still sees one host. An unconfigured port THROWS naming itself (nothing fails silently).\n */\nimport type { SupabaseClient } from \"@supabase/supabase-js\";\n\n/** A Supabase client over any schema: the package cannot import the app's generated database types. */\nexport type SheetsSupabase = SupabaseClient<any, any, any>;\n\nexport interface SheetsHostPorts {\n /** The app's database client (signed in as the person). */\n getSupabase(): SheetsSupabase;\n /** The organization a write acts in: the record's own when given, otherwise the active one. */\n ensureOrgId(organizationId: string | null): Promise<string>;\n /** Keep the original of an imported spreadsheet in the file store, in `folderPath`. */\n uploadOriginalFile(file: File, options: { folderPath: string }): Promise<{ fileId: string }>;\n}\n\nconst SLOT = Symbol.for(\"ai-matrx.office.sheets-host\");\ntype Slot = { ports?: SheetsHostPorts };\nconst slot = (): Slot => {\n const g = globalThis as Record<symbol, Slot | undefined>;\n return (g[SLOT] ??= {});\n};\n\nexport function configureSheetsHost(ports: SheetsHostPorts): void {\n slot().ports = ports;\n}\n\nexport function getSheetsHost(): SheetsHostPorts {\n const ports = slot().ports;\n if (!ports) throw new Error(\"@ai-matrx/office/sheets: configureSheetsHost(ports) was not called before the workbook service ran.\");\n return ports;\n}\n","/**\n * Workbook service — typed wrappers for `udt_workbooks` + `udt_workbook_snapshots`.\n *\n * Workbooks are the lossless-spreadsheet surface (P4): metadata in\n * `udt_workbooks`, content state in append-only `udt_workbook_snapshots`. The\n * editor (Univer or equivalent) hydrates from the LATEST snapshot and writes\n * a new snapshot per save (debounced on the client — see WorkbookEditor).\n *\n * What lives elsewhere:\n * - Sharing / permissions: features/sharing/ + `has_permission(...)` RLS\n * - Realtime: @ai-matrx/office/univer/collab useWorkbookRealtime\n * - Component: the Sheets editor\n */\nimport { requireOrganizationContext } from \"@ai-matrx/api\";\nimport { getClaimsUser } from \"@ai-matrx/auth\";\nimport { tryWriteOne, writeOneRow } from \"@ai-matrx/data/db\";\nimport type { ServiceResult } from \"@ai-matrx/records/core\";\n\nimport type { Workbook, WorkbookSnapshot, WorkbookSnapshotOrigin } from \"../core/types\";\nimport { getSheetsHost } from \"./ports\";\n\n/** The app's database client, read through the host port at call time. */\nconst db = () => getSheetsHost().getSupabase();\n\n// ─── workbooks ────────────────────────────────────────────────────────────────\n\nconst WORKBOOK_SOURCE_LABELS: Record<string, string> = {\n created: \"Created\",\n imported_xlsx: \"Imported Excel\",\n imported_gsheet: \"Imported from Google Sheets\",\n imported_csv: \"Imported CSV\",\n linked_gsheet: \"Imported from Google Sheets\",\n};\n\n/** Honest, human label for `udt_workbooks.source`. */\nexport function workbookSourceLabel(source: string): string {\n return WORKBOOK_SOURCE_LABELS[source] ?? source.replace(/_/g, \" \");\n}\n\nexport type CreateWorkbookArgs = {\n name: string;\n description?: string | null;\n /** Origin label for the workbook itself, mirrors `udt_workbooks.source`. */\n source?:\n | \"created\"\n | \"imported_xlsx\"\n | \"imported_gsheet\"\n | \"imported_csv\"\n | \"linked_gsheet\";\n organizationId: string;\n projectId?: string | null;\n taskId?: string | null;\n isPublic?: boolean;\n /**\n * cld_files.id of the source upload (XLSX / CSV blob). Set on the import\n * flow so the lossless original is recoverable; FK is ON DELETE SET NULL,\n * so deleting the file just nulls the link — the workbook survives.\n */\n originalFileId?: string | null;\n};\n\nexport async function createWorkbook(\n args: CreateWorkbookArgs,\n): Promise<ServiceResult<Workbook>> {\n let organizationId: string;\n try {\n organizationId = requireOrganizationContext(undefined, args.organizationId);\n } catch (error) {\n return {\n success: false,\n error:\n error instanceof Error\n ? error.message\n : \"Select an organization before creating a workbook.\",\n };\n }\n\n const { data: userData, error: userErr } = await getClaimsUser(db());\n if (userErr || !userData?.user) {\n return {\n success: false,\n error: userErr?.message ?? \"not authenticated\",\n };\n }\n\n const { data, error } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .insert({\n workbook_name: args.name,\n description: args.description ?? null,\n source: args.source ?? \"created\",\n organization_id: organizationId,\n project_id: args.projectId ?? null,\n task_id: args.taskId ?? null,\n original_file_id: args.originalFileId ?? null,\n // CANONICAL columns (workbench_udt_canonical_step1). `visibility` is the\n // source of truth; legacy `is_public` is derived from it by the\n // workbench._bridge_legacy_owner trigger. A new workbook defaults to\n // `internal` — org work product, not an individual's private thing\n // (db-rules §6) — unless the caller explicitly asked for public.\n created_by: userData.user.id,\n visibility: args.isPublic ? \"public\" : \"internal\",\n })\n .select(\"*\")\n .single();\n if (error) return { success: false, error: error.message };\n return { success: true, data: data as Workbook };\n}\n\nexport async function listAccessibleWorkbooks(): Promise<\n ServiceResult<Workbook[]>\n> {\n // RLS handles owner / published-to-the-web / shared access.\n const { data, error } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .select(\"*\")\n .is(\"deleted_at\", null)\n .order(\"updated_at\", { ascending: false });\n if (error) return { success: false, error: error.message };\n return { success: true, data: (data ?? []) as Workbook[] };\n}\n\nexport async function getWorkbook(\n workbookId: string,\n): Promise<ServiceResult<Workbook>> {\n const { data, error } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .select(\"*\")\n .eq(\"id\", workbookId)\n .is(\"deleted_at\", null)\n .single();\n if (error) return { success: false, error: error.message };\n return { success: true, data: data as Workbook };\n}\n\nexport async function renameWorkbook(\n workbookId: string,\n name: string,\n): Promise<ServiceResult<Workbook>> {\n const { data, error } = await writeOneRow(\n db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .update({ workbook_name: name, updated_at: new Date().toISOString() })\n .eq(\"id\", workbookId)\n .select(\"*\"),\n { action: \"update\", noun: \"workbook\" },\n );\n if (error) return { success: false, error: error.message };\n return { success: true, data: data as Workbook };\n}\n\n/**\n * Move the workbook into a project (or out of one with `null`). Sibling of\n * `renameWorkbook`: the one named setter for `project_id`.\n */\nexport async function moveWorkbook(\n workbookId: string,\n projectId: string | null,\n): Promise<ServiceResult<Workbook>> {\n const { data, error } = await writeOneRow(\n db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .update({ project_id: projectId, updated_at: new Date().toISOString() })\n .eq(\"id\", workbookId)\n .select(\"*\"),\n { action: \"update\", noun: \"workbook\" },\n );\n if (error) return { success: false, error: error.message };\n return { success: true, data: data as Workbook };\n}\n\n/**\n * Rewrite the workbook's description. Sibling of `renameWorkbook` — the two\n * human-authored fields on `udt_workbooks` each get a named setter so callers\n * never hand-roll a `.from(\"udt_workbooks\").update(...)`. Pass `null` (or an\n * empty string) to clear it.\n *\n * Written by the import flow at creation (\"Imported from <file>\") and, since\n * the workbooks surface became agent-writable, by the `workbook_description`\n * write target on `/workbooks/[id]`.\n */\nexport async function updateWorkbookDescription(\n workbookId: string,\n description: string | null,\n): Promise<ServiceResult<Workbook>> {\n const { data, error } = await writeOneRow(\n db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .update({\n description: description && description.length > 0 ? description : null,\n updated_at: new Date().toISOString(),\n })\n .eq(\"id\", workbookId)\n .select(\"*\"),\n { action: \"update\", noun: \"workbook\" },\n );\n if (error) return { success: false, error: error.message };\n return { success: true, data: data as Workbook };\n}\n\n/**\n * Soft delete — the workbook is tombstoned, not destroyed, and its snapshots stay\n * with it. Every read path filters `deleted_at is null`. Pair with\n * restoreWorkbook for undo.\n */\nexport async function deleteWorkbook(\n workbookId: string,\n): Promise<ServiceResult<true>> {\n const { error } = await tryWriteOne(\n db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .update({ deleted_at: new Date().toISOString() })\n .eq(\"id\", workbookId)\n .select(\"id\"),\n { action: \"delete\", noun: \"workbook\" },\n );\n if (error) return { success: false, error: error.message };\n return { success: true, data: true };\n}\n\n/**\n * Archive (delete means archive: never a hard delete) — only for rolling back a workbook this very flow just created and\n * failed to populate (see the import path in app/(core)/workbooks/page.tsx).\n * Never use this for a user-initiated delete: that is deleteWorkbook, which\n * tombstones and stays recoverable.\n */\nexport async function discardFailedWorkbook(\n workbookId: string,\n): Promise<ServiceResult<true>> {\n const { error } = await tryWriteOne(\n db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .update({ deleted_at: new Date().toISOString() })\n .eq(\"id\", workbookId)\n .select(\"id\"),\n { action: \"archive\", noun: \"workbook\" },\n );\n if (error) return { success: false, error: error.message };\n return { success: true, data: true };\n}\n\nexport async function restoreWorkbook(\n workbookId: string,\n): Promise<ServiceResult<true>> {\n const { error } = await tryWriteOne(\n db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .update({ deleted_at: null })\n .eq(\"id\", workbookId)\n .select(\"id\"),\n { action: \"restore\", noun: \"workbook\" },\n );\n if (error) return { success: false, error: error.message };\n return { success: true, data: true };\n}\n\n/** Trash view: the caller's own archived workbooks (RLS decides what is readable). */\nexport async function listTrashedWorkbooks(): Promise<\n ServiceResult<Workbook[]>\n> {\n const { data, error } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .select(\"*\")\n .not(\"deleted_at\", \"is\", null)\n .order(\"deleted_at\", { ascending: false });\n if (error) return { success: false, error: error.message };\n return { success: true, data: (data ?? []) as Workbook[] };\n}\n\n/**\n * An independent copy of a workbook: its own row in the original's organization\n * and project, with the latest snapshot copied over. Editing the copy never\n * touches the original.\n */\nexport async function copyWorkbook(\n workbookId: string,\n name?: string,\n): Promise<ServiceResult<Workbook>> {\n const original = await getWorkbook(workbookId);\n if (!original.success) return original;\n const row = original.data;\n if (!row.organization_id) {\n return {\n success: false,\n error: \"This workbook has no organization and cannot be copied.\",\n };\n }\n const created = await createWorkbook({\n name: name ?? `Copy of ${row.workbook_name}`,\n description: row.description ?? null,\n organizationId: row.organization_id,\n projectId: row.project_id ?? null,\n });\n if (!created.success) return created;\n const latest = await getLatestSnapshot(workbookId);\n if (!latest.success) return latest;\n if (latest.data) {\n const saved = await saveSnapshot({\n workbookId: created.data.id,\n snapshot: latest.data.snapshot,\n label: latest.data.label,\n origin: \"autosave\",\n });\n if (!saved.success) return saved;\n }\n return created;\n}\n\n// ─── snapshots (workbook content) ────────────────────────────────────────────\n\n/**\n * Latest-snapshot fetch — what an opened workbook hydrates from. Returns\n * `data: null` (success path) when the workbook has no snapshots yet (newly\n * created, never saved). Distinguish \"no snapshot\" from \"load error\" by\n * checking `result.data === null`.\n */\nexport async function getLatestSnapshot(\n workbookId: string,\n): Promise<ServiceResult<WorkbookSnapshot | null>> {\n const { data, error } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbook_snapshots\")\n .select(\"*\")\n .eq(\"workbook_id\", workbookId)\n .order(\"created_at\", { ascending: false })\n .limit(1)\n .maybeSingle();\n if (error) return { success: false, error: error.message };\n return { success: true, data: (data ?? null) as WorkbookSnapshot | null };\n}\n\nexport type SaveSnapshotArgs = {\n workbookId: string;\n snapshot: unknown; // opaque to us — editor library decides the shape\n label?: string | null;\n origin?: WorkbookSnapshotOrigin;\n};\n\nexport async function saveSnapshot(\n args: SaveSnapshotArgs,\n): Promise<ServiceResult<WorkbookSnapshot>> {\n const { data: userData } = await getClaimsUser(db());\n // A snapshot is a component of its workbook and carries the workbook's organization.\n const { data: workbook, error: workbookError } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .select(\"organization_id\")\n .eq(\"id\", args.workbookId)\n .single();\n if (workbookError) return { success: false, error: workbookError.message };\n const { data, error } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbook_snapshots\")\n .insert({\n organization_id: workbook.organization_id,\n workbook_id: args.workbookId,\n snapshot: args.snapshot as never,\n label: args.label ?? null,\n origin: args.origin ?? \"autosave\",\n created_by: userData?.user?.id ?? null,\n })\n .select(\"*\")\n .single();\n if (error) return { success: false, error: error.message };\n\n // Touch the parent workbook's updated_at so list views can sort by recency\n // without scanning snapshots. Best-effort — failure here is harmless.\n // write-lands-exempt: best-effort recency stamp on the parent workbook; the snapshot insert above is the real write\n await db()\n .schema(\"workbench\")\n .from(\"udt_workbooks\")\n .update({ updated_at: new Date().toISOString() })\n .eq(\"id\", args.workbookId);\n\n return { success: true, data: data as WorkbookSnapshot };\n}\n\nexport async function listSnapshots(\n workbookId: string,\n limit = 50,\n): Promise<ServiceResult<WorkbookSnapshot[]>> {\n const { data, error } = await db()\n .schema(\"workbench\")\n .from(\"udt_workbook_snapshots\")\n // component-created-by-ok: append-only snapshot with NO updated_by column and NO parent-rewrite trigger — created_by is the author the client wrote at insert (the only person field this table has)\n .select(\"id, workbook_id, label, origin, created_by, created_at\")\n .eq(\"workbook_id\", workbookId)\n .order(\"created_at\", { ascending: false })\n .limit(limit);\n if (error) return { success: false, error: error.message };\n return { success: true, data: (data ?? []) as WorkbookSnapshot[] };\n}\n"]}
|
package/dist/core.d.cts
CHANGED
|
@@ -315,6 +315,10 @@ type DocumentSource = "created" | "imported_docx" | "imported_md" | "imported_tx
|
|
|
315
315
|
type ShownTo = "only_me" | "my_team" | "everyone" | "everyone_on_ai_matrx";
|
|
316
316
|
/** `platform.visibility`. */
|
|
317
317
|
type Visibility = "personal" | "internal" | "link" | "public";
|
|
318
|
+
/** Origin of a snapshot. Free text in the database; this union is advisory. */
|
|
319
|
+
type WorkbookSnapshotOrigin = "autosave" | "manual" | "imported" | "restored" | "named";
|
|
320
|
+
/** Same advisory union as workbooks: a string column in the database. */
|
|
321
|
+
type DocumentSnapshotOrigin = WorkbookSnapshotOrigin;
|
|
318
322
|
/** A row of `workbench.udt_workbooks`. */
|
|
319
323
|
interface Workbook {
|
|
320
324
|
created_at: string;
|
|
@@ -394,4 +398,4 @@ interface DocumentSnapshot {
|
|
|
394
398
|
snapshot: unknown;
|
|
395
399
|
}
|
|
396
400
|
|
|
397
|
-
export { AUTOMATE_TAB, type DocumentRow, type DocumentSnapshot, type DocumentSource, type EditorMenu, type EditorMenuAction, type EditorMenuEntry, type EditorMenuSeparator, type EditorMenuSubmenu, type EditorShortcut, type EditorToolbarItem, type FlatEditorAction, type GoogleOnlyRows, type GoogleProduct, HELP_HEAD_CONTROLS, OFFICE_PRODUCTS, type OfficeHostMap, type OfficeProduct, type PageSetup, type ResolvedRibbonControl, type ResolvedRibbonGroup, type ResolvedRibbonTab, type RibbonControlSpec, type RibbonGroupSpec, type RibbonSize, type RibbonTabSpec, type ShownTo, type Visibility, type Workbook, type WorkbookSnapshot, type WorkbookSource, boundActions, configureOfficeHosts, flattenMenus, formatShortcut, googleExtensionsMenu, googleHelpHead, indexCommands, isMacPlatform, matchesShortcut, officeHref, officeOrigin, resolveRibbon, ribbonCoverage, searchActions, sep, soon };
|
|
401
|
+
export { AUTOMATE_TAB, type DocumentRow, type DocumentSnapshot, type DocumentSnapshotOrigin, type DocumentSource, type EditorMenu, type EditorMenuAction, type EditorMenuEntry, type EditorMenuSeparator, type EditorMenuSubmenu, type EditorShortcut, type EditorToolbarItem, type FlatEditorAction, type GoogleOnlyRows, type GoogleProduct, HELP_HEAD_CONTROLS, OFFICE_PRODUCTS, type OfficeHostMap, type OfficeProduct, type PageSetup, type ResolvedRibbonControl, type ResolvedRibbonGroup, type ResolvedRibbonTab, type RibbonControlSpec, type RibbonGroupSpec, type RibbonSize, type RibbonTabSpec, type ShownTo, type Visibility, type Workbook, type WorkbookSnapshot, type WorkbookSnapshotOrigin, type WorkbookSource, boundActions, configureOfficeHosts, flattenMenus, formatShortcut, googleExtensionsMenu, googleHelpHead, indexCommands, isMacPlatform, matchesShortcut, officeHref, officeOrigin, resolveRibbon, ribbonCoverage, searchActions, sep, soon };
|
package/dist/core.d.ts
CHANGED
|
@@ -315,6 +315,10 @@ type DocumentSource = "created" | "imported_docx" | "imported_md" | "imported_tx
|
|
|
315
315
|
type ShownTo = "only_me" | "my_team" | "everyone" | "everyone_on_ai_matrx";
|
|
316
316
|
/** `platform.visibility`. */
|
|
317
317
|
type Visibility = "personal" | "internal" | "link" | "public";
|
|
318
|
+
/** Origin of a snapshot. Free text in the database; this union is advisory. */
|
|
319
|
+
type WorkbookSnapshotOrigin = "autosave" | "manual" | "imported" | "restored" | "named";
|
|
320
|
+
/** Same advisory union as workbooks: a string column in the database. */
|
|
321
|
+
type DocumentSnapshotOrigin = WorkbookSnapshotOrigin;
|
|
318
322
|
/** A row of `workbench.udt_workbooks`. */
|
|
319
323
|
interface Workbook {
|
|
320
324
|
created_at: string;
|
|
@@ -394,4 +398,4 @@ interface DocumentSnapshot {
|
|
|
394
398
|
snapshot: unknown;
|
|
395
399
|
}
|
|
396
400
|
|
|
397
|
-
export { AUTOMATE_TAB, type DocumentRow, type DocumentSnapshot, type DocumentSource, type EditorMenu, type EditorMenuAction, type EditorMenuEntry, type EditorMenuSeparator, type EditorMenuSubmenu, type EditorShortcut, type EditorToolbarItem, type FlatEditorAction, type GoogleOnlyRows, type GoogleProduct, HELP_HEAD_CONTROLS, OFFICE_PRODUCTS, type OfficeHostMap, type OfficeProduct, type PageSetup, type ResolvedRibbonControl, type ResolvedRibbonGroup, type ResolvedRibbonTab, type RibbonControlSpec, type RibbonGroupSpec, type RibbonSize, type RibbonTabSpec, type ShownTo, type Visibility, type Workbook, type WorkbookSnapshot, type WorkbookSource, boundActions, configureOfficeHosts, flattenMenus, formatShortcut, googleExtensionsMenu, googleHelpHead, indexCommands, isMacPlatform, matchesShortcut, officeHref, officeOrigin, resolveRibbon, ribbonCoverage, searchActions, sep, soon };
|
|
401
|
+
export { AUTOMATE_TAB, type DocumentRow, type DocumentSnapshot, type DocumentSnapshotOrigin, type DocumentSource, type EditorMenu, type EditorMenuAction, type EditorMenuEntry, type EditorMenuSeparator, type EditorMenuSubmenu, type EditorShortcut, type EditorToolbarItem, type FlatEditorAction, type GoogleOnlyRows, type GoogleProduct, HELP_HEAD_CONTROLS, OFFICE_PRODUCTS, type OfficeHostMap, type OfficeProduct, type PageSetup, type ResolvedRibbonControl, type ResolvedRibbonGroup, type ResolvedRibbonTab, type RibbonControlSpec, type RibbonGroupSpec, type RibbonSize, type RibbonTabSpec, type ShownTo, type Visibility, type Workbook, type WorkbookSnapshot, type WorkbookSnapshotOrigin, type WorkbookSource, boundActions, configureOfficeHosts, flattenMenus, formatShortcut, googleExtensionsMenu, googleHelpHead, indexCommands, isMacPlatform, matchesShortcut, officeHref, officeOrigin, resolveRibbon, ribbonCoverage, searchActions, sep, soon };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/univer/ports.ts
|
|
2
|
+
var SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.office.univer-host");
|
|
3
|
+
var slot = () => {
|
|
4
|
+
const g = globalThis;
|
|
5
|
+
return g[SLOT] ??= {};
|
|
6
|
+
};
|
|
7
|
+
function getUniverHost() {
|
|
8
|
+
const ports = slot().ports;
|
|
9
|
+
if (!ports) throw new Error("@ai-matrx/office/univer: configureUniverHost(ports) was not called before an editor mounted.");
|
|
10
|
+
return ports;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// src/univer/univerImageStore.ts
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
var _core = require('@univerjs/core');
|
|
21
|
+
var MATRX_IMAGE_PREFIX = "matrx-file:";
|
|
22
|
+
var isMatrxImageSource = (source) => source.startsWith(MATRX_IMAGE_PREFIX);
|
|
23
|
+
var matrxImageFileId = (source) => source.slice(MATRX_IMAGE_PREFIX.length);
|
|
24
|
+
|
|
25
|
+
// src/univer/matrxImagePorts.ts
|
|
26
|
+
var matrxImagePorts = {
|
|
27
|
+
async upload(file) {
|
|
28
|
+
return getUniverHost().files.upload(file);
|
|
29
|
+
},
|
|
30
|
+
getBlob(fileId) {
|
|
31
|
+
return getUniverHost().files.getBlob(fileId);
|
|
32
|
+
},
|
|
33
|
+
onUploadError(error) {
|
|
34
|
+
getUniverHost().notifyUploadError(error);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
async function resolveExportImage(source) {
|
|
38
|
+
let blob;
|
|
39
|
+
if (isMatrxImageSource(source)) {
|
|
40
|
+
blob = await getUniverHost().files.getBlob(matrxImageFileId(source));
|
|
41
|
+
} else {
|
|
42
|
+
const res = await fetch(source);
|
|
43
|
+
if (!res.ok) return null;
|
|
44
|
+
blob = await res.blob();
|
|
45
|
+
}
|
|
46
|
+
const extension = blob.type.includes("gif") ? "gif" : blob.type.includes("png") ? "png" : "jpeg";
|
|
47
|
+
return { bytes: new Uint8Array(await blob.arrayBuffer()), extension };
|
|
48
|
+
}
|
|
49
|
+
async function uploadImportedImage(bytes, extension) {
|
|
50
|
+
const mime = extension === "jpg" ? "image/jpeg" : `image/${extension}`;
|
|
51
|
+
const { fileId } = await getUniverHost().files.upload(new File([bytes], `image.${extension}`, { type: mime }));
|
|
52
|
+
return fileId;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
exports.matrxImagePorts = matrxImagePorts; exports.resolveExportImage = resolveExportImage; exports.uploadImportedImage = uploadImportedImage;
|
|
59
|
+
//# sourceMappingURL=matrxImagePorts-JDFYE4QI.cjs.map
|