Thanks for contributing! We will review your contribution, and reach out
via email or on our
@@ -155,7 +138,6 @@ import { getAssetIcon } from "@/store/components.store";
import { useModuleStore } from "@/store/module.store";
import AssetNameModal from "./AssetNameModal.vue";
import AssetListItem from "./AssetListItem.vue";
-import ModuleExportModal from "./modules/ModuleExportModal.vue";
import SidebarSubpanelTitle from "./SidebarSubpanelTitle.vue";
import IconButton from "./IconButton.vue";
@@ -169,35 +151,11 @@ const createAssetReqStatus = assetStore.getRequestStatus("CREATE_VARIANT");
const loadAssetsReqStatus = assetStore.getRequestStatus(
"LOAD_SCHEMA_VARIANT_LIST",
);
-const loadModulesReqStatus = assetStore.getRequestStatus("LOAD_MODULES");
+const syncModulesReqStatus = moduleStore.getRequestStatus("SYNC");
-const contributeAssetModalRef = ref>();
-const exportSuccessModalRef = ref>();
+const contributeAssetSuccessModalRef = ref>();
const newAssetModalRef = ref>();
-const contributeLoadingTexts = [
- "Engaging Photon Torpedos...",
- "Reticulating Splines...",
- "Revolutionizing DevOps...",
- "Calibrating Hyperspace Matrix...",
- "Syncing Neural Circuitry...",
- "Optimizing Tachyon Weave...",
- "Tuning Fractal Harmonics...",
- "Reshuffling Multiverse Threads...",
- "Harmonizing Subspace Arrays...",
- "Modulating Cybernetic Matrices...",
- "Configuring Exo-Geometric Arrays...",
- "Initializing Flux Capacitors...",
- "Balancing Subatomic Resonance...",
- "Fine-tuning Quantum Entanglement...",
- "Matrixing Hyperdimensional Grids...",
- "Coalescing Esoteric Code...",
- "Syncopating Quantum Flux...",
- "Reformatting Reality Lattice...",
- "Fine-tuning Temporal Flux...",
- "Syncing Cosmic Harmonics...",
-];
-
const searchRef = ref>();
const searchString = ref("");
@@ -205,11 +163,8 @@ const onSearch = (search: string) => {
searchString.value = search.trim().toLocaleLowerCase();
};
-const canContribute = computed(() =>
- assetList.value.some((a) => a.canContribute),
-);
const canUpdate = computed(
- () => Object.keys(assetStore.upgradeableModules).length > 0,
+ () => Object.keys(moduleStore.upgradeableModules).length !== 0,
);
const categorizedAssets = computed(() =>
@@ -263,7 +218,7 @@ const categoryColor = (category: string) => {
return "#000";
};
-const loadModules = async () => assetStore.LOAD_MODULES();
+const syncModules = async () => moduleStore.SYNC();
const newAsset = async (newAssetName: string) => {
const result = await assetStore.CREATE_VARIANT(newAssetName);
@@ -277,7 +232,7 @@ const newAsset = async (newAssetName: string) => {
};
const updateAllAssets = () => {
- Object.values(assetStore.upgradeableModules).forEach((module) => {
+ Object.values(moduleStore.upgradeableModules).forEach((module) => {
moduleStore.INSTALL_REMOTE_MODULE(module.id);
});
router.replace({
@@ -285,13 +240,10 @@ const updateAllAssets = () => {
});
};
-const contributeAsset = () => contributeAssetModalRef.value?.open();
-const onExport = () => exportSuccessModalRef.value?.open();
-
const filters = computed(() => [
assetList.value.filter((a) => a.canContribute),
assetList.value.filter(
- (a) => !!assetStore.upgradeableModules[a.schemaVariantId],
+ (a) => !!moduleStore.upgradeableModules[a.schemaVariantId],
),
assetList.value.filter((a) => !a.isLocked),
]);
diff --git a/app/web/src/components/CustomizeTabs.vue b/app/web/src/components/CustomizeTabs.vue
index 21421dd3e6..643f6b38eb 100644
--- a/app/web/src/components/CustomizeTabs.vue
+++ b/app/web/src/components/CustomizeTabs.vue
@@ -11,7 +11,8 @@
- NEW ASSETS
+ NEW ASSETS
+
@@ -31,11 +32,13 @@ import { PropType, ref } from "vue";
import { TabGroup, TabGroupItem, PillCounter } from "@si/vue-lib/design-system";
import { useFeatureFlagsStore } from "@/store/feature_flags.store";
import { useAssetStore } from "@/store/asset.store";
+import { useModuleStore } from "@/store/module.store";
const router = useRouter();
const route = useRoute();
const featureFlagsStore = useFeatureFlagsStore();
const assetStore = useAssetStore();
+const moduleStore = useModuleStore();
const group = ref>();
diff --git a/app/web/src/components/InstallAsset.vue b/app/web/src/components/InstallAsset.vue
index 64772e8dfb..92321e5185 100644
--- a/app/web/src/components/InstallAsset.vue
+++ b/app/web/src/components/InstallAsset.vue
@@ -88,8 +88,8 @@ import {
Icon,
} from "@si/vue-lib/design-system";
import { useModuleStore, ModuleSpec } from "@/store/module.store";
-import { ModuleId } from "@/api/sdf/dal/schema";
import { nilId } from "@/utils/nilId";
+import { ModuleId } from "@/api/sdf/dal/module";
import TruncateWithTooltip from "./TruncateWithTooltip.vue";
import CodeEditor from "./CodeEditor.vue";
diff --git a/app/web/src/components/InstallAssetsPanel.vue b/app/web/src/components/InstallAssetsPanel.vue
index 7957b25da0..be603ca1d4 100644
--- a/app/web/src/components/InstallAssetsPanel.vue
+++ b/app/web/src/components/InstallAssetsPanel.vue
@@ -1,8 +1,8 @@
@@ -16,7 +16,7 @@
/>
>();
const searchString = ref("");
@@ -77,16 +77,16 @@ const onSearch = (search: string) => {
};
const filteredModules = computed(() =>
- assetStore.installableModules.filter((m) =>
+ moduleStore.installableModules.filter((m) =>
m.name.toLocaleLowerCase().includes(searchString.value),
),
);
-const loadModulesReqStatus = assetStore.getRequestStatus("LOAD_MODULES");
+const syncModulesReqStatus = moduleStore.getRequestStatus("SYNC");
-const selectedModule = ref();
+const selectedModule = ref();
-const selectModule = (module: Module) => {
+const selectModule = (module: LatestModule) => {
selectedModule.value = module;
const newQueryObj = {
...{ m: module.id },
diff --git a/app/web/src/components/Workspace/WorkspaceCustomizeAssets.vue b/app/web/src/components/Workspace/WorkspaceCustomizeAssets.vue
index b1052350ec..853e570b80 100644
--- a/app/web/src/components/Workspace/WorkspaceCustomizeAssets.vue
+++ b/app/web/src/components/Workspace/WorkspaceCustomizeAssets.vue
@@ -144,6 +144,7 @@ import {
import { useRoute } from "vue-router";
import { useAssetStore } from "@/store/asset.store";
import { useFuncStore } from "@/store/func/funcs.store";
+import { useModuleStore } from "@/store/module.store";
import router from "@/router";
import AssetCard from "../AssetCard.vue";
import AssetListPanel from "../AssetListPanel.vue";
@@ -162,6 +163,7 @@ import WorkspaceCustomizeEmptyState from "../WorkspaceCustomizeEmptyState.vue";
const assetStore = useAssetStore();
const funcStore = useFuncStore();
+const moduleStore = useModuleStore();
const selectedVariantId = computed(() => assetStore.selectedVariantId);
const selectedFuncId = computed(() => funcStore.selectedFuncId);
@@ -186,7 +188,7 @@ const rightClickMenuItems = computed(() => {
const canUpdate = [];
assetStore.selectedSchemaVariantRecords.forEach((asset) => {
if (asset.canContribute) canContribute.push(asset);
- if (assetStore.upgradeableModules[asset.schemaVariantId])
+ if (moduleStore.upgradeableModules[asset.schemaVariantId])
canUpdate.push(asset);
});
diff --git a/app/web/src/components/modules/ModuleExportModal.vue b/app/web/src/components/modules/ModuleExportModal.vue
deleted file mode 100644
index 9dedde3ca4..0000000000
--- a/app/web/src/components/modules/ModuleExportModal.vue
+++ /dev/null
@@ -1,205 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- -
- •
- {{ schemaVariantsById?.[svId]?.schemaName }}
-
- {{ schemaVariantsById?.[svId]?.displayName }}
- {{ svTimestampStringById[svId] }}
-
-
-
-
-
-
- Everything you contribute will receive a code review, and we will reach
- out if we have any questions or concerns. Assuming things look good, we
- will then include your asset in a future version of System Initiative!
-
-
- By clicking the 'Contribute to System Initiative' button, you agree to
- license any code submitted under the terms of the
- Apache License, Version 2.0, and that you intend for System Initiative, Inc. to distribute it.
-
-
-
-
-
-
-
diff --git a/app/web/src/store/asset.store.ts b/app/web/src/store/asset.store.ts
index 44487f65cd..c24943ba9d 100644
--- a/app/web/src/store/asset.store.ts
+++ b/app/web/src/store/asset.store.ts
@@ -4,13 +4,7 @@ import * as _ from "lodash-es";
import { addStoreHooks, ApiRequest } from "@si/vue-lib/pinia";
import { useWorkspacesStore } from "@/store/workspaces.store";
import { FuncId, FuncKind } from "@/api/sdf/dal/func";
-import {
- Module,
- ModuleId,
- SchemaId,
- SchemaVariant,
- SchemaVariantId,
-} from "@/api/sdf/dal/schema";
+import { SchemaId, SchemaVariant, SchemaVariantId } from "@/api/sdf/dal/schema";
import { Visibility } from "@/api/sdf/dal/visibility";
import keyedDebouncer from "@/utils/keyedDebouncer";
import router from "@/router";
@@ -18,6 +12,7 @@ import { PropKind } from "@/api/sdf/dal/prop";
import { nonNullable } from "@/utils/typescriptLinter";
import { useFuncStore } from "./func/funcs.store";
import { useChangeSetsStore } from "./change_sets.store";
+import { useModuleStore } from "./module.store";
import { useRealtimeStore } from "./realtime/realtime.store";
import handleStoreError from "./errors";
import { useComponentsStore } from "./components.store";
@@ -80,18 +75,19 @@ export const schemaVariantDisplayName = (schemaVariant: SchemaVariant) =>
: schemaVariant.displayName;
export const useAssetStore = () => {
- const changeSetsStore = useChangeSetsStore();
- const changeSetId = changeSetsStore.selectedChangeSetId;
+ const changeSetStore = useChangeSetsStore();
+ const changeSetId = changeSetStore.selectedChangeSetId;
const visibility = {
// changeSetId should not be empty if we are actually using this store
// so we can give it a bad value and let it throw an error
visibility_change_set_pk: changeSetId || "XXX",
};
- const workspacesStore = useWorkspacesStore();
- const workspaceId = workspacesStore.selectedWorkspacePk;
+ const workspaceStore = useWorkspacesStore();
+ const workspaceId = workspaceStore.selectedWorkspacePk;
- const funcsStore = useFuncStore();
+ const funcStore = useFuncStore();
+ const moduleStore = useModuleStore();
let assetSaveDebouncer: ReturnType | undefined;
@@ -100,8 +96,6 @@ export const useAssetStore = () => {
state: () => ({
variantList: [] as SchemaVariant[],
variantsById: {} as Record,
- upgradeableModules: {} as Record,
- installableModulesById: {} as Record,
executeSchemaVariantTaskId: undefined as string | undefined,
executeSchemaVariantTaskRunning: false as boolean,
@@ -129,8 +123,6 @@ export const useAssetStore = () => {
return state.selectedSchemaVariants[0];
else return undefined;
},
- installableModules: (state) =>
- Object.values(state.installableModulesById),
selectedSchemaVariant(): SchemaVariant | undefined {
if (this.selectedVariantId)
return this.variantFromListById[this.selectedVariantId];
@@ -183,13 +175,13 @@ export const useAssetStore = () => {
this.selectedSchemaVariants = [id];
this.syncSelectionIntoUrl();
const variant = this.variantFromListById[id];
- if (variant?.assetFuncId) funcsStore.FETCH_CODE(variant.assetFuncId);
+ if (variant?.assetFuncId) funcStore.FETCH_CODE(variant.assetFuncId);
},
async setFuncSelection(id?: FuncId) {
// ignore the old func selections and replace with one func or no funcs
- funcsStore.selectedFuncId = id;
+ funcStore.selectedFuncId = id;
if (id) {
- await funcsStore.FETCH_CODE(id);
+ await funcStore.FETCH_CODE(id);
this.selectedFuncs = [id];
} else {
this.selectedFuncs = [];
@@ -198,8 +190,8 @@ export const useAssetStore = () => {
},
async addFuncSelection(id: FuncId) {
if (!this.selectedFuncs.includes(id)) this.selectedFuncs.push(id);
- await funcsStore.FETCH_CODE(id);
- funcsStore.selectedFuncId = id;
+ await funcStore.FETCH_CODE(id);
+ funcStore.selectedFuncId = id;
this.syncSelectionIntoUrl();
},
removeFuncSelection(id: FuncId) {
@@ -228,7 +220,7 @@ export const useAssetStore = () => {
async syncUrlIntoSelection() {
this.selectedSchemaVariants = [];
this.selectedFuncs = [];
- funcsStore.selectedFuncId = undefined;
+ funcStore.selectedFuncId = undefined;
const ids = ((router.currentRoute.value.query?.s as string) || "")
.split("|")
.filter(Boolean);
@@ -242,16 +234,16 @@ export const useAssetStore = () => {
this.selectedSchemaVariants.push(id);
const variant = this.variantFromListById[id];
if (variant?.assetFuncId)
- promises.push(funcsStore.FETCH_CODE(variant.assetFuncId));
+ promises.push(funcStore.FETCH_CODE(variant.assetFuncId));
} else if (id.startsWith("f_")) {
id = id.substring(2);
this.selectedFuncs.push(id);
- promises.push(funcsStore.FETCH_CODE(id));
+ promises.push(funcStore.FETCH_CODE(id));
fnIds.push(id);
}
});
await Promise.all(promises);
- funcsStore.selectedFuncId = fnIds[fnIds.length - 1];
+ funcStore.selectedFuncId = fnIds[fnIds.length - 1];
}
},
@@ -301,10 +293,10 @@ export const useAssetStore = () => {
},
async CREATE_VARIANT(name: string) {
- if (changeSetsStore.creatingChangeSet)
+ if (changeSetStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
- if (changeSetId === changeSetsStore.headChangeSetId)
- changeSetsStore.creatingChangeSet = true;
+ if (changeSetId === changeSetStore.headChangeSetId)
+ changeSetStore.creatingChangeSet = true;
return new ApiRequest({
method: "post",
url: "/variant/create_variant",
@@ -324,10 +316,10 @@ export const useAssetStore = () => {
},
async CLONE_VARIANT(schemaVariantId: SchemaVariantId, name: string) {
- if (changeSetsStore.creatingChangeSet)
+ if (changeSetStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
- if (changeSetsStore.headSelected)
- changeSetsStore.creatingChangeSet = true;
+ if (changeSetStore.headSelected)
+ changeSetStore.creatingChangeSet = true;
return new ApiRequest<
{ id: SchemaVariantId; success: boolean },
@@ -384,10 +376,10 @@ export const useAssetStore = () => {
},
async SAVE_SCHEMA_VARIANT(schemaVariant: SchemaVariant, code?: string) {
- if (changeSetsStore.creatingChangeSet)
+ if (changeSetStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
- if (changeSetsStore.headSelected)
- changeSetsStore.creatingChangeSet = true;
+ if (changeSetStore.headSelected)
+ changeSetStore.creatingChangeSet = true;
if (schemaVariant.isLocked)
throw new Error(
@@ -408,17 +400,17 @@ export const useAssetStore = () => {
},
onSuccess: () => {
if (code) {
- const f = funcsStore.funcCodeById[schemaVariant.assetFuncId];
+ const f = funcStore.funcCodeById[schemaVariant.assetFuncId];
if (f) f.code = code;
}
},
});
},
async REGENERATE_VARIANT(schemaVariantId: SchemaVariantId) {
- if (changeSetsStore.creatingChangeSet)
+ if (changeSetStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
- if (changeSetsStore.headSelected)
- changeSetsStore.creatingChangeSet = true;
+ if (changeSetStore.headSelected)
+ changeSetStore.creatingChangeSet = true;
this.detachmentWarnings = [];
const variant = this.variantFromListById[schemaVariantId];
@@ -438,26 +430,6 @@ export const useAssetStore = () => {
});
},
- async LOAD_MODULES() {
- return new ApiRequest<
- {
- upgradeable: Record;
- installable: Module[];
- },
- Visibility
- >({
- url: `v2/workspaces/${workspaceId}/change-sets/${changeSetId}/modules/sync`,
- params: { ...visibility },
- onSuccess: (response) => {
- this.upgradeableModules = response.upgradeable;
- this.installableModulesById = _.keyBy(
- response.installable,
- (m) => m.id,
- );
- },
- });
- },
-
async LOAD_SCHEMA_VARIANT_LIST() {
return new ApiRequest({
url: `v2/workspaces/${workspaceId}/change-sets/${changeSetId}/schema-variants`,
@@ -469,10 +441,10 @@ export const useAssetStore = () => {
},
async CREATE_UNLOCKED_COPY(id: SchemaVariantId) {
- if (changeSetsStore.creatingChangeSet)
+ if (changeSetStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
- if (changeSetsStore.headSelected)
- changeSetsStore.creatingChangeSet = true;
+ if (changeSetStore.headSelected)
+ changeSetStore.creatingChangeSet = true;
this.detachmentWarnings = [];
@@ -495,10 +467,10 @@ export const useAssetStore = () => {
});
},
async DELETE_UNLOCKED_VARIANT(id: SchemaVariantId) {
- if (changeSetsStore.creatingChangeSet)
+ if (changeSetStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
- if (changeSetsStore.headSelected)
- changeSetsStore.creatingChangeSet = true;
+ if (changeSetStore.headSelected)
+ changeSetStore.creatingChangeSet = true;
return new ApiRequest({
method: "post",
@@ -520,7 +492,7 @@ export const useAssetStore = () => {
async onActivated() {
await Promise.all([
this.LOAD_SCHEMA_VARIANT_LIST(),
- this.LOAD_MODULES(),
+ moduleStore.SYNC(),
]);
const stopWatchingUrl = watch(
() => {
@@ -567,7 +539,7 @@ export const useAssetStore = () => {
callback: (data) => {
if (data.changeSetId !== changeSetId) return;
this.LOAD_SCHEMA_VARIANT_LIST();
- this.LOAD_MODULES();
+ moduleStore.SYNC();
},
},
{
@@ -605,7 +577,7 @@ export const useAssetStore = () => {
callback: async (data) => {
if (data.changeSetId !== changeSetId) return;
this.LOAD_SCHEMA_VARIANT_LIST();
- this.LOAD_MODULES();
+ moduleStore.SYNC();
useComponentsStore().FETCH_AVAILABLE_SCHEMAS();
},
},
@@ -623,7 +595,7 @@ export const useAssetStore = () => {
eventType: "ChangeSetApplied",
callback: () => {
this.LOAD_SCHEMA_VARIANT_LIST();
- this.LOAD_MODULES();
+ moduleStore.SYNC();
},
},
// For the async api endpoints
diff --git a/app/web/src/store/module.store.ts b/app/web/src/store/module.store.ts
index 1a2c88a7ae..24541c6605 100644
--- a/app/web/src/store/module.store.ts
+++ b/app/web/src/store/module.store.ts
@@ -4,12 +4,18 @@ import { addStoreHooks, ApiRequest } from "@si/vue-lib/pinia";
import { useWorkspacesStore } from "@/store/workspaces.store";
import { ChangeSetId } from "@/api/sdf/dal/change_set";
import router from "@/router";
+import { SchemaVariantId } from "@/api/sdf/dal/schema";
+import { Visibility } from "@/api/sdf/dal/visibility";
+import {
+ LatestModule,
+ ModuleContributeRequest,
+ ModuleId,
+} from "@/api/sdf/dal/module";
import { useChangeSetsStore } from "./change_sets.store";
import { useRouterStore } from "./router.store";
import { useRealtimeStore } from "./realtime/realtime.store";
import { ModuleIndexApiRequest } from ".";
-export type ModuleId = string;
export type ModuleName = string;
export type ModuleHash = string;
export type ModuleSlug = ModuleHash;
@@ -20,13 +26,6 @@ export interface ModuleFuncView {
description?: string;
}
-export interface ModuleExportRequest {
- name: string;
- version: string;
- description?: string;
- schemaVariants: string[];
-}
-
export interface LocalModuleSummary {
name: string;
hash: ModuleHash;
@@ -118,6 +117,11 @@ function getVisibilityParams(forceChangeSetId?: ChangeSetId) {
export const useModuleStore = () => {
const changeSetsStore = useChangeSetsStore();
const changeSetId = changeSetsStore.selectedChangeSetId;
+ const visibility = {
+ // changeSetId should not be empty if we are actually using this store
+ // so we can give it a bad value and let it throw an error
+ visibility_change_set_pk: changeSetId || "XXX",
+ };
const workspacesStore = useWorkspacesStore();
const workspaceId = workspacesStore.selectedWorkspacePk;
@@ -127,6 +131,8 @@ export const useModuleStore = () => {
`ws${workspaceId || "NONE"}/cs${changeSetId || "NONE"}/modules`,
{
state: () => ({
+ upgradeableModules: {} as Record,
+ installableModulesById: {} as Record,
localModulesByName: {} as Record,
localModuleDetailsByName: {} as Record<
ModuleName,
@@ -146,6 +152,8 @@ export const useModuleStore = () => {
exportingWorkspaceOperationRunning: false as boolean,
}),
getters: {
+ installableModules: (state) =>
+ Object.values(state.installableModulesById),
urlSelectedModuleSlug: () => {
const route = useRouterStore().currentRoute;
return route?.params?.moduleSlug as ModuleSlug | undefined;
@@ -200,6 +208,38 @@ export const useModuleStore = () => {
},
},
actions: {
+ async SYNC() {
+ return new ApiRequest<
+ {
+ upgradeable: Record;
+ installable: LatestModule[];
+ },
+ Visibility
+ >({
+ url: `v2/workspaces/${workspaceId}/change-sets/${changeSetId}/modules/sync`,
+ params: { ...visibility },
+ onSuccess: (response) => {
+ this.upgradeableModules = response.upgradeable;
+ this.installableModulesById = _.keyBy(
+ response.installable,
+ (m) => m.id,
+ );
+ },
+ });
+ },
+
+ async CONTRIBUTE(request: ModuleContributeRequest) {
+ return new ApiRequest({
+ method: "post",
+ url: `v2/workspaces/${workspaceId}/change-sets/${changeSetId}/modules/contribute`,
+ params: {
+ name: request.name,
+ version: request.version,
+ schemaVariantId: request.schemaVariantId,
+ },
+ });
+ },
+
async LOAD_LOCAL_MODULES() {
return new ApiRequest<{ modules: LocalModuleSummary[] }>({
url: "/module/list_modules",
@@ -409,14 +449,6 @@ export const useModuleStore = () => {
this.exportingWorkspaceOperationId = null;
this.exportingWorkspaceOperationError = undefined;
},
-
- async EXPORT_MODULE(exportRequest: ModuleExportRequest) {
- return new ApiRequest({
- method: "post",
- url: "/module/export_module",
- params: { ...exportRequest, ...getVisibilityParams() },
- });
- },
},
onActivated() {
// This store is activated very early, and we might not have a change
diff --git a/app/web/src/store/workspaces.store.ts b/app/web/src/store/workspaces.store.ts
index adcb8f6116..2a9daf510f 100644
--- a/app/web/src/store/workspaces.store.ts
+++ b/app/web/src/store/workspaces.store.ts
@@ -4,8 +4,8 @@ import { watch } from "vue";
import { addStoreHooks, ApiRequest } from "@si/vue-lib/pinia";
import storage from "local-storage-fallback";
import { useRealtimeStore } from "@/store/realtime/realtime.store";
-import { ModuleId } from "@/store/module.store";
import router from "@/router";
+import { ModuleId } from "@/api/sdf/dal/module";
import { useAuthStore, UserId } from "./auth.store";
import { useRouterStore } from "./router.store";
import handleStoreError from "./errors";
diff --git a/lib/dal/src/module.rs b/lib/dal/src/module.rs
index a8b107a43e..f2b4b82f3f 100644
--- a/lib/dal/src/module.rs
+++ b/lib/dal/src/module.rs
@@ -14,6 +14,8 @@ use tokio::sync::TryLockError;
use tokio::time::Instant;
use crate::layer_db_types::{ModuleContent, ModuleContentV2};
+use crate::pkg::export::PkgExporter;
+use crate::pkg::PkgError;
use crate::workspace_snapshot::content_address::{ContentAddress, ContentAddressDiscriminants};
use crate::workspace_snapshot::edge_weight::{
EdgeWeight, EdgeWeightError, EdgeWeightKind, EdgeWeightKindDiscriminants,
@@ -22,8 +24,9 @@ use crate::workspace_snapshot::node_weight::category_node_weight::CategoryNodeKi
use crate::workspace_snapshot::node_weight::{NodeWeight, NodeWeightError};
use crate::workspace_snapshot::WorkspaceSnapshotError;
use crate::{
- pk, ChangeSetError, DalContext, Func, FuncError, Schema, SchemaError, SchemaId, SchemaVariant,
- SchemaVariantError, SchemaVariantId, Timestamp, TransactionsError,
+ pk, ChangeSetError, DalContext, Func, FuncError, HistoryActor, Schema, SchemaError, SchemaId,
+ SchemaVariant, SchemaVariantError, SchemaVariantId, Timestamp, TransactionsError, User,
+ UserError,
};
#[remain::sorted]
@@ -33,6 +36,8 @@ pub enum ModuleError {
ChangeSet(#[from] ChangeSetError),
#[error("edge weight error: {0}")]
EdgeWeight(#[from] EdgeWeightError),
+ #[error("found empty metadata (name: '{0}') (version: '{1}')")]
+ EmptyMetadata(String, String),
#[error("func error: {0}")]
Func(#[from] FuncError),
#[error("layer db error: {0}")]
@@ -41,6 +46,8 @@ pub enum ModuleError {
MissingSchemaId(String, String),
#[error("node weight error: {0}")]
NodeWeight(#[from] NodeWeightError),
+ #[error("pkg error: {0}")]
+ Pkg(#[from] Box),
#[error("schema error: {0}")]
Schema(#[from] SchemaError),
#[error("schema variant error: {0}")]
@@ -51,6 +58,8 @@ pub enum ModuleError {
Transactions(#[from] TransactionsError),
#[error("try lock error: {0}")]
TryLock(#[from] TryLockError),
+ #[error("user error: {0}")]
+ User(#[from] UserError),
#[error("workspace snapshot error: {0}")]
WorkspaceSnapshot(#[from] WorkspaceSnapshotError),
}
@@ -511,4 +520,78 @@ impl Module {
Ok(synced_modules)
}
+
+ /// Prepares a given [`SchemaId`] and its corresponding [`Module`] for contribution.
+ #[allow(clippy::type_complexity)]
+ #[instrument(
+ name = "module.prepare_contribution"
+ level = "info",
+ skip_all,
+ fields(
+ name = name.as_ref(),
+ version = version.as_ref(),
+ %schema_variant_id
+ )
+ )]
+ pub async fn prepare_contribution(
+ ctx: &DalContext,
+ name: impl AsRef,
+ version: impl AsRef,
+ schema_variant_id: SchemaVariantId,
+ ) -> ModuleResult<(String, String, Option, Option, Vec)> {
+ let user = match ctx.history_actor() {
+ HistoryActor::User(user_pk) => User::get_by_pk(ctx, *user_pk).await?,
+ _ => None,
+ };
+ let (created_by_name, created_by_email) = user
+ .map(|user| (user.name().to_owned(), user.email().to_owned()))
+ .unwrap_or((
+ "unauthenticated user name".into(),
+ "unauthenticated user email".into(),
+ ));
+ debug!(%created_by_name, %created_by_email, "preparing module contribution");
+
+ // Sanitize and validate metadata.
+ let name = name.as_ref().trim();
+ let version = version.as_ref().trim();
+ if name.is_empty() || version.is_empty() {
+ return Err(ModuleError::EmptyMetadata(
+ name.to_string(),
+ version.to_string(),
+ ));
+ }
+
+ // The frontend will send us the schema variant as this is what we care about from
+ // there. We can then use that schema variant to be able to understand the associated
+ // schema for it.
+ let variant = SchemaVariant::get_by_id_or_error(ctx, schema_variant_id).await?;
+ let associated_schema = variant.schema(ctx).await?;
+
+ // Create module payload.
+ let mut exporter = PkgExporter::new_for_module_contribution(
+ name,
+ version,
+ &created_by_email,
+ associated_schema.id(),
+ );
+ let module_payload = exporter.export_as_bytes(ctx).await.map_err(Box::new)?;
+
+ // Check if local information exists for contribution metadata.
+ let (local_module_based_on_hash, local_module_schema_id) =
+ match Module::find_for_member_id(ctx, associated_schema.id()).await? {
+ Some(module) => (
+ Some(module.root_hash().to_string()),
+ module.schema_id().map(|id| id.into()),
+ ),
+ None => (None, None),
+ };
+
+ Ok((
+ name.to_string(),
+ version.to_string(),
+ local_module_based_on_hash,
+ local_module_schema_id,
+ module_payload,
+ ))
+ }
}
diff --git a/lib/dal/src/pkg/export.rs b/lib/dal/src/pkg/export.rs
index 79e5425509..a374529c47 100644
--- a/lib/dal/src/pkg/export.rs
+++ b/lib/dal/src/pkg/export.rs
@@ -45,7 +45,11 @@ pub struct PkgExporter {
}
impl PkgExporter {
- pub fn new_module_exporter(
+ /// Creates an unopinionated [`PkgExporter`].
+ ///
+ /// _Note:_ if you are unsure which constructor method to use, you likely want
+ /// [`Self::new_for_module_contribution`].
+ pub fn new(
name: impl Into,
version: impl Into,
description: Option>,
@@ -64,8 +68,18 @@ impl PkgExporter {
}
}
+ /// Creates a new [`PkgExporter`] for contributing an individual module.
+ pub fn new_for_module_contribution(
+ name: impl Into,
+ version: impl Into,
+ created_by: impl Into,
+ schema_id: SchemaId,
+ ) -> Self {
+ Self::new(name, version, None::, created_by, vec![schema_id])
+ }
+
fn new_standalone_variant_exporter(schema_name: &str) -> Self {
- Self::new_module_exporter(schema_name, "", None::, "", vec![])
+ Self::new(schema_name, "", None::, "", vec![])
}
pub async fn export_as_bytes(&mut self, ctx: &DalContext) -> PkgResult> {
@@ -184,7 +198,7 @@ impl PkgExporter {
}
data_builder.display_name(variant.display_name());
- data_builder.component_type(get_component_type(ctx, variant).await?);
+ data_builder.component_type(Self::get_component_type(ctx, variant).await?);
data_builder.description(variant.description());
if let Some(authoring_func_id) =
@@ -1045,24 +1059,25 @@ impl PkgExporter {
Ok(funcs)
}
-}
-pub async fn get_component_type(
- ctx: &DalContext,
- variant: &SchemaVariant,
-) -> Result {
- let type_prop =
- Prop::find_prop_by_path(ctx, variant.id(), &PropPath::new(["root", "si", "type"])).await?;
-
- if let Some(av_id) = Prop::attribute_values_for_prop_id(ctx, type_prop.id())
- .await?
- .pop()
- {
- let av = AttributeValue::get_by_id_or_error(ctx, av_id).await?;
- if let Some(type_value) = av.view(ctx).await? {
- let component_type: ComponentType = serde_json::from_value(type_value)?;
- return Ok(component_type.into());
+ async fn get_component_type(
+ ctx: &DalContext,
+ variant: &SchemaVariant,
+ ) -> Result {
+ let type_prop =
+ Prop::find_prop_by_path(ctx, variant.id(), &PropPath::new(["root", "si", "type"]))
+ .await?;
+
+ if let Some(av_id) = Prop::attribute_values_for_prop_id(ctx, type_prop.id())
+ .await?
+ .pop()
+ {
+ let av = AttributeValue::get_by_id_or_error(ctx, av_id).await?;
+ if let Some(type_value) = av.view(ctx).await? {
+ let component_type: ComponentType = serde_json::from_value(type_value)?;
+ return Ok(component_type.into());
+ }
}
+ Ok(variant.component_type().into())
}
- Ok(variant.component_type().into())
}
diff --git a/lib/dal/src/schema/variant.rs b/lib/dal/src/schema/variant.rs
index 5af4158f5a..0a1f9f32ec 100644
--- a/lib/dal/src/schema/variant.rs
+++ b/lib/dal/src/schema/variant.rs
@@ -13,6 +13,7 @@ use telemetry::prelude::*;
use thiserror::Error;
use url::ParseError;
+use crate::action::prototype::{ActionKind, ActionPrototype};
use crate::attribute::prototype::argument::{
AttributePrototypeArgument, AttributePrototypeArgumentError,
};
@@ -26,6 +27,7 @@ use crate::layer_db_types::{
ContentTypeError, InputSocketContent, OutputSocketContent, SchemaVariantContent,
SchemaVariantContentV2,
};
+use crate::module::Module;
use crate::prop::{PropError, PropPath};
use crate::schema::variant::root_prop::RootProp;
use crate::socket::input::InputSocketError;
@@ -49,16 +51,13 @@ use crate::{AttributeValue, Component, ComponentError, FuncBackendResponseType,
use self::root_prop::RootPropChild;
+pub mod authoring;
mod json;
pub mod leaves;
mod metadata_view;
pub mod root_prop;
mod value_from;
-pub mod authoring;
-
-use crate::action::prototype::{ActionKind, ActionPrototype};
-use crate::module::Module;
pub use json::SchemaVariantJson;
pub use json::SchemaVariantMetadataJson;
pub use metadata_view::SchemaVariantMetadataView;
@@ -263,8 +262,6 @@ impl SchemaVariant {
props: front_end_props,
can_create_new_components: is_default || !self.is_locked,
can_contribute,
- // FIXME(nick): this needs to be dropped once the v2 modules sync route is in use.
- can_update: false,
})
}
}
@@ -783,8 +780,6 @@ impl SchemaVariant {
}
}
- /// A schema variant can be contributed if it is default, locked and does not belong to
- /// a module, which means it has been updated locally
pub async fn can_be_contributed_by_id(
ctx: &DalContext,
id: SchemaVariantId,
diff --git a/lib/dal/tests/integration_test/module.rs b/lib/dal/tests/integration_test/module.rs
index 37b56c34a2..c4dca3d6e9 100644
--- a/lib/dal/tests/integration_test/module.rs
+++ b/lib/dal/tests/integration_test/module.rs
@@ -3,6 +3,7 @@ use dal::module::Module;
use dal::pkg::export::PkgExporter;
use dal::{DalContext, Schema};
use dal_test::test;
+use pretty_assertions_sorted::assert_eq;
use si_pkg::{SocketSpecArity, SocketSpecKind};
use std::collections::HashMap;
use ulid::Ulid;
@@ -89,16 +90,10 @@ async fn module_export_simple(ctx: &mut DalContext) {
assert!(default_schema_variant.is_some());
let name = "Paul's Test Pkg".to_string();
- let description = "The Bison".to_string();
let version = "2019-06-03".to_string();
let user = "System Initiative".to_string();
- let mut exporter = PkgExporter::new_module_exporter(
- name.clone(),
- version.clone(),
- Some(description.clone()),
- &user,
- vec![schema.id()],
- );
+ let mut exporter =
+ PkgExporter::new_for_module_contribution(name.clone(), version.clone(), &user, schema.id());
let exported_pkg = exporter
.export_as_spec(ctx)
@@ -106,7 +101,6 @@ async fn module_export_simple(ctx: &mut DalContext) {
.expect("unable to get the pkg spec");
assert_eq!(exported_pkg.name, name.clone());
- assert_eq!(exported_pkg.description, description.clone());
assert_eq!(exported_pkg.version, version.clone());
assert_eq!(exported_pkg.created_by, user.clone());
assert_eq!(exported_pkg.funcs.len(), 14);
@@ -242,3 +236,33 @@ async fn dummy_sync(ctx: &DalContext) {
actual // actual
);
}
+
+#[test]
+async fn prepare_contribution_works(ctx: &DalContext) {
+ let schema = Schema::find_by_name(ctx, "swifty")
+ .await
+ .expect("could not find by name")
+ .expect("schema not found");
+ let name = "Paul's Test Pkg With Extra Spaces At The End ";
+ let version = " Version With Spaces At The Beginning 2019-06-03";
+
+ let default_variant_id = schema
+ .get_default_schema_variant_id(ctx)
+ .await
+ .expect("unable to get a default variant")
+ .expect("error getting the default variant id");
+
+ let (actual_name, actual_version, _, _, _) =
+ Module::prepare_contribution(ctx, name, version, default_variant_id)
+ .await
+ .expect("could not prepare contribution");
+
+ assert_eq!(
+ name.trim().to_string(), // expected
+ actual_name // actual
+ );
+ assert_eq!(
+ version.trim().to_string(), // expected
+ actual_version // actual
+ );
+}
diff --git a/lib/sdf-server/src/server/service/module.rs b/lib/sdf-server/src/server/service/module.rs
index 11fa64db95..4148eca9b7 100644
--- a/lib/sdf-server/src/server/service/module.rs
+++ b/lib/sdf-server/src/server/service/module.rs
@@ -19,12 +19,12 @@ use si_std::CanonicalFileError;
use std::path::{Path, PathBuf};
use thiserror::Error;
use tokio::fs::read_dir;
+
const PKG_EXTENSION: &str = "sipkg";
const MAX_NAME_SEARCH_ATTEMPTS: usize = 100;
pub mod approval_process;
pub mod builtin_module_spec;
-pub mod export_module;
mod export_workspace;
pub mod get_module;
pub mod import_workspace_vote;
@@ -43,7 +43,6 @@ pub enum ModuleError {
ChangeSet(#[from] ChangeSetError),
#[error("Changeset not found: {0}")]
ChangeSetNotFound(ChangeSetId),
-
#[error(transparent)]
DalPkg(#[from] DalPkgError),
#[error("Trying to export from/import into root tenancy")]
@@ -232,7 +231,6 @@ pub async fn pkg_open(builder: &DalContextBuilder, file_name: &str) -> ModuleRes
pub fn routes() -> Router {
Router::new()
- .route("/export_module", post(export_module::export_module))
.route(
"/export_workspace",
post(export_workspace::export_workspace),
diff --git a/lib/sdf-server/src/server/service/module/export_module.rs b/lib/sdf-server/src/server/service/module/export_module.rs
deleted file mode 100644
index 3f3e15b242..0000000000
--- a/lib/sdf-server/src/server/service/module/export_module.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-use crate::server::extract::{AccessBuilder, HandlerContext, PosthogClient, RawAccessToken};
-use crate::server::tracking::track;
-use crate::service::module::{ModuleError, ModuleResult};
-use axum::extract::OriginalUri;
-use axum::Json;
-use dal::module::Module;
-use dal::pkg::export::PkgExporter;
-use dal::{HistoryActor, SchemaVariant, SchemaVariantId, User, Visibility};
-use serde::{Deserialize, Serialize};
-use telemetry::prelude::*;
-
-#[derive(Deserialize, Serialize, Debug)]
-#[serde(rename_all = "camelCase")]
-pub struct ExportModuleRequest {
- pub name: String,
- pub version: String,
- pub description: Option,
- pub schema_variants: Vec,
- #[serde(flatten)]
- pub visibility: Visibility,
-}
-
-#[derive(Deserialize, Serialize, Debug)]
-#[serde(rename_all = "camelCase")]
-pub struct ExportModuleResponse {
- pub success: bool,
- pub full_path: String,
-}
-
-pub async fn export_module(
- HandlerContext(builder): HandlerContext,
- AccessBuilder(request_ctx): AccessBuilder,
- RawAccessToken(raw_access_token): RawAccessToken,
- PosthogClient(posthog_client): PosthogClient,
- OriginalUri(original_uri): OriginalUri,
- Json(request): Json,
-) -> ModuleResult> {
- let ctx = builder.build(request_ctx.build(request.visibility)).await?;
-
- if request.name.trim().is_empty() {
- return Err(ModuleError::PackageNameEmpty);
- }
-
- if request.version.trim().is_empty() {
- return Err(ModuleError::PackageVersionEmpty);
- }
-
- if request.schema_variants.is_empty() {
- return Err(ModuleError::PackageExportEmpty);
- }
-
- let module_index_url = match ctx.module_index_url() {
- Some(url) => url,
- None => return Err(ModuleError::ModuleIndexNotConfigured),
- };
-
- let user = match ctx.history_actor() {
- HistoryActor::User(user_pk) => User::get_by_pk(&ctx, *user_pk).await?,
- _ => None,
- };
-
- let (created_by_name, created_by_email) = user
- .map(|user| (user.name().to_owned(), user.email().to_owned()))
- .unwrap_or((
- "unauthenticated user name".into(),
- "unauthenticated user email".into(),
- ));
-
- info!("Packaging module");
-
- // XXX:rework frontend to send schema ids
- let mut schema_ids = vec![];
- for variant_id in &request.schema_variants {
- let schema = SchemaVariant::get_by_id_or_error(&ctx, *variant_id)
- .await?
- .schema(&ctx)
- .await?;
- schema_ids.push(schema.id());
- }
-
- let (based_on_hash, module_schema_id) = if schema_ids.len() == 1 {
- match schema_ids.first().copied() {
- None => (None, None),
- Some(schema_id) => match Module::find_for_member_id(&ctx, schema_id).await? {
- Some(module) => (Some(module.root_hash().to_string()), module.schema_id()),
- None => (None, None),
- },
- }
- } else {
- (None, None)
- };
-
- let mut exporter = PkgExporter::new_module_exporter(
- &request.name,
- &request.version,
- request.description.as_ref(),
- &created_by_email,
- schema_ids,
- );
-
- let module_payload = exporter.export_as_bytes(&ctx).await?;
-
- let index_client = module_index_client::ModuleIndexClient::new(
- module_index_url.try_into()?,
- &raw_access_token,
- );
- let response = index_client
- .upload_module(
- request.name.trim(),
- request.version.trim(),
- based_on_hash,
- module_schema_id.map(|id| id.to_string()),
- module_payload,
- )
- .await?;
-
- track(
- &posthog_client,
- &ctx,
- &original_uri,
- "export_module",
- serde_json::json!({
- "pkg_name": request.name,
- "pkg_version": request.version,
- "pkg_description": request.description,
- "pkg_created_by_name": created_by_name,
- "pkg_created_by_email": created_by_email,
- "pkg_schema_count": request.schema_variants.len(),
- "pkg_hash": response.latest_hash,
- }),
- );
-
- ctx.commit().await?;
-
- Ok(Json(ExportModuleResponse {
- success: true,
- full_path: "Get this from module-index service".to_owned(),
- }))
-}
diff --git a/lib/sdf-server/src/server/service/v2/module.rs b/lib/sdf-server/src/server/service/v2/module.rs
index bcf781023c..8e49a9fa31 100644
--- a/lib/sdf-server/src/server/service/v2/module.rs
+++ b/lib/sdf-server/src/server/service/v2/module.rs
@@ -1,19 +1,25 @@
use axum::{
http::StatusCode,
response::{IntoResponse, Response},
- routing::get,
+ routing::{get, post},
Router,
};
+use si_frontend_types as frontend_types;
use telemetry::prelude::*;
use thiserror::Error;
use crate::{server::state::AppState, service::ApiError};
+mod contribute;
mod sync;
#[remain::sorted]
#[derive(Debug, Error)]
pub enum ModulesAPIError {
+ #[error("axum http error: {0}")]
+ AxumHttp(#[from] axum::http::Error),
+ #[error("module not contributed: {0:?}")]
+ ContributionFailure(frontend_types::ModuleContributeRequest),
#[error("module error: {0}")]
Module(#[from] dal::module::ModuleError),
#[error("module index client error: {0}")]
@@ -41,6 +47,8 @@ impl IntoResponse for ModulesAPIError {
error!(%schema_variant_id, "schema variant not found");
StatusCode::NOT_FOUND
}
+ Self::Module(dal::module::ModuleError::EmptyMetadata(_, _)) => StatusCode::BAD_REQUEST,
+ Self::ContributionFailure(_) => StatusCode::BAD_REQUEST,
_ => ApiError::DEFAULT_ERROR_STATUS_CODE,
};
@@ -49,5 +57,7 @@ impl IntoResponse for ModulesAPIError {
}
pub fn v2_routes() -> Router {
- Router::new().route("/sync", get(sync::sync))
+ Router::new()
+ .route("/contribute", post(contribute::contribute))
+ .route("/sync", get(sync::sync))
}
diff --git a/lib/sdf-server/src/server/service/v2/module/contribute.rs b/lib/sdf-server/src/server/service/v2/module/contribute.rs
new file mode 100644
index 0000000000..9be281d166
--- /dev/null
+++ b/lib/sdf-server/src/server/service/v2/module/contribute.rs
@@ -0,0 +1,74 @@
+use axum::{
+ extract::{OriginalUri, Path},
+ response::IntoResponse,
+ Json,
+};
+
+use dal::{module::Module, ChangeSetId, WorkspacePk};
+use module_index_client::ModuleIndexClient;
+use si_frontend_types as frontend_types;
+
+use crate::server::{
+ extract::{AccessBuilder, HandlerContext, PosthogClient, RawAccessToken},
+ tracking::track,
+};
+
+use super::ModulesAPIError;
+
+pub async fn contribute(
+ HandlerContext(builder): HandlerContext,
+ AccessBuilder(access_builder): AccessBuilder,
+ RawAccessToken(raw_access_token): RawAccessToken,
+ PosthogClient(posthog_client): PosthogClient,
+ OriginalUri(original_uri): OriginalUri,
+ Path((_workspace_pk, change_set_id)): Path<(WorkspacePk, ChangeSetId)>,
+ Json(request): Json,
+) -> Result {
+ let ctx = builder
+ .build(access_builder.build(change_set_id.into()))
+ .await?;
+
+ // Prepare a module index client. We'll re-use it for every request.
+ let module_index_url = match ctx.module_index_url() {
+ Some(url) => url,
+ None => return Err(ModulesAPIError::ModuleIndexNotConfigured),
+ };
+ let index_client = ModuleIndexClient::new(module_index_url.try_into()?, &raw_access_token);
+
+ let (name, version, based_on_hash, schema_id, payload) = Module::prepare_contribution(
+ &ctx,
+ request.name.as_str(),
+ request.version.as_str(),
+ request.schema_variant_id.into(),
+ )
+ .await?;
+
+ let response = index_client
+ .upload_module(
+ name.as_str(),
+ version.as_str(),
+ based_on_hash.clone(),
+ schema_id.map(|id| id.to_string()),
+ payload,
+ )
+ .await?;
+
+ ctx.commit().await?;
+
+ track(
+ &posthog_client,
+ &ctx,
+ &original_uri,
+ "contribute",
+ serde_json::json!({
+ "name": name,
+ "version": version,
+ "based_on_hash": based_on_hash,
+ "schema_variant_id": request.schema_variant_id,
+ "schema_id": schema_id,
+ "pkg_hash": response.latest_hash,
+ }),
+ );
+
+ Ok(axum::response::Response::builder().body(axum::body::Empty::new())?)
+}
diff --git a/lib/si-frontend-types-rs/src/lib.rs b/lib/si-frontend-types-rs/src/lib.rs
index 5dd019bebd..719f84f326 100644
--- a/lib/si-frontend-types-rs/src/lib.rs
+++ b/lib/si-frontend-types-rs/src/lib.rs
@@ -1,12 +1,12 @@
mod func;
+mod module;
mod schema_variant;
-mod synced_modules;
pub use crate::func::{
AttributeArgumentBinding, FuncArgument, FuncArgumentKind, FuncBinding, FuncBindings, FuncCode,
FuncSummary, LeafInputLocation,
};
+pub use crate::module::{LatestModule, ModuleContributeRequest, SyncedModules};
pub use crate::schema_variant::{
ComponentType, InputSocket, OutputSocket, Prop, PropKind, SchemaVariant,
};
-pub use crate::synced_modules::{LatestModule, SyncedModules};
diff --git a/lib/si-frontend-types-rs/src/synced_modules.rs b/lib/si-frontend-types-rs/src/module.rs
similarity index 68%
rename from lib/si-frontend-types-rs/src/synced_modules.rs
rename to lib/si-frontend-types-rs/src/module.rs
index 1bce1bde9a..95d9e332c8 100644
--- a/lib/si-frontend-types-rs/src/synced_modules.rs
+++ b/lib/si-frontend-types-rs/src/module.rs
@@ -17,3 +17,11 @@ impl SyncedModules {
Self::default()
}
}
+
+#[derive(Clone, Debug, Deserialize, Eq, Serialize, PartialEq)]
+#[serde(rename_all = "camelCase")]
+pub struct ModuleContributeRequest {
+ pub name: String,
+ pub version: String,
+ pub schema_variant_id: SchemaVariantId,
+}
diff --git a/lib/si-frontend-types-rs/src/schema_variant.rs b/lib/si-frontend-types-rs/src/schema_variant.rs
index 6ba9b54db6..603e682f68 100644
--- a/lib/si-frontend-types-rs/src/schema_variant.rs
+++ b/lib/si-frontend-types-rs/src/schema_variant.rs
@@ -27,8 +27,6 @@ pub struct SchemaVariant {
pub timestamp: Timestamp,
pub can_create_new_components: bool, // if yes, show in modeling screen, if not, only show in customize
pub can_contribute: bool,
- // FIXME(nick): this needs to be dropped once the v2 modules sync route is in use.
- pub can_update: bool,
}
#[remain::sorted]
diff --git a/support/buck2/buck2-sync-cargo-deps.py b/support/buck2/buck2-sync-cargo-deps.py
index 44b56ebcaa..093a57a22d 100755
--- a/support/buck2/buck2-sync-cargo-deps.py
+++ b/support/buck2/buck2-sync-cargo-deps.py
@@ -39,15 +39,18 @@ def parse_args() -> argparse.Namespace:
def main() -> int:
args = parse_args()
- # cargo_lock_updated = update_cargo_lock(
- # Path("Cargo.toml"),
- # Path("Cargo.lock"),
- # args.check,
- # )
- # if cargo_lock_updated and args.check:
- # print("xxx Rust Cargo.lock is not in sync with Cargo.toml")
- # print(REMEDIATE_MSG)
- # return 1
+ # TODO(nick): make it so that lockfile generation does not update deps. We probably need to use "--locked" or
+ # something analogous. If you are reading this and do not know what I am talking about, reach out to Fletcher. If
+ # you are Fletcher... hi Fletcher!
+ cargo_lock_updated = update_cargo_lock(
+ Path("Cargo.toml"),
+ Path("Cargo.lock"),
+ args.check,
+ )
+ if cargo_lock_updated and args.check:
+ print("xxx Rust Cargo.lock is not in sync with Cargo.toml")
+ print(REMEDIATE_MSG)
+ return 1
cargo_toml_updated = update_third_party_rust_cargo_toml(
Path("Cargo.toml"),