@memberjunction/database-designer-actions 0.0.1 → 5.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +4 -0
- package/CHANGELOG.md +37 -0
- package/dist/actions/base-database-designer.action.d.ts +52 -0
- package/dist/actions/base-database-designer.action.d.ts.map +1 -0
- package/dist/actions/base-database-designer.action.js +162 -0
- package/dist/actions/base-database-designer.action.js.map +1 -0
- package/dist/actions/create-entity.action.d.ts +36 -0
- package/dist/actions/create-entity.action.d.ts.map +1 -0
- package/dist/actions/create-entity.action.js +65 -0
- package/dist/actions/create-entity.action.js.map +1 -0
- package/dist/actions/describe-entity.action.d.ts +29 -0
- package/dist/actions/describe-entity.action.d.ts.map +1 -0
- package/dist/actions/describe-entity.action.js +116 -0
- package/dist/actions/describe-entity.action.js.map +1 -0
- package/dist/actions/list-entities.action.d.ts +26 -0
- package/dist/actions/list-entities.action.d.ts.map +1 -0
- package/dist/actions/list-entities.action.js +91 -0
- package/dist/actions/list-entities.action.js.map +1 -0
- package/dist/actions/modify-entity.action.d.ts +28 -0
- package/dist/actions/modify-entity.action.d.ts.map +1 -0
- package/dist/actions/modify-entity.action.js +65 -0
- package/dist/actions/modify-entity.action.js.map +1 -0
- package/dist/actions/validate-entity-schema.action.d.ts +38 -0
- package/dist/actions/validate-entity-schema.action.d.ts.map +1 -0
- package/dist/actions/validate-entity-schema.action.js +85 -0
- package/dist/actions/validate-entity-schema.action.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/package.json +32 -7
- package/src/__tests__/validate-entity-schema.action.test.ts +243 -0
- package/src/actions/base-database-designer.action.ts +210 -0
- package/src/actions/create-entity.action.ts +66 -0
- package/src/actions/describe-entity.action.ts +160 -0
- package/src/actions/list-entities.action.ts +110 -0
- package/src/actions/modify-entity.action.ts +75 -0
- package/src/actions/validate-entity-schema.action.ts +89 -0
- package/src/index.ts +15 -0
- package/tsconfig.json +16 -0
- package/vitest.config.ts +8 -0
- package/README.md +0 -45
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module list-entities.action
|
|
3
|
+
* @description Returns a summary list of entities created via the Database Designer.
|
|
4
|
+
*
|
|
5
|
+
* Queries MJ: Entity Settings for records with `MJ:UDT:Owner = contextUser.ID`
|
|
6
|
+
* then joins with Entities metadata to build a human-readable summary.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
10
|
+
import { BaseAction } from '@memberjunction/actions';
|
|
11
|
+
import type { ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
|
|
12
|
+
import { RunView, Metadata, UserInfo } from '@memberjunction/core';
|
|
13
|
+
|
|
14
|
+
import { UDT_SETTINGS, escapeSqlLiteral } from '@memberjunction/database-designer-core';
|
|
15
|
+
|
|
16
|
+
import { BaseDatabaseDesignerAction } from './base-database-designer.action.js';
|
|
17
|
+
|
|
18
|
+
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
interface EntitySummary {
|
|
21
|
+
EntityID: string;
|
|
22
|
+
EntityName: string;
|
|
23
|
+
SchemaName: string;
|
|
24
|
+
TableName: string;
|
|
25
|
+
Description: string | null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ─── Registration ─────────────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Lists all entities created by the current user via the Database Designer.
|
|
32
|
+
*
|
|
33
|
+
* Input params: none — uses `ContextUser` for ownership lookup.
|
|
34
|
+
*
|
|
35
|
+
* Output params:
|
|
36
|
+
* - `Entities` — Array of EntitySummary objects.
|
|
37
|
+
* - `EntityCount` — Total number of entities owned by this user.
|
|
38
|
+
*/
|
|
39
|
+
@RegisterClass(BaseAction, 'List My Entities')
|
|
40
|
+
export class ListMyEntitiesAction extends BaseDatabaseDesignerAction {
|
|
41
|
+
protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
|
|
42
|
+
try {
|
|
43
|
+
const userID = params.ContextUser?.ID;
|
|
44
|
+
if (!userID) {
|
|
45
|
+
return {
|
|
46
|
+
Success: false,
|
|
47
|
+
ResultCode: 'NO_USER_CONTEXT',
|
|
48
|
+
Message: 'ContextUser is required to list owned entities.',
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const entities = await this.loadUserEntities(userID, params);
|
|
53
|
+
|
|
54
|
+
this.addOutputParam(params, 'Entities', entities);
|
|
55
|
+
this.addOutputParam(params, 'EntityCount', entities.length);
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
Success: true,
|
|
59
|
+
ResultCode: 'SUCCESS',
|
|
60
|
+
Message: `Found ${entities.length} entity${entities.length === 1 ? '' : 'ies'} created by this user.`,
|
|
61
|
+
};
|
|
62
|
+
} catch (err) {
|
|
63
|
+
return this.handleUnexpected(err, 'List My Entities');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ─── Private helpers ──────────────────────────────────────────────────
|
|
68
|
+
|
|
69
|
+
/** Query Entity Settings for ownership records, then enrich from metadata. */
|
|
70
|
+
private async loadUserEntities(
|
|
71
|
+
userID: string,
|
|
72
|
+
params: RunActionParams
|
|
73
|
+
): Promise<EntitySummary[]> {
|
|
74
|
+
const rv = new RunView();
|
|
75
|
+
const settingsResult = await rv.RunView<{ EntityID: string }>({
|
|
76
|
+
EntityName: 'MJ: Entity Settings',
|
|
77
|
+
ExtraFilter: `Name = '${UDT_SETTINGS.OWNER_KEY}' AND Value = '${escapeSqlLiteral(userID)}'`,
|
|
78
|
+
Fields: ['EntityID'],
|
|
79
|
+
ResultType: 'simple',
|
|
80
|
+
}, params.ContextUser);
|
|
81
|
+
|
|
82
|
+
if (!settingsResult.Success || settingsResult.Results.length === 0) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const entityIDs = settingsResult.Results.map(r => r.EntityID);
|
|
87
|
+
return this.buildEntitySummaries(entityIDs, params.ContextUser);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Look up entity metadata for a list of entity IDs. */
|
|
91
|
+
private buildEntitySummaries(
|
|
92
|
+
entityIDs: string[],
|
|
93
|
+
contextUser: UserInfo
|
|
94
|
+
): EntitySummary[] {
|
|
95
|
+
const md = new Metadata(); // global-provider-ok: MJAPI server-side, single-provider deployment
|
|
96
|
+
return entityIDs.reduce<EntitySummary[]>((acc, id) => {
|
|
97
|
+
const info = md.Entities.find(e => UUIDsEqual(e.ID, id));
|
|
98
|
+
if (info) {
|
|
99
|
+
acc.push({
|
|
100
|
+
EntityID: info.ID,
|
|
101
|
+
EntityName: info.Name,
|
|
102
|
+
SchemaName: info.SchemaName ?? '',
|
|
103
|
+
TableName: info.BaseTable ?? '',
|
|
104
|
+
Description: info.Description ?? null,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return acc;
|
|
108
|
+
}, []);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module modify-entity.action
|
|
3
|
+
* @description Action that applies ALTER TABLE changes to an existing MJ entity
|
|
4
|
+
* based on a new `TableDefinition` (desired state).
|
|
5
|
+
*
|
|
6
|
+
* Execution path:
|
|
7
|
+
* 1. Extract and validate params
|
|
8
|
+
* 2. Authorization check
|
|
9
|
+
* 3. Load existing table info via DatabaseDesignerPipelineExecutor.LoadExistingTableInfo
|
|
10
|
+
* 4. Delegate to DatabaseDesignerPipelineExecutor.ModifyEntity
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
14
|
+
import { BaseAction } from '@memberjunction/actions';
|
|
15
|
+
import type { ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
DatabaseDesignerPipelineExecutor,
|
|
19
|
+
UDT_SETTINGS,
|
|
20
|
+
} from '@memberjunction/database-designer-core';
|
|
21
|
+
|
|
22
|
+
import { BaseDatabaseDesignerAction } from './base-database-designer.action.js';
|
|
23
|
+
|
|
24
|
+
// ─── Registration ─────────────────────────────────────────────────────────────
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Applies ALTER TABLE changes to an existing MemberJunction entity.
|
|
28
|
+
*
|
|
29
|
+
* Input params:
|
|
30
|
+
* - `TableDefinition` (required) — desired table state as a JSON object.
|
|
31
|
+
* - `SkipGitCommit` (optional, default false)
|
|
32
|
+
* - `SkipRestart` (optional, default false)
|
|
33
|
+
*
|
|
34
|
+
* Output params written on success:
|
|
35
|
+
* - `EntityID`, `EntityName`, `SchemaName`, `TableName`, `PipelineSteps`
|
|
36
|
+
*/
|
|
37
|
+
@RegisterClass(BaseAction, 'Modify Entity')
|
|
38
|
+
export class ModifyEntityAction extends BaseDatabaseDesignerAction {
|
|
39
|
+
protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
|
|
40
|
+
try {
|
|
41
|
+
const { td, error: tdError } = this.getTableDefinitionParam(params);
|
|
42
|
+
if (tdError) return tdError;
|
|
43
|
+
|
|
44
|
+
const authError = await this.checkAuthorization(td!, 'alter', params.ContextUser);
|
|
45
|
+
if (authError) {
|
|
46
|
+
return { Success: false, ResultCode: 'UNAUTHORIZED', Message: authError };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const existingInfo = await DatabaseDesignerPipelineExecutor.LoadExistingTableInfo(
|
|
50
|
+
td!.SchemaName,
|
|
51
|
+
td!.TableName,
|
|
52
|
+
params.ContextUser
|
|
53
|
+
);
|
|
54
|
+
if (!existingInfo) {
|
|
55
|
+
return {
|
|
56
|
+
Success: false,
|
|
57
|
+
ResultCode: 'ENTITY_NOT_FOUND',
|
|
58
|
+
Message: `Table '${td!.SchemaName}.${td!.TableName}' was not found in the database.`,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const options = this.buildPipelineOptions(params, UDT_SETTINGS.SOURCE_DATABASE_DESIGNER);
|
|
63
|
+
const execResult = await DatabaseDesignerPipelineExecutor.ModifyEntity(
|
|
64
|
+
td!,
|
|
65
|
+
existingInfo,
|
|
66
|
+
params.ContextUser,
|
|
67
|
+
options
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
return this.buildPipelineResult(execResult, params);
|
|
71
|
+
} catch (err) {
|
|
72
|
+
return this.handleUnexpected(err, 'Modify Entity');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module validate-entity-schema.action
|
|
3
|
+
* @description Action that validates a `TableDefinition` against all Entity
|
|
4
|
+
* Designer pre-creation checks without executing the RSU pipeline.
|
|
5
|
+
*
|
|
6
|
+
* Intended callers:
|
|
7
|
+
* - Angular visual wizard (Step 4 — Review) pre-validates before the user
|
|
8
|
+
* submits to `CreateEntityAction` so errors surface early without a
|
|
9
|
+
* round-trip through the full pipeline.
|
|
10
|
+
* - Any workflow that needs a dry-run validation step before creation.
|
|
11
|
+
*
|
|
12
|
+
* This action runs the same `DatabaseSchemaValidationService` that the agent
|
|
13
|
+
* path (`DatabaseDesignerSchemaValidator`) uses, ensuring both paths are
|
|
14
|
+
* governed by identical rules.
|
|
15
|
+
*
|
|
16
|
+
* Input params:
|
|
17
|
+
* - `TableDefinition` (required) — JSON object conforming to the schema-engine
|
|
18
|
+
* `TableDefinition` interface.
|
|
19
|
+
* - `ModificationType` (optional, default 'create') — 'create' | 'alter'.
|
|
20
|
+
* Determines which authorization is checked before validation.
|
|
21
|
+
*
|
|
22
|
+
* Output params written on both success and validation failure:
|
|
23
|
+
* - `ValidationResult` — `{ Valid, Errors, Warnings }` — always present on
|
|
24
|
+
* `Success: true` so callers can inspect details without parsing `Message`.
|
|
25
|
+
*
|
|
26
|
+
* ResultCode values:
|
|
27
|
+
* - `VALIDATION_PASSED` — definition is valid, safe to proceed to CreateEntity.
|
|
28
|
+
* - `VALIDATION_FAILED` — definition has errors; inspect `ValidationResult.Errors`.
|
|
29
|
+
* - `UNAUTHORIZED` — contextUser lacks the required authorization.
|
|
30
|
+
* - `MISSING_PARAMETER` — required params were not provided.
|
|
31
|
+
* - `UNEXPECTED_ERROR` — unhandled exception (check server logs).
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
35
|
+
import { BaseAction } from '@memberjunction/actions';
|
|
36
|
+
import type { ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
|
|
37
|
+
|
|
38
|
+
import {
|
|
39
|
+
DatabaseSchemaValidationService,
|
|
40
|
+
} from '@memberjunction/database-designer-core';
|
|
41
|
+
|
|
42
|
+
import { BaseDatabaseDesignerAction } from './base-database-designer.action.js';
|
|
43
|
+
|
|
44
|
+
// ─── Registration ─────────────────────────────────────────────────────────────
|
|
45
|
+
|
|
46
|
+
@RegisterClass(BaseAction, 'Validate Entity Schema')
|
|
47
|
+
export class ValidateEntitySchemaAction extends BaseDatabaseDesignerAction {
|
|
48
|
+
|
|
49
|
+
protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
|
|
50
|
+
try {
|
|
51
|
+
const { td, error: tdError } = this.getTableDefinitionParam(params);
|
|
52
|
+
if (tdError) return tdError;
|
|
53
|
+
|
|
54
|
+
const modificationType = this.getModificationTypeParam(params);
|
|
55
|
+
|
|
56
|
+
// Authorization check: verify the user is allowed to perform this
|
|
57
|
+
// operation type before revealing any validation details.
|
|
58
|
+
const authError = await this.checkAuthorization(td!, modificationType, params.ContextUser);
|
|
59
|
+
if (authError) {
|
|
60
|
+
return { Success: false, ResultCode: 'UNAUTHORIZED', Message: authError };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Run all deterministic validation checks via the shared service.
|
|
64
|
+
const service = new DatabaseSchemaValidationService();
|
|
65
|
+
const validationResult = await service.validate(td!, params.ContextUser, modificationType);
|
|
66
|
+
|
|
67
|
+
// Always write the structured result as an output param so callers
|
|
68
|
+
// can read Errors/Warnings without parsing the human-readable Message.
|
|
69
|
+
this.addOutputParam(params, 'ValidationResult', validationResult);
|
|
70
|
+
|
|
71
|
+
if (validationResult.Valid) {
|
|
72
|
+
return {
|
|
73
|
+
Success: true,
|
|
74
|
+
ResultCode: 'VALIDATION_PASSED',
|
|
75
|
+
Message: 'Validation passed. The entity definition is ready for creation.',
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
Success: true, // Action ran successfully — validation result is the output
|
|
81
|
+
ResultCode: 'VALIDATION_FAILED',
|
|
82
|
+
Message: `Validation failed: ${validationResult.Errors.join('; ')}`,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
} catch (err) {
|
|
86
|
+
return this.handleUnexpected(err, 'Validate Entity Schema');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @memberjunction/database-designer-actions
|
|
3
|
+
* @description Database Designer action classes for use by AI agents,
|
|
4
|
+
* workflow engines, and low-code builders.
|
|
5
|
+
*
|
|
6
|
+
* Importing this module registers all action driver classes with the MJ
|
|
7
|
+
* ClassFactory so they are discoverable at runtime.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export * from './actions/base-database-designer.action.js';
|
|
11
|
+
export * from './actions/create-entity.action.js';
|
|
12
|
+
export * from './actions/modify-entity.action.js';
|
|
13
|
+
export * from './actions/list-entities.action.js';
|
|
14
|
+
export * from './actions/describe-entity.action.js';
|
|
15
|
+
export * from './actions/validate-entity-schema.action.js';
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../../tsconfig.server.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "dist",
|
|
5
|
+
"rootDir": "src"
|
|
6
|
+
},
|
|
7
|
+
"include": [
|
|
8
|
+
"src/**/*"
|
|
9
|
+
],
|
|
10
|
+
"exclude": [
|
|
11
|
+
"node_modules",
|
|
12
|
+
"src/**/*.test.ts",
|
|
13
|
+
"src/**/*.spec.ts",
|
|
14
|
+
"vitest.config.ts"
|
|
15
|
+
]
|
|
16
|
+
}
|
package/vitest.config.ts
ADDED
package/README.md
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# @memberjunction/database-designer-actions
|
|
2
|
-
|
|
3
|
-
## ⚠️ IMPORTANT NOTICE ⚠️
|
|
4
|
-
|
|
5
|
-
**This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
|
|
6
|
-
|
|
7
|
-
This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
|
|
8
|
-
|
|
9
|
-
## Purpose
|
|
10
|
-
|
|
11
|
-
This package exists to:
|
|
12
|
-
1. Configure OIDC trusted publishing for the package name `@memberjunction/database-designer-actions`
|
|
13
|
-
2. Enable secure, token-less publishing from CI/CD workflows
|
|
14
|
-
3. Establish provenance for packages published under this name
|
|
15
|
-
|
|
16
|
-
## What is OIDC Trusted Publishing?
|
|
17
|
-
|
|
18
|
-
OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
|
|
19
|
-
|
|
20
|
-
## Setup Instructions
|
|
21
|
-
|
|
22
|
-
To properly configure OIDC trusted publishing for this package:
|
|
23
|
-
|
|
24
|
-
1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
|
|
25
|
-
2. Configure the trusted publisher (e.g., GitHub Actions)
|
|
26
|
-
3. Specify the repository and workflow that should be allowed to publish
|
|
27
|
-
4. Use the configured workflow to publish your actual package
|
|
28
|
-
|
|
29
|
-
## DO NOT USE THIS PACKAGE
|
|
30
|
-
|
|
31
|
-
This package is a placeholder for OIDC configuration only. It:
|
|
32
|
-
- Contains no executable code
|
|
33
|
-
- Provides no functionality
|
|
34
|
-
- Should not be installed as a dependency
|
|
35
|
-
- Exists only for administrative purposes
|
|
36
|
-
|
|
37
|
-
## More Information
|
|
38
|
-
|
|
39
|
-
For more details about npm's trusted publishing feature, see:
|
|
40
|
-
- [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
|
|
41
|
-
- [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
**Maintained for OIDC setup purposes only**
|