@powerhousedao/vetra-builder-package 0.0.4 → 0.0.6

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.
@@ -1,11 +1,16 @@
1
- import { generateId } from "document-model";
1
+ import { toPascalCase } from "document-drive/utils/misc";
2
2
  export const reducer = {
3
3
  addPackageOperation(state, action, dispatch) {
4
4
  const { spaceId } = action.input;
5
- const packageId = generateId();
6
- state.spaces
7
- .find((space) => space.id === spaceId)
8
- ?.packages.push({
5
+ const packageId = spaceId + "-" + toPascalCase(action.input.name);
6
+ // Find the space index
7
+ const spaceIndex = state.spaces.findIndex((space) => space.id === spaceId);
8
+ if (spaceIndex === -1) {
9
+ console.warn(`Space with id ${spaceId} not found`);
10
+ return;
11
+ }
12
+ // Create the new package
13
+ const newPackage = {
9
14
  id: packageId,
10
15
  ...action.input,
11
16
  category: action.input.category ?? "",
@@ -24,11 +29,22 @@ export const reducer = {
24
29
  },
25
30
  keywords: action.input.keywords?.map((keyword) => {
26
31
  return {
27
- id: generateId(),
32
+ id: keyword,
28
33
  label: keyword,
29
34
  };
30
35
  }) ?? [],
31
- });
36
+ };
37
+ // Create new space with the package added
38
+ const updatedSpace = {
39
+ ...state.spaces[spaceIndex],
40
+ packages: [...state.spaces[spaceIndex].packages, newPackage],
41
+ };
42
+ // Replace the space in state
43
+ state.spaces = [
44
+ ...state.spaces.slice(0, spaceIndex),
45
+ updatedSpace,
46
+ ...state.spaces.slice(spaceIndex + 1),
47
+ ];
32
48
  },
33
49
  setPackageDriveIdOperation(state, action, dispatch) {
34
50
  const { packageId, driveId } = action.input;
@@ -56,17 +72,29 @@ export const reducer = {
56
72
  const { ids, insertAfter, spaceId } = action.input;
57
73
  for (const space of state.spaces) {
58
74
  if (space.id === spaceId) {
59
- space.packages = space.packages.sort((a, b) => {
60
- const aIndex = ids.indexOf(a.id);
61
- const bIndex = ids.indexOf(b.id);
62
- if (aIndex === -1) {
63
- return 1;
75
+ // Remove the packages being reordered from their current positions
76
+ const reorderedPackages = space.packages.filter((pkg) => ids.includes(pkg.id));
77
+ const remainingPackages = space.packages.filter((pkg) => !ids.includes(pkg.id));
78
+ if (insertAfter) {
79
+ // Find the insertAfter package index in remaining packages
80
+ const insertAfterIndex = remainingPackages.findIndex((pkg) => pkg.id === insertAfter);
81
+ if (insertAfterIndex !== -1) {
82
+ // Insert the reordered packages after the insertAfter package
83
+ space.packages = [
84
+ ...remainingPackages.slice(0, insertAfterIndex + 1),
85
+ ...reorderedPackages,
86
+ ...remainingPackages.slice(insertAfterIndex + 1),
87
+ ];
64
88
  }
65
- if (bIndex === -1) {
66
- return -1;
89
+ else {
90
+ // If insertAfter package not found, just append to the end
91
+ space.packages = [...reorderedPackages, ...remainingPackages];
67
92
  }
68
- return aIndex - bIndex;
69
- });
93
+ }
94
+ else {
95
+ // No insertAfter specified, just append to the end
96
+ space.packages = [...reorderedPackages, ...remainingPackages];
97
+ }
70
98
  }
71
99
  }
72
100
  },
@@ -5,6 +5,19 @@ export const reducer = {
5
5
  },
6
6
  setProfileNameOperation(state, action, dispatch) {
7
7
  const { name } = action.input;
8
+ if (!state.profile) {
9
+ state.profile = {
10
+ logo: null,
11
+ name: "",
12
+ slug: "",
13
+ description: null,
14
+ socials: {
15
+ xProfile: null,
16
+ github: null,
17
+ website: null,
18
+ },
19
+ };
20
+ }
8
21
  state.profile.name = name ?? state.profile.name;
9
22
  },
10
23
  setSlugOperation(state, action, dispatch) {
@@ -1,9 +1,9 @@
1
- import { generateId } from "document-model";
1
+ import { toPascalCase } from "document-drive/utils/misc";
2
2
  export const reducer = {
3
3
  addSpaceOperation(state, action, dispatch) {
4
4
  const { title, description } = action.input;
5
5
  state.spaces.push({
6
- id: generateId(),
6
+ id: toPascalCase(title),
7
7
  title: title ?? "",
8
8
  description: description ?? "",
9
9
  packages: [],
@@ -25,22 +25,28 @@ export const reducer = {
25
25
  },
26
26
  reorderSpacesOperation(state, action, dispatch) {
27
27
  const { ids, insertAfter } = action.input;
28
- state.spaces = state.spaces.sort((a, b) => {
29
- const aIndex = ids.indexOf(a.id);
30
- const bIndex = ids.indexOf(b.id);
31
- if (aIndex === -1) {
32
- return 1;
33
- }
34
- if (bIndex === -1) {
35
- return -1;
36
- }
37
- return aIndex - bIndex;
38
- });
28
+ // Remove the spaces being reordered from their current positions
29
+ const reorderedSpaces = state.spaces.filter((space) => ids.includes(space.id));
30
+ const remainingSpaces = state.spaces.filter((space) => !ids.includes(space.id));
39
31
  if (insertAfter) {
40
- const insertAfterIndex = ids.indexOf(insertAfter);
32
+ // Find the insertAfter space index in remaining spaces
33
+ const insertAfterIndex = remainingSpaces.findIndex((space) => space.id === insertAfter);
41
34
  if (insertAfterIndex !== -1) {
42
- state.spaces.splice(insertAfterIndex + 1, 0, state.spaces.splice(insertAfterIndex, 1)[0]);
35
+ // Insert the reordered spaces after the insertAfter space
36
+ state.spaces = [
37
+ ...remainingSpaces.slice(0, insertAfterIndex + 1),
38
+ ...reorderedSpaces,
39
+ ...remainingSpaces.slice(insertAfterIndex + 1),
40
+ ];
43
41
  }
42
+ else {
43
+ // If insertAfter space not found, just append to the end
44
+ state.spaces = [...reorderedSpaces, ...remainingSpaces];
45
+ }
46
+ }
47
+ else {
48
+ // No insertAfter specified, just append to the end
49
+ state.spaces = [...reorderedSpaces, ...remainingSpaces];
44
50
  }
45
51
  },
46
52
  };
@@ -1,9 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Button } from "@powerhousedao/design-system";
3
2
  import { useDocumentById } from "@powerhousedao/reactor-browser";
4
3
  import { useCallback, useState } from "react";
5
4
  import { actions, } from "../../document-models/builder-account/index.js";
6
- import { Form, StringField, UrlField } from "@powerhousedao/document-engineering";
5
+ import { Form, StringField, UrlField, Button } from "@powerhousedao/document-engineering";
7
6
  export default function Editor(props) {
8
7
  const { document: initialDocument } = props;
9
8
  const [document, dispatch] = useDocumentById(initialDocument.header.id);
@@ -195,8 +194,8 @@ export default function Editor(props) {
195
194
  const handleRemoveMember = useCallback((ethAddress) => {
196
195
  dispatch(actions.removeMember({ ethAddress }));
197
196
  }, [dispatch]);
198
- return (_jsxs("div", { className: "html-defaults-container min-h-screen bg-gray-50", children: [_jsx("div", { className: "bg-white shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsx("div", { className: "py-6", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center space-x-4", children: [_jsx("div", { className: "flex-shrink-0", children: profile.logo ? (_jsx("img", { className: "w-12 h-12 rounded-lg object-cover", src: profile.logo, alt: "Logo" })) : (_jsx("div", { className: "w-12 h-12 bg-blue-600 rounded-lg flex items-center justify-center", children: _jsx("svg", { className: "w-6 h-6 text-white", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" }) }) })) }), _jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-bold text-gray-900", children: profile.name || "Builder Account" }), _jsx("p", { className: "text-sm text-gray-500", children: profile.slug ? `@${profile.slug}` : "Manage your builder profile and packages" })] })] }), _jsx("div", { className: "flex items-center space-x-3", children: _jsx(Button, { color: "light", onClick: () => setIsEditingProfile(!isEditingProfile), children: isEditingProfile ? "Cancel" : "Edit Profile" }) })] }) }) }) }), _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8", children: _jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-8", children: [_jsxs("div", { className: "lg:col-span-2 space-y-8", children: [_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsxs("div", { className: "px-6 py-4 border-b border-gray-200", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Profile Information" }), _jsx("p", { className: "text-sm text-gray-500", children: "Manage your builder profile details" })] }), _jsx("div", { className: "p-6", children: isEditingProfile ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-6", children: [_jsx(StringField, { name: "profileName", label: "Profile Name", value: profile.name, onChange: (e) => handleSetProfileName(e.target.value), placeholder: "Enter your profile name", description: "Your public display name" }), _jsx(StringField, { name: "slug", label: "Slug", value: profile.slug, onChange: (e) => handleSetSlug(e.target.value), placeholder: "your-slug", description: "Unique identifier for your profile (used in URLs)" }), _jsx(StringField, { name: "description", label: "Description", value: profile.description || "", onChange: (e) => handleSetProfileDescription(e.target.value), placeholder: "Tell us about yourself and your work", description: "Brief description of your work and interests" }), _jsx(UrlField, { name: "logo", label: "Logo URL", value: profile.logo || "", onChange: (e) => handleSetLogo(e.target.value), placeholder: "https://example.com/logo.png", description: "URL to your profile logo image" }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-md font-medium text-gray-900", children: "Social Links" }), _jsx(UrlField, { name: "github", label: "GitHub", value: profile.socials.github || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, github: e.target.value }), placeholder: "https://github.com/username" }), _jsx(UrlField, { name: "website", label: "Website", value: profile.socials.website || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, website: e.target.value }), placeholder: "https://your-website.com" }), _jsx(UrlField, { name: "x", label: "X (Twitter)", value: profile.socials.xProfile || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, x: e.target.value }), placeholder: "https://x.com/username" })] }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsEditingProfile(false), children: "Cancel" }), _jsx(Button, { onClick: () => setIsEditingProfile(false), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Name" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.name || "Not set" })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Slug" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.slug ? `@${profile.slug}` : "Not set" })] })] }), profile.description && (_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Description" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.description })] })), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Social Links" }), _jsxs("div", { className: "mt-2 flex space-x-4", children: [profile.socials.github && (_jsx("a", { href: profile.socials.github, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "GitHub" })), profile.socials.website && (_jsx("a", { href: profile.socials.website, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "Website" })), profile.socials.xProfile && (_jsx("a", { href: profile.socials.xProfile, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "X (Twitter)" })), !profile.socials.github && !profile.socials.website && !profile.socials.xProfile && (_jsx("span", { className: "text-gray-500 text-sm", children: "No social links added" }))] })] })] })) })] }), _jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Spaces" }), _jsx("p", { className: "text-sm text-gray-500", children: "Organize your packages into spaces" })] }), _jsx(Button, { onClick: () => setIsAddingSpace(true), children: "Add Space" })] }) }), _jsxs("div", { className: "p-6", children: [isAddingSpace ? (_jsx("div", { className: "p-4 bg-gray-50 rounded-lg", children: _jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "spaceTitle", label: "Space Title", value: newSpaceTitle, onChange: (e) => setNewSpaceTitle(e.target.value), placeholder: "Enter space title" }), _jsx(StringField, { name: "spaceDescription", label: "Description (optional)", value: newSpaceDescription, onChange: (e) => setNewSpaceDescription(e.target.value), placeholder: "Enter space description" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsAddingSpace(false), children: "Cancel" }), _jsx(Button, { onClick: handleAddSpace, disabled: !newSpaceTitle.trim(), children: "Add Space" })] })] }) }) })) : null, _jsx("div", { className: "space-y-4", children: spaces.length > 0 ? (spaces.map((space) => (_jsxs("div", { className: "border border-gray-200 rounded-lg p-4", children: [editingSpaceId === space.id ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "editingSpaceTitle", label: "Space Title", value: editingSpaceTitle, onChange: (e) => setEditingSpaceTitle(e.target.value), placeholder: "Enter space title" }), _jsx(StringField, { name: "editingSpaceDescription", label: "Description (optional)", value: editingSpaceDescription, onChange: (e) => setEditingSpaceDescription(e.target.value), placeholder: "Enter space description" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: handleCancelSpaceEdit, children: "Cancel" }), _jsx(Button, { onClick: handleSaveSpaceEdit, disabled: !editingSpaceTitle.trim(), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-md font-medium text-gray-900", children: space.title }), space.description && (_jsx("p", { className: "text-sm text-gray-500 mt-1", children: space.description })), _jsxs("p", { className: "text-xs text-gray-400 mt-1", children: [space.packages.length, " package", space.packages.length !== 1 ? 's' : ''] })] }), _jsxs("div", { className: "flex space-x-2", children: [_jsx(Button, { color: "light", size: "small", onClick: () => handleStartEditingSpace(space.id), children: "Edit" }), _jsx(Button, { color: "light", size: "small", onClick: () => {
197
+ return (_jsxs("div", { className: "html-defaults-container min-h-screen bg-gray-50", children: [_jsx("div", { className: "bg-white shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsx("div", { className: "py-6", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center space-x-4", children: [_jsx("div", { className: "flex-shrink-0", children: profile.logo ? (_jsx("img", { className: "w-12 h-12 rounded-lg object-cover", src: profile.logo, alt: "Logo" })) : (_jsx("div", { className: "w-12 h-12 bg-blue-600 rounded-lg flex items-center justify-center", children: _jsx("svg", { className: "w-6 h-6 text-white", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" }) }) })) }), _jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-bold text-gray-900", children: profile.name || "Builder Account" }), _jsx("p", { className: "text-sm text-gray-500", children: profile.slug ? `@${profile.slug}` : "Manage your builder profile and packages" })] })] }), _jsx("div", { className: "flex items-center space-x-3", children: _jsx(Button, { color: "light", onClick: () => setIsEditingProfile(!isEditingProfile), children: isEditingProfile ? "Cancel" : "Edit Profile" }) })] }) }) }) }), _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8", children: _jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-8", children: [_jsxs("div", { className: "lg:col-span-2 space-y-8", children: [_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsxs("div", { className: "px-6 py-4 border-b border-gray-200", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Profile Information" }), _jsx("p", { className: "text-sm text-gray-500", children: "Manage your builder profile details" })] }), _jsx("div", { className: "p-6", children: isEditingProfile ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-6", children: [_jsx(StringField, { name: "profileName", label: "Profile Name", value: profile.name, onChange: (e) => handleSetProfileName(e.target.value), placeholder: "Enter your profile name", description: "Your public display name" }), _jsx(StringField, { name: "slug", label: "Slug", value: profile.slug, onChange: (e) => handleSetSlug(e.target.value), placeholder: "your-slug", description: "Unique identifier for your profile (used in URLs)" }), _jsx(StringField, { name: "description", label: "Description", value: profile.description || "", onChange: (e) => handleSetProfileDescription(e.target.value), placeholder: "Tell us about yourself and your work", description: "Brief description of your work and interests" }), _jsx(UrlField, { name: "logo", label: "Logo URL", value: profile.logo || "", onChange: (e) => handleSetLogo(e.target.value), placeholder: "https://example.com/logo.png", description: "URL to your profile logo image" }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-md font-medium text-gray-900", children: "Social Links" }), _jsx(UrlField, { name: "github", label: "GitHub", value: profile.socials.github || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, github: e.target.value }), placeholder: "https://github.com/username" }), _jsx(UrlField, { name: "website", label: "Website", value: profile.socials.website || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, website: e.target.value }), placeholder: "https://your-website.com" }), _jsx(UrlField, { name: "x", label: "X (Twitter)", value: profile.socials.xProfile || "", onChange: (e) => handleUpdateSocials({ ...profile.socials, x: e.target.value }), placeholder: "https://x.com/username" })] }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsEditingProfile(false), children: "Cancel" }), _jsx(Button, { onClick: () => setIsEditingProfile(false), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Name" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.name || "Not set" })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Slug" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.slug ? `@${profile.slug}` : "Not set" })] })] }), profile.description && (_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Description" }), _jsx("p", { className: "mt-1 text-sm text-gray-900", children: profile.description })] })), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Social Links" }), _jsxs("div", { className: "mt-2 flex space-x-4", children: [profile.socials.github && (_jsx("a", { href: profile.socials.github, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "GitHub" })), profile.socials.website && (_jsx("a", { href: profile.socials.website, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "Website" })), profile.socials.xProfile && (_jsx("a", { href: profile.socials.xProfile, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:text-blue-800", children: "X (Twitter)" })), !profile.socials.github && !profile.socials.website && !profile.socials.xProfile && (_jsx("span", { className: "text-gray-500 text-sm", children: "No social links added" }))] })] })] })) })] }), _jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Spaces" }), _jsx("p", { className: "text-sm text-gray-500", children: "Organize your packages into spaces" })] }), _jsx(Button, { onClick: () => setIsAddingSpace(true), children: "Add Space" })] }) }), _jsxs("div", { className: "p-6", children: [isAddingSpace ? (_jsx("div", { className: "p-4 bg-gray-50 rounded-lg", children: _jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "spaceTitle", label: "Space Title", value: newSpaceTitle, onChange: (e) => setNewSpaceTitle(e.target.value), placeholder: "Enter space title" }), _jsx(StringField, { name: "spaceDescription", label: "Description (optional)", value: newSpaceDescription, onChange: (e) => setNewSpaceDescription(e.target.value), placeholder: "Enter space description" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsAddingSpace(false), children: "Cancel" }), _jsx(Button, { onClick: handleAddSpace, disabled: !newSpaceTitle.trim(), children: "Add Space" })] })] }) }) })) : null, _jsx("div", { className: "space-y-4", children: spaces.length > 0 ? (spaces.map((space) => (_jsxs("div", { className: "border border-gray-200 rounded-lg p-4", children: [editingSpaceId === space.id ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "editingSpaceTitle", label: "Space Title", value: editingSpaceTitle, onChange: (e) => setEditingSpaceTitle(e.target.value), placeholder: "Enter space title" }), _jsx(StringField, { name: "editingSpaceDescription", label: "Description (optional)", value: editingSpaceDescription, onChange: (e) => setEditingSpaceDescription(e.target.value), placeholder: "Enter space description" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: handleCancelSpaceEdit, children: "Cancel" }), _jsx(Button, { onClick: handleSaveSpaceEdit, disabled: !editingSpaceTitle.trim(), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-md font-medium text-gray-900", children: space.title }), space.description && (_jsx("p", { className: "text-sm text-gray-500 mt-1", children: space.description })), _jsxs("p", { className: "text-xs text-gray-400 mt-1", children: [space.packages.length, " package", space.packages.length !== 1 ? 's' : ''] })] }), _jsxs("div", { className: "flex space-x-2", children: [_jsx(Button, { color: "light", size: "sm", onClick: () => handleStartEditingSpace(space.id), children: "Edit" }), _jsx(Button, { color: "light", size: "sm", onClick: () => {
199
198
  setSelectedSpaceForPackage(space.id);
200
199
  setIsAddingPackage(true);
201
- }, children: "Add Package" }), _jsx(Button, { color: "red", size: "small", onClick: () => handleDeleteSpace(space.id), children: "Delete" })] })] })), space.packages.length > 0 && (_jsx("div", { className: "mt-4 space-y-2", children: space.packages.map((pkg) => (_jsx("div", { className: "p-3 bg-gray-50 rounded border", children: editingPackageId === pkg.id ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-3", children: [_jsx(StringField, { name: "editingPackageName", label: "Package Name", value: editingPackageName, onChange: (e) => setEditingPackageName(e.target.value), placeholder: "Enter package name" }), _jsx(StringField, { name: "editingPackageDescription", label: "Description", value: editingPackageDescription, onChange: (e) => setEditingPackageDescription(e.target.value), placeholder: "Enter package description" }), _jsx(StringField, { name: "editingPackageCategory", label: "Category", value: editingPackageCategory, onChange: (e) => setEditingPackageCategory(e.target.value), placeholder: "Enter package category" }), _jsx(UrlField, { name: "editingPackageGithub", label: "GitHub URL", value: editingPackageGithub, onChange: (e) => setEditingPackageGithub(e.target.value), placeholder: "https://github.com/username/repo" }), _jsx(UrlField, { name: "editingPackageNpm", label: "NPM URL", value: editingPackageNpm, onChange: (e) => setEditingPackageNpm(e.target.value), placeholder: "https://www.npmjs.com/package/package-name" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: handleCancelPackageEdit, children: "Cancel" }), _jsx(Button, { onClick: handleSavePackageEdit, disabled: !editingPackageName.trim(), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("span", { className: "font-medium text-gray-900", children: pkg.name }), pkg.description && (_jsx("p", { className: "text-sm text-gray-500", children: pkg.description })), pkg.category && (_jsxs("p", { className: "text-xs text-gray-400", children: ["Category: ", pkg.category] }))] }), _jsxs("div", { className: "flex space-x-2", children: [_jsx(Button, { color: "light", size: "small", onClick: () => handleStartEditingPackage(pkg.id), children: "Edit" }), _jsx(Button, { color: "red", size: "small", onClick: () => handleDeletePackage(pkg.id), children: "Remove" })] })] })) }, pkg.id))) }))] }, space.id)))) : (_jsx("div", { className: "text-center py-8 text-gray-500", children: _jsx("p", { children: "No spaces created yet. Create a space to organize your packages." }) })) })] })] }), isAddingPackage && (_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Add Package" }) }), _jsx("div", { className: "p-6", children: _jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "packageName", label: "Package Name", value: newPackageName, onChange: (e) => setNewPackageName(e.target.value), placeholder: "Enter package name" }), _jsx(StringField, { name: "packageDescription", label: "Description", value: newPackageDescription, onChange: (e) => setNewPackageDescription(e.target.value), placeholder: "Enter package description" }), _jsx(StringField, { name: "packageCategory", label: "Category", value: newPackageCategory, onChange: (e) => setNewPackageCategory(e.target.value), placeholder: "Enter package category" }), _jsx(UrlField, { name: "packageGithub", label: "GitHub URL", value: newPackageGithub, onChange: (e) => setNewPackageGithub(e.target.value), placeholder: "https://github.com/username/repo" }), _jsx(UrlField, { name: "packageNpm", label: "NPM URL", value: newPackageNpm, onChange: (e) => setNewPackageNpm(e.target.value), placeholder: "https://www.npmjs.com/package/package-name" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsAddingPackage(false), children: "Cancel" }), _jsx(Button, { onClick: handleAddPackage, disabled: !newPackageName.trim() || !selectedSpaceForPackage, children: "Add Package" })] })] }) }) })] }))] }), _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsxs("div", { className: "px-6 py-4 border-b border-gray-200", children: [_jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Team Members" }), _jsx("p", { className: "text-sm text-gray-500", children: "Manage team access" })] }), _jsx("div", { className: "p-6", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex space-x-2", children: [_jsx("input", { type: "text", value: newMemberAddress, onChange: (e) => setNewMemberAddress(e.target.value), placeholder: "0x...", className: "flex-1 px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" }), _jsx(Button, { onClick: handleAddMember, disabled: !newMemberAddress.trim(), children: "Add" })] }), _jsx("div", { className: "space-y-2", children: members.length > 0 ? (members.map((address, index) => (_jsxs("div", { className: "flex items-center justify-between p-2 bg-gray-50 rounded border", children: [_jsx("span", { className: "text-sm font-mono text-gray-700 truncate", children: address }), _jsx(Button, { color: "red", size: "small", onClick: () => handleRemoveMember(address), children: "Remove" })] }, index)))) : (_jsx("p", { className: "text-sm text-gray-500", children: "No team members added yet" })) })] }) })] }), _jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Quick Stats" }) }), _jsx("div", { className: "p-6", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Spaces" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: spaces.length })] }), _jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Total Packages" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: spaces.reduce((total, space) => total + space.packages.length, 0) })] }), _jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Team Members" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: members.length })] })] }) })] })] })] }) })] }));
200
+ }, children: "Add Package" }), _jsx(Button, { color: "red", size: "sm", onClick: () => handleDeleteSpace(space.id), children: "Delete" })] })] })), space.packages.length > 0 && (_jsx("div", { className: "mt-4 space-y-2", children: space.packages.map((pkg) => (_jsx("div", { className: "p-3 bg-gray-50 rounded border", children: editingPackageId === pkg.id ? (_jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-3", children: [_jsx(StringField, { name: "editingPackageName", label: "Package Name", value: editingPackageName, onChange: (e) => setEditingPackageName(e.target.value), placeholder: "Enter package name" }), _jsx(StringField, { name: "editingPackageDescription", label: "Description", value: editingPackageDescription, onChange: (e) => setEditingPackageDescription(e.target.value), placeholder: "Enter package description" }), _jsx(StringField, { name: "editingPackageCategory", label: "Category", value: editingPackageCategory, onChange: (e) => setEditingPackageCategory(e.target.value), placeholder: "Enter package category" }), _jsx(UrlField, { name: "editingPackageGithub", label: "GitHub URL", value: editingPackageGithub, onChange: (e) => setEditingPackageGithub(e.target.value), placeholder: "https://github.com/username/repo" }), _jsx(UrlField, { name: "editingPackageNpm", label: "NPM URL", value: editingPackageNpm, onChange: (e) => setEditingPackageNpm(e.target.value), placeholder: "https://www.npmjs.com/package/package-name" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: handleCancelPackageEdit, children: "Cancel" }), _jsx(Button, { onClick: handleSavePackageEdit, disabled: !editingPackageName.trim(), children: "Save Changes" })] })] }) })) : (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("span", { className: "font-medium text-gray-900", children: pkg.name }), pkg.description && (_jsx("p", { className: "text-sm text-gray-500", children: pkg.description })), pkg.category && (_jsxs("p", { className: "text-xs text-gray-400", children: ["Category: ", pkg.category] }))] }), _jsxs("div", { className: "flex space-x-2", children: [_jsx(Button, { color: "light", size: "sm", onClick: () => handleStartEditingPackage(pkg.id), children: "Edit" }), _jsx(Button, { color: "red", size: "sm", onClick: () => handleDeletePackage(pkg.id), children: "Remove" })] })] })) }, pkg.id))) }))] }, space.id)))) : (_jsx("div", { className: "text-center py-8 text-gray-500", children: _jsx("p", { children: "No spaces created yet. Create a space to organize your packages." }) })) })] })] }), isAddingPackage && (_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Add Package" }) }), _jsx("div", { className: "p-6", children: _jsx(Form, { onSubmit: (e) => e.preventDefault(), children: _jsxs("div", { className: "space-y-4", children: [_jsx(StringField, { name: "packageName", label: "Package Name", value: newPackageName, onChange: (e) => setNewPackageName(e.target.value), placeholder: "Enter package name" }), _jsx(StringField, { name: "packageDescription", label: "Description", value: newPackageDescription, onChange: (e) => setNewPackageDescription(e.target.value), placeholder: "Enter package description" }), _jsx(StringField, { name: "packageCategory", label: "Category", value: newPackageCategory, onChange: (e) => setNewPackageCategory(e.target.value), placeholder: "Enter package category" }), _jsx(UrlField, { name: "packageGithub", label: "GitHub URL", value: newPackageGithub, onChange: (e) => setNewPackageGithub(e.target.value), placeholder: "https://github.com/username/repo" }), _jsx(UrlField, { name: "packageNpm", label: "NPM URL", value: newPackageNpm, onChange: (e) => setNewPackageNpm(e.target.value), placeholder: "https://www.npmjs.com/package/package-name" }), _jsxs("div", { className: "flex justify-end space-x-3", children: [_jsx(Button, { color: "light", onClick: () => setIsAddingPackage(false), children: "Cancel" }), _jsx(Button, { onClick: handleAddPackage, disabled: !newPackageName.trim() || !selectedSpaceForPackage, children: "Add Package" })] })] }) }) })] }))] }), _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsxs("div", { className: "px-6 py-4 border-b border-gray-200", children: [_jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Team Members" }), _jsx("p", { className: "text-sm text-gray-500", children: "Manage team access" })] }), _jsx("div", { className: "p-6", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex space-x-2", children: [_jsx("input", { type: "text", value: newMemberAddress, onChange: (e) => setNewMemberAddress(e.target.value), placeholder: "0x...", className: "flex-1 px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" }), _jsx(Button, { onClick: handleAddMember, disabled: !newMemberAddress.trim(), children: "Add" })] }), _jsx("div", { className: "space-y-2", children: members.length > 0 ? (members.map((address, index) => (_jsxs("div", { className: "flex items-center justify-between p-2 bg-gray-50 rounded border", children: [_jsx("span", { className: "text-sm font-mono text-gray-700 truncate", children: address }), _jsx(Button, { color: "red", size: "sm", onClick: () => handleRemoveMember(address), children: "Remove" })] }, index)))) : (_jsx("p", { className: "text-sm text-gray-500", children: "No team members added yet" })) })] }) })] }), _jsxs("div", { className: "bg-white rounded-lg shadow-sm border", children: [_jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: _jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Quick Stats" }) }), _jsx("div", { className: "p-6", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Spaces" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: spaces.length })] }), _jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Total Packages" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: spaces.reduce((total, space) => total + space.packages.length, 0) })] }), _jsxs("div", { className: "flex justify-between items-center", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Team Members" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: members.length })] })] }) })] })] })] }) })] }));
202
201
  }
@@ -3,7 +3,7 @@ export const module = {
3
3
  Component: Editor,
4
4
  documentTypes: ["powerhouse/vetra/builder-account"],
5
5
  config: {
6
- id: "editor-id",
6
+ id: "builder-account-editor-id",
7
7
  disableExternalControls: true,
8
8
  documentToolbarEnabled: true,
9
9
  showSwitchboardLink: true,
@@ -2,17 +2,17 @@
2
2
  * This file aggregates all processor factories
3
3
  * Auto-generated by codegen - DO NOT EDIT MANUALLY
4
4
  */
5
- // Import processor factories here as they are generated
5
+ // Import other processor factories here as they are generated
6
6
  import { vetraReadModelProcessorFactory } from "./vetra-read-model/factory.js";
7
7
  export const processorFactory = (module) => {
8
8
  // Initialize all processor factories once with the module
9
9
  const factories = [];
10
- // Add processors here as they are generated
10
+ // Add other processors here as they are generated
11
11
  factories.push(vetraReadModelProcessorFactory(module));
12
12
  // Return the inner function that will be called for each drive
13
13
  return async (driveHeader) => {
14
14
  const processors = [];
15
- // Call each cached factory with the driveHeader
15
+ // Call each cached factory with the driveId
16
16
  for (const factory of factories) {
17
17
  const factoryProcessors = await factory(driveHeader);
18
18
  processors.push(...factoryProcessors);
@@ -1,6 +1,6 @@
1
1
  import { RelationalDbProcessor } from "document-drive/processors/relational";
2
- import { generateId } from "document-model";
3
2
  import { up } from "./migrations.js";
3
+ import { toPascalCase } from "document-drive/utils/misc";
4
4
  export class VetraReadModelProcessor extends RelationalDbProcessor {
5
5
  static getNamespace(driveId) {
6
6
  // Default namespace: `${this.name}_${driveId.replaceAll("-", "_")}`
@@ -18,71 +18,71 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
18
18
  continue;
19
19
  }
20
20
  for (const operation of strand.operations) {
21
- await this.handleOperation(strand.documentId, operation.action);
21
+ await this.handleOperation(strand.documentId, operation.action, operation.state);
22
22
  }
23
23
  }
24
24
  }
25
- async handleOperation(documentId, action) {
25
+ async handleOperation(documentId, action, state) {
26
26
  switch (action.type) {
27
27
  // Profile operations
28
28
  case "SET_LOGO":
29
- await this.handleSetLogo(documentId, action);
29
+ await this.handleSetLogo(documentId, action, state);
30
30
  break;
31
31
  case "SET_PROFILE_NAME":
32
- await this.handleSetProfileName(documentId, action);
32
+ await this.handleSetProfileName(documentId, action, state);
33
33
  break;
34
34
  case "SET_SLUG":
35
- await this.handleSetSlug(documentId, action);
35
+ await this.handleSetSlug(documentId, action, state);
36
36
  break;
37
37
  case "SET_PROFILE_DESCRIPTION":
38
- await this.handleSetProfileDescription(documentId, action);
38
+ await this.handleSetProfileDescription(documentId, action, state);
39
39
  break;
40
40
  case "UPDATE_SOCIALS":
41
- await this.handleUpdateSocials(documentId, action);
41
+ await this.handleUpdateSocials(documentId, action, state);
42
42
  break;
43
43
  // Members operations
44
44
  case "ADD_MEMBER":
45
- await this.handleAddMember(documentId, action);
45
+ await this.handleAddMember(documentId, action, state);
46
46
  break;
47
47
  case "REMOVE_MEMBER":
48
- await this.handleRemoveMember(documentId, action);
48
+ await this.handleRemoveMember(documentId, action, state);
49
49
  break;
50
50
  // Spaces operations
51
51
  case "ADD_SPACE":
52
- await this.handleAddSpace(documentId, action);
52
+ await this.handleAddSpace(documentId, action, state);
53
53
  break;
54
54
  case "DELETE_SPACE":
55
- await this.handleDeleteSpace(documentId, action);
55
+ await this.handleDeleteSpace(documentId, action, state);
56
56
  break;
57
57
  case "SET_SPACE_TITLE":
58
- await this.handleSetSpaceTitle(documentId, action);
58
+ await this.handleSetSpaceTitle(documentId, action, state);
59
59
  break;
60
60
  case "SET_SPACE_DESCRIPTION":
61
- await this.handleSetSpaceDescription(documentId, action);
61
+ await this.handleSetSpaceDescription(documentId, action, state);
62
62
  break;
63
63
  case "REORDER_SPACES":
64
- await this.handleReorderSpaces(documentId, action);
64
+ await this.handleReorderSpaces(documentId, action, state);
65
65
  break;
66
66
  // Packages operations
67
67
  case "ADD_PACKAGE":
68
- await this.handleAddPackage(documentId, action);
68
+ await this.handleAddPackage(documentId, action, state);
69
69
  break;
70
70
  case "SET_PACKAGE_DRIVE_ID":
71
- await this.handleSetPackageDriveId(documentId, action);
71
+ await this.handleSetPackageDriveId(documentId, action, state);
72
72
  break;
73
73
  case "UPDATE_PACKAGE":
74
- await this.handleUpdatePackage(documentId, action);
74
+ await this.handleUpdatePackage(documentId, action, state);
75
75
  break;
76
76
  case "REORDER_PACKAGES":
77
- await this.handleReorderPackages(documentId, action);
77
+ await this.handleReorderPackages(documentId, action, state);
78
78
  break;
79
79
  case "DELETE_PACKAGE":
80
- await this.handleDeletePackage(documentId, action);
80
+ await this.handleDeletePackage(documentId, action, state);
81
81
  break;
82
82
  }
83
83
  }
84
84
  // Profile operations
85
- async handleSetLogo(documentId, action) {
85
+ async handleSetLogo(documentId, action, state) {
86
86
  await this.ensureBuilderAccount(documentId);
87
87
  await this.relationalDb
88
88
  .updateTable("builder_accounts")
@@ -93,7 +93,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
93
93
  .where("id", "=", documentId)
94
94
  .execute();
95
95
  }
96
- async handleSetProfileName(documentId, action) {
96
+ async handleSetProfileName(documentId, action, state) {
97
97
  await this.ensureBuilderAccount(documentId);
98
98
  await this.relationalDb
99
99
  .updateTable("builder_accounts")
@@ -104,7 +104,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
104
104
  .where("id", "=", documentId)
105
105
  .execute();
106
106
  }
107
- async handleSetSlug(documentId, action) {
107
+ async handleSetSlug(documentId, action, state) {
108
108
  await this.ensureBuilderAccount(documentId);
109
109
  await this.relationalDb
110
110
  .updateTable("builder_accounts")
@@ -115,7 +115,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
115
115
  .where("id", "=", documentId)
116
116
  .execute();
117
117
  }
118
- async handleSetProfileDescription(documentId, action) {
118
+ async handleSetProfileDescription(documentId, action, state) {
119
119
  await this.ensureBuilderAccount(documentId);
120
120
  await this.relationalDb
121
121
  .updateTable("builder_accounts")
@@ -126,7 +126,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
126
126
  .where("id", "=", documentId)
127
127
  .execute();
128
128
  }
129
- async handleUpdateSocials(documentId, action) {
129
+ async handleUpdateSocials(documentId, action, state) {
130
130
  await this.ensureBuilderAccount(documentId);
131
131
  await this.relationalDb
132
132
  .updateTable("builder_accounts")
@@ -140,7 +140,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
140
140
  .execute();
141
141
  }
142
142
  // Members operations
143
- async handleAddMember(documentId, action) {
143
+ async handleAddMember(documentId, action, state) {
144
144
  await this.ensureBuilderAccount(documentId);
145
145
  if (!action.input.ethAddress)
146
146
  return;
@@ -155,7 +155,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
155
155
  await this.relationalDb
156
156
  .insertInto("builder_account_members")
157
157
  .values({
158
- id: generateId(),
158
+ id: action.input.ethAddress,
159
159
  builder_account_id: documentId,
160
160
  eth_address: action.input.ethAddress,
161
161
  created_at: new Date(),
@@ -163,7 +163,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
163
163
  .execute();
164
164
  }
165
165
  }
166
- async handleRemoveMember(documentId, action) {
166
+ async handleRemoveMember(documentId, action, state) {
167
167
  if (!action.input.ethAddress)
168
168
  return;
169
169
  await this.relationalDb
@@ -173,9 +173,9 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
173
173
  .execute();
174
174
  }
175
175
  // Spaces operations
176
- async handleAddSpace(documentId, action) {
176
+ async handleAddSpace(documentId, action, state) {
177
177
  await this.ensureBuilderAccount(documentId);
178
- const spaceId = generateId();
178
+ const spaceId = toPascalCase(action.input.title);
179
179
  await this.relationalDb
180
180
  .insertInto("builder_spaces")
181
181
  .values({
@@ -190,14 +190,14 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
190
190
  .onConflict((oc) => oc.column("id").doNothing())
191
191
  .execute();
192
192
  }
193
- async handleDeleteSpace(documentId, action) {
193
+ async handleDeleteSpace(documentId, action, state) {
194
194
  await this.relationalDb
195
195
  .deleteFrom("builder_spaces")
196
196
  .where("id", "=", action.input.id)
197
197
  .where("builder_account_id", "=", documentId)
198
198
  .execute();
199
199
  }
200
- async handleSetSpaceTitle(documentId, action) {
200
+ async handleSetSpaceTitle(documentId, action, state) {
201
201
  await this.relationalDb
202
202
  .updateTable("builder_spaces")
203
203
  .set({
@@ -208,7 +208,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
208
208
  .where("builder_account_id", "=", documentId)
209
209
  .execute();
210
210
  }
211
- async handleSetSpaceDescription(documentId, action) {
211
+ async handleSetSpaceDescription(documentId, action, state) {
212
212
  await this.relationalDb
213
213
  .updateTable("builder_spaces")
214
214
  .set({
@@ -219,7 +219,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
219
219
  .where("builder_account_id", "=", documentId)
220
220
  .execute();
221
221
  }
222
- async handleReorderSpaces(documentId, action) {
222
+ async handleReorderSpaces(documentId, action, state) {
223
223
  const { ids, insertAfter } = action.input;
224
224
  for (let i = 0; i < ids.length; i++) {
225
225
  const spaceId = ids[i];
@@ -236,12 +236,12 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
236
236
  }
237
237
  }
238
238
  // Packages operations
239
- async handleAddPackage(documentId, action) {
240
- const packageId = generateId();
239
+ async handleAddPackage(documentId, action, state) {
240
+ const packageId = action.input.spaceId + "-" + toPascalCase(action.input.name);
241
241
  await this.relationalDb
242
242
  .insertInto("builder_packages")
243
243
  .values({
244
- id: packageId,
244
+ id: `${packageId}`,
245
245
  space_id: action.input.spaceId,
246
246
  name: action.input.name,
247
247
  description: action.input.description || null,
@@ -264,7 +264,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
264
264
  await this.relationalDb
265
265
  .insertInto("builder_package_keywords")
266
266
  .values({
267
- id: generateId(),
267
+ id: `${packageId}-${keyword}`,
268
268
  package_id: packageId,
269
269
  label: keyword,
270
270
  created_at: new Date(),
@@ -273,7 +273,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
273
273
  }
274
274
  }
275
275
  }
276
- async handleSetPackageDriveId(documentId, action) {
276
+ async handleSetPackageDriveId(documentId, action, state) {
277
277
  await this.relationalDb
278
278
  .updateTable("builder_packages")
279
279
  .set({
@@ -283,7 +283,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
283
283
  .where("id", "=", action.input.packageId)
284
284
  .execute();
285
285
  }
286
- async handleUpdatePackage(documentId, action) {
286
+ async handleUpdatePackage(documentId, action, state) {
287
287
  const updates = { updated_at: new Date() };
288
288
  if (action.input.title !== undefined) {
289
289
  updates.name = action.input.title;
@@ -297,7 +297,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
297
297
  .where("id", "=", action.input.id)
298
298
  .execute();
299
299
  }
300
- async handleReorderPackages(documentId, action) {
300
+ async handleReorderPackages(documentId, action, state) {
301
301
  const { ids, insertAfter, spaceId } = action.input;
302
302
  for (let i = 0; i < ids.length; i++) {
303
303
  const packageId = ids[i];
@@ -313,7 +313,7 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
313
313
  .execute();
314
314
  }
315
315
  }
316
- async handleDeletePackage(documentId, action) {
316
+ async handleDeletePackage(documentId, action, state) {
317
317
  await this.relationalDb
318
318
  .deleteFrom("builder_packages")
319
319
  .where("id", "=", action.input.id)
@@ -3,57 +3,9 @@ export const getResolvers = (subgraph) => {
3
3
  const reactor = subgraph.reactor;
4
4
  const db = subgraph.relationalDb;
5
5
  return {
6
- Query: {
7
- fetchAllBuilderAccounts: async (parent, args, context) => {
8
- const driveId = context.driveId || "default";
9
- const accounts = await VetraReadModelProcessor.query(driveId, db)
10
- .selectFrom("builder_accounts")
11
- .selectAll()
12
- .execute();
13
- return accounts.map((account) => ({
14
- id: account.id,
15
- profileName: account.profile_name,
16
- profileSlug: account.profile_slug,
17
- profileLogo: account.profile_logo,
18
- profileDescription: account.profile_description,
19
- profileSocialsX: account.profile_socials_x,
20
- profileSocialsGithub: account.profile_socials_github,
21
- profileSocialsWebsite: account.profile_socials_website,
22
- createdAt: account.created_at.toISOString(),
23
- updatedAt: account.updated_at.toISOString(),
24
- spaces: [], // Will be resolved by field resolver
25
- members: [], // Will be resolved by field resolver
26
- }));
27
- },
28
- fetchBuilderAccount: async (parent, args, context) => {
29
- const driveId = context.driveId || "default";
30
- const account = await VetraReadModelProcessor.query(driveId, db)
31
- .selectFrom("builder_accounts")
32
- .selectAll()
33
- .where("id", "=", args.id)
34
- .executeTakeFirst();
35
- if (!account) {
36
- return null;
37
- }
38
- return {
39
- id: account.id,
40
- profileName: account.profile_name,
41
- profileSlug: account.profile_slug,
42
- profileLogo: account.profile_logo,
43
- profileDescription: account.profile_description,
44
- profileSocialsX: account.profile_socials_x,
45
- profileSocialsGithub: account.profile_socials_github,
46
- profileSocialsWebsite: account.profile_socials_website,
47
- createdAt: account.created_at.toISOString(),
48
- updatedAt: account.updated_at.toISOString(),
49
- spaces: [], // Will be resolved by field resolver
50
- members: [], // Will be resolved by field resolver
51
- };
52
- },
53
- },
54
- BuilderAccount: {
6
+ BuilderAccountType: {
55
7
  spaces: async (parent, args, context) => {
56
- const driveId = context.driveId || "default";
8
+ const driveId = context.driveId || "powerhouse";
57
9
  const spaces = await VetraReadModelProcessor.query(driveId, db)
58
10
  .selectFrom("builder_spaces")
59
11
  .selectAll()
@@ -68,11 +20,12 @@ export const getResolvers = (subgraph) => {
68
20
  sortOrder: space.sort_order,
69
21
  createdAt: space.created_at.toISOString(),
70
22
  updatedAt: space.updated_at.toISOString(),
23
+ driveId: driveId, // Pass driveId to field resolvers
71
24
  packages: [], // Will be resolved by field resolver
72
25
  }));
73
26
  },
74
27
  members: async (parent, args, context) => {
75
- const driveId = context.driveId || "default";
28
+ const driveId = context.driveId || "powerhouse";
76
29
  const members = await VetraReadModelProcessor.query(driveId, db)
77
30
  .selectFrom("builder_account_members")
78
31
  .selectAll()
@@ -88,7 +41,7 @@ export const getResolvers = (subgraph) => {
88
41
  },
89
42
  BuilderSpace: {
90
43
  packages: async (parent, args, context) => {
91
- const driveId = context.driveId || "default";
44
+ const driveId = parent.driveId || context.driveId || "powerhouse";
92
45
  const packages = await VetraReadModelProcessor.query(driveId, db)
93
46
  .selectFrom("builder_packages")
94
47
  .selectAll()
@@ -116,7 +69,7 @@ export const getResolvers = (subgraph) => {
116
69
  },
117
70
  BuilderPackage: {
118
71
  keywords: async (parent, args, context) => {
119
- const driveId = context.driveId || "default";
72
+ const driveId = context.driveId || "powerhouse";
120
73
  const keywords = await VetraReadModelProcessor.query(driveId, db)
121
74
  .selectFrom("builder_package_keywords")
122
75
  .selectAll()
@@ -130,5 +83,61 @@ export const getResolvers = (subgraph) => {
130
83
  }));
131
84
  },
132
85
  },
86
+ Query: {
87
+ fetchAllBuilderAccounts: async (parent, args) => {
88
+ const driveId = args.driveId || "powerhouse";
89
+ const search = args.search;
90
+ let accounts = VetraReadModelProcessor.query(driveId, db)
91
+ .selectFrom("builder_accounts")
92
+ .selectAll();
93
+ if (search) {
94
+ accounts = accounts.where((eb) => {
95
+ return eb("profile_name", "ilike", `%${search}%`)
96
+ .or("profile_slug", "ilike", `%${search}%`)
97
+ .or("profile_description", "ilike", `%${search}%`);
98
+ });
99
+ }
100
+ const results = await accounts.execute();
101
+ return results.map((account) => ({
102
+ id: account.id,
103
+ profileName: account.profile_name,
104
+ profileSlug: account.profile_slug,
105
+ profileLogo: account.profile_logo,
106
+ profileDescription: account.profile_description,
107
+ profileSocialsX: account.profile_socials_x,
108
+ profileSocialsGithub: account.profile_socials_github,
109
+ profileSocialsWebsite: account.profile_socials_website,
110
+ createdAt: account.created_at.toISOString(),
111
+ updatedAt: account.updated_at.toISOString(),
112
+ driveId: driveId, // Pass driveId to field resolvers
113
+ spaces: [], // Will be resolved by field resolver
114
+ members: [], // Will be resolved by field resolver
115
+ }));
116
+ },
117
+ fetchBuilderAccount: async (parent, args) => {
118
+ const driveId = args.driveId || "powerhouse";
119
+ const account = await VetraReadModelProcessor.query(driveId, db)
120
+ .selectFrom("builder_accounts")
121
+ .selectAll()
122
+ .where("id", "=", args.id)
123
+ .executeTakeFirst();
124
+ if (!account) {
125
+ return null;
126
+ }
127
+ return {
128
+ id: account.id,
129
+ profileName: account.profile_name,
130
+ profileSlug: account.profile_slug,
131
+ profileLogo: account.profile_logo,
132
+ profileDescription: account.profile_description,
133
+ profileSocialsX: account.profile_socials_x,
134
+ profileSocialsGithub: account.profile_socials_github,
135
+ profileSocialsWebsite: account.profile_socials_website,
136
+ createdAt: account.created_at.toISOString(),
137
+ updatedAt: account.updated_at.toISOString(),
138
+ driveId: driveId, // Pass driveId to field resolvers
139
+ };
140
+ },
141
+ },
133
142
  };
134
143
  };
@@ -61,9 +61,18 @@ export const schema = gql `
61
61
  createdAt: String!
62
62
  }
63
63
 
64
+ type BuilderAccountFilter {
65
+ profileName: String
66
+ profileSlug: String
67
+ profileLogo: String
68
+ profileDescription: String
69
+ }
70
+
64
71
  type Query {
65
- example(driveId: String!): String
66
- fetchAllBuilderAccounts: [BuilderAccountType!]!
67
- fetchBuilderAccount(id: String!): BuilderAccountType
72
+ fetchAllBuilderAccounts(
73
+ driveId: String
74
+ search: String
75
+ ): [BuilderAccountType!]!
76
+ fetchBuilderAccount(driveId: String, id: String!): BuilderAccountType
68
77
  }
69
78
  `;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@powerhousedao/vetra-builder-package",
3
3
  "description": "",
4
- "version": "0.0.4",
4
+ "version": "0.0.6",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",
7
7
  "files": [