Skip to content

Commit

Permalink
feat: locking mechanism (#4065)
Browse files Browse the repository at this point in the history
  • Loading branch information
brunozoric authored Apr 30, 2024
1 parent 4935d18 commit d35a4ea
Show file tree
Hide file tree
Showing 184 changed files with 7,095 additions and 244 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pullRequests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ jobs:
- 18
package: >-
${{
fromJson('[{"cmd":"packages/api","id":"api"},{"cmd":"packages/api-admin-settings","id":"api-admin-settings"},{"cmd":"packages/api-authentication","id":"api-authentication"},{"cmd":"packages/api-authentication-cognito","id":"api-authentication-cognito"},{"cmd":"packages/api-dynamodb-to-elasticsearch","id":"api-dynamodb-to-elasticsearch"},{"cmd":"packages/api-headless-cms-ddb","id":"api-headless-cms-ddb"},{"cmd":"packages/api-wcp","id":"api-wcp"},{"cmd":"packages/api-websockets","id":"api-websockets"},{"cmd":"packages/app-aco","id":"app-aco"},{"cmd":"packages/app-admin","id":"app-admin"},{"cmd":"packages/cwp-template-aws","id":"cwp-template-aws"},{"cmd":"packages/data-migration","id":"data-migration"},{"cmd":"packages/db-dynamodb","id":"db-dynamodb"},{"cmd":"packages/form","id":"form"},{"cmd":"packages/handler","id":"handler"},{"cmd":"packages/handler-aws","id":"handler-aws"},{"cmd":"packages/handler-graphql","id":"handler-graphql"},{"cmd":"packages/handler-logs","id":"handler-logs"},{"cmd":"packages/ioc","id":"ioc"},{"cmd":"packages/lexical-converter","id":"lexical-converter"},{"cmd":"packages/plugins","id":"plugins"},{"cmd":"packages/pubsub","id":"pubsub"},{"cmd":"packages/react-composition","id":"react-composition"},{"cmd":"packages/react-properties","id":"react-properties"},{"cmd":"packages/react-rich-text-lexical-renderer","id":"react-rich-text-lexical-renderer"},{"cmd":"packages/utils","id":"utils"},{"cmd":"packages/validation","id":"validation"}]')
fromJson('[{"cmd":"packages/api","id":"api"},{"cmd":"packages/api-admin-settings","id":"api-admin-settings"},{"cmd":"packages/api-authentication","id":"api-authentication"},{"cmd":"packages/api-authentication-cognito","id":"api-authentication-cognito"},{"cmd":"packages/api-dynamodb-to-elasticsearch","id":"api-dynamodb-to-elasticsearch"},{"cmd":"packages/api-headless-cms-ddb","id":"api-headless-cms-ddb"},{"cmd":"packages/api-locking-mechanism","id":"api-locking-mechanism"},{"cmd":"packages/api-wcp","id":"api-wcp"},{"cmd":"packages/api-websockets","id":"api-websockets"},{"cmd":"packages/app-aco","id":"app-aco"},{"cmd":"packages/app-admin","id":"app-admin"},{"cmd":"packages/cwp-template-aws","id":"cwp-template-aws"},{"cmd":"packages/data-migration","id":"data-migration"},{"cmd":"packages/db-dynamodb","id":"db-dynamodb"},{"cmd":"packages/form","id":"form"},{"cmd":"packages/handler","id":"handler"},{"cmd":"packages/handler-aws","id":"handler-aws"},{"cmd":"packages/handler-graphql","id":"handler-graphql"},{"cmd":"packages/handler-logs","id":"handler-logs"},{"cmd":"packages/ioc","id":"ioc"},{"cmd":"packages/lexical-converter","id":"lexical-converter"},{"cmd":"packages/plugins","id":"plugins"},{"cmd":"packages/pubsub","id":"pubsub"},{"cmd":"packages/react-composition","id":"react-composition"},{"cmd":"packages/react-properties","id":"react-properties"},{"cmd":"packages/react-rich-text-lexical-renderer","id":"react-rich-text-lexical-renderer"},{"cmd":"packages/utils","id":"utils"},{"cmd":"packages/validation","id":"validation"}]')
}}
runs-on: ${{ matrix.os }}
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pushDev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ jobs:
- 18
package: >-
${{
fromJson('[{"cmd":"packages/api","id":"api"},{"cmd":"packages/api-admin-settings","id":"api-admin-settings"},{"cmd":"packages/api-authentication","id":"api-authentication"},{"cmd":"packages/api-authentication-cognito","id":"api-authentication-cognito"},{"cmd":"packages/api-dynamodb-to-elasticsearch","id":"api-dynamodb-to-elasticsearch"},{"cmd":"packages/api-headless-cms-ddb","id":"api-headless-cms-ddb"},{"cmd":"packages/api-wcp","id":"api-wcp"},{"cmd":"packages/api-websockets","id":"api-websockets"},{"cmd":"packages/app-aco","id":"app-aco"},{"cmd":"packages/app-admin","id":"app-admin"},{"cmd":"packages/cwp-template-aws","id":"cwp-template-aws"},{"cmd":"packages/data-migration","id":"data-migration"},{"cmd":"packages/db-dynamodb","id":"db-dynamodb"},{"cmd":"packages/form","id":"form"},{"cmd":"packages/handler","id":"handler"},{"cmd":"packages/handler-aws","id":"handler-aws"},{"cmd":"packages/handler-graphql","id":"handler-graphql"},{"cmd":"packages/handler-logs","id":"handler-logs"},{"cmd":"packages/ioc","id":"ioc"},{"cmd":"packages/lexical-converter","id":"lexical-converter"},{"cmd":"packages/plugins","id":"plugins"},{"cmd":"packages/pubsub","id":"pubsub"},{"cmd":"packages/react-composition","id":"react-composition"},{"cmd":"packages/react-properties","id":"react-properties"},{"cmd":"packages/react-rich-text-lexical-renderer","id":"react-rich-text-lexical-renderer"},{"cmd":"packages/utils","id":"utils"},{"cmd":"packages/validation","id":"validation"}]')
fromJson('[{"cmd":"packages/api","id":"api"},{"cmd":"packages/api-admin-settings","id":"api-admin-settings"},{"cmd":"packages/api-authentication","id":"api-authentication"},{"cmd":"packages/api-authentication-cognito","id":"api-authentication-cognito"},{"cmd":"packages/api-dynamodb-to-elasticsearch","id":"api-dynamodb-to-elasticsearch"},{"cmd":"packages/api-headless-cms-ddb","id":"api-headless-cms-ddb"},{"cmd":"packages/api-locking-mechanism","id":"api-locking-mechanism"},{"cmd":"packages/api-wcp","id":"api-wcp"},{"cmd":"packages/api-websockets","id":"api-websockets"},{"cmd":"packages/app-aco","id":"app-aco"},{"cmd":"packages/app-admin","id":"app-admin"},{"cmd":"packages/cwp-template-aws","id":"cwp-template-aws"},{"cmd":"packages/data-migration","id":"data-migration"},{"cmd":"packages/db-dynamodb","id":"db-dynamodb"},{"cmd":"packages/form","id":"form"},{"cmd":"packages/handler","id":"handler"},{"cmd":"packages/handler-aws","id":"handler-aws"},{"cmd":"packages/handler-graphql","id":"handler-graphql"},{"cmd":"packages/handler-logs","id":"handler-logs"},{"cmd":"packages/ioc","id":"ioc"},{"cmd":"packages/lexical-converter","id":"lexical-converter"},{"cmd":"packages/plugins","id":"plugins"},{"cmd":"packages/pubsub","id":"pubsub"},{"cmd":"packages/react-composition","id":"react-composition"},{"cmd":"packages/react-properties","id":"react-properties"},{"cmd":"packages/react-rich-text-lexical-renderer","id":"react-rich-text-lexical-renderer"},{"cmd":"packages/utils","id":"utils"},{"cmd":"packages/validation","id":"validation"}]')
}}
runs-on: ${{ matrix.os }}
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pushNext.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ jobs:
- 18
package: >-
${{
fromJson('[{"cmd":"packages/api","id":"api"},{"cmd":"packages/api-admin-settings","id":"api-admin-settings"},{"cmd":"packages/api-authentication","id":"api-authentication"},{"cmd":"packages/api-authentication-cognito","id":"api-authentication-cognito"},{"cmd":"packages/api-dynamodb-to-elasticsearch","id":"api-dynamodb-to-elasticsearch"},{"cmd":"packages/api-headless-cms-ddb","id":"api-headless-cms-ddb"},{"cmd":"packages/api-wcp","id":"api-wcp"},{"cmd":"packages/api-websockets","id":"api-websockets"},{"cmd":"packages/app-aco","id":"app-aco"},{"cmd":"packages/app-admin","id":"app-admin"},{"cmd":"packages/cwp-template-aws","id":"cwp-template-aws"},{"cmd":"packages/data-migration","id":"data-migration"},{"cmd":"packages/db-dynamodb","id":"db-dynamodb"},{"cmd":"packages/form","id":"form"},{"cmd":"packages/handler","id":"handler"},{"cmd":"packages/handler-aws","id":"handler-aws"},{"cmd":"packages/handler-graphql","id":"handler-graphql"},{"cmd":"packages/handler-logs","id":"handler-logs"},{"cmd":"packages/ioc","id":"ioc"},{"cmd":"packages/lexical-converter","id":"lexical-converter"},{"cmd":"packages/plugins","id":"plugins"},{"cmd":"packages/pubsub","id":"pubsub"},{"cmd":"packages/react-composition","id":"react-composition"},{"cmd":"packages/react-properties","id":"react-properties"},{"cmd":"packages/react-rich-text-lexical-renderer","id":"react-rich-text-lexical-renderer"},{"cmd":"packages/utils","id":"utils"},{"cmd":"packages/validation","id":"validation"}]')
fromJson('[{"cmd":"packages/api","id":"api"},{"cmd":"packages/api-admin-settings","id":"api-admin-settings"},{"cmd":"packages/api-authentication","id":"api-authentication"},{"cmd":"packages/api-authentication-cognito","id":"api-authentication-cognito"},{"cmd":"packages/api-dynamodb-to-elasticsearch","id":"api-dynamodb-to-elasticsearch"},{"cmd":"packages/api-headless-cms-ddb","id":"api-headless-cms-ddb"},{"cmd":"packages/api-locking-mechanism","id":"api-locking-mechanism"},{"cmd":"packages/api-wcp","id":"api-wcp"},{"cmd":"packages/api-websockets","id":"api-websockets"},{"cmd":"packages/app-aco","id":"app-aco"},{"cmd":"packages/app-admin","id":"app-admin"},{"cmd":"packages/cwp-template-aws","id":"cwp-template-aws"},{"cmd":"packages/data-migration","id":"data-migration"},{"cmd":"packages/db-dynamodb","id":"db-dynamodb"},{"cmd":"packages/form","id":"form"},{"cmd":"packages/handler","id":"handler"},{"cmd":"packages/handler-aws","id":"handler-aws"},{"cmd":"packages/handler-graphql","id":"handler-graphql"},{"cmd":"packages/handler-logs","id":"handler-logs"},{"cmd":"packages/ioc","id":"ioc"},{"cmd":"packages/lexical-converter","id":"lexical-converter"},{"cmd":"packages/plugins","id":"plugins"},{"cmd":"packages/pubsub","id":"pubsub"},{"cmd":"packages/react-composition","id":"react-composition"},{"cmd":"packages/react-properties","id":"react-properties"},{"cmd":"packages/react-rich-text-lexical-renderer","id":"react-rich-text-lexical-renderer"},{"cmd":"packages/utils","id":"utils"},{"cmd":"packages/validation","id":"validation"}]')
}}
runs-on: ${{ matrix.os }}
env:
Expand Down
1 change: 1 addition & 0 deletions apps/api/graphql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@webiny/api-i18n": "0.0.0",
"@webiny/api-i18n-content": "0.0.0",
"@webiny/api-i18n-ddb": "0.0.0",
"@webiny/api-locking-mechanism": "0.0.0",
"@webiny/api-page-builder": "0.0.0",
"@webiny/api-page-builder-aco": "0.0.0",
"@webiny/api-page-builder-import-export": "0.0.0",
Expand Down
2 changes: 2 additions & 0 deletions apps/api/graphql/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { createBenchmarkEnablePlugin } from "~/plugins/benchmarkEnable";
import { createCountDynamoDbTask } from "~/plugins/countDynamoDbTask";
import { createContinuingTask } from "~/plugins/continuingTask";
import { createWebsockets } from "@webiny/api-websockets";
import { createLockingMechanism } from "@webiny/api-locking-mechanism";

const debug = process.env.DEBUG === "true";
const documentClient = getDocumentClient();
Expand Down Expand Up @@ -70,6 +71,7 @@ export const handler = createHandler({
})
}),
createHeadlessCmsGraphQL(),
createLockingMechanism(),
createBackgroundTasks(),
createFileManagerContext({
storageOperations: createFileManagerStorageOperations({
Expand Down
5 changes: 5 additions & 0 deletions apps/api/graphql/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
{
"path": "../../../packages/api-audit-logs/tsconfig.build.json"
},
{
"path": "../../../packages/api-locking-mechanism/tsconfig.build.json"
},
{
"path": "../../../packages/api-file-manager/tsconfig.build.json"
},
Expand Down Expand Up @@ -153,6 +156,8 @@
"@webiny/api-headless-cms-aco": ["../../../packages/api-headless-cms-aco/src"],
"@webiny/api-headless-cms-ddb/*": ["../../../packages/api-headless-cms-ddb/src/*"],
"@webiny/api-headless-cms-ddb": ["../../../packages/api-headless-cms-ddb/src"],
"@webiny/api-locking-mechanism/*": ["../../../packages/api-locking-mechanism/src/*"],
"@webiny/api-locking-mechanism": ["../../../packages/api-locking-mechanism/src"],
"@webiny/api-headless-cms-tasks/*": ["../../../packages/api-headless-cms-tasks/src/*"],
"@webiny/api-headless-cms-tasks": ["../../../packages/api-headless-cms-tasks/src"],
"@webiny/api-i18n/*": ["../../../packages/api-i18n/src/*"],
Expand Down
2 changes: 1 addition & 1 deletion packages/api-file-manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@webiny/tasks": "0.0.0",
"@webiny/validation": "0.0.0",
"lodash": "4.17.21",
"object-hash": "^2.1.1"
"object-hash": "^3.0.0"
},
"devDependencies": {
"@babel/cli": "^7.23.9",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useGraphQLHandler } from "../testHelpers/useGraphQLHandler";
import { CmsGraphQLSchemaPlugin } from "~/plugins";
import { createCmsGraphQLSchemaPlugin } from "~/plugins";

const graphqlSchemaPlugin = new CmsGraphQLSchemaPlugin({
const graphqlSchemaPlugin = createCmsGraphQLSchemaPlugin({
typeDefs: /* GraphQL */ `
extend type Query {
getOne: Int
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useGraphQLHandler } from "../testHelpers/useGraphQLHandler";
import { CmsGraphQLSchemaPlugin } from "~/plugins";
import { createCmsGraphQLSchemaPlugin } from "~/plugins";

const graphqlSchemaPlugin = new CmsGraphQLSchemaPlugin({
const graphqlSchemaPlugin = createCmsGraphQLSchemaPlugin({
typeDefs: /* GraphQL */ `
type BrokenType {
# types without fields are invalid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ interface CanAccessModelParams extends GetModelsAccessControlListParams {
}

interface GetEntriesAccessControlListParams {
model: CmsModel;
entry?: CmsEntry;
model: Pick<CmsModel, "modelId" | "createdBy" | "group" | "locale" | "authorization">;
entry?: Pick<CmsEntry, "entryId" | "createdBy">;
}

interface CanAccessEntryParams extends GetEntriesAccessControlListParams {
export interface CanAccessEntryParams extends GetEntriesAccessControlListParams {
rwd?: string;
pw?: string;
}
Expand All @@ -57,6 +57,10 @@ interface EntriesAccessControlEntry extends AccessControlEntry {

type EntriesAccessControlList = EntriesAccessControlEntry[];

interface IModelAuthorizationDisabledParams {
model: Pick<CmsModel, "authorization">;
}

export class AccessControl {
getIdentity: AccessControlParams["getIdentity"];
getGroupsPermissions: AccessControlParams["getGroupsPermissions"];
Expand Down Expand Up @@ -653,7 +657,7 @@ export class AccessControl {
return permissions.some(p => this.fullAccessPermissions.filter(Boolean).includes(p.name));
}

private modelAuthorizationDisabled(params: { model: CmsModel }) {
private modelAuthorizationDisabled(params: IModelAuthorizationDisabledParams) {
if ("authorization" in params.model) {
const { authorization } = params.model;
if (typeof authorization === "boolean") {
Expand Down
5 changes: 0 additions & 5 deletions packages/api-headless-cms/src/crud/contentEntry.crud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
CmsModel,
CmsStorageEntry,
EntryBeforeListTopicParams,
HeadlessCms,
HeadlessCmsStorageOperations,
OnEntryAfterCreateTopicParams,
OnEntryAfterDeleteMultipleTopicParams,
Expand Down Expand Up @@ -1303,8 +1302,6 @@ export const createContentEntryCrud = (params: CreateContentEntryCrudParams): Cm
);
},
/**
* TODO determine if this method is required at all.
*
* @internal
*/
async getEntry(model, params) {
Expand All @@ -1326,7 +1323,6 @@ export const createContentEntryCrud = (params: CreateContentEntryCrudParams): Cm
});
},
async listLatestEntries<T = CmsEntryValues>(
this: HeadlessCms,
model: CmsModel,
params?: CmsEntryListParams
): Promise<[CmsEntry<T>[], CmsEntryMeta]> {
Expand All @@ -1338,7 +1334,6 @@ export const createContentEntryCrud = (params: CreateContentEntryCrudParams): Cm
);
},
async listDeletedEntries<T = CmsEntryValues>(
this: HeadlessCms,
model: CmsModel,
params?: CmsEntryListParams
): Promise<[CmsEntry<T>[], CmsEntryMeta]> {
Expand Down
16 changes: 8 additions & 8 deletions packages/api-headless-cms/src/crud/contentModel.crud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ export const createModelsCrud = (params: CreateModelsCrudParams): CmsModelContex
};

const managers = new Map<string, CmsModelManager>();
const updateManager = async (
const updateManager = async <T>(
context: CmsContext,
model: CmsModel
): Promise<CmsModelManager> => {
const manager = await contentModelManagerFactory(context, model);
): Promise<CmsModelManager<T>> => {
const manager = await contentModelManagerFactory<T>(context, model);
managers.set(model.modelId, manager);
return manager;
};
Expand Down Expand Up @@ -206,15 +206,15 @@ export const createModelsCrud = (params: CreateModelsCrudParams): CmsModelContex
});
};

const getEntryManager: CmsModelContext["getEntryManager"] = async (
target
): Promise<CmsModelManager> => {
const getEntryManager: CmsModelContext["getEntryManager"] = async <T>(
target: string | Pick<CmsModel, "modelId">
): Promise<CmsModelManager<T>> => {
const modelId = typeof target === "string" ? target : target.modelId;
if (managers.has(modelId)) {
return managers.get(modelId) as CmsModelManager;
return managers.get(modelId) as CmsModelManager<T>;
}
const model = await getModelFromCache(modelId);
return await updateManager(context, model);
return await updateManager<T>(context, model);
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@ import { CmsModel, CmsContext, ModelManagerPlugin, CmsModelManager } from "~/typ

const defaultName = "content-model-manager-default";

export const contentModelManagerFactory = async (
export const contentModelManagerFactory = async <T>(
context: CmsContext,
model: CmsModel
): Promise<CmsModelManager> => {
): Promise<CmsModelManager<T>> => {
const pluginsByType = context.plugins
.byType<ModelManagerPlugin>("cms-content-model-manager")
.reverse();
for (const plugin of pluginsByType) {
const target = Array.isArray(plugin.modelId) ? plugin.modelId : [plugin.modelId];
if (target.includes(model.modelId) === true && plugin.name !== defaultName) {
return await plugin.create(context, model);
return await plugin.create<T>(context, model);
}
}
const plugin = pluginsByType.find(plugin => plugin.name === defaultName);
if (!plugin) {
throw new Error("There is no default plugin to create CmsModelManager");
}
return await plugin.create(context, model);
return await plugin.create<T>(context, model);
};
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import gql from "graphql-tag";
import WebinyError from "@webiny/error";
import {
CmsModel,
CmsContext,
CmsModel,
CmsModelField,
CmsModelFieldToGraphQLPlugin,
CmsModelFieldToGraphQLPluginValidateChildFieldsValidate,
Expand All @@ -16,7 +16,11 @@ import { getBaseFieldType } from "~/utils/getBaseFieldType";
import { getContentModelTitleFieldId } from "./fields/titleField";
import { getContentModelDescriptionFieldId } from "./fields/descriptionField";
import { getContentModelImageFieldId } from "./fields/imageField";
import { CmsGraphQLSchemaPlugin, CmsGraphQLSchemaSorterPlugin } from "~/plugins";
import {
CmsGraphQLSchemaPlugin,
CmsGraphQLSchemaSorterPlugin,
ICmsGraphQLSchemaPlugin
} from "~/plugins";
import { buildSchemaPlugins } from "~/graphql/buildSchemaPlugins";
import { createExecutableSchema } from "~/graphql/createExecutableSchema";
import { generateAlphaNumericId } from "@webiny/utils";
Expand Down Expand Up @@ -227,8 +231,8 @@ const createGraphQLSchema = async (params: CreateGraphQLSchemaParams): Promise<a
});

const plugins = context.plugins
.byType<CmsGraphQLSchemaPlugin>(CmsGraphQLSchemaPlugin.type)
.reduce<Record<string, CmsGraphQLSchemaPlugin>>((collection, plugin) => {
.byType<ICmsGraphQLSchemaPlugin>(CmsGraphQLSchemaPlugin.type)
.reduce<Record<string, ICmsGraphQLSchemaPlugin>>((collection, plugin) => {
const name =
plugin.name || `${CmsGraphQLSchemaPlugin.type}-${generateAlphaNumericId(16)}`;
collection[name] = plugin;
Expand Down
4 changes: 2 additions & 2 deletions packages/api-headless-cms/src/export/graphql/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { CmsGraphQLSchemaPlugin } from "~/plugins";
import { createCmsGraphQLSchemaPlugin } from "~/plugins";
import { ErrorResponse, Response } from "@webiny/handler-graphql";
import { ContextPlugin } from "@webiny/handler";
import { CmsContext } from "~/types";

const plugin = new CmsGraphQLSchemaPlugin({
const plugin = createCmsGraphQLSchemaPlugin({
typeDefs: /* GraphQL */ `
type CmsExportStructureResponse {
data: String
Expand Down
Loading

0 comments on commit d35a4ea

Please sign in to comment.