New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@memberjunction/core

Package Overview
Dependencies
Maintainers
0
Versions
261
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@memberjunction/core - npm Package Compare versions

Comparing version 2.24.1 to 2.25.0

6

dist/generic/baseEntity.d.ts

@@ -84,2 +84,3 @@ import { EntityFieldInfo, EntityInfo, EntityFieldTSType, EntityPermissionType, RecordChange, ValidationResult, EntityRelationshipInfo } from './entityInfo';

relatedEntityList: DataObjectRelatedEntityParam[];
constructor(oldValues?: boolean, omitNullValues?: boolean, omitEmptyStrings?: boolean, excludeFields?: string[], includeRelatedEntityData?: boolean, relatedEntityList?: DataObjectRelatedEntityParam[]);
}

@@ -302,3 +303,3 @@ export declare class BaseEntityAIActionParams {

*/
GetDataObjectJSON(params: DataObjectParams, minifyJSON?: boolean): Promise<string>;
GetDataObjectJSON(params?: DataObjectParams, minifyJSON?: boolean): Promise<string>;
/**

@@ -310,3 +311,3 @@ * This utility method generates a completely new object that has properties that map to the fields and values in the entity at the time it is called. It is a copy, NOT a link, so any changes

*/
GetDataObject(params: DataObjectParams): Promise<any>;
GetDataObject(params?: DataObjectParams): Promise<any>;
GetRelatedEntityData(re: EntityRelationshipInfo, filter?: string, maxRecords?: number): Promise<any[]>;

@@ -359,2 +360,3 @@ GetRelatedEntityDataExt(re: EntityRelationshipInfo, filter?: string, maxRecords?: number): Promise<{

private _InnerSave;
private finalizeSave;
/**

@@ -361,0 +363,0 @@ * Internal helper method for the class and sub-classes - used to easily get the Active User which is either the ContextCurrentUser, if defined, or the Metadata.Provider.CurrentUser if not.

@@ -240,9 +240,9 @@ "use strict";

class DataObjectParams {
constructor() {
this.oldValues = false;
this.omitNullValues = true;
this.omitEmptyStrings = true;
this.excludeFields = null;
this.includeRelatedEntityData = true;
this.relatedEntityList = null;
constructor(oldValues = false, omitNullValues = false, omitEmptyStrings = false, excludeFields = [], includeRelatedEntityData = false, relatedEntityList = []) {
this.oldValues = oldValues;
this.omitNullValues = omitNullValues;
this.omitEmptyStrings = omitEmptyStrings;
this.excludeFields = excludeFields;
this.includeRelatedEntityData = includeRelatedEntityData;
this.relatedEntityList = relatedEntityList;
}

@@ -560,3 +560,3 @@ }

*/
async GetDataObjectJSON(params, minifyJSON = true) {
async GetDataObjectJSON(params = null, minifyJSON = true) {
const obj = await this.GetDataObject(params);

@@ -574,3 +574,5 @@ if (minifyJSON)

*/
async GetDataObject(params) {
async GetDataObject(params = null) {
if (!params)
params = new DataObjectParams();
// first, get the object from GetAll

@@ -754,13 +756,25 @@ const obj = this.GetAll(params.oldValues);

const data = await this.ProviderToUse.Save(this, this.ActiveUser, _options);
if (data) {
this.init(); // wipe out the current data to flush out the DIRTY flags, load the ID as part of this too
this.SetMany(data, false, true); // set the new values from the data returned from the save, this will also reset the old values
const result = this.LatestResult;
if (result)
result.NewValues = this.Fields.map(f => { return { FieldName: f.CodeName, Value: f.Value }; }); // set the latest values here
this.RaiseEvent('save', null);
if (!this.TransactionGroup) {
// no transaction group, so we have our results here
return this.finalizeSave(data);
}
else {
// we are part of a transaction group, so we return true and subscribe to the transaction groups' events and do the finalization work then
this.TransactionGroup.TransactionNotifications$.subscribe(({ success, results, error }) => {
if (success) {
const transItem = results.find(r => r.Transaction.BaseEntity === this);
if (transItem) {
this.finalizeSave(transItem.Result); // we get the resulting data from the transaction result, not data above as that will be blank when in a TG
}
else {
// should never get here, but if we do, we need to throw an error
throw new Error('Transaction group did not return a result for the entity object');
}
}
else {
throw error; // push this to the catch block below and that will add to the result history
}
});
return true;
}
else
return false;
}

@@ -790,2 +804,16 @@ else {

}
finalizeSave(data) {
if (data) {
this.init(); // wipe out the current data to flush out the DIRTY flags, load the ID as part of this too
this.SetMany(data, false, true); // set the new values from the data returned from the save, this will also reset the old values
const result = this.LatestResult;
if (result)
result.NewValues = this.Fields.map(f => { return { FieldName: f.CodeName, Value: f.Value }; }); // set the latest values here
this.RaiseEvent('save', null);
return true;
}
else {
return false;
}
}
/**

@@ -977,6 +1005,30 @@ * Internal helper method for the class and sub-classes - used to easily get the Active User which is either the ContextCurrentUser, if defined, or the Metadata.Provider.CurrentUser if not.

if (await this.ProviderToUse.Delete(this, options, this.ActiveUser)) {
// record deleted correctly
this.RaiseEvent('delete', { OldValues: oldVals });
// wipe out the current data to flush out the DIRTY flags by calling NewRecord()
this.NewRecord(); // will trigger a new record event here too
if (!this.TransactionGroup) {
// NOT part of a transaction - raise event immediately
// record deleted correctly
this.RaiseEvent('delete', { OldValues: oldVals });
// wipe out the current data to flush out the DIRTY flags by calling NewRecord()
this.NewRecord(); // will trigger a new record event here too
}
else {
// part of a transaction, wait for the transaction to submit successfully and then
// raise the event
this.TransactionGroup.TransactionNotifications$.subscribe(({ success, results, error }) => {
if (success) {
this.RaiseEvent('delete', { OldValues: oldVals });
// wipe out the current data to flush out the DIRTY flags by calling NewRecord()
this.NewRecord(); // will trigger a new record event here too
}
else {
// transaction failed, so we need to add a new result to the history here
newResult.Success = false;
newResult.Type = 'delete';
newResult.Message = error && error.message ? error.message : error;
newResult.Errors = error.Errors || [];
newResult.OriginalValues = this.Fields.map(f => { return { FieldName: f.CodeName, Value: f.OldValue }; });
newResult.EndedAt = new Date();
this.ResultHistory.push(newResult);
}
});
}
return true;

@@ -983,0 +1035,0 @@ }

@@ -11,8 +11,11 @@ import { BaseEntity } from "./baseEntity";

private _baseEntity;
private _operationType;
get Vars(): any;
get ExtraData(): any;
get Instruction(): string;
set Instruction(value: string);
get CallBack(): Function;
get BaseEntity(): BaseEntity;
constructor(baseEntity: BaseEntity, instruction: string, vars: any, extraData: any, callBack: Function);
get OperationType(): 'Create' | 'Update' | 'Delete';
constructor(baseEntity: BaseEntity, operationType: 'Create' | 'Update' | 'Delete', instruction: string, vars: any, extraData: any, callBack: Function);
}

@@ -41,2 +44,30 @@ /**

/**
* This class is used to encapsulate the concept of a variable to be used within a transaction group. This is designed to allow for the flow
* of data from one item in a transaction group to another. For example say you had a transaction group where you are creating a new record in
* EntityA and you wanted to get the newly created ID value from that record and then set it into a field called "EntityA_ID" in a record in EntityB.
* You can do this by telling the TransactionGroup about these variables with the AddVariable() method in the TransactionGroupBase/sub-classes.
*/
export declare class TransactionVariable {
private _name;
private _entityObject;
private _fieldName;
private _type;
private _processedValue;
private _isProcessed;
get Name(): string;
get EntityObject(): BaseEntity;
get FieldName(): string;
get Type(): 'Define' | 'Use';
/**
* Indicates if the variable has been processed. This is only true after the transaction group has been submitted and the results have been mapped back to the variables.
*/
get IsProcessed(): boolean;
/**
* Processed Value is only available after the related transaction item has been executed and the results have been mapped back to the variables that are related to that transaction item.
*/
get ProcessedValue(): any;
set ProcessedValue(value: any);
constructor(name: string, entityObject: BaseEntity, fieldName: string, type: 'Define' | 'Use');
}
/**
* TransactionGroup is a class that handles the bundling of multiple transactions into a single request. The provider handles

@@ -58,3 +89,27 @@ * the implementation details. If a transaction group is provided to the baseEntity object before either Save() or Delete() is called

private _pendingTransactions;
protected PendingTransactions(): TransactionItem[];
private _variables;
private _status;
protected get PendingTransactions(): TransactionItem[];
get Status(): 'Pending' | 'In Progress' | 'Complete' | 'Failed';
/**
* The array of variables that are to be used within the transaction group. These are used to pass data from one transaction item to another. See documentation on @class TransactionVariable
*/
get Variables(): TransactionVariable[];
/**
* Adds a new variable to the transaction group.
*/
AddVariable(newVariable: TransactionVariable): void;
private transactionNotifier;
get TransactionNotifications$(): import("rxjs").Observable<{
success: boolean;
results?: TransactionResult[];
error?: any;
}>;
/**
* Notifies observers about transaction success or failure
* @param success Whether the transaction was successful
* @param results The transaction results (if applicable)
* @param error Any error that occurred (if applicable)
*/
private NotifyTransactionStatus;
private _preprocessingItems;

@@ -78,3 +133,4 @@ /**

/**
* This is used by the BaseEntity/Provider objects to manage transactions on your behalf. Do not directly interact with this method. Instead use the TransactionGroup property on
* This is used by the BaseEntity/Provider objects to manage transactions on your behalf.
* WARNING: Do NOT directly call this method. Instead set the TransactionGroup property on
* the @BaseEntity class to make an entity object part of a transaction group.

@@ -84,10 +140,32 @@ * @param transaction

AddTransaction(transaction: TransactionItem): void;
protected abstract HandleSubmit(item: TransactionItem[]): Promise<TransactionResult[]>;
/**
* Subclasses of the TransactionGroupBase class must implement this method to handle the actual transaction submission which is provider-specific.
*/
protected abstract HandleSubmit(): Promise<TransactionResult[]>;
/**
* Helper method for sub-classes to map a variable to a position in the pending transactions array
* @param variable
* @returns
*/
protected MapVariableEntityObjectToPosition(variable: TransactionVariable): number;
/**
* Submits the transaction group to the provider for handling. The provider will handle the actual transaction and call the callback functions
* @returns true if the transaction was successful, false if it failed. If the method fails, check each of the individual BaseEntity objects within
* the TransactionGroup for their result histories using BaseEntity.ResultHistory and BaseEntity.LatestResult
* @param allowRetryOfFailedTransaction If true, the transaction group will be resubmitted even if it has failed. If false, the transaction group will not be resubmitted if it has failed.
*/
Submit(): Promise<boolean>;
Submit(allowRetryOfFailedTransaction?: boolean): Promise<boolean>;
/**
* This utility method is to be used by sub-classes to set the values of the variables on the BaseEntity objects before the transaction is executed for variables
* that are defined as 'Use' type. This is used to pass values from one transaction item to another.
* @param entityObject
* @returns the number of values set on the entity object
*/
protected SetEntityValuesFromVariables(entityObject: BaseEntity): number;
/**
* This utility method is to be used by sub-classes to set the values of the variables on the BaseEntity objects after the transaction is executed for variables
* @returns the number of variables that had their processed values set from the provided entity object
*/
protected SetVariableValuesFromEntity(entityObject: BaseEntity, queryResults: any): number;
}
//# sourceMappingURL=transactionGroup.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransactionGroupBase = exports.TransactionPreprocessingItem = exports.TransactionResult = exports.TransactionItem = void 0;
exports.TransactionGroupBase = exports.TransactionVariable = exports.TransactionPreprocessingItem = exports.TransactionResult = exports.TransactionItem = void 0;
const rxjs_1 = require("rxjs");
const logging_1 = require("./logging");

@@ -18,2 +19,5 @@ /**

}
set Instruction(value) {
this._instruction = value;
}
get CallBack() {

@@ -25,3 +29,7 @@ return this._callBack;

}
constructor(baseEntity, instruction, vars, extraData, callBack) {
get OperationType() {
return this._operationType;
}
constructor(baseEntity, operationType, instruction, vars, extraData, callBack) {
this._operationType = operationType;
this._baseEntity = baseEntity;

@@ -58,2 +66,46 @@ this._instruction = instruction;

/**
* This class is used to encapsulate the concept of a variable to be used within a transaction group. This is designed to allow for the flow
* of data from one item in a transaction group to another. For example say you had a transaction group where you are creating a new record in
* EntityA and you wanted to get the newly created ID value from that record and then set it into a field called "EntityA_ID" in a record in EntityB.
* You can do this by telling the TransactionGroup about these variables with the AddVariable() method in the TransactionGroupBase/sub-classes.
*/
class TransactionVariable {
get Name() {
return this._name;
}
get EntityObject() {
return this._entityObject;
}
get FieldName() {
return this._fieldName;
}
get Type() {
return this._type;
}
/**
* Indicates if the variable has been processed. This is only true after the transaction group has been submitted and the results have been mapped back to the variables.
*/
get IsProcessed() {
return this._isProcessed;
}
/**
* Processed Value is only available after the related transaction item has been executed and the results have been mapped back to the variables that are related to that transaction item.
*/
get ProcessedValue() {
return this._processedValue;
}
set ProcessedValue(value) {
this._processedValue = value;
this._isProcessed = true;
}
constructor(name, entityObject, fieldName, type) {
this._isProcessed = false;
this._name = name;
this._entityObject = entityObject;
this._fieldName = fieldName;
this._type = type;
}
}
exports.TransactionVariable = TransactionVariable;
/**
* TransactionGroup is a class that handles the bundling of multiple transactions into a single request. The provider handles

@@ -76,8 +128,40 @@ * the implementation details. If a transaction group is provided to the baseEntity object before either Save() or Delete() is called

this._pendingTransactions = [];
this._variables = [];
this._status = 'Pending';
// RxJS Subject to notify about transaction status
this.transactionNotifier = new rxjs_1.Subject();
this._preprocessingItems = [];
}
PendingTransactions() {
get PendingTransactions() {
return this._pendingTransactions;
}
get Status() {
return this._status;
}
/**
* The array of variables that are to be used within the transaction group. These are used to pass data from one transaction item to another. See documentation on @class TransactionVariable
*/
get Variables() {
return this._variables;
}
/**
* Adds a new variable to the transaction group.
*/
AddVariable(newVariable) {
this._variables.push(newVariable);
}
// Expose transaction notifications as an observable
get TransactionNotifications$() {
return this.transactionNotifier.asObservable();
}
/**
* Notifies observers about transaction success or failure
* @param success Whether the transaction was successful
* @param results The transaction results (if applicable)
* @param error Any error that occurred (if applicable)
*/
NotifyTransactionStatus(success, results, error) {
this.transactionNotifier.next({ success, results, error });
}
/**
* If an entity object needs to conduct any type of asynchronous preprocessing before a transaction is submitted, it must notify its transaction group

@@ -129,3 +213,4 @@ * that it is doing so with this method. This causes the TransactionGroup to wait for all preprocessing to be completed before submitting the transaction.

/**
* This is used by the BaseEntity/Provider objects to manage transactions on your behalf. Do not directly interact with this method. Instead use the TransactionGroup property on
* This is used by the BaseEntity/Provider objects to manage transactions on your behalf.
* WARNING: Do NOT directly call this method. Instead set the TransactionGroup property on
* the @BaseEntity class to make an entity object part of a transaction group.

@@ -138,7 +223,35 @@ * @param transaction

/**
* Helper method for sub-classes to map a variable to a position in the pending transactions array
* @param variable
* @returns
*/
MapVariableEntityObjectToPosition(variable) {
const index = this._pendingTransactions.findIndex((t) => {
return t.BaseEntity === variable.EntityObject;
});
return index;
}
/**
* Submits the transaction group to the provider for handling. The provider will handle the actual transaction and call the callback functions
* @returns true if the transaction was successful, false if it failed. If the method fails, check each of the individual BaseEntity objects within
* the TransactionGroup for their result histories using BaseEntity.ResultHistory and BaseEntity.LatestResult
* @param allowRetryOfFailedTransaction If true, the transaction group will be resubmitted even if it has failed. If false, the transaction group will not be resubmitted if it has failed.
*/
async Submit() {
async Submit(allowRetryOfFailedTransaction = false) {
if (this.Status === 'Complete') {
throw new Error('TransactionGroup has already been completed');
}
else if (this.Status === 'In Progress') {
throw new Error('TransactionGroup is already in progress');
}
else if (this.Status === 'Failed') {
if (!allowRetryOfFailedTransaction) {
throw new Error('TransactionGroup has failed and cannot be resubmitted unless allowRetryOfFailedTransaction is set to true');
}
else {
// the caller has specifid that we can retry the transaction even if it has failed, log this and continue
(0, logging_1.LogStatus)('TransactionGroupBase.Submit', 'TransactionGroup is in a failed state, resubmitting');
}
}
this._status = 'In Progress';
try {

@@ -149,3 +262,3 @@ // Wait for all preprocessing to be complete

// subclass handles the actual submit implementation whatever that does
let results = await this.HandleSubmit(this._pendingTransactions);
let results = await this.HandleSubmit();
// now we have the results back, so we can call the callback functions

@@ -156,5 +269,13 @@ for (let i = 0; i < results.length; i++) {

// now, see if there are any false values for results[x].Success, if so, we have to return false
return results.every((r) => r.Success);
const overallSuccess = results.every(r => r.Success);
this.NotifyTransactionStatus(overallSuccess, results);
this._status = overallSuccess ? 'Complete' : 'Failed';
return overallSuccess;
}
return true;
else {
// there are no transactions to submit, so we just return true and go back to pending since there were no transactions
(0, logging_1.LogStatus)('TransactionGroupBase.Submit', 'No transactions to submit, switching status back to Pending');
this._status = 'Pending';
return true;
}
}

@@ -167,7 +288,66 @@ catch (err) {

}
this.NotifyTransactionStatus(false, undefined, err);
this._status = 'Failed';
return false;
}
}
/**
* This utility method is to be used by sub-classes to set the values of the variables on the BaseEntity objects before the transaction is executed for variables
* that are defined as 'Use' type. This is used to pass values from one transaction item to another.
* @param entityObject
* @returns the number of values set on the entity object
*/
SetEntityValuesFromVariables(entityObject) {
let numSet = 0;
const vars = this.Variables.filter(v => v.EntityObject === entityObject);
// we have variables that we need to handle for this object. For any variables that have type of 'Use'
// we need to set those values on the object before we execute the query
for (const varItem of vars) {
if (varItem.Type === 'Use') {
// get the value from the variable that matches the NAME that has Type === 'Define'
const defineVar = this.Variables.find(v => v.Name.trim().toLowerCase() === varItem.Name.trim().toLowerCase() && v.Type === 'Define');
if (defineVar) {
if (defineVar.IsProcessed) {
// found the variable definition, now get the value from that BaseEntity from the variable's source field name
const value = defineVar.ProcessedValue;
// set the value on the BaseEntity for the current item
entityObject.Set(varItem.FieldName, value);
numSet++;
}
else {
// the definition of the variable was never processed, so we can't set the value, must throw an exception and blow up the transaction
throw new Error(`Variable ${varItem.Name} was never processed, can't continue with transaction`);
}
}
else {
// we can't set the value, must throw an exception and blow up the transaction
throw new Error(`Unable to find variable definition for variable ${varItem.Name}, can't continue with transaction`);
}
}
}
return numSet;
}
/**
* This utility method is to be used by sub-classes to set the values of the variables on the BaseEntity objects after the transaction is executed for variables
* @returns the number of variables that had their processed values set from the provided entity object
*/
SetVariableValuesFromEntity(entityObject, queryResults) {
let numVarsSet = 0;
const vars = this.Variables.filter(v => v.EntityObject === entityObject);
// we have variables that we need to handle for this object. For any variables that have type of 'Define'
// we need to set those values on the variable object after we execute the query and have the results
for (const varItem of vars) {
if (varItem.Type === 'Define') {
// get the value from the query results
const value = queryResults[varItem.FieldName];
// stash the value into the variable object
varItem.ProcessedValue = value;
// increment the counter
numVarsSet++;
}
}
return numVarsSet;
}
}
exports.TransactionGroupBase = TransactionGroupBase;
//# sourceMappingURL=transactionGroup.js.map

@@ -6,2 +6,3 @@ import { IMetadataProvider } from "./interfaces";

export declare function TypeScriptTypeFromSQLType(sqlType: string): 'string' | 'number' | 'boolean' | 'Date';
export declare function TypeScriptTypeFromSQLTypeWithNullableOption(sqlType: string, addNullableOption: boolean): 'string' | 'string | null' | 'number' | 'number | null' | 'boolean' | 'boolean | null' | 'Date' | 'Date | null';
/**

@@ -8,0 +9,0 @@ * Formats a value based on the parameters passed in

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GetEntityNameFromSchemaAndViewString = exports.StripContainingParens = exports.StripSingleQuotes = exports.StripUnicodePrefix = exports.ExtractActualDefaultValue = exports.Concurrent = exports.CodeNameFromString = exports.StripStopWords = exports.CommonStopWords = exports.SQLMaxLength = exports.SQLFullType = exports.FormatValue = exports.TypeScriptTypeFromSQLType = void 0;
exports.GetEntityNameFromSchemaAndViewString = exports.StripContainingParens = exports.StripSingleQuotes = exports.StripUnicodePrefix = exports.ExtractActualDefaultValue = exports.Concurrent = exports.CodeNameFromString = exports.StripStopWords = exports.CommonStopWords = exports.SQLMaxLength = exports.SQLFullType = exports.FormatValue = exports.TypeScriptTypeFromSQLTypeWithNullableOption = exports.TypeScriptTypeFromSQLType = void 0;
const logging_1 = require("./logging");

@@ -32,2 +32,12 @@ const metadata_1 = require("./metadata");

exports.TypeScriptTypeFromSQLType = TypeScriptTypeFromSQLType;
function TypeScriptTypeFromSQLTypeWithNullableOption(sqlType, addNullableOption) {
const retVal = TypeScriptTypeFromSQLType(sqlType);
if (addNullableOption) {
return retVal + ' | null';
}
else {
return retVal;
}
}
exports.TypeScriptTypeFromSQLTypeWithNullableOption = TypeScriptTypeFromSQLTypeWithNullableOption;
/**

@@ -34,0 +44,0 @@ * Formats a value based on the parameters passed in

{
"name": "@memberjunction/core",
"version": "2.24.1",
"version": "2.25.0",
"description": "MemberJunction: Core Library including Metadata, Application, Entity Retrieval and Manipulation, and Utilities",

@@ -22,3 +22,3 @@ "main": "dist/index.js",

"dependencies": {
"@memberjunction/global": "2.24.1",
"@memberjunction/global": "2.25.0",
"rxjs": "^7.8.1",

@@ -25,0 +25,0 @@ "zod": "^3.23.8"

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc