@powerhousedao/vetra-builder-package 5.0.2 โ 5.2.0-staging.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/builder-team/actions.d.ts +28 -0
- package/dist/document-models/builder-team/actions.d.ts.map +1 -0
- package/dist/document-models/builder-team/actions.js +10 -0
- package/dist/document-models/builder-team/builder-team.json +234 -0
- package/dist/document-models/builder-team/gen/actions.d.ts +8 -8
- package/dist/document-models/builder-team/gen/actions.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/actions.js +4 -4
- package/dist/document-models/builder-team/gen/creators.d.ts +8 -4
- package/dist/document-models/builder-team/gen/creators.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/creators.js +8 -4
- package/dist/document-models/builder-team/gen/document-model.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/document-model.js +220 -220
- package/dist/document-models/builder-team/gen/document-schema.d.ts +50 -0
- package/dist/document-models/builder-team/gen/document-schema.d.ts.map +1 -0
- package/dist/document-models/builder-team/gen/document-schema.js +33 -0
- package/dist/document-models/builder-team/gen/document-type.d.ts +2 -0
- package/dist/document-models/builder-team/gen/document-type.d.ts.map +1 -0
- package/dist/document-models/builder-team/gen/document-type.js +1 -0
- package/dist/document-models/builder-team/gen/index.d.ts +14 -5
- package/dist/document-models/builder-team/gen/index.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/index.js +14 -5
- package/dist/document-models/builder-team/gen/member/actions.d.ts +5 -5
- package/dist/document-models/builder-team/gen/member/actions.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/member/actions.js +1 -1
- package/dist/document-models/builder-team/gen/member/creators.d.ts +2 -2
- package/dist/document-models/builder-team/gen/member/creators.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/member/creators.js +5 -6
- package/dist/document-models/builder-team/gen/member/error.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/member/operations.d.ts +3 -3
- package/dist/document-models/builder-team/gen/member/operations.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/member/operations.js +1 -3
- package/dist/document-models/builder-team/gen/packages/actions.d.ts +6 -6
- package/dist/document-models/builder-team/gen/packages/actions.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/packages/actions.js +1 -1
- package/dist/document-models/builder-team/gen/packages/creators.d.ts +2 -2
- package/dist/document-models/builder-team/gen/packages/creators.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/packages/creators.js +6 -7
- package/dist/document-models/builder-team/gen/packages/error.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/packages/operations.d.ts +3 -3
- package/dist/document-models/builder-team/gen/packages/operations.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/packages/operations.js +1 -3
- package/dist/document-models/builder-team/gen/ph-factories.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/ph-factories.js +16 -14
- package/dist/document-models/builder-team/gen/profile/actions.d.ts +7 -7
- package/dist/document-models/builder-team/gen/profile/actions.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/profile/actions.js +1 -1
- package/dist/document-models/builder-team/gen/profile/creators.d.ts +2 -2
- package/dist/document-models/builder-team/gen/profile/creators.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/profile/creators.js +7 -8
- package/dist/document-models/builder-team/gen/profile/error.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/profile/operations.d.ts +3 -3
- package/dist/document-models/builder-team/gen/profile/operations.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/profile/operations.js +1 -3
- package/dist/document-models/builder-team/gen/reducer.d.ts +1 -3
- package/dist/document-models/builder-team/gen/reducer.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/reducer.js +86 -70
- package/dist/document-models/builder-team/gen/schema/index.d.ts +1 -1
- package/dist/document-models/builder-team/gen/schema/index.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/schema/index.js +1 -1
- package/dist/document-models/builder-team/gen/schema/types.d.ts +13 -1
- package/dist/document-models/builder-team/gen/schema/types.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/schema/zod.d.ts +3 -3
- package/dist/document-models/builder-team/gen/schema/zod.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/schema/zod.js +22 -22
- package/dist/document-models/builder-team/gen/spaces/actions.d.ts +6 -6
- package/dist/document-models/builder-team/gen/spaces/actions.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/spaces/actions.js +1 -1
- package/dist/document-models/builder-team/gen/spaces/creators.d.ts +2 -2
- package/dist/document-models/builder-team/gen/spaces/creators.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/spaces/creators.js +6 -7
- package/dist/document-models/builder-team/gen/spaces/error.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/spaces/operations.d.ts +3 -3
- package/dist/document-models/builder-team/gen/spaces/operations.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/spaces/operations.js +1 -3
- package/dist/document-models/builder-team/gen/types.d.ts +4 -5
- package/dist/document-models/builder-team/gen/types.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/types.js +1 -2
- package/dist/document-models/builder-team/gen/utils.d.ts +7 -4
- package/dist/document-models/builder-team/gen/utils.d.ts.map +1 -1
- package/dist/document-models/builder-team/gen/utils.js +41 -20
- package/dist/document-models/builder-team/hooks.d.ts +11 -0
- package/dist/document-models/builder-team/hooks.d.ts.map +1 -0
- package/dist/document-models/builder-team/hooks.js +26 -0
- package/dist/document-models/builder-team/index.d.ts +5 -45
- package/dist/document-models/builder-team/index.d.ts.map +1 -1
- package/dist/document-models/builder-team/index.js +5 -22
- package/dist/document-models/builder-team/module.d.ts +5 -0
- package/dist/document-models/builder-team/module.d.ts.map +1 -0
- package/dist/document-models/builder-team/module.js +10 -0
- package/dist/document-models/builder-team/src/index.d.ts +2 -0
- package/dist/document-models/builder-team/src/index.d.ts.map +1 -0
- package/dist/document-models/builder-team/src/index.js +1 -0
- package/dist/document-models/builder-team/src/reducers/member.d.ts +2 -2
- package/dist/document-models/builder-team/src/reducers/member.d.ts.map +1 -1
- package/dist/document-models/builder-team/src/reducers/member.js +8 -5
- package/dist/document-models/builder-team/src/reducers/packages.d.ts +2 -2
- package/dist/document-models/builder-team/src/reducers/packages.d.ts.map +1 -1
- package/dist/document-models/builder-team/src/reducers/packages.js +8 -8
- package/dist/document-models/builder-team/src/reducers/profile.d.ts +2 -2
- package/dist/document-models/builder-team/src/reducers/profile.d.ts.map +1 -1
- package/dist/document-models/builder-team/src/reducers/profile.js +6 -6
- package/dist/document-models/builder-team/src/reducers/spaces.d.ts +2 -2
- package/dist/document-models/builder-team/src/reducers/spaces.d.ts.map +1 -1
- package/dist/document-models/builder-team/src/reducers/spaces.js +7 -7
- package/dist/document-models/builder-team/src/tests/document-model.test.d.ts +4 -0
- package/dist/document-models/builder-team/src/tests/document-model.test.d.ts.map +1 -1
- package/dist/document-models/builder-team/src/tests/document-model.test.js +92 -6
- package/dist/document-models/builder-team/src/tests/member.test.d.ts +0 -4
- package/dist/document-models/builder-team/src/tests/member.test.d.ts.map +1 -1
- package/dist/document-models/builder-team/src/tests/member.test.js +15 -20
- package/dist/document-models/builder-team/src/tests/packages.test.d.ts +0 -4
- package/dist/document-models/builder-team/src/tests/packages.test.d.ts.map +1 -1
- package/dist/document-models/builder-team/src/tests/packages.test.js +25 -20
- package/dist/document-models/builder-team/src/tests/profile.test.d.ts +0 -4
- package/dist/document-models/builder-team/src/tests/profile.test.d.ts.map +1 -1
- package/dist/document-models/builder-team/src/tests/profile.test.js +23 -24
- package/dist/document-models/builder-team/src/tests/spaces.test.d.ts +0 -4
- package/dist/document-models/builder-team/src/tests/spaces.test.d.ts.map +1 -1
- package/dist/document-models/builder-team/src/tests/spaces.test.js +25 -20
- package/dist/document-models/builder-team/utils.d.ts +14 -0
- package/dist/document-models/builder-team/utils.d.ts.map +1 -0
- package/dist/document-models/builder-team/utils.js +7 -0
- package/dist/document-models/document-models.d.ts +3 -0
- package/dist/document-models/document-models.d.ts.map +1 -0
- package/dist/document-models/document-models.js +4 -0
- package/dist/document-models/index.d.ts +1 -2
- package/dist/document-models/index.d.ts.map +1 -1
- package/dist/document-models/index.js +1 -2
- package/dist/editors/builder-team-editor/components/EditName.d.ts +3 -0
- package/dist/editors/builder-team-editor/components/EditName.d.ts.map +1 -0
- package/dist/editors/builder-team-editor/components/EditName.js +31 -0
- package/dist/editors/builder-team-editor/components/PackagesTable.d.ts.map +1 -1
- package/dist/editors/builder-team-editor/components/PackagesTable.js +0 -1
- package/dist/editors/builder-team-editor/editor.d.ts +1 -1
- package/dist/editors/builder-team-editor/editor.d.ts.map +1 -1
- package/dist/editors/builder-team-editor/editor.js +2 -4
- package/dist/editors/builder-team-editor/hooks/usePackageHandlers.d.ts +1 -2
- package/dist/editors/builder-team-editor/hooks/usePackageHandlers.d.ts.map +1 -1
- package/dist/editors/builder-team-editor/hooks/usePackageHandlers.js +1 -1
- package/dist/editors/builder-team-editor/module.d.ts +4 -0
- package/dist/editors/builder-team-editor/module.d.ts.map +1 -0
- package/dist/editors/builder-team-editor/module.js +10 -0
- package/dist/editors/editors.d.ts +3 -0
- package/dist/editors/editors.d.ts.map +1 -0
- package/dist/editors/editors.js +4 -0
- package/dist/editors/index.d.ts +1 -2
- package/dist/editors/index.d.ts.map +1 -1
- package/dist/editors/index.js +1 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/processors/vetra-builder-relational-db-processor/builder-team-handlers.d.ts +1 -1
- package/dist/processors/vetra-builder-relational-db-processor/builder-team-handlers.d.ts.map +1 -1
- package/dist/processors/vetra-builder-relational-db-processor/builder-team-handlers.js +1 -1
- package/dist/processors/vetra-builder-relational-db-processor/migrations.d.ts.map +1 -1
- package/dist/processors/vetra-builder-relational-db-processor/migrations.js +0 -3
- package/dist/scripts/add-builder-team-model.d.ts +2 -0
- package/dist/scripts/add-builder-team-model.d.ts.map +1 -0
- package/dist/scripts/add-builder-team-model.js +122 -0
- package/dist/scripts/create-remote-drives.d.ts +17 -0
- package/dist/scripts/create-remote-drives.d.ts.map +1 -0
- package/dist/scripts/create-remote-drives.js +946 -0
- package/dist/scripts/introspect-schema.d.ts +8 -0
- package/dist/scripts/introspect-schema.d.ts.map +1 -0
- package/dist/scripts/introspect-schema.js +216 -0
- package/dist/scripts/upload-to-drive.js +0 -2
- package/dist/style.css +8 -1
- package/dist/subgraphs/vetra-builders/resolvers.d.ts.map +1 -1
- package/dist/subgraphs/vetra-builders/resolvers.js +0 -1
- package/package.json +71 -54
|
@@ -0,0 +1,946 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Create Remote Drives from GitHub Repositories
|
|
4
|
+
*
|
|
5
|
+
* This script:
|
|
6
|
+
* 1. Fetches powerhouse.manifest.json from GitHub repositories
|
|
7
|
+
* 2. Creates remote drives at localhost:4001/graphql
|
|
8
|
+
* 3. Creates package documents in each drive with manifest data
|
|
9
|
+
* 4. Creates document model documents with full specifications
|
|
10
|
+
*
|
|
11
|
+
* Usage (from project root):
|
|
12
|
+
* npm run create-drives
|
|
13
|
+
* OR
|
|
14
|
+
* npx tsx scripts/create-remote-drives.ts
|
|
15
|
+
*/
|
|
16
|
+
import { generateId } from "document-model/core";
|
|
17
|
+
import { ReactorBuilder, MemoryStorage, InMemoryCache, SynchronizationManager, DefaultEventEmitter, EventQueueManager, ListenerManager, baseDocumentModels, } from "document-drive";
|
|
18
|
+
import * as documentModels from "../document-models/index.js";
|
|
19
|
+
import * as vetraDocumentModels from "@powerhousedao/vetra/document-models";
|
|
20
|
+
// List of GitHub repository URLs to process
|
|
21
|
+
const GITHUB_REPOS = [
|
|
22
|
+
// "https://github.com/powerhouse-inc/vetra-builder-package",
|
|
23
|
+
// "https://github.com/powerhouse-inc/network-admin",
|
|
24
|
+
// "https://github.com/powerhouse-inc/project-management",
|
|
25
|
+
// "https://github.com/powerhouse-inc/contributor-billing",
|
|
26
|
+
// "https://github.com/powerhouse-inc/effective-octo-adventure",
|
|
27
|
+
// "https://github.com/powerhouse-inc/renown-package",
|
|
28
|
+
"https://github.com/powerhouse-inc/chatroom-demo",
|
|
29
|
+
// Add more repository URLs here
|
|
30
|
+
];
|
|
31
|
+
// GraphQL endpoint
|
|
32
|
+
const GRAPHQL_ENDPOINT = "https://switchboard.vetra.io/graphql";
|
|
33
|
+
// const GRAPHQL_ENDPOINT = "http://localhost:4001/graphql";
|
|
34
|
+
/**
|
|
35
|
+
* Convert string to kebab-case
|
|
36
|
+
*/
|
|
37
|
+
function toKebabCase(str) {
|
|
38
|
+
return (str
|
|
39
|
+
// Insert hyphen before uppercase letters
|
|
40
|
+
.replace(/([a-z])([A-Z])/g, "$1-$2")
|
|
41
|
+
// Convert to lowercase
|
|
42
|
+
.toLowerCase()
|
|
43
|
+
// Replace spaces and other non-alphanumeric chars with hyphens
|
|
44
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
45
|
+
// Remove leading/trailing hyphens
|
|
46
|
+
.replace(/^-+|-+$/g, ""));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Fetch document model specs that exist in the repository
|
|
50
|
+
*/
|
|
51
|
+
async function fetchDocumentModelSpecs(repoUrl, documentModels) {
|
|
52
|
+
const results = [];
|
|
53
|
+
const seenSpecs = new Set();
|
|
54
|
+
// Try to fetch each document model JSON file
|
|
55
|
+
for (const model of documentModels) {
|
|
56
|
+
try {
|
|
57
|
+
// Convert model name to kebab-case for filename
|
|
58
|
+
const filename = toKebabCase(model.name);
|
|
59
|
+
const rawUrl = repoUrl
|
|
60
|
+
.replace("https://github.com/", "https://raw.githubusercontent.com/")
|
|
61
|
+
.replace(/\/$/, "") +
|
|
62
|
+
`/main/document-models/${filename}/${filename}.json`;
|
|
63
|
+
const response = await fetch(rawUrl);
|
|
64
|
+
if (response.ok) {
|
|
65
|
+
const spec = await response.json();
|
|
66
|
+
// Deduplicate by spec.id to avoid showing same model multiple times
|
|
67
|
+
if (!seenSpecs.has(spec.id)) {
|
|
68
|
+
seenSpecs.add(spec.id);
|
|
69
|
+
results.push({ id: spec.id, name: spec.name, spec });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
// Try master branch as fallback
|
|
74
|
+
const masterUrl = rawUrl.replace("/main/", "/master/");
|
|
75
|
+
const masterResponse = await fetch(masterUrl);
|
|
76
|
+
if (masterResponse.ok) {
|
|
77
|
+
const spec = await masterResponse.json();
|
|
78
|
+
if (!seenSpecs.has(spec.id)) {
|
|
79
|
+
seenSpecs.add(spec.id);
|
|
80
|
+
results.push({ id: spec.id, name: spec.name, spec });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
// Skip models that don't exist in this repo
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return results;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Fetch powerhouse.manifest.json from GitHub repository
|
|
94
|
+
*/
|
|
95
|
+
async function fetchManifest(repoUrl) {
|
|
96
|
+
// Convert GitHub URL to raw content URL
|
|
97
|
+
// https://github.com/user/repo -> https://raw.githubusercontent.com/user/repo/main/powerhouse.manifest.json
|
|
98
|
+
const rawUrl = repoUrl
|
|
99
|
+
.replace("https://github.com/", "https://raw.githubusercontent.com/")
|
|
100
|
+
.replace(/\/$/, "") + "/main/powerhouse.manifest.json";
|
|
101
|
+
console.log(`๐ฅ Fetching manifest from: ${rawUrl}`);
|
|
102
|
+
try {
|
|
103
|
+
const response = await fetch(rawUrl);
|
|
104
|
+
if (!response.ok) {
|
|
105
|
+
// Try with 'master' branch if 'main' fails
|
|
106
|
+
const masterUrl = rawUrl.replace("/main/", "/master/");
|
|
107
|
+
console.log(` โ Main branch failed, trying master: ${masterUrl}`);
|
|
108
|
+
const masterResponse = await fetch(masterUrl);
|
|
109
|
+
if (!masterResponse.ok) {
|
|
110
|
+
throw new Error(`Failed to fetch manifest: ${response.status} ${response.statusText}`);
|
|
111
|
+
}
|
|
112
|
+
const manifest = await masterResponse.json();
|
|
113
|
+
console.log(` โ Fetched manifest: ${manifest.name}`);
|
|
114
|
+
return manifest;
|
|
115
|
+
}
|
|
116
|
+
const manifest = await response.json();
|
|
117
|
+
console.log(` โ Fetched manifest: ${manifest.name}`);
|
|
118
|
+
return manifest;
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
console.error(` โ Error fetching manifest:`, error);
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Create a remote drive via GraphQL mutation (or skip if it already exists)
|
|
127
|
+
*/
|
|
128
|
+
async function createDrive(manifest, repoUrl) {
|
|
129
|
+
const driveName = manifest.name;
|
|
130
|
+
const driveId = toKebabCase(manifest.name);
|
|
131
|
+
const driveSlug = driveId;
|
|
132
|
+
console.log(`\n๐ Creating drive: ${driveName}`);
|
|
133
|
+
console.log(` ID: ${driveId}`);
|
|
134
|
+
console.log(` Slug: ${driveSlug}`);
|
|
135
|
+
const mutation = `
|
|
136
|
+
mutation AddDrive($id: String, $name: String!, $slug: String, $preferredEditor: String) {
|
|
137
|
+
addDrive(
|
|
138
|
+
id: $id
|
|
139
|
+
name: $name
|
|
140
|
+
slug: $slug
|
|
141
|
+
preferredEditor: $preferredEditor
|
|
142
|
+
) {
|
|
143
|
+
id
|
|
144
|
+
name
|
|
145
|
+
slug
|
|
146
|
+
preferredEditor
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
`;
|
|
150
|
+
const variables = {
|
|
151
|
+
id: driveId,
|
|
152
|
+
name: driveName,
|
|
153
|
+
slug: driveSlug,
|
|
154
|
+
preferredEditor: "vetra-drive-app",
|
|
155
|
+
};
|
|
156
|
+
try {
|
|
157
|
+
const response = await fetch(GRAPHQL_ENDPOINT, {
|
|
158
|
+
method: "POST",
|
|
159
|
+
headers: {
|
|
160
|
+
"Content-Type": "application/json",
|
|
161
|
+
},
|
|
162
|
+
body: JSON.stringify({
|
|
163
|
+
query: mutation,
|
|
164
|
+
variables,
|
|
165
|
+
}),
|
|
166
|
+
});
|
|
167
|
+
const result = await response.json();
|
|
168
|
+
if (result.errors) {
|
|
169
|
+
// Check if the error is about drive already existing
|
|
170
|
+
const alreadyExistsError = result.errors.find((err) => err.message?.includes("uses id that already exists"));
|
|
171
|
+
if (alreadyExistsError) {
|
|
172
|
+
console.log(` โน Drive already exists, skipping creation`);
|
|
173
|
+
return driveId;
|
|
174
|
+
}
|
|
175
|
+
console.error(` โ GraphQL errors:`, JSON.stringify(result.errors, null, 2));
|
|
176
|
+
throw new Error(`Failed to create drive: ${JSON.stringify(result.errors)}`);
|
|
177
|
+
}
|
|
178
|
+
const createdDrive = result.data?.addDrive;
|
|
179
|
+
console.log(` โ Drive created successfully`);
|
|
180
|
+
console.log(` ID: ${createdDrive.id}`);
|
|
181
|
+
console.log(` Name: ${createdDrive.name}`);
|
|
182
|
+
console.log(` Slug: ${createdDrive.slug}`);
|
|
183
|
+
return createdDrive.id;
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
console.error(` โ Error creating drive:`, error);
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Create a package document in the drive
|
|
192
|
+
*/
|
|
193
|
+
async function createPackageDocument(driveId, manifest, repoUrl) {
|
|
194
|
+
console.log(`\n๐ฆ Creating package document in drive: ${driveId}`);
|
|
195
|
+
// Using VetraPackage_createDocument mutation
|
|
196
|
+
const mutation = `
|
|
197
|
+
mutation VetraPackage_createDocument($driveId: String, $name: String) {
|
|
198
|
+
VetraPackage_createDocument(driveId: $driveId, name: $name)
|
|
199
|
+
}
|
|
200
|
+
`;
|
|
201
|
+
const variables = {
|
|
202
|
+
name: manifest.name,
|
|
203
|
+
driveId: driveId,
|
|
204
|
+
};
|
|
205
|
+
try {
|
|
206
|
+
const response = await fetch(GRAPHQL_ENDPOINT, {
|
|
207
|
+
method: "POST",
|
|
208
|
+
headers: {
|
|
209
|
+
"Content-Type": "application/json",
|
|
210
|
+
},
|
|
211
|
+
body: JSON.stringify({
|
|
212
|
+
query: mutation,
|
|
213
|
+
variables,
|
|
214
|
+
}),
|
|
215
|
+
});
|
|
216
|
+
const result = await response.json();
|
|
217
|
+
if (result.errors) {
|
|
218
|
+
console.error(` โ GraphQL errors:`, JSON.stringify(result.errors, null, 2));
|
|
219
|
+
throw new Error(`Failed to create package document: ${JSON.stringify(result.errors)}`);
|
|
220
|
+
}
|
|
221
|
+
const documentId = result.data?.VetraPackage_createDocument;
|
|
222
|
+
console.log(` โ Package document created`);
|
|
223
|
+
console.log(` Document ID (PHID): ${documentId}`);
|
|
224
|
+
return documentId;
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
console.error(` โ Error creating package document:`, error);
|
|
228
|
+
throw error;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Create an editor document in the drive
|
|
233
|
+
*/
|
|
234
|
+
async function createEditorDocument(driveId, editor) {
|
|
235
|
+
// Create the editor document
|
|
236
|
+
const createMutation = `
|
|
237
|
+
mutation DocumentEditor_createDocument($driveId: String, $name: String!) {
|
|
238
|
+
DocumentEditor_createDocument(driveId: $driveId, name: $name)
|
|
239
|
+
}
|
|
240
|
+
`;
|
|
241
|
+
const createResponse = await fetch(GRAPHQL_ENDPOINT, {
|
|
242
|
+
method: "POST",
|
|
243
|
+
headers: {
|
|
244
|
+
"Content-Type": "application/json",
|
|
245
|
+
},
|
|
246
|
+
body: JSON.stringify({
|
|
247
|
+
query: createMutation,
|
|
248
|
+
variables: {
|
|
249
|
+
driveId,
|
|
250
|
+
name: editor.name,
|
|
251
|
+
},
|
|
252
|
+
}),
|
|
253
|
+
});
|
|
254
|
+
const createResult = await createResponse.json();
|
|
255
|
+
if (createResult.errors) {
|
|
256
|
+
throw new Error(`Failed to create editor: ${JSON.stringify(createResult.errors)}`);
|
|
257
|
+
}
|
|
258
|
+
const documentId = createResult.data?.DocumentEditor_createDocument;
|
|
259
|
+
// Set editor name (using ID as fallback)
|
|
260
|
+
const setNameMutation = `
|
|
261
|
+
mutation DocumentEditor_setEditorName($driveId: String, $docId: PHID, $input: DocumentEditor_SetEditorNameInput) {
|
|
262
|
+
DocumentEditor_setEditorName(driveId: $driveId, docId: $docId, input: $input)
|
|
263
|
+
}
|
|
264
|
+
`;
|
|
265
|
+
await fetch(GRAPHQL_ENDPOINT, {
|
|
266
|
+
method: "POST",
|
|
267
|
+
headers: {
|
|
268
|
+
"Content-Type": "application/json",
|
|
269
|
+
},
|
|
270
|
+
body: JSON.stringify({
|
|
271
|
+
query: setNameMutation,
|
|
272
|
+
variables: {
|
|
273
|
+
driveId,
|
|
274
|
+
docId: documentId,
|
|
275
|
+
input: { name: editor.id },
|
|
276
|
+
},
|
|
277
|
+
}),
|
|
278
|
+
});
|
|
279
|
+
// Add document types
|
|
280
|
+
for (const docType of editor.documentTypes) {
|
|
281
|
+
const addTypeMutation = `
|
|
282
|
+
mutation DocumentEditor_addDocumentType($driveId: String, $docId: PHID, $input: DocumentEditor_AddDocumentTypeInput) {
|
|
283
|
+
DocumentEditor_addDocumentType(driveId: $driveId, docId: $docId, input: $input)
|
|
284
|
+
}
|
|
285
|
+
`;
|
|
286
|
+
await fetch(GRAPHQL_ENDPOINT, {
|
|
287
|
+
method: "POST",
|
|
288
|
+
headers: {
|
|
289
|
+
"Content-Type": "application/json",
|
|
290
|
+
},
|
|
291
|
+
body: JSON.stringify({
|
|
292
|
+
query: addTypeMutation,
|
|
293
|
+
variables: {
|
|
294
|
+
driveId,
|
|
295
|
+
docId: documentId,
|
|
296
|
+
input: { documentType: docType },
|
|
297
|
+
},
|
|
298
|
+
}),
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
return documentId;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Create a subgraph document in the drive
|
|
305
|
+
*/
|
|
306
|
+
async function createSubgraphDocument(driveId, subgraph) {
|
|
307
|
+
// Create the subgraph document
|
|
308
|
+
const createMutation = `
|
|
309
|
+
mutation SubgraphModule_createDocument($driveId: String, $name: String!) {
|
|
310
|
+
SubgraphModule_createDocument(driveId: $driveId, name: $name)
|
|
311
|
+
}
|
|
312
|
+
`;
|
|
313
|
+
const createResponse = await fetch(GRAPHQL_ENDPOINT, {
|
|
314
|
+
method: "POST",
|
|
315
|
+
headers: {
|
|
316
|
+
"Content-Type": "application/json",
|
|
317
|
+
},
|
|
318
|
+
body: JSON.stringify({
|
|
319
|
+
query: createMutation,
|
|
320
|
+
variables: {
|
|
321
|
+
driveId,
|
|
322
|
+
name: subgraph.name,
|
|
323
|
+
},
|
|
324
|
+
}),
|
|
325
|
+
});
|
|
326
|
+
const createResult = await createResponse.json();
|
|
327
|
+
if (createResult.errors) {
|
|
328
|
+
throw new Error(`Failed to create subgraph: ${JSON.stringify(createResult.errors)}`);
|
|
329
|
+
}
|
|
330
|
+
const documentId = createResult.data?.SubgraphModule_createDocument;
|
|
331
|
+
// Set subgraph name (using ID)
|
|
332
|
+
const setNameMutation = `
|
|
333
|
+
mutation SubgraphModule_setSubgraphName($driveId: String, $docId: PHID, $input: SubgraphModule_SetSubgraphNameInput) {
|
|
334
|
+
SubgraphModule_setSubgraphName(driveId: $driveId, docId: $docId, input: $input)
|
|
335
|
+
}
|
|
336
|
+
`;
|
|
337
|
+
await fetch(GRAPHQL_ENDPOINT, {
|
|
338
|
+
method: "POST",
|
|
339
|
+
headers: {
|
|
340
|
+
"Content-Type": "application/json",
|
|
341
|
+
},
|
|
342
|
+
body: JSON.stringify({
|
|
343
|
+
query: setNameMutation,
|
|
344
|
+
variables: {
|
|
345
|
+
driveId,
|
|
346
|
+
docId: documentId,
|
|
347
|
+
input: { name: subgraph.id },
|
|
348
|
+
},
|
|
349
|
+
}),
|
|
350
|
+
});
|
|
351
|
+
return documentId;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Retry with exponential backoff
|
|
355
|
+
*/
|
|
356
|
+
async function retryWithBackoff(fn, maxRetries = 3, baseDelay = 1000) {
|
|
357
|
+
let lastError;
|
|
358
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
359
|
+
try {
|
|
360
|
+
return await fn();
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
lastError = error;
|
|
364
|
+
if (attempt < maxRetries - 1) {
|
|
365
|
+
const delay = baseDelay * Math.pow(2, attempt);
|
|
366
|
+
console.log(` โ Attempt ${attempt + 1} failed, retrying in ${delay}ms...`);
|
|
367
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
throw lastError;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Wait for sync to complete by checking drive state
|
|
375
|
+
*/
|
|
376
|
+
async function waitForSync(driveServer, driveId, timeout = 15000) {
|
|
377
|
+
const startTime = Date.now();
|
|
378
|
+
while (Date.now() - startTime < timeout) {
|
|
379
|
+
try {
|
|
380
|
+
// Try to get the drive - if it succeeds, sync is complete
|
|
381
|
+
await driveServer.getDrive(driveId);
|
|
382
|
+
// Add an additional small delay after drive is accessible
|
|
383
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
catch (error) {
|
|
387
|
+
// Drive not ready yet, wait a bit
|
|
388
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
throw new Error(`Sync timeout after ${timeout}ms`);
|
|
392
|
+
}
|
|
393
|
+
// Shared drive server instance
|
|
394
|
+
let sharedDriveServer = null;
|
|
395
|
+
/**
|
|
396
|
+
* Get or create the shared drive server instance
|
|
397
|
+
*/
|
|
398
|
+
async function getSharedDriveServer() {
|
|
399
|
+
if (!sharedDriveServer) {
|
|
400
|
+
const allDocumentModels = [
|
|
401
|
+
...baseDocumentModels,
|
|
402
|
+
...Object.values(documentModels),
|
|
403
|
+
...Object.values(vetraDocumentModels),
|
|
404
|
+
];
|
|
405
|
+
sharedDriveServer = new ReactorBuilder(allDocumentModels).build();
|
|
406
|
+
await sharedDriveServer.initialize();
|
|
407
|
+
}
|
|
408
|
+
return sharedDriveServer;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Cleanup the shared drive server
|
|
412
|
+
*/
|
|
413
|
+
async function cleanupSharedDriveServer() {
|
|
414
|
+
if (sharedDriveServer) {
|
|
415
|
+
if (typeof sharedDriveServer.shutdown === "function") {
|
|
416
|
+
await sharedDriveServer.shutdown();
|
|
417
|
+
}
|
|
418
|
+
sharedDriveServer = null;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Register remote drive with local drive server to enable processors
|
|
423
|
+
*/
|
|
424
|
+
async function registerRemoteDrive(driveId) {
|
|
425
|
+
const SWITCHBOARD_URL = "https://switchboard.vetra.io";
|
|
426
|
+
const remoteDriveUrl = `${SWITCHBOARD_URL}/d/${driveId}`;
|
|
427
|
+
// Get shared drive server
|
|
428
|
+
const driveServer = await getSharedDriveServer();
|
|
429
|
+
// Add remote drive (with retry logic)
|
|
430
|
+
await retryWithBackoff(async () => {
|
|
431
|
+
try {
|
|
432
|
+
// Check if drive already exists
|
|
433
|
+
await driveServer.getDrive(driveId);
|
|
434
|
+
console.log(` โ Drive ${driveId} already registered in local server`);
|
|
435
|
+
}
|
|
436
|
+
catch (error) {
|
|
437
|
+
// Drive doesn't exist, add it
|
|
438
|
+
console.log(` ๐ก Registering remote drive: ${remoteDriveUrl}`);
|
|
439
|
+
try {
|
|
440
|
+
await driveServer.addRemoteDrive(remoteDriveUrl, {
|
|
441
|
+
availableOffline: true,
|
|
442
|
+
listeners: [
|
|
443
|
+
{
|
|
444
|
+
block: true,
|
|
445
|
+
callInfo: {
|
|
446
|
+
data: remoteDriveUrl,
|
|
447
|
+
name: "switchboard-push",
|
|
448
|
+
transmitterType: "SwitchboardPush",
|
|
449
|
+
},
|
|
450
|
+
filter: {
|
|
451
|
+
branch: ["main"],
|
|
452
|
+
documentId: ["*"],
|
|
453
|
+
documentType: ["*"],
|
|
454
|
+
scope: ["global"],
|
|
455
|
+
},
|
|
456
|
+
listenerId: generateId(),
|
|
457
|
+
label: "Switchboard Sync",
|
|
458
|
+
system: true,
|
|
459
|
+
},
|
|
460
|
+
],
|
|
461
|
+
sharingType: "public",
|
|
462
|
+
triggers: [],
|
|
463
|
+
});
|
|
464
|
+
// Wait for initial sync
|
|
465
|
+
console.log(` โณ Waiting for drive sync...`);
|
|
466
|
+
await waitForSync(driveServer, driveId);
|
|
467
|
+
console.log(` โ Drive registered and synced`);
|
|
468
|
+
}
|
|
469
|
+
catch (syncError) {
|
|
470
|
+
// If sync fails, it might be because the drive is still being created on remote
|
|
471
|
+
console.log(` โ Sync warning (may be expected):`, syncError instanceof Error ? syncError.message : String(syncError));
|
|
472
|
+
// Give it a moment and try to get the drive anyway
|
|
473
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}, 5, 1000);
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Create document model document using drive server sync approach
|
|
480
|
+
* Steps:
|
|
481
|
+
* 1. Use shared drive server with ALL document models loaded
|
|
482
|
+
* 2. Add remote drive for synchronization (if not already added)
|
|
483
|
+
* 3. Wait for syncing to complete
|
|
484
|
+
* 4. Create new document
|
|
485
|
+
* 5. Add operations to populate document
|
|
486
|
+
* 6. Wait for operations to sync
|
|
487
|
+
*/
|
|
488
|
+
async function createDocumentModelDocumentViaDriveServer(driveId, name, spec) {
|
|
489
|
+
const SWITCHBOARD_URL = "http://localhost:4001";
|
|
490
|
+
const remoteDriveUrl = `${SWITCHBOARD_URL}/d/${driveId}`;
|
|
491
|
+
// Step 1: Get shared drive server
|
|
492
|
+
const driveServer = await getSharedDriveServer();
|
|
493
|
+
// Step 2: Add remote drive (with retry logic)
|
|
494
|
+
await retryWithBackoff(async () => {
|
|
495
|
+
try {
|
|
496
|
+
// Check if drive already exists
|
|
497
|
+
await driveServer.getDrive(driveId);
|
|
498
|
+
console.log(` โ Drive ${driveId} already exists in local server`);
|
|
499
|
+
}
|
|
500
|
+
catch (error) {
|
|
501
|
+
// Drive doesn't exist, add it
|
|
502
|
+
console.log(` ๐ก Adding remote drive: ${remoteDriveUrl}`);
|
|
503
|
+
try {
|
|
504
|
+
await driveServer.addRemoteDrive(remoteDriveUrl, {
|
|
505
|
+
availableOffline: true,
|
|
506
|
+
listeners: [
|
|
507
|
+
{
|
|
508
|
+
block: true,
|
|
509
|
+
callInfo: {
|
|
510
|
+
data: remoteDriveUrl,
|
|
511
|
+
name: "switchboard-push",
|
|
512
|
+
transmitterType: "SwitchboardPush",
|
|
513
|
+
},
|
|
514
|
+
filter: {
|
|
515
|
+
branch: ["main"],
|
|
516
|
+
documentId: ["*"],
|
|
517
|
+
documentType: ["*"],
|
|
518
|
+
scope: ["global"],
|
|
519
|
+
},
|
|
520
|
+
listenerId: generateId(),
|
|
521
|
+
label: "Switchboard Sync",
|
|
522
|
+
system: true,
|
|
523
|
+
},
|
|
524
|
+
],
|
|
525
|
+
sharingType: "public",
|
|
526
|
+
triggers: [],
|
|
527
|
+
});
|
|
528
|
+
// Step 3: Wait for initial sync
|
|
529
|
+
console.log(` โณ Waiting for initial sync...`);
|
|
530
|
+
await waitForSync(driveServer, driveId);
|
|
531
|
+
console.log(` โ Sync complete`);
|
|
532
|
+
}
|
|
533
|
+
catch (syncError) {
|
|
534
|
+
// If sync fails, it might be because the drive is still being created on remote
|
|
535
|
+
console.log(` โ Sync warning (may be expected):`, syncError instanceof Error ? syncError.message : String(syncError));
|
|
536
|
+
// Give it a moment and try to get the drive anyway
|
|
537
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}, 5, 1000);
|
|
541
|
+
// Step 4: Create new document (with retry)
|
|
542
|
+
const createResult = await retryWithBackoff(async () => {
|
|
543
|
+
return await driveServer.createDocument({
|
|
544
|
+
driveId,
|
|
545
|
+
documentType: "powerhouse/document-model",
|
|
546
|
+
name,
|
|
547
|
+
// Don't pass id - let it be auto-generated with signed header
|
|
548
|
+
});
|
|
549
|
+
});
|
|
550
|
+
const documentId = createResult.documentId || createResult.id || createResult;
|
|
551
|
+
// Small delay to let document creation propagate
|
|
552
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
553
|
+
// Step 5: Add operations from spec to populate the document
|
|
554
|
+
if (spec.specifications && spec.specifications.length > 0) {
|
|
555
|
+
const specification = spec.specifications[0];
|
|
556
|
+
const actions = [];
|
|
557
|
+
// Add basic metadata
|
|
558
|
+
actions.push({ type: "SET_MODEL_NAME", input: { name: spec.name } });
|
|
559
|
+
actions.push({ type: "SET_MODEL_ID", input: { id: spec.id } });
|
|
560
|
+
actions.push({
|
|
561
|
+
type: "SET_MODEL_EXTENSION",
|
|
562
|
+
input: { extension: spec.extension },
|
|
563
|
+
});
|
|
564
|
+
actions.push({
|
|
565
|
+
type: "SET_MODEL_DESCRIPTION",
|
|
566
|
+
input: { description: spec.description },
|
|
567
|
+
});
|
|
568
|
+
actions.push({
|
|
569
|
+
type: "SET_AUTHOR_NAME",
|
|
570
|
+
input: { name: spec.author.name },
|
|
571
|
+
});
|
|
572
|
+
actions.push({
|
|
573
|
+
type: "SET_AUTHOR_WEBSITE",
|
|
574
|
+
input: { website: spec.author.website },
|
|
575
|
+
});
|
|
576
|
+
// Add state schema
|
|
577
|
+
if (specification.state?.global?.schema) {
|
|
578
|
+
actions.push({
|
|
579
|
+
type: "SET_STATE_SCHEMA",
|
|
580
|
+
input: {
|
|
581
|
+
schema: specification.state.global.schema,
|
|
582
|
+
scope: "global",
|
|
583
|
+
},
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
if (specification.state?.global?.initialValue) {
|
|
587
|
+
actions.push({
|
|
588
|
+
type: "SET_INITIAL_STATE",
|
|
589
|
+
input: {
|
|
590
|
+
initialValue: specification.state.global.initialValue,
|
|
591
|
+
scope: "global",
|
|
592
|
+
},
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
// Add modules and operations
|
|
596
|
+
if (specification.modules) {
|
|
597
|
+
for (const module of specification.modules) {
|
|
598
|
+
actions.push({
|
|
599
|
+
type: "ADD_MODULE",
|
|
600
|
+
input: {
|
|
601
|
+
id: module.id,
|
|
602
|
+
name: module.name,
|
|
603
|
+
description: module.description || "",
|
|
604
|
+
},
|
|
605
|
+
});
|
|
606
|
+
if (module.operations) {
|
|
607
|
+
for (const operation of module.operations) {
|
|
608
|
+
actions.push({
|
|
609
|
+
type: "ADD_OPERATION",
|
|
610
|
+
input: {
|
|
611
|
+
id: operation.id,
|
|
612
|
+
moduleId: module.id,
|
|
613
|
+
name: operation.name,
|
|
614
|
+
description: operation.description || "",
|
|
615
|
+
scope: operation.scope,
|
|
616
|
+
},
|
|
617
|
+
});
|
|
618
|
+
if (operation.schema) {
|
|
619
|
+
actions.push({
|
|
620
|
+
type: "SET_OPERATION_SCHEMA",
|
|
621
|
+
input: {
|
|
622
|
+
id: operation.id,
|
|
623
|
+
schema: operation.schema,
|
|
624
|
+
},
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
if (operation.reducer) {
|
|
628
|
+
actions.push({
|
|
629
|
+
type: "SET_OPERATION_REDUCER",
|
|
630
|
+
input: {
|
|
631
|
+
id: operation.id,
|
|
632
|
+
reducer: operation.reducer,
|
|
633
|
+
},
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
// Apply all actions (with retry)
|
|
641
|
+
await retryWithBackoff(async () => {
|
|
642
|
+
await driveServer.addActions(documentId, actions);
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
// Step 6: Wait for operations to sync (increased delay for large documents)
|
|
646
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
647
|
+
return documentId;
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Create a processor document in the drive
|
|
651
|
+
*/
|
|
652
|
+
async function createProcessorDocument(driveId, processor) {
|
|
653
|
+
// Create the processor document
|
|
654
|
+
const createMutation = `
|
|
655
|
+
mutation ProcessorModule_createDocument($driveId: String, $name: String!) {
|
|
656
|
+
ProcessorModule_createDocument(driveId: $driveId, name: $name)
|
|
657
|
+
}
|
|
658
|
+
`;
|
|
659
|
+
const createResponse = await fetch(GRAPHQL_ENDPOINT, {
|
|
660
|
+
method: "POST",
|
|
661
|
+
headers: {
|
|
662
|
+
"Content-Type": "application/json",
|
|
663
|
+
},
|
|
664
|
+
body: JSON.stringify({
|
|
665
|
+
query: createMutation,
|
|
666
|
+
variables: {
|
|
667
|
+
driveId,
|
|
668
|
+
name: processor.name,
|
|
669
|
+
},
|
|
670
|
+
}),
|
|
671
|
+
});
|
|
672
|
+
const createResult = await createResponse.json();
|
|
673
|
+
if (createResult.errors) {
|
|
674
|
+
throw new Error(`Failed to create processor: ${JSON.stringify(createResult.errors)}`);
|
|
675
|
+
}
|
|
676
|
+
const documentId = createResult.data?.ProcessorModule_createDocument;
|
|
677
|
+
// Set processor name (using ID)
|
|
678
|
+
const setNameMutation = `
|
|
679
|
+
mutation ProcessorModule_setProcessorName($driveId: String, $docId: PHID, $input: ProcessorModule_SetProcessorNameInput) {
|
|
680
|
+
ProcessorModule_setProcessorName(driveId: $driveId, docId: $docId, input: $input)
|
|
681
|
+
}
|
|
682
|
+
`;
|
|
683
|
+
await fetch(GRAPHQL_ENDPOINT, {
|
|
684
|
+
method: "POST",
|
|
685
|
+
headers: {
|
|
686
|
+
"Content-Type": "application/json",
|
|
687
|
+
},
|
|
688
|
+
body: JSON.stringify({
|
|
689
|
+
query: setNameMutation,
|
|
690
|
+
variables: {
|
|
691
|
+
driveId,
|
|
692
|
+
docId: documentId,
|
|
693
|
+
input: { name: processor.id },
|
|
694
|
+
},
|
|
695
|
+
}),
|
|
696
|
+
});
|
|
697
|
+
// Add document types
|
|
698
|
+
for (const docType of processor.documentTypes) {
|
|
699
|
+
const addTypeMutation = `
|
|
700
|
+
mutation ProcessorModule_addDocumentType($driveId: String, $docId: PHID, $input: ProcessorModule_AddDocumentTypeInput) {
|
|
701
|
+
ProcessorModule_addDocumentType(driveId: $driveId, docId: $docId, input: $input)
|
|
702
|
+
}
|
|
703
|
+
`;
|
|
704
|
+
await fetch(GRAPHQL_ENDPOINT, {
|
|
705
|
+
method: "POST",
|
|
706
|
+
headers: {
|
|
707
|
+
"Content-Type": "application/json",
|
|
708
|
+
},
|
|
709
|
+
body: JSON.stringify({
|
|
710
|
+
query: addTypeMutation,
|
|
711
|
+
variables: {
|
|
712
|
+
driveId,
|
|
713
|
+
docId: documentId,
|
|
714
|
+
input: { documentType: docType },
|
|
715
|
+
},
|
|
716
|
+
}),
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
return documentId;
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Set package document fields via GraphQL mutations
|
|
723
|
+
*/
|
|
724
|
+
async function updatePackageDocument(driveId, documentId, manifest, repoUrl) {
|
|
725
|
+
console.log(`\nโ๏ธ Updating package document fields...`);
|
|
726
|
+
// Set basic package info
|
|
727
|
+
const operations = [
|
|
728
|
+
{
|
|
729
|
+
name: "SET_PACKAGE_NAME",
|
|
730
|
+
mutation: "VetraPackage_setPackageName",
|
|
731
|
+
input: { name: manifest.name },
|
|
732
|
+
},
|
|
733
|
+
{
|
|
734
|
+
name: "SET_PACKAGE_DESCRIPTION",
|
|
735
|
+
mutation: "VetraPackage_setPackageDescription",
|
|
736
|
+
input: { description: manifest.description },
|
|
737
|
+
},
|
|
738
|
+
{
|
|
739
|
+
name: "SET_PACKAGE_CATEGORY",
|
|
740
|
+
mutation: "VetraPackage_setPackageCategory",
|
|
741
|
+
input: { category: manifest.category },
|
|
742
|
+
},
|
|
743
|
+
{
|
|
744
|
+
name: "SET_PACKAGE_AUTHOR",
|
|
745
|
+
mutation: "VetraPackage_setPackageAuthor",
|
|
746
|
+
input: {
|
|
747
|
+
name: manifest.publisher.name,
|
|
748
|
+
website: manifest.publisher.url,
|
|
749
|
+
},
|
|
750
|
+
},
|
|
751
|
+
{
|
|
752
|
+
name: "SET_PACKAGE_GITHUB_URL",
|
|
753
|
+
mutation: "VetraPackage_setPackageGithubUrl",
|
|
754
|
+
input: { url: repoUrl },
|
|
755
|
+
},
|
|
756
|
+
];
|
|
757
|
+
// Add npm URL if available
|
|
758
|
+
if (manifest.npmUrl) {
|
|
759
|
+
operations.push({
|
|
760
|
+
name: "SET_PACKAGE_NPM_URL",
|
|
761
|
+
mutation: "VetraPackage_setPackageNpmUrl",
|
|
762
|
+
input: { url: manifest.npmUrl },
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
for (const op of operations) {
|
|
766
|
+
try {
|
|
767
|
+
const mutation = `
|
|
768
|
+
mutation Update($driveId: String, $docId: PHID, $input: VetraPackage_${op.name
|
|
769
|
+
.split("_")
|
|
770
|
+
.map((p) => p.charAt(0) + p.slice(1).toLowerCase())
|
|
771
|
+
.join("")}Input) {
|
|
772
|
+
${op.mutation}(driveId: $driveId, docId: $docId, input: $input)
|
|
773
|
+
}
|
|
774
|
+
`;
|
|
775
|
+
const variables = {
|
|
776
|
+
driveId,
|
|
777
|
+
docId: documentId,
|
|
778
|
+
input: op.input,
|
|
779
|
+
};
|
|
780
|
+
const response = await fetch(GRAPHQL_ENDPOINT, {
|
|
781
|
+
method: "POST",
|
|
782
|
+
headers: {
|
|
783
|
+
"Content-Type": "application/json",
|
|
784
|
+
},
|
|
785
|
+
body: JSON.stringify({
|
|
786
|
+
query: mutation,
|
|
787
|
+
variables,
|
|
788
|
+
}),
|
|
789
|
+
});
|
|
790
|
+
const result = await response.json();
|
|
791
|
+
if (result.errors) {
|
|
792
|
+
console.log(` โ Skipping ${op.name}: ${result.errors[0]?.message}`);
|
|
793
|
+
}
|
|
794
|
+
else {
|
|
795
|
+
console.log(` โ ${op.name}`);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
catch (error) {
|
|
799
|
+
console.log(` โ Skipping ${op.name}: ${error instanceof Error ? error.message : String(error)}`);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
// Create editor documents
|
|
803
|
+
if (manifest.editors && manifest.editors.length > 0) {
|
|
804
|
+
console.log(`\n ๐ Creating ${manifest.editors.length} editor documents...`);
|
|
805
|
+
for (let i = 0; i < manifest.editors.length; i++) {
|
|
806
|
+
const editor = manifest.editors[i];
|
|
807
|
+
try {
|
|
808
|
+
await createEditorDocument(driveId, editor);
|
|
809
|
+
console.log(` โ ${editor.name}`);
|
|
810
|
+
// Add delay between editor creations (except after the last one)
|
|
811
|
+
if (i < manifest.editors.length - 1) {
|
|
812
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
catch (error) {
|
|
816
|
+
console.log(` โ Failed to create ${editor.name}: ${error instanceof Error ? error.message : String(error)}`);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
// Create subgraph documents
|
|
821
|
+
if (manifest.subgraphs && manifest.subgraphs.length > 0) {
|
|
822
|
+
console.log(`\n ๐ Creating ${manifest.subgraphs.length} subgraph documents...`);
|
|
823
|
+
for (const subgraph of manifest.subgraphs) {
|
|
824
|
+
try {
|
|
825
|
+
await createSubgraphDocument(driveId, subgraph);
|
|
826
|
+
console.log(` โ ${subgraph.name}`);
|
|
827
|
+
}
|
|
828
|
+
catch (error) {
|
|
829
|
+
console.log(` โ Failed to create ${subgraph.name}: ${error instanceof Error ? error.message : String(error)}`);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
// Create processor documents
|
|
834
|
+
if (manifest.processors && manifest.processors.length > 0) {
|
|
835
|
+
console.log(`\n โ๏ธ Creating ${manifest.processors.length} processor documents...`);
|
|
836
|
+
for (const processor of manifest.processors) {
|
|
837
|
+
try {
|
|
838
|
+
await createProcessorDocument(driveId, processor);
|
|
839
|
+
console.log(` โ ${processor.name}`);
|
|
840
|
+
}
|
|
841
|
+
catch (error) {
|
|
842
|
+
console.log(` โ Failed to create ${processor.name}: ${error instanceof Error ? error.message : String(error)}`);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
// Create document model documents using drive server sync
|
|
847
|
+
if (manifest.documentModels && manifest.documentModels.length > 0) {
|
|
848
|
+
console.log(`\n ๐ Fetching document model specifications from repository...`);
|
|
849
|
+
const documentModelSpecs = await fetchDocumentModelSpecs(repoUrl, manifest.documentModels);
|
|
850
|
+
if (documentModelSpecs.length > 0) {
|
|
851
|
+
console.log(` Found ${documentModelSpecs.length} document model(s) in this repository`);
|
|
852
|
+
console.log(`\n ๐ Creating document model documents...`);
|
|
853
|
+
for (let i = 0; i < documentModelSpecs.length; i++) {
|
|
854
|
+
const { id, name, spec } = documentModelSpecs[i];
|
|
855
|
+
try {
|
|
856
|
+
await createDocumentModelDocumentViaDriveServer(driveId, name, spec);
|
|
857
|
+
const version = spec.specifications?.[0]?.version || "unknown";
|
|
858
|
+
const modulesCount = spec.specifications?.[0]?.modules?.length || 0;
|
|
859
|
+
const operationsCount = spec.specifications?.[0]?.modules?.reduce((total, mod) => total + (mod.operations?.length || 0), 0) || 0;
|
|
860
|
+
console.log(` โ ${name} (v${version}) - ${modulesCount} modules, ${operationsCount} operations`);
|
|
861
|
+
// Add delay between document model creations (except after the last one)
|
|
862
|
+
if (i < documentModelSpecs.length - 1) {
|
|
863
|
+
console.log(` โฑ Waiting before next document model...`);
|
|
864
|
+
await new Promise((resolve) => setTimeout(resolve, 1500));
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
catch (error) {
|
|
868
|
+
console.log(` โ Failed to create ${name}: ${error instanceof Error ? error.message : String(error)}`);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
else {
|
|
873
|
+
console.log(` โ No document model files found in this repository`);
|
|
874
|
+
console.log(` Listed in manifest: ${manifest.documentModels
|
|
875
|
+
.map((m) => m.name)
|
|
876
|
+
.join(", ")}`);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* Process a single repository
|
|
882
|
+
*/
|
|
883
|
+
async function processRepository(repoUrl) {
|
|
884
|
+
console.log(`\n${"=".repeat(80)}`);
|
|
885
|
+
console.log(`Processing: ${repoUrl}`);
|
|
886
|
+
console.log("=".repeat(80));
|
|
887
|
+
try {
|
|
888
|
+
// Step 1: Fetch manifest
|
|
889
|
+
const manifest = await fetchManifest(repoUrl);
|
|
890
|
+
// Step 2: Create drive
|
|
891
|
+
const driveId = await createDrive(manifest, repoUrl);
|
|
892
|
+
// Step 2.5: Register drive with local server to enable processors
|
|
893
|
+
console.log(`\n๐ Registering drive to enable processors...`);
|
|
894
|
+
await registerRemoteDrive(driveId);
|
|
895
|
+
// Step 3: Create package document
|
|
896
|
+
const documentId = await createPackageDocument(driveId, manifest, repoUrl);
|
|
897
|
+
// Step 4: Update package document with manifest data
|
|
898
|
+
await updatePackageDocument(driveId, documentId, manifest, repoUrl);
|
|
899
|
+
console.log(`\nโ
Successfully processed: ${manifest.name}`);
|
|
900
|
+
console.log(` Drive ID: ${driveId}`);
|
|
901
|
+
console.log(` Document ID: ${documentId}`);
|
|
902
|
+
console.log(` Drive URL: http://localhost:4001/d/${driveId}`);
|
|
903
|
+
}
|
|
904
|
+
catch (error) {
|
|
905
|
+
console.error(`\nโ Failed to process ${repoUrl}:`, error);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
/**
|
|
909
|
+
* Main function
|
|
910
|
+
*/
|
|
911
|
+
async function main() {
|
|
912
|
+
console.log("=== Create Remote Drives from GitHub Repositories ===");
|
|
913
|
+
console.log(`GraphQL Endpoint: ${GRAPHQL_ENDPOINT}`);
|
|
914
|
+
console.log(`Repositories to process: ${GITHUB_REPOS.length}`);
|
|
915
|
+
let successCount = 0;
|
|
916
|
+
let errorCount = 0;
|
|
917
|
+
try {
|
|
918
|
+
for (const repoUrl of GITHUB_REPOS) {
|
|
919
|
+
try {
|
|
920
|
+
await processRepository(repoUrl);
|
|
921
|
+
successCount++;
|
|
922
|
+
}
|
|
923
|
+
catch (error) {
|
|
924
|
+
errorCount++;
|
|
925
|
+
console.error(`Error processing ${repoUrl}:`, error);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
console.log(`\n${"=".repeat(80)}`);
|
|
929
|
+
console.log("=== Summary ===");
|
|
930
|
+
console.log(`Total repositories: ${GITHUB_REPOS.length}`);
|
|
931
|
+
console.log(`โ Success: ${successCount}`);
|
|
932
|
+
console.log(`โ Errors: ${errorCount}`);
|
|
933
|
+
console.log("=".repeat(80));
|
|
934
|
+
}
|
|
935
|
+
finally {
|
|
936
|
+
// Cleanup shared drive server
|
|
937
|
+
console.log("\n๐งน Cleaning up shared drive server...");
|
|
938
|
+
await cleanupSharedDriveServer();
|
|
939
|
+
console.log("โ Cleanup complete");
|
|
940
|
+
}
|
|
941
|
+
if (errorCount > 0) {
|
|
942
|
+
process.exit(1);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
// Run the script
|
|
946
|
+
main().catch(console.error);
|