@powerhousedao/contributor-billing 0.1.53 → 1.0.0-dev.10
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/document-models/account-transactions/gen/schema/zod.d.ts.map +1 -1
- package/dist/document-models/account-transactions/gen/schema/zod.js +3 -3
- package/dist/document-models/account-transactions/module.d.ts +1 -1
- package/dist/document-models/account-transactions/module.d.ts.map +1 -1
- package/dist/document-models/account-transactions/module.js +1 -1
- package/dist/document-models/accounts/gen/schema/zod.d.ts.map +1 -1
- package/dist/document-models/accounts/module.d.ts +1 -1
- package/dist/document-models/accounts/module.d.ts.map +1 -1
- package/dist/document-models/accounts/module.js +1 -1
- package/dist/document-models/billing-statement/gen/schema/zod.d.ts.map +1 -1
- package/dist/document-models/billing-statement/gen/schema/zod.js +4 -4
- package/dist/document-models/billing-statement/module.d.ts +1 -1
- package/dist/document-models/billing-statement/module.d.ts.map +1 -1
- package/dist/document-models/billing-statement/module.js +1 -1
- package/dist/document-models/expense-report/gen/schema/zod.d.ts.map +1 -1
- package/dist/document-models/expense-report/gen/schema/zod.js +38 -18
- package/dist/document-models/expense-report/module.d.ts +1 -1
- package/dist/document-models/expense-report/module.d.ts.map +1 -1
- package/dist/document-models/expense-report/module.js +1 -1
- package/dist/document-models/invoice/gen/document-model.d.ts.map +1 -1
- package/dist/document-models/invoice/gen/document-model.js +150 -150
- package/dist/document-models/invoice/gen/schema/types.d.ts +3 -6
- package/dist/document-models/invoice/gen/schema/types.d.ts.map +1 -1
- package/dist/document-models/invoice/gen/schema/zod.d.ts +2 -8
- package/dist/document-models/invoice/gen/schema/zod.d.ts.map +1 -1
- package/dist/document-models/invoice/gen/schema/zod.js +14 -25
- package/dist/document-models/invoice/module.d.ts +1 -1
- package/dist/document-models/invoice/module.d.ts.map +1 -1
- package/dist/document-models/invoice/module.js +1 -1
- package/dist/document-models/invoice/src/reducers/general.d.ts.map +1 -1
- package/dist/document-models/invoice/src/reducers/general.js +8 -0
- package/dist/document-models/invoice/src/reducers/items.d.ts.map +1 -1
- package/dist/document-models/invoice/src/reducers/items.js +2 -1
- package/dist/document-models/invoice/src/reducers/parties.d.ts.map +1 -1
- package/dist/document-models/invoice/src/reducers/parties.js +6 -2
- package/dist/document-models/invoice/src/reducers/transitions.d.ts +0 -5
- package/dist/document-models/invoice/src/reducers/transitions.d.ts.map +1 -1
- package/dist/document-models/invoice/src/reducers/transitions.js +19 -6
- package/dist/document-models/invoice/tests/general.test.js +11 -2
- package/dist/document-models/invoice/tests/items.test.js +1 -1
- package/dist/document-models/invoice/tests/parties.test.js +1 -1
- package/dist/document-models/invoice/tests/transitions.test.js +7 -2
- package/dist/document-models/operational-hub-profile/module.d.ts +1 -1
- package/dist/document-models/operational-hub-profile/module.d.ts.map +1 -1
- package/dist/document-models/operational-hub-profile/module.js +1 -1
- package/dist/document-models/snapshot-report/gen/schema/zod.d.ts.map +1 -1
- package/dist/document-models/snapshot-report/gen/schema/zod.js +12 -12
- package/dist/document-models/snapshot-report/module.d.ts +1 -1
- package/dist/document-models/snapshot-report/module.d.ts.map +1 -1
- package/dist/document-models/snapshot-report/module.js +1 -1
- package/dist/editors/accounts-editor/editor.d.ts.map +1 -1
- package/dist/editors/accounts-editor/editor.js +2 -2
- package/dist/editors/builder-team-admin/components/DriveExplorer.d.ts.map +1 -1
- package/dist/editors/builder-team-admin/components/DriveExplorer.js +64 -4
- package/dist/editors/builder-team-admin/module.js +1 -1
- package/dist/editors/contributor-billing/components/DashboardHome.d.ts.map +1 -1
- package/dist/editors/contributor-billing/components/DashboardHome.js +2 -8
- package/dist/editors/contributor-billing/components/DocumentDropZone.d.ts.map +1 -1
- package/dist/editors/contributor-billing/components/DocumentDropZone.js +37 -8
- package/dist/editors/contributor-billing/components/DriveContents.d.ts.map +1 -1
- package/dist/editors/contributor-billing/components/DriveContents.js +4 -1
- package/dist/editors/contributor-billing/components/DriveExplorer.d.ts.map +1 -1
- package/dist/editors/contributor-billing/components/DriveExplorer.js +54 -3
- package/dist/editors/contributor-billing/components/FolderTree.d.ts.map +1 -1
- package/dist/editors/contributor-billing/components/FolderTree.js +6 -15
- package/dist/editors/contributor-billing/components/InvoiceTable/HeaderControls.d.ts +2 -1
- package/dist/editors/contributor-billing/components/InvoiceTable/HeaderControls.d.ts.map +1 -1
- package/dist/editors/contributor-billing/components/InvoiceTable/HeaderControls.js +41 -6
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTable.d.ts +1 -1
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTable.d.ts.map +1 -1
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTable.js +16 -1
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableContainer.d.ts +3 -1
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableContainer.d.ts.map +1 -1
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableContainer.js +13 -11
- package/dist/editors/contributor-billing/components/MonthReportCard.d.ts +11 -4
- package/dist/editors/contributor-billing/components/MonthReportCard.d.ts.map +1 -1
- package/dist/editors/contributor-billing/components/MonthReportCard.js +55 -6
- package/dist/editors/contributor-billing/components/MonthlyReportsOverview.d.ts +1 -1
- package/dist/editors/contributor-billing/components/MonthlyReportsOverview.d.ts.map +1 -1
- package/dist/editors/contributor-billing/components/MonthlyReportsOverview.js +104 -7
- package/dist/editors/contributor-billing/components/ReportingView.d.ts +0 -3
- package/dist/editors/contributor-billing/components/ReportingView.d.ts.map +1 -1
- package/dist/editors/contributor-billing/components/ReportingView.js +65 -8
- package/dist/editors/contributor-billing/components/ToastRenderer.d.ts +2 -0
- package/dist/editors/contributor-billing/components/ToastRenderer.d.ts.map +1 -0
- package/dist/editors/contributor-billing/components/ToastRenderer.js +14 -0
- package/dist/editors/contributor-billing/components/cbToast.d.ts +16 -0
- package/dist/editors/contributor-billing/components/cbToast.d.ts.map +1 -0
- package/dist/editors/contributor-billing/components/cbToast.js +29 -0
- package/dist/editors/contributor-billing/hooks/useDocumentAutoPlacement.d.ts.map +1 -1
- package/dist/editors/contributor-billing/hooks/useDocumentAutoPlacement.js +42 -2
- package/dist/editors/contributor-billing/hooks/useMonthlyReports.d.ts +4 -0
- package/dist/editors/contributor-billing/hooks/useMonthlyReports.d.ts.map +1 -1
- package/dist/editors/contributor-billing/hooks/useMonthlyReports.js +4 -0
- package/dist/editors/contributor-billing/module.js +1 -1
- package/dist/editors/invoice/InvoicePDF.d.ts.map +1 -1
- package/dist/editors/invoice/InvoicePDF.js +12 -9
- package/dist/editors/invoice/editor.d.ts.map +1 -1
- package/dist/editors/invoice/editor.js +6 -10
- package/dist/editors/invoice/exportUBL.d.ts.map +1 -1
- package/dist/editors/invoice/exportUBL.js +1 -2
- package/dist/editors/invoice/ingestPDF.js +1 -1
- package/dist/editors/invoice/invoiceToGnosis.d.ts.map +1 -1
- package/dist/editors/invoice/invoiceToGnosis.js +25 -22
- package/dist/editors/invoice/invoiceToast.d.ts +4 -0
- package/dist/editors/invoice/invoiceToast.d.ts.map +1 -0
- package/dist/editors/invoice/invoiceToast.js +6 -0
- package/dist/editors/invoice/legalEntity/legalEntity.d.ts +2 -1
- package/dist/editors/invoice/legalEntity/legalEntity.d.ts.map +1 -1
- package/dist/editors/invoice/legalEntity/legalEntity.js +3 -14
- package/dist/editors/invoice/legalEntity/walletSection.d.ts +1 -0
- package/dist/editors/invoice/legalEntity/walletSection.d.ts.map +1 -1
- package/dist/editors/invoice/legalEntity/walletSection.js +2 -2
- package/dist/editors/invoice/lineItems.js +1 -1
- package/dist/editors/invoice/requestFinance.d.ts +3 -2
- package/dist/editors/invoice/requestFinance.d.ts.map +1 -1
- package/dist/editors/invoice/requestFinance.js +38 -42
- package/dist/editors/invoice/validation/validationHandler.d.ts +1 -1
- package/dist/editors/invoice/validation/validationHandler.d.ts.map +1 -1
- package/dist/editors/invoice/validation/validationHandler.js +15 -2
- package/dist/editors/invoice/validation/validationManager.d.ts +1 -1
- package/dist/editors/invoice/validation/validationManager.d.ts.map +1 -1
- package/dist/editors/invoice/validation/validationManager.js +2 -1
- package/dist/editors/invoice/validation/validationRules.d.ts +1 -0
- package/dist/editors/invoice/validation/validationRules.d.ts.map +1 -1
- package/dist/editors/invoice/validation/validationRules.js +26 -1
- package/dist/editors/snapshot-report-editor/components/DateRangePicker.d.ts +19 -0
- package/dist/editors/snapshot-report-editor/components/DateRangePicker.d.ts.map +1 -0
- package/dist/editors/snapshot-report-editor/components/DateRangePicker.js +66 -0
- package/dist/editors/snapshot-report-editor/editor.d.ts.map +1 -1
- package/dist/editors/snapshot-report-editor/editor.js +72 -48
- package/dist/scripts/download-all-drive-documents/download-drive-documents.d.ts +33 -0
- package/dist/scripts/download-all-drive-documents/download-drive-documents.d.ts.map +1 -0
- package/dist/scripts/download-all-drive-documents/download-drive-documents.js +583 -0
- package/dist/scripts/invoice/requestFinance.d.ts +18 -1
- package/dist/scripts/invoice/requestFinance.d.ts.map +1 -1
- package/dist/scripts/invoice/requestFinance.js +17 -5
- package/dist/scripts/upload-phd-documents/upload-phd-documents.d.ts +20 -0
- package/dist/scripts/upload-phd-documents/upload-phd-documents.d.ts.map +1 -0
- package/dist/scripts/upload-phd-documents/upload-phd-documents.js +313 -0
- package/dist/style.css +201 -106
- package/dist/subgraphs/budget-statements/resolvers.d.ts +38 -0
- package/dist/subgraphs/budget-statements/resolvers.d.ts.map +1 -1
- package/dist/subgraphs/budget-statements/resolvers.js +192 -62
- package/dist/subgraphs/budget-statements/resolvers.test.d.ts +2 -0
- package/dist/subgraphs/budget-statements/resolvers.test.d.ts.map +1 -0
- package/dist/subgraphs/budget-statements/resolvers.test.js +339 -0
- package/dist/subgraphs/budget-statements/schema.d.ts.map +1 -1
- package/dist/subgraphs/budget-statements/schema.js +8 -0
- package/dist/subgraphs/index.d.ts +0 -1
- package/dist/subgraphs/index.d.ts.map +1 -1
- package/dist/subgraphs/index.js +0 -1
- package/dist/subgraphs/invoice-addon/customResolvers.d.ts +70 -11
- package/dist/subgraphs/invoice-addon/customResolvers.d.ts.map +1 -1
- package/dist/subgraphs/invoice-addon/customResolvers.js +12 -27
- package/package.json +35 -28
- package/dist/document-models/invoice/src/tests/document-model.test.d.ts +0 -10
- package/dist/document-models/invoice/src/tests/document-model.test.d.ts.map +0 -1
- package/dist/document-models/invoice/src/tests/document-model.test.js +0 -104
- package/dist/document-models/invoice/src/tests/general.test.d.ts +0 -6
- package/dist/document-models/invoice/src/tests/general.test.d.ts.map +0 -1
- package/dist/document-models/invoice/src/tests/general.test.js +0 -49
- package/dist/document-models/invoice/src/tests/items.test.d.ts +0 -6
- package/dist/document-models/invoice/src/tests/items.test.d.ts.map +0 -1
- package/dist/document-models/invoice/src/tests/items.test.js +0 -59
- package/dist/document-models/invoice/src/tests/parties.test.d.ts +0 -6
- package/dist/document-models/invoice/src/tests/parties.test.d.ts.map +0 -1
- package/dist/document-models/invoice/src/tests/parties.test.js +0 -69
- package/dist/document-models/invoice/src/tests/transitions.test.d.ts +0 -6
- package/dist/document-models/invoice/src/tests/transitions.test.d.ts.map +0 -1
- package/dist/document-models/invoice/src/tests/transitions.test.js +0 -59
- package/dist/document-models/invoice/utils/statusTransitions.d.ts +0 -13
- package/dist/document-models/invoice/utils/statusTransitions.d.ts.map +0 -1
- package/dist/document-models/invoice/utils/statusTransitions.js +0 -13
- package/dist/editors/builder-team-admin/components/overview/SubscriptionsStats.d.ts +0 -15
- package/dist/editors/builder-team-admin/components/overview/SubscriptionsStats.d.ts.map +0 -1
- package/dist/editors/builder-team-admin/components/overview/SubscriptionsStats.js +0 -61
- package/dist/editors/contributor-billing/components/CreateHubProfileModal.d.ts +0 -12
- package/dist/editors/contributor-billing/components/CreateHubProfileModal.d.ts.map +0 -1
- package/dist/editors/contributor-billing/components/CreateHubProfileModal.js +0 -74
- package/dist/subgraphs/resources-services/index.d.ts +0 -11
- package/dist/subgraphs/resources-services/index.d.ts.map +0 -1
- package/dist/subgraphs/resources-services/index.js +0 -11
- package/dist/subgraphs/resources-services/resolvers.d.ts +0 -3
- package/dist/subgraphs/resources-services/resolvers.d.ts.map +0 -1
- package/dist/subgraphs/resources-services/resolvers.js +0 -462
- package/dist/subgraphs/resources-services/schema.d.ts +0 -3
- package/dist/subgraphs/resources-services/schema.d.ts.map +0 -1
- package/dist/subgraphs/resources-services/schema.js +0 -284
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Upload local .phd documents to a Powerhouse switchboard.
|
|
4
|
+
*
|
|
5
|
+
* Works with ANY document type — reads header.json and operations.json from
|
|
6
|
+
* the .phd file, auto-detects the document type, creates a new document via
|
|
7
|
+
* the matching _createDocument mutation, then replays all operations via
|
|
8
|
+
* pushUpdates on the drive endpoint.
|
|
9
|
+
*
|
|
10
|
+
* REQUIRES: Bun runtime (https://bun.sh)
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* bun scripts/upload-phd-documents/upload-phd-documents.ts <switchboard-url> <drive-id> <file.phd> [file2.phd ...]
|
|
14
|
+
*
|
|
15
|
+
* Examples:
|
|
16
|
+
* bun scripts/upload-phd-documents/upload-phd-documents.ts http://localhost:4001 preview-f80015b9 "op hub.phd" "oh service.phd"
|
|
17
|
+
* bun scripts/upload-phd-documents/upload-phd-documents.ts http://localhost:4001 preview-f80015b9 invoice.phd
|
|
18
|
+
*/
|
|
19
|
+
import { inflateRawSync } from "node:zlib";
|
|
20
|
+
import fs from "node:fs";
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// ZIP reader (from download script)
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
function readZipEntry(zipBuf, entryName) {
|
|
25
|
+
let offset = 0;
|
|
26
|
+
while (offset + 30 <= zipBuf.length) {
|
|
27
|
+
const sig = zipBuf.readUInt32LE(offset);
|
|
28
|
+
if (sig !== 0x04034b50)
|
|
29
|
+
break;
|
|
30
|
+
const compressionMethod = zipBuf.readUInt16LE(offset + 8);
|
|
31
|
+
const compressedSize = zipBuf.readUInt32LE(offset + 18);
|
|
32
|
+
const nameLen = zipBuf.readUInt16LE(offset + 26);
|
|
33
|
+
const extraLen = zipBuf.readUInt16LE(offset + 28);
|
|
34
|
+
const nameStart = offset + 30;
|
|
35
|
+
const name = zipBuf
|
|
36
|
+
.subarray(nameStart, nameStart + nameLen)
|
|
37
|
+
.toString("utf-8");
|
|
38
|
+
const dataStart = nameStart + nameLen + extraLen;
|
|
39
|
+
const dataEnd = dataStart + compressedSize;
|
|
40
|
+
if (name === entryName) {
|
|
41
|
+
const raw = zipBuf.subarray(dataStart, dataEnd);
|
|
42
|
+
if (compressionMethod === 8) {
|
|
43
|
+
return Buffer.from(inflateRawSync(raw));
|
|
44
|
+
}
|
|
45
|
+
return Buffer.from(raw);
|
|
46
|
+
}
|
|
47
|
+
offset = dataEnd;
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
function readPhdJson(filePath, entryName) {
|
|
52
|
+
const zipBuf = fs.readFileSync(filePath);
|
|
53
|
+
const buf = readZipEntry(zipBuf, entryName);
|
|
54
|
+
if (!buf)
|
|
55
|
+
throw new Error(`${entryName} not found in ${filePath}`);
|
|
56
|
+
return JSON.parse(buf.toString("utf-8"));
|
|
57
|
+
}
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// GraphQL helper
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
const REQUEST_DELAY_MS = 200;
|
|
62
|
+
const PUSH_BATCH_SIZE = 50;
|
|
63
|
+
function sleep(ms) {
|
|
64
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
65
|
+
}
|
|
66
|
+
async function gql(endpoint, query, variables) {
|
|
67
|
+
const res = await fetch(endpoint, {
|
|
68
|
+
method: "POST",
|
|
69
|
+
headers: { "Content-Type": "application/json" },
|
|
70
|
+
body: JSON.stringify({ query, variables }),
|
|
71
|
+
});
|
|
72
|
+
if (!res.ok) {
|
|
73
|
+
const body = await res.text().catch(() => "");
|
|
74
|
+
throw new Error(`GraphQL ${res.status}: ${body.slice(0, 500)}`);
|
|
75
|
+
}
|
|
76
|
+
const json = (await res.json());
|
|
77
|
+
if (json.errors?.length) {
|
|
78
|
+
throw new Error(`GraphQL errors:\n${json.errors.map((e) => ` - ${e.message}`).join("\n")}`);
|
|
79
|
+
}
|
|
80
|
+
if (!json.data)
|
|
81
|
+
throw new Error("No data returned from GraphQL");
|
|
82
|
+
return json.data;
|
|
83
|
+
}
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
// Document type -> mutation prefix mapping
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
/**
|
|
88
|
+
* Discover available _createDocument mutations by introspecting the API.
|
|
89
|
+
* Returns a map of documentType -> mutation prefix.
|
|
90
|
+
* e.g. "powerhouse/resource-template" -> "ResourceTemplate"
|
|
91
|
+
*/
|
|
92
|
+
async function discoverDocumentTypes(endpoint) {
|
|
93
|
+
const data = await gql(endpoint, `{ __schema { mutationType { fields { name } } } }`);
|
|
94
|
+
const map = new Map();
|
|
95
|
+
for (const field of data.__schema.mutationType.fields) {
|
|
96
|
+
if (!field.name.endsWith("_createDocument"))
|
|
97
|
+
continue;
|
|
98
|
+
const prefix = field.name.replace("_createDocument", "");
|
|
99
|
+
// Convert PascalCase prefix to kebab-case document type
|
|
100
|
+
const kebab = prefix.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
101
|
+
const docType = `powerhouse/${kebab}`;
|
|
102
|
+
map.set(docType, prefix);
|
|
103
|
+
}
|
|
104
|
+
return map;
|
|
105
|
+
}
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
// Create document via type-specific _createDocument mutation
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
async function createDocument(endpoint, driveId, mutationPrefix, name) {
|
|
110
|
+
const mutationName = `${mutationPrefix}_createDocument`;
|
|
111
|
+
const data = await gql(endpoint, `mutation ($name: String!, $driveId: String) {
|
|
112
|
+
${mutationName}(name: $name, driveId: $driveId)
|
|
113
|
+
}`, { name, driveId });
|
|
114
|
+
return data[mutationName];
|
|
115
|
+
}
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
// Push operations via pushUpdates on the drive endpoint
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
async function pushOperations(driveEndpoint, driveId, docId, documentType, operations) {
|
|
120
|
+
let totalPushed = 0;
|
|
121
|
+
for (const scope of ["global", "local"]) {
|
|
122
|
+
const scopeOps = operations[scope];
|
|
123
|
+
if (!scopeOps?.length)
|
|
124
|
+
continue;
|
|
125
|
+
console.log(` Pushing ${scopeOps.length} ${scope} operations...`);
|
|
126
|
+
for (let i = 0; i < scopeOps.length; i += PUSH_BATCH_SIZE) {
|
|
127
|
+
const batch = scopeOps.slice(i, i + PUSH_BATCH_SIZE);
|
|
128
|
+
const inputOps = batch.map((op) => ({
|
|
129
|
+
index: op.index,
|
|
130
|
+
skip: op.skip,
|
|
131
|
+
type: op.action.type,
|
|
132
|
+
id: op.id,
|
|
133
|
+
actionId: op.action.id || op.id,
|
|
134
|
+
input: JSON.stringify(op.action.input),
|
|
135
|
+
hash: op.hash,
|
|
136
|
+
timestampUtcMs: op.timestampUtcMs,
|
|
137
|
+
error: op.error ?? null,
|
|
138
|
+
}));
|
|
139
|
+
const strand = {
|
|
140
|
+
driveId,
|
|
141
|
+
documentId: docId,
|
|
142
|
+
documentType,
|
|
143
|
+
scope,
|
|
144
|
+
branch: "main",
|
|
145
|
+
operations: inputOps,
|
|
146
|
+
};
|
|
147
|
+
if (i > 0)
|
|
148
|
+
await sleep(REQUEST_DELAY_MS);
|
|
149
|
+
const result = await gql(driveEndpoint, `mutation ($strands: [InputStrandUpdate!]) {
|
|
150
|
+
pushUpdates(strands: $strands) { revision status error }
|
|
151
|
+
}`, { strands: [strand] });
|
|
152
|
+
const update = result.pushUpdates[0];
|
|
153
|
+
if (update.status !== "SUCCESS") {
|
|
154
|
+
throw new Error(`pushUpdates failed at batch ${Math.floor(i / PUSH_BATCH_SIZE) + 1}: ` +
|
|
155
|
+
`status=${update.status}, error=${update.error}`);
|
|
156
|
+
}
|
|
157
|
+
totalPushed += batch.length;
|
|
158
|
+
const batchNum = Math.floor(i / PUSH_BATCH_SIZE) + 1;
|
|
159
|
+
const totalBatches = Math.ceil(scopeOps.length / PUSH_BATCH_SIZE);
|
|
160
|
+
console.log(` [${batchNum}/${totalBatches}] ${batch.length} ops -> revision ${update.revision}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return totalPushed;
|
|
164
|
+
}
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
// State verification
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
async function verifyState(driveEndpoint, docId, expectedGlobal) {
|
|
169
|
+
const data = await gql(driveEndpoint, `query ($id: String!) { document(id: $id) { stateJSON } }`, { id: docId });
|
|
170
|
+
const actual = data.document.stateJSON;
|
|
171
|
+
const expectedStr = JSON.stringify(expectedGlobal, Object.keys(expectedGlobal).sort());
|
|
172
|
+
const actualStr = JSON.stringify(actual, Object.keys(actual).sort());
|
|
173
|
+
if (expectedStr === actualStr)
|
|
174
|
+
return true;
|
|
175
|
+
// Count differences for reporting
|
|
176
|
+
const allKeys = new Set([
|
|
177
|
+
...Object.keys(expectedGlobal),
|
|
178
|
+
...Object.keys(actual),
|
|
179
|
+
]);
|
|
180
|
+
let diffs = 0;
|
|
181
|
+
for (const key of allKeys) {
|
|
182
|
+
const ev = JSON.stringify(expectedGlobal[key], null, 0);
|
|
183
|
+
const av = JSON.stringify(actual[key], null, 0);
|
|
184
|
+
if (ev !== av) {
|
|
185
|
+
diffs++;
|
|
186
|
+
if (diffs <= 5) {
|
|
187
|
+
const evShort = (ev || "undefined").slice(0, 60);
|
|
188
|
+
const avShort = (av || "undefined").slice(0, 60);
|
|
189
|
+
console.log(` DIFF: ${key}: expected=${evShort} actual=${avShort}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (diffs > 5) {
|
|
194
|
+
console.log(` ... and ${diffs - 5} more differences`);
|
|
195
|
+
}
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
199
|
+
// Upload a single .phd file
|
|
200
|
+
// ---------------------------------------------------------------------------
|
|
201
|
+
async function uploadPhdFile(baseUrl, driveId, filePath, typeMap) {
|
|
202
|
+
const endpoint = `${baseUrl}/graphql`;
|
|
203
|
+
const driveEndpoint = `${baseUrl}/d/${driveId}`;
|
|
204
|
+
// 1. Read .phd contents
|
|
205
|
+
const header = readPhdJson(filePath, "header.json");
|
|
206
|
+
const operations = readPhdJson(filePath, "operations.json");
|
|
207
|
+
const currentState = readPhdJson(filePath, "current-state.json");
|
|
208
|
+
const docType = header.documentType;
|
|
209
|
+
const docName = header.name || filePath.replace(/^.*\//, "").replace(/\.phd$/, "");
|
|
210
|
+
const globalOpsCount = operations.global?.length ?? 0;
|
|
211
|
+
const localOpsCount = operations.local?.length ?? 0;
|
|
212
|
+
console.log(`\n${"─".repeat(60)}`);
|
|
213
|
+
console.log(` File: ${filePath}`);
|
|
214
|
+
console.log(` Type: ${docType}`);
|
|
215
|
+
console.log(` Name: ${docName || "(unnamed)"}`);
|
|
216
|
+
console.log(` Ops: ${globalOpsCount} global, ${localOpsCount} local`);
|
|
217
|
+
// 2. Find the matching _createDocument mutation
|
|
218
|
+
const mutationPrefix = typeMap.get(docType);
|
|
219
|
+
if (!mutationPrefix) {
|
|
220
|
+
throw new Error(`No _createDocument mutation found for type "${docType}". ` +
|
|
221
|
+
`Available types: ${[...typeMap.keys()].join(", ")}`);
|
|
222
|
+
}
|
|
223
|
+
// 3. Create the document
|
|
224
|
+
console.log(` Creating ${mutationPrefix} document...`);
|
|
225
|
+
const docId = await createDocument(endpoint, driveId, mutationPrefix, docName || "Untitled");
|
|
226
|
+
console.log(` Created: ${docId}`);
|
|
227
|
+
// 4. Push operations
|
|
228
|
+
let totalPushed = 0;
|
|
229
|
+
if (globalOpsCount + localOpsCount > 0) {
|
|
230
|
+
await sleep(REQUEST_DELAY_MS);
|
|
231
|
+
totalPushed = await pushOperations(driveEndpoint, driveId, docId, docType, operations);
|
|
232
|
+
console.log(` Pushed: ${totalPushed} operations`);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
console.log(` No operations to push`);
|
|
236
|
+
}
|
|
237
|
+
// 5. Verify state
|
|
238
|
+
await sleep(REQUEST_DELAY_MS);
|
|
239
|
+
console.log(` Verifying state...`);
|
|
240
|
+
const stateMatch = await verifyState(driveEndpoint, docId, currentState.global);
|
|
241
|
+
if (stateMatch) {
|
|
242
|
+
console.log(` State: EXACT MATCH`);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
console.log(` State: MISMATCH (see diffs above — may be expected with schema changes)`);
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
file: filePath,
|
|
249
|
+
documentType: docType,
|
|
250
|
+
docId,
|
|
251
|
+
name: docName,
|
|
252
|
+
operationsPushed: totalPushed,
|
|
253
|
+
stateMatch,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
// Main
|
|
258
|
+
// ---------------------------------------------------------------------------
|
|
259
|
+
async function main() {
|
|
260
|
+
const args = process.argv.slice(2);
|
|
261
|
+
if (args.length < 3) {
|
|
262
|
+
console.log("Usage: bun scripts/upload-phd-documents/upload-phd-documents.ts <switchboard-url> <drive-id> <file.phd> [file2.phd ...]");
|
|
263
|
+
console.log("\nExamples:" +
|
|
264
|
+
'\n bun scripts/upload-phd-documents/upload-phd-documents.ts http://localhost:4001 preview-f80015b9 "op hub.phd" "oh service.phd"' +
|
|
265
|
+
"\n bun scripts/upload-phd-documents/upload-phd-documents.ts http://localhost:4001 preview-f80015b9 invoice.phd");
|
|
266
|
+
process.exit(1);
|
|
267
|
+
}
|
|
268
|
+
const [rawBaseUrl, driveId, ...phdFiles] = args;
|
|
269
|
+
const baseUrl = rawBaseUrl.replace(/\/+$/, "").replace(/\/graphql$/i, "");
|
|
270
|
+
console.log(`Switchboard: ${baseUrl}`);
|
|
271
|
+
console.log(`Drive: ${driveId}`);
|
|
272
|
+
console.log(`Files: ${phdFiles.length}`);
|
|
273
|
+
// Discover available document types from the API
|
|
274
|
+
console.log(`\nDiscovering document types...`);
|
|
275
|
+
const typeMap = await discoverDocumentTypes(`${baseUrl}/graphql`);
|
|
276
|
+
console.log(` Found ${typeMap.size} types: ${[...typeMap.keys()].join(", ")}`);
|
|
277
|
+
// Upload each .phd file
|
|
278
|
+
const results = [];
|
|
279
|
+
const failures = [];
|
|
280
|
+
for (const file of phdFiles) {
|
|
281
|
+
try {
|
|
282
|
+
const result = await uploadPhdFile(baseUrl, driveId, file, typeMap);
|
|
283
|
+
results.push(result);
|
|
284
|
+
}
|
|
285
|
+
catch (err) {
|
|
286
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
287
|
+
console.error(`\n FAILED: ${file}`);
|
|
288
|
+
console.error(` Reason: ${reason}`);
|
|
289
|
+
failures.push({ file, reason });
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// Summary
|
|
293
|
+
console.log(`\n${"=".repeat(60)}`);
|
|
294
|
+
console.log(`DONE`);
|
|
295
|
+
console.log(`${"=".repeat(60)}`);
|
|
296
|
+
console.log(` Drive: ${driveId}`);
|
|
297
|
+
console.log(` Uploaded: ${results.length}`);
|
|
298
|
+
console.log(` Failed: ${failures.length}`);
|
|
299
|
+
for (const r of results) {
|
|
300
|
+
const stateIcon = r.stateMatch ? "OK" : "~";
|
|
301
|
+
console.log(` [${stateIcon}] ${r.name || r.file} (${r.documentType}) -> ${r.docId} (${r.operationsPushed} ops)`);
|
|
302
|
+
}
|
|
303
|
+
for (const f of failures) {
|
|
304
|
+
console.log(` [X] ${f.file}: ${f.reason}`);
|
|
305
|
+
}
|
|
306
|
+
if (failures.length > 0) {
|
|
307
|
+
process.exit(1);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
main().catch((err) => {
|
|
311
|
+
console.error(err);
|
|
312
|
+
process.exit(1);
|
|
313
|
+
});
|