@memberjunction/server 4.4.0 → 5.0.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.
Files changed (115) hide show
  1. package/dist/agents/skip-agent.js +9 -9
  2. package/dist/agents/skip-agent.js.map +1 -1
  3. package/dist/apolloServer/TransactionPlugin.d.ts +4 -0
  4. package/dist/apolloServer/TransactionPlugin.d.ts.map +1 -0
  5. package/dist/apolloServer/TransactionPlugin.js +46 -0
  6. package/dist/apolloServer/TransactionPlugin.js.map +1 -0
  7. package/dist/auth/APIKeyScopeAuth.js.map +1 -1
  8. package/dist/auth/__tests__/backward-compatibility.test.d.ts +2 -0
  9. package/dist/auth/__tests__/backward-compatibility.test.d.ts.map +1 -0
  10. package/dist/auth/__tests__/backward-compatibility.test.js +135 -0
  11. package/dist/auth/__tests__/backward-compatibility.test.js.map +1 -0
  12. package/dist/auth/exampleNewUserSubClass.d.ts +2 -2
  13. package/dist/auth/exampleNewUserSubClass.d.ts.map +1 -1
  14. package/dist/auth/index.js.map +1 -1
  15. package/dist/auth/newUsers.d.ts +2 -2
  16. package/dist/auth/newUsers.d.ts.map +1 -1
  17. package/dist/auth/newUsers.js +6 -6
  18. package/dist/auth/newUsers.js.map +1 -1
  19. package/dist/entitySubclasses/entityPermissions.server.d.ts +2 -2
  20. package/dist/entitySubclasses/entityPermissions.server.d.ts.map +1 -1
  21. package/dist/entitySubclasses/entityPermissions.server.js +3 -3
  22. package/dist/entitySubclasses/entityPermissions.server.js.map +1 -1
  23. package/dist/generated/generated.d.ts +10724 -10721
  24. package/dist/generated/generated.d.ts.map +1 -1
  25. package/dist/generated/generated.js +48710 -48698
  26. package/dist/generated/generated.js.map +1 -1
  27. package/dist/generic/DeleteOptionsInput.d.ts +12 -2
  28. package/dist/generic/DeleteOptionsInput.d.ts.map +1 -1
  29. package/dist/generic/DeleteOptionsInput.js +12 -2
  30. package/dist/generic/DeleteOptionsInput.js.map +1 -1
  31. package/dist/generic/ResolverBase.d.ts.map +1 -1
  32. package/dist/generic/ResolverBase.js +6 -6
  33. package/dist/generic/ResolverBase.js.map +1 -1
  34. package/dist/generic/RunViewResolver.js +3 -3
  35. package/dist/generic/RunViewResolver.js.map +1 -1
  36. package/dist/resolvers/AskSkipResolver.d.ts +123 -0
  37. package/dist/resolvers/AskSkipResolver.d.ts.map +1 -0
  38. package/dist/resolvers/AskSkipResolver.js +1788 -0
  39. package/dist/resolvers/AskSkipResolver.js.map +1 -0
  40. package/dist/resolvers/ComponentRegistryResolver.js.map +1 -1
  41. package/dist/resolvers/CreateQueryResolver.d.ts +3 -3
  42. package/dist/resolvers/CreateQueryResolver.d.ts.map +1 -1
  43. package/dist/resolvers/CreateQueryResolver.js +19 -19
  44. package/dist/resolvers/CreateQueryResolver.js.map +1 -1
  45. package/dist/resolvers/EntityResolver.js +1 -1
  46. package/dist/resolvers/EntityResolver.js.map +1 -1
  47. package/dist/resolvers/FileCategoryResolver.js +4 -4
  48. package/dist/resolvers/FileCategoryResolver.js.map +1 -1
  49. package/dist/resolvers/FileResolver.js +20 -20
  50. package/dist/resolvers/FileResolver.js.map +1 -1
  51. package/dist/resolvers/GetDataContextDataResolver.js +1 -1
  52. package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
  53. package/dist/resolvers/ISAEntityResolver.d.ts +22 -1
  54. package/dist/resolvers/ISAEntityResolver.d.ts.map +1 -1
  55. package/dist/resolvers/ISAEntityResolver.js +77 -1
  56. package/dist/resolvers/ISAEntityResolver.js.map +1 -1
  57. package/dist/resolvers/ReportResolver.js +3 -3
  58. package/dist/resolvers/ReportResolver.js.map +1 -1
  59. package/dist/resolvers/RunAIAgentResolver.js +3 -3
  60. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  61. package/dist/resolvers/RunAIPromptResolver.js +1 -1
  62. package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
  63. package/dist/resolvers/RunTemplateResolver.js +2 -2
  64. package/dist/resolvers/RunTemplateResolver.js.map +1 -1
  65. package/dist/resolvers/SyncDataResolver.js +1 -1
  66. package/dist/resolvers/SyncDataResolver.js.map +1 -1
  67. package/dist/resolvers/SyncRolesUsersResolver.d.ts +9 -9
  68. package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
  69. package/dist/resolvers/SyncRolesUsersResolver.js +10 -10
  70. package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
  71. package/dist/resolvers/UserFavoriteResolver.js +2 -2
  72. package/dist/resolvers/UserFavoriteResolver.js.map +1 -1
  73. package/dist/resolvers/UserResolver.js +8 -8
  74. package/dist/resolvers/UserResolver.js.map +1 -1
  75. package/dist/resolvers/UserViewResolver.js +5 -5
  76. package/dist/resolvers/UserViewResolver.js.map +1 -1
  77. package/dist/rest/ViewOperationsHandler.js +1 -1
  78. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  79. package/dist/scheduler/LearningCycleScheduler.d.ts +4 -0
  80. package/dist/scheduler/LearningCycleScheduler.d.ts.map +1 -0
  81. package/dist/scheduler/LearningCycleScheduler.js +4 -0
  82. package/dist/scheduler/LearningCycleScheduler.js.map +1 -0
  83. package/dist/services/TaskOrchestrator.d.ts +1 -1
  84. package/dist/services/TaskOrchestrator.js +5 -5
  85. package/dist/services/TaskOrchestrator.js.map +1 -1
  86. package/package.json +52 -52
  87. package/src/agents/skip-agent.ts +9 -9
  88. package/src/auth/APIKeyScopeAuth.ts +5 -5
  89. package/src/auth/exampleNewUserSubClass.ts +2 -2
  90. package/src/auth/index.ts +3 -3
  91. package/src/auth/newUsers.ts +9 -9
  92. package/src/entitySubclasses/entityPermissions.server.ts +3 -3
  93. package/src/generated/generated.ts +31186 -31177
  94. package/src/generic/DeleteOptionsInput.ts +12 -2
  95. package/src/generic/ResolverBase.ts +7 -7
  96. package/src/generic/RunViewResolver.ts +3 -3
  97. package/src/resolvers/APIKeyResolver.ts +2 -2
  98. package/src/resolvers/ComponentRegistryResolver.ts +9 -9
  99. package/src/resolvers/CreateQueryResolver.ts +18 -18
  100. package/src/resolvers/EntityResolver.ts +1 -1
  101. package/src/resolvers/FileCategoryResolver.ts +5 -5
  102. package/src/resolvers/FileResolver.ts +27 -27
  103. package/src/resolvers/GetDataContextDataResolver.ts +2 -2
  104. package/src/resolvers/ISAEntityResolver.ts +77 -1
  105. package/src/resolvers/ReportResolver.ts +4 -4
  106. package/src/resolvers/RunAIAgentResolver.ts +7 -7
  107. package/src/resolvers/RunAIPromptResolver.ts +1 -1
  108. package/src/resolvers/RunTemplateResolver.ts +4 -4
  109. package/src/resolvers/SyncDataResolver.ts +3 -3
  110. package/src/resolvers/SyncRolesUsersResolver.ts +26 -26
  111. package/src/resolvers/UserFavoriteResolver.ts +2 -2
  112. package/src/resolvers/UserResolver.ts +8 -8
  113. package/src/resolvers/UserViewResolver.ts +6 -6
  114. package/src/rest/ViewOperationsHandler.ts +1 -1
  115. package/src/services/TaskOrchestrator.ts +31 -31
@@ -128,7 +128,7 @@ export class SkipProxyAgent extends BaseAgent {
128
128
  }
129
129
 
130
130
  // Load conversation messages from database if conversationId is provided
131
- // This ensures we get real UUIDs from ConversationDetailEntity records
131
+ // This ensures we get real UUIDs from MJConversationDetailEntity records
132
132
  let skipMessages: SkipMessage[];
133
133
  if (conversationId && params.contextUser) {
134
134
  skipMessages = await this.loadMessagesFromDatabase(conversationId, params.contextUser);
@@ -204,7 +204,7 @@ export class SkipProxyAgent extends BaseAgent {
204
204
  try {
205
205
  const rv = new RunView();
206
206
  const result = await rv.RunView({
207
- EntityName: 'Conversation Details',
207
+ EntityName: 'MJ: Conversation Details',
208
208
  ExtraFilter: `ConversationID='${conversationId}'`,
209
209
  OrderBy: '__mj_CreatedAt ASC'
210
210
  }, contextUser);
@@ -458,7 +458,7 @@ const demoSpecJson = {
458
458
  "usageContext": "Main entity list display and filtering"
459
459
  },
460
460
  {
461
- "name": "Entity Fields",
461
+ "name": "MJ: Entity Fields",
462
462
  "description": "Fields belonging to each entity",
463
463
  "displayFields": [
464
464
  "Name",
@@ -565,7 +565,7 @@ const demoSpecJson = {
565
565
  "usageContext": "Details panel to show entity fields"
566
566
  },
567
567
  {
568
- "name": "Entity Relationships",
568
+ "name": "MJ: Entity Relationships",
569
569
  "description": "Relationships between entities",
570
570
  "displayFields": [
571
571
  "RelatedEntity",
@@ -760,7 +760,7 @@ const demoSpecJson = {
760
760
  "usageContext": "Main entity list display and filtering"
761
761
  },
762
762
  {
763
- "name": "Entity Fields",
763
+ "name": "MJ: Entity Fields",
764
764
  "description": "Fields belonging to each entity",
765
765
  "displayFields": [
766
766
  "Name",
@@ -867,7 +867,7 @@ const demoSpecJson = {
867
867
  "usageContext": "Details panel to show entity fields"
868
868
  },
869
869
  {
870
- "name": "Entity Relationships",
870
+ "name": "MJ: Entity Relationships",
871
871
  "description": "Relationships between entities",
872
872
  "displayFields": [
873
873
  "RelatedEntity",
@@ -1154,7 +1154,7 @@ const demoSpecJson = {
1154
1154
  "usageContext": "Main entity list display and filtering"
1155
1155
  },
1156
1156
  {
1157
- "name": "Entity Fields",
1157
+ "name": "MJ: Entity Fields",
1158
1158
  "description": "Fields belonging to each entity",
1159
1159
  "displayFields": [
1160
1160
  "Name",
@@ -1261,7 +1261,7 @@ const demoSpecJson = {
1261
1261
  "usageContext": "Details panel to show entity fields"
1262
1262
  },
1263
1263
  {
1264
- "name": "Entity Relationships",
1264
+ "name": "MJ: Entity Relationships",
1265
1265
  "description": "Relationships between entities",
1266
1266
  "displayFields": [
1267
1267
  "RelatedEntity",
@@ -1509,5 +1509,5 @@ const demoSpecJson = {
1509
1509
  }
1510
1510
  ],
1511
1511
  "libraries": [],
1512
- "code": "function EntityBrowser({ utilities, styles, components, callbacks, savedUserSettings, onSaveUserSettings }) {\n // Extract child components\n const { EntityList, EntityDetails, EntityFilter } = components;\n \n // Initialize state from saved settings where appropriate\n const [selectedEntityId, setSelectedEntityId] = useState(savedUserSettings?.selectedEntityId);\n const [viewMode, setViewMode] = useState(savedUserSettings?.viewMode || 'grid');\n const [filters, setFilters] = useState(savedUserSettings?.filters || {});\n const [sortBy, setSortBy] = useState(savedUserSettings?.sortBy || 'Name');\n const [sortDirection, setSortDirection] = useState(savedUserSettings?.sortDirection || 'asc');\n const [filterPanelCollapsed, setFilterPanelCollapsed] = useState(savedUserSettings?.filterPanelCollapsed || false);\n \n // Runtime UI state (not persisted)\n const [entities, setEntities] = useState([]);\n const [entityFields, setEntityFields] = useState([]);\n const [entityRelationships, setEntityRelationships] = useState([]);\n const [loading, setLoading] = useState(true);\n const [detailsPanelOpen, setDetailsPanelOpen] = useState(false);\n const [searchQuery, setSearchQuery] = useState('');\n const [uniqueSchemas, setUniqueSchemas] = useState([]);\n const [uniqueTables, setUniqueTables] = useState([]);\n \n // Load entities on mount and when filters/sort change\n useEffect(() => {\n const loadEntities = async () => {\n setLoading(true);\n try {\n // Build filter string\n let filterParts = [];\n if (filters.schema) {\n filterParts.push(`SchemaName = '${filters.schema}'`);\n }\n if (filters.table) {\n filterParts.push(`BaseTable = '${filters.table}'`);\n }\n if (searchQuery) {\n filterParts.push(`(Name LIKE '%${searchQuery}%' OR DisplayName LIKE '%${searchQuery}%' OR Description LIKE '%${searchQuery}%')`);\n }\n \n const result = await utilities.rv.RunView({\n EntityName: 'Entities',\n Fields: ['ID', 'Name', 'DisplayName', 'NameSuffix', 'Description', 'SchemaName', 'BaseTable', 'BaseView'],\n OrderBy: `${sortBy} ${sortDirection.toUpperCase()}`,\n ExtraFilter: filterParts.length > 0 ? filterParts.join(' AND ') : undefined\n });\n \n if (result?.Success && result?.Results) {\n setEntities(result.Results);\n \n // Extract unique schemas and tables for filter dropdowns\n const schemas = [...new Set(result.Results.map(e => e.SchemaName).filter(Boolean))];\n const tables = [...new Set(result.Results.map(e => e.BaseTable).filter(Boolean))];\n setUniqueSchemas(schemas);\n setUniqueTables(tables);\n } else {\n console.error('Failed to load entities:', result?.ErrorMessage);\n setEntities([]);\n }\n } catch (error) {\n console.error('Error loading entities:', error);\n setEntities([]);\n } finally {\n setLoading(false);\n }\n };\n \n loadEntities();\n }, [filters, sortBy, sortDirection, searchQuery, utilities.rv]);\n \n // Load entity details when selection changes\n useEffect(() => {\n const loadEntityDetails = async () => {\n if (!selectedEntityId) {\n setEntityFields([]);\n setEntityRelationships([]);\n return;\n }\n \n try {\n // Load fields\n const fieldsResult = await utilities.rv.RunView({\n EntityName: 'Entity Fields',\n Fields: ['Name', 'DisplayName', 'Type', 'Length', 'AllowsNull', 'IsPrimaryKey', 'IsUnique', 'Sequence'],\n OrderBy: 'Sequence ASC, Name ASC',\n ExtraFilter: `EntityID = '${selectedEntityId}'`\n });\n \n if (fieldsResult?.Success && fieldsResult?.Results) {\n setEntityFields(fieldsResult.Results);\n } else {\n setEntityFields([]);\n }\n \n // Load relationships\n const relationshipsResult = await utilities.rv.RunView({\n EntityName: 'Entity Relationships',\n Fields: ['RelatedEntity', 'Type', 'DisplayName', 'RelatedEntityJoinField', 'Sequence'],\n OrderBy: 'Sequence ASC, RelatedEntity ASC',\n ExtraFilter: `EntityID = '${selectedEntityId}'`\n });\n \n if (relationshipsResult?.Success && relationshipsResult?.Results) {\n setEntityRelationships(relationshipsResult.Results);\n } else {\n setEntityRelationships([]);\n }\n } catch (error) {\n console.error('Error loading entity details:', error);\n setEntityFields([]);\n setEntityRelationships([]);\n }\n };\n \n loadEntityDetails();\n }, [selectedEntityId, utilities.rv]);\n \n // Handle entity selection\n const handleSelectEntity = useCallback((entityId) => {\n setSelectedEntityId(entityId);\n setDetailsPanelOpen(true);\n \n // Save user preference\n onSaveUserSettings?.({\n ...savedUserSettings,\n selectedEntityId: entityId\n });\n }, [savedUserSettings, onSaveUserSettings]);\n \n // Handle view mode change\n const handleViewModeChange = useCallback((mode) => {\n setViewMode(mode);\n \n // Save preference\n onSaveUserSettings?.({\n ...savedUserSettings,\n viewMode: mode\n });\n }, [savedUserSettings, onSaveUserSettings]);\n \n // Handle filter changes\n const handleFilterChange = useCallback((newFilters) => {\n setFilters(newFilters);\n \n // Save filter preferences\n onSaveUserSettings?.({\n ...savedUserSettings,\n filters: newFilters\n });\n }, [savedUserSettings, onSaveUserSettings]);\n \n // Handle sort changes\n const handleSortChange = useCallback((newSortBy, newSortDirection) => {\n setSortBy(newSortBy);\n setSortDirection(newSortDirection);\n \n // Save sort preferences\n onSaveUserSettings?.({\n ...savedUserSettings,\n sortBy: newSortBy,\n sortDirection: newSortDirection\n });\n }, [savedUserSettings, onSaveUserSettings]);\n \n // Handle filter panel toggle\n const handleToggleFilter = useCallback(() => {\n const newCollapsed = !filterPanelCollapsed;\n setFilterPanelCollapsed(newCollapsed);\n \n // Save collapsed state\n onSaveUserSettings?.({\n ...savedUserSettings,\n filterPanelCollapsed: newCollapsed\n });\n }, [filterPanelCollapsed, savedUserSettings, onSaveUserSettings]);\n \n // Handle opening entity record (kept for backward compatibility with details panel)\n const handleOpenRecord = useCallback((entityName) => {\n console.log('Root handleOpenRecord called with entityName:', entityName);\n console.log('Callbacks object:', callbacks);\n if (callbacks?.OpenEntityRecord && entityName) {\n console.log('Calling OpenEntityRecord callback with:', 'Entities', entityName);\n // Open the Entities entity record for the selected entity\n callbacks.OpenEntityRecord('Entities', [{ FieldName: 'Name', Value: entityName }]);\n } else {\n console.error('OpenEntityRecord callback not available or entityName missing');\n }\n }, [callbacks]);\n \n // Handle closing details panel\n const handleCloseDetails = useCallback(() => {\n setDetailsPanelOpen(false);\n }, []);\n \n // Handle search\n const handleSearch = useCallback((query) => {\n setSearchQuery(query);\n }, []);\n \n // Get selected entity object\n const selectedEntity = entities.find(e => e.ID === selectedEntityId);\n \n // Helper function to get border radius value\n const getBorderRadius = (size) => {\n return typeof styles.borders.radius === 'object' ? styles.borders.radius[size] : styles.borders.radius;\n };\n \n // Loading state\n if (loading && entities.length === 0) {\n return (\n <div style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n height: '100vh',\n fontSize: styles.typography.fontSize.lg,\n color: styles.colors.textSecondary\n }}>\n Loading entities...\n </div>\n );\n }\n \n return (\n <div style={{\n display: 'flex',\n height: '100vh',\n backgroundColor: styles.colors.background,\n overflow: 'hidden'\n }}>\n {/* Filter Panel */}\n {EntityFilter && (\n <EntityFilter\n filters={filters}\n onFilterChange={handleFilterChange}\n schemas={uniqueSchemas}\n tables={uniqueTables}\n isCollapsed={filterPanelCollapsed}\n onToggleCollapse={handleToggleFilter}\n savedUserSettings={savedUserSettings?.filterPanel}\n onSaveUserSettings={(settings) => onSaveUserSettings?.({\n ...savedUserSettings,\n filterPanel: settings\n })}\n utilities={utilities}\n styles={styles}\n components={components}\n callbacks={callbacks}\n />\n )}\n \n {/* Main Content Area */}\n <div style={{\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden'\n }}>\n {/* Header */}\n <div style={{\n padding: styles.spacing.lg,\n borderBottom: `1px solid ${styles.colors.border}`,\n backgroundColor: styles.colors.surface\n }}>\n <div style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: styles.spacing.md\n }}>\n <h1 style={{\n margin: 0,\n fontSize: styles.typography.fontSize.xxl || styles.typography.fontSize.xl,\n fontWeight: styles.typography.fontWeight?.bold || '700',\n color: styles.colors.text\n }}>\n Entity Browser\n </h1>\n \n {/* View Mode Toggle */}\n <div style={{\n display: 'flex',\n gap: styles.spacing.sm,\n alignItems: 'center'\n }}>\n <span style={{\n fontSize: styles.typography.fontSize.md,\n color: styles.colors.textSecondary\n }}>\n View:\n </span>\n <button\n onClick={() => handleViewModeChange('grid')}\n style={{\n padding: `${styles.spacing.sm} ${styles.spacing.md}`,\n backgroundColor: viewMode === 'grid' ? styles.colors.primary : styles.colors.background,\n color: viewMode === 'grid' ? 'white' : styles.colors.text,\n border: `1px solid ${styles.colors.border}`,\n borderRadius: getBorderRadius('sm'),\n cursor: 'pointer',\n fontSize: styles.typography.fontSize.md\n }}\n >\n Grid\n </button>\n <button\n onClick={() => handleViewModeChange('card')}\n style={{\n padding: `${styles.spacing.sm} ${styles.spacing.md}`,\n backgroundColor: viewMode === 'card' ? styles.colors.primary : styles.colors.background,\n color: viewMode === 'card' ? 'white' : styles.colors.text,\n border: `1px solid ${styles.colors.border}`,\n borderRadius: getBorderRadius('sm'),\n cursor: 'pointer',\n fontSize: styles.typography.fontSize.md\n }}\n >\n Cards\n </button>\n </div>\n </div>\n \n {/* Search Bar */}\n <div style={{\n display: 'flex',\n gap: styles.spacing.md\n }}>\n <input\n type=\"text\"\n placeholder=\"Search entities...\"\n value={searchQuery}\n onChange={(e) => handleSearch(e.target.value)}\n style={{\n flex: 1,\n padding: styles.spacing.md,\n fontSize: styles.typography.fontSize.md,\n border: `1px solid ${styles.colors.border}`,\n borderRadius: getBorderRadius('sm'),\n backgroundColor: styles.colors.background\n }}\n />\n {searchQuery && (\n <button\n onClick={() => handleSearch('')}\n style={{\n padding: `${styles.spacing.sm} ${styles.spacing.md}`,\n backgroundColor: styles.colors.surfaceHover || styles.colors.surface,\n color: styles.colors.text,\n border: `1px solid ${styles.colors.border}`,\n borderRadius: getBorderRadius('sm'),\n cursor: 'pointer',\n fontSize: styles.typography.fontSize.md\n }}\n >\n Clear\n </button>\n )}\n </div>\n </div>\n \n {/* Entity List */}\n <div style={{\n flex: 1,\n overflow: 'auto',\n padding: styles.spacing.lg\n }}>\n {EntityList && (\n <EntityList\n entities={entities}\n viewMode={viewMode}\n selectedEntityId={selectedEntityId}\n onSelectEntity={handleSelectEntity}\n sortBy={sortBy}\n sortDirection={sortDirection}\n onSortChange={handleSortChange}\n savedUserSettings={savedUserSettings?.entityList}\n onSaveUserSettings={(settings) => onSaveUserSettings?.({\n ...savedUserSettings,\n entityList: settings\n })}\n utilities={utilities}\n styles={styles}\n components={components}\n callbacks={callbacks}\n />\n )}\n \n {/* Empty State */}\n {entities.length === 0 && !loading && (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n padding: styles.spacing.xxl || styles.spacing.xl,\n color: styles.colors.textSecondary\n }}>\n <div style={{\n fontSize: styles.typography.fontSize.xl,\n marginBottom: styles.spacing.md\n }}>\n No entities found\n </div>\n <div style={{\n fontSize: styles.typography.fontSize.md\n }}>\n {searchQuery || Object.keys(filters).length > 0\n ? 'Try adjusting your filters or search query'\n : 'No entities are available'}\n </div>\n </div>\n )}\n </div>\n </div>\n \n {/* Details Panel */}\n {EntityDetails && (\n <EntityDetails\n entity={selectedEntity}\n fields={entityFields}\n relationships={entityRelationships}\n isOpen={detailsPanelOpen}\n onClose={handleCloseDetails}\n onOpenRecord={() => handleOpenRecord(selectedEntity?.Name)}\n savedUserSettings={savedUserSettings?.detailsPanel}\n onSaveUserSettings={(settings) => onSaveUserSettings?.({\n ...savedUserSettings,\n detailsPanel: settings\n })}\n utilities={utilities}\n styles={styles}\n components={components}\n callbacks={callbacks}\n />\n )}\n </div>\n );\n}"
1512
+ "code": "function EntityBrowser({ utilities, styles, components, callbacks, savedUserSettings, onSaveUserSettings }) {\n // Extract child components\n const { EntityList, EntityDetails, EntityFilter } = components;\n \n // Initialize state from saved settings where appropriate\n const [selectedEntityId, setSelectedEntityId] = useState(savedUserSettings?.selectedEntityId);\n const [viewMode, setViewMode] = useState(savedUserSettings?.viewMode || 'grid');\n const [filters, setFilters] = useState(savedUserSettings?.filters || {});\n const [sortBy, setSortBy] = useState(savedUserSettings?.sortBy || 'Name');\n const [sortDirection, setSortDirection] = useState(savedUserSettings?.sortDirection || 'asc');\n const [filterPanelCollapsed, setFilterPanelCollapsed] = useState(savedUserSettings?.filterPanelCollapsed || false);\n \n // Runtime UI state (not persisted)\n const [entities, setEntities] = useState([]);\n const [entityFields, setEntityFields] = useState([]);\n const [entityRelationships, setEntityRelationships] = useState([]);\n const [loading, setLoading] = useState(true);\n const [detailsPanelOpen, setDetailsPanelOpen] = useState(false);\n const [searchQuery, setSearchQuery] = useState('');\n const [uniqueSchemas, setUniqueSchemas] = useState([]);\n const [uniqueTables, setUniqueTables] = useState([]);\n \n // Load entities on mount and when filters/sort change\n useEffect(() => {\n const loadEntities = async () => {\n setLoading(true);\n try {\n // Build filter string\n let filterParts = [];\n if (filters.schema) {\n filterParts.push(`SchemaName = '${filters.schema}'`);\n }\n if (filters.table) {\n filterParts.push(`BaseTable = '${filters.table}'`);\n }\n if (searchQuery) {\n filterParts.push(`(Name LIKE '%${searchQuery}%' OR DisplayName LIKE '%${searchQuery}%' OR Description LIKE '%${searchQuery}%')`);\n }\n \n const result = await utilities.rv.RunView({\n EntityName: 'MJ: Entities',\n Fields: ['ID', 'Name', 'DisplayName', 'NameSuffix', 'Description', 'SchemaName', 'BaseTable', 'BaseView'],\n OrderBy: `${sortBy} ${sortDirection.toUpperCase()}`,\n ExtraFilter: filterParts.length > 0 ? filterParts.join(' AND ') : undefined\n });\n \n if (result?.Success && result?.Results) {\n setEntities(result.Results);\n \n // Extract unique schemas and tables for filter dropdowns\n const schemas = [...new Set(result.Results.map(e => e.SchemaName).filter(Boolean))];\n const tables = [...new Set(result.Results.map(e => e.BaseTable).filter(Boolean))];\n setUniqueSchemas(schemas);\n setUniqueTables(tables);\n } else {\n console.error('Failed to load entities:', result?.ErrorMessage);\n setEntities([]);\n }\n } catch (error) {\n console.error('Error loading entities:', error);\n setEntities([]);\n } finally {\n setLoading(false);\n }\n };\n \n loadEntities();\n }, [filters, sortBy, sortDirection, searchQuery, utilities.rv]);\n \n // Load entity details when selection changes\n useEffect(() => {\n const loadEntityDetails = async () => {\n if (!selectedEntityId) {\n setEntityFields([]);\n setEntityRelationships([]);\n return;\n }\n \n try {\n // Load fields\n const fieldsResult = await utilities.rv.RunView({\n EntityName: 'MJ: Entity Fields',\n Fields: ['Name', 'DisplayName', 'Type', 'Length', 'AllowsNull', 'IsPrimaryKey', 'IsUnique', 'Sequence'],\n OrderBy: 'Sequence ASC, Name ASC',\n ExtraFilter: `EntityID = '${selectedEntityId}'`\n });\n \n if (fieldsResult?.Success && fieldsResult?.Results) {\n setEntityFields(fieldsResult.Results);\n } else {\n setEntityFields([]);\n }\n \n // Load relationships\n const relationshipsResult = await utilities.rv.RunView({\n EntityName: 'MJ: Entity Relationships',\n Fields: ['RelatedEntity', 'Type', 'DisplayName', 'RelatedEntityJoinField', 'Sequence'],\n OrderBy: 'Sequence ASC, RelatedEntity ASC',\n ExtraFilter: `EntityID = '${selectedEntityId}'`\n });\n \n if (relationshipsResult?.Success && relationshipsResult?.Results) {\n setEntityRelationships(relationshipsResult.Results);\n } else {\n setEntityRelationships([]);\n }\n } catch (error) {\n console.error('Error loading entity details:', error);\n setEntityFields([]);\n setEntityRelationships([]);\n }\n };\n \n loadEntityDetails();\n }, [selectedEntityId, utilities.rv]);\n \n // Handle entity selection\n const handleSelectEntity = useCallback((entityId) => {\n setSelectedEntityId(entityId);\n setDetailsPanelOpen(true);\n \n // Save user preference\n onSaveUserSettings?.({\n ...savedUserSettings,\n selectedEntityId: entityId\n });\n }, [savedUserSettings, onSaveUserSettings]);\n \n // Handle view mode change\n const handleViewModeChange = useCallback((mode) => {\n setViewMode(mode);\n \n // Save preference\n onSaveUserSettings?.({\n ...savedUserSettings,\n viewMode: mode\n });\n }, [savedUserSettings, onSaveUserSettings]);\n \n // Handle filter changes\n const handleFilterChange = useCallback((newFilters) => {\n setFilters(newFilters);\n \n // Save filter preferences\n onSaveUserSettings?.({\n ...savedUserSettings,\n filters: newFilters\n });\n }, [savedUserSettings, onSaveUserSettings]);\n \n // Handle sort changes\n const handleSortChange = useCallback((newSortBy, newSortDirection) => {\n setSortBy(newSortBy);\n setSortDirection(newSortDirection);\n \n // Save sort preferences\n onSaveUserSettings?.({\n ...savedUserSettings,\n sortBy: newSortBy,\n sortDirection: newSortDirection\n });\n }, [savedUserSettings, onSaveUserSettings]);\n \n // Handle filter panel toggle\n const handleToggleFilter = useCallback(() => {\n const newCollapsed = !filterPanelCollapsed;\n setFilterPanelCollapsed(newCollapsed);\n \n // Save collapsed state\n onSaveUserSettings?.({\n ...savedUserSettings,\n filterPanelCollapsed: newCollapsed\n });\n }, [filterPanelCollapsed, savedUserSettings, onSaveUserSettings]);\n \n // Handle opening entity record (kept for backward compatibility with details panel)\n const handleOpenRecord = useCallback((entityName) => {\n console.log('Root handleOpenRecord called with entityName:', entityName);\n console.log('Callbacks object:', callbacks);\n if (callbacks?.OpenEntityRecord && entityName) {\n console.log('Calling OpenEntityRecord callback with:', 'MJ: Entities', entityName);\n // Open the Entities entity record for the selected entity\n callbacks.OpenEntityRecord('MJ: Entities', [{ FieldName: 'Name', Value: entityName }]);\n } else {\n console.error('OpenEntityRecord callback not available or entityName missing');\n }\n }, [callbacks]);\n \n // Handle closing details panel\n const handleCloseDetails = useCallback(() => {\n setDetailsPanelOpen(false);\n }, []);\n \n // Handle search\n const handleSearch = useCallback((query) => {\n setSearchQuery(query);\n }, []);\n \n // Get selected entity object\n const selectedEntity = entities.find(e => e.ID === selectedEntityId);\n \n // Helper function to get border radius value\n const getBorderRadius = (size) => {\n return typeof styles.borders.radius === 'object' ? styles.borders.radius[size] : styles.borders.radius;\n };\n \n // Loading state\n if (loading && entities.length === 0) {\n return (\n <div style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n height: '100vh',\n fontSize: styles.typography.fontSize.lg,\n color: styles.colors.textSecondary\n }}>\n Loading entities...\n </div>\n );\n }\n \n return (\n <div style={{\n display: 'flex',\n height: '100vh',\n backgroundColor: styles.colors.background,\n overflow: 'hidden'\n }}>\n {/* Filter Panel */}\n {EntityFilter && (\n <EntityFilter\n filters={filters}\n onFilterChange={handleFilterChange}\n schemas={uniqueSchemas}\n tables={uniqueTables}\n isCollapsed={filterPanelCollapsed}\n onToggleCollapse={handleToggleFilter}\n savedUserSettings={savedUserSettings?.filterPanel}\n onSaveUserSettings={(settings) => onSaveUserSettings?.({\n ...savedUserSettings,\n filterPanel: settings\n })}\n utilities={utilities}\n styles={styles}\n components={components}\n callbacks={callbacks}\n />\n )}\n \n {/* Main Content Area */}\n <div style={{\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden'\n }}>\n {/* Header */}\n <div style={{\n padding: styles.spacing.lg,\n borderBottom: `1px solid ${styles.colors.border}`,\n backgroundColor: styles.colors.surface\n }}>\n <div style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: styles.spacing.md\n }}>\n <h1 style={{\n margin: 0,\n fontSize: styles.typography.fontSize.xxl || styles.typography.fontSize.xl,\n fontWeight: styles.typography.fontWeight?.bold || '700',\n color: styles.colors.text\n }}>\n Entity Browser\n </h1>\n \n {/* View Mode Toggle */}\n <div style={{\n display: 'flex',\n gap: styles.spacing.sm,\n alignItems: 'center'\n }}>\n <span style={{\n fontSize: styles.typography.fontSize.md,\n color: styles.colors.textSecondary\n }}>\n View:\n </span>\n <button\n onClick={() => handleViewModeChange('grid')}\n style={{\n padding: `${styles.spacing.sm} ${styles.spacing.md}`,\n backgroundColor: viewMode === 'grid' ? styles.colors.primary : styles.colors.background,\n color: viewMode === 'grid' ? 'white' : styles.colors.text,\n border: `1px solid ${styles.colors.border}`,\n borderRadius: getBorderRadius('sm'),\n cursor: 'pointer',\n fontSize: styles.typography.fontSize.md\n }}\n >\n Grid\n </button>\n <button\n onClick={() => handleViewModeChange('card')}\n style={{\n padding: `${styles.spacing.sm} ${styles.spacing.md}`,\n backgroundColor: viewMode === 'card' ? styles.colors.primary : styles.colors.background,\n color: viewMode === 'card' ? 'white' : styles.colors.text,\n border: `1px solid ${styles.colors.border}`,\n borderRadius: getBorderRadius('sm'),\n cursor: 'pointer',\n fontSize: styles.typography.fontSize.md\n }}\n >\n Cards\n </button>\n </div>\n </div>\n \n {/* Search Bar */}\n <div style={{\n display: 'flex',\n gap: styles.spacing.md\n }}>\n <input\n type=\"text\"\n placeholder=\"Search entities...\"\n value={searchQuery}\n onChange={(e) => handleSearch(e.target.value)}\n style={{\n flex: 1,\n padding: styles.spacing.md,\n fontSize: styles.typography.fontSize.md,\n border: `1px solid ${styles.colors.border}`,\n borderRadius: getBorderRadius('sm'),\n backgroundColor: styles.colors.background\n }}\n />\n {searchQuery && (\n <button\n onClick={() => handleSearch('')}\n style={{\n padding: `${styles.spacing.sm} ${styles.spacing.md}`,\n backgroundColor: styles.colors.surfaceHover || styles.colors.surface,\n color: styles.colors.text,\n border: `1px solid ${styles.colors.border}`,\n borderRadius: getBorderRadius('sm'),\n cursor: 'pointer',\n fontSize: styles.typography.fontSize.md\n }}\n >\n Clear\n </button>\n )}\n </div>\n </div>\n \n {/* Entity List */}\n <div style={{\n flex: 1,\n overflow: 'auto',\n padding: styles.spacing.lg\n }}>\n {EntityList && (\n <EntityList\n entities={entities}\n viewMode={viewMode}\n selectedEntityId={selectedEntityId}\n onSelectEntity={handleSelectEntity}\n sortBy={sortBy}\n sortDirection={sortDirection}\n onSortChange={handleSortChange}\n savedUserSettings={savedUserSettings?.entityList}\n onSaveUserSettings={(settings) => onSaveUserSettings?.({\n ...savedUserSettings,\n entityList: settings\n })}\n utilities={utilities}\n styles={styles}\n components={components}\n callbacks={callbacks}\n />\n )}\n \n {/* Empty State */}\n {entities.length === 0 && !loading && (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n padding: styles.spacing.xxl || styles.spacing.xl,\n color: styles.colors.textSecondary\n }}>\n <div style={{\n fontSize: styles.typography.fontSize.xl,\n marginBottom: styles.spacing.md\n }}>\n No entities found\n </div>\n <div style={{\n fontSize: styles.typography.fontSize.md\n }}>\n {searchQuery || Object.keys(filters).length > 0\n ? 'Try adjusting your filters or search query'\n : 'No entities are available'}\n </div>\n </div>\n )}\n </div>\n </div>\n \n {/* Details Panel */}\n {EntityDetails && (\n <EntityDetails\n entity={selectedEntity}\n fields={entityFields}\n relationships={entityRelationships}\n isOpen={detailsPanelOpen}\n onClose={handleCloseDetails}\n onOpenRecord={() => handleOpenRecord(selectedEntity?.Name)}\n savedUserSettings={savedUserSettings?.detailsPanel}\n onSaveUserSettings={(settings) => onSaveUserSettings?.({\n ...savedUserSettings,\n detailsPanel: settings\n })}\n utilities={utilities}\n styles={styles}\n components={components}\n callbacks={callbacks}\n />\n )}\n </div>\n );\n}"
1513
1513
  }
@@ -7,7 +7,7 @@
7
7
  import { AuthorizationError } from 'type-graphql';
8
8
  import { GetAPIKeyEngine, AuthorizationResult, AuthorizationRequest } from '@memberjunction/api-keys';
9
9
  import { UserInfo, RunView } from '@memberjunction/core';
10
- import { APIKeyEntity, APIApplicationEntity } from '@memberjunction/core-entities';
10
+ import { MJAPIKeyEntity, MJAPIApplicationEntity } from '@memberjunction/core-entities';
11
11
 
12
12
  /**
13
13
  * Application names used by the API Key authorization system
@@ -94,7 +94,7 @@ export async function CheckAPIKeyScope(
94
94
 
95
95
  // Get the API key to find the user ID
96
96
  const rv = new RunView();
97
- const keyResult = await rv.RunView<APIKeyEntity>({
97
+ const keyResult = await rv.RunView<MJAPIKeyEntity>({
98
98
  EntityName: 'MJ: API Keys',
99
99
  ExtraFilter: `ID='${apiKeyId}'`,
100
100
  ResultType: 'entity_object'
@@ -115,7 +115,7 @@ export async function CheckAPIKeyScope(
115
115
  const apiKey = keyResult.Results[0];
116
116
 
117
117
  // Get the application by name
118
- const appResult = await rv.RunView<APIApplicationEntity>({
118
+ const appResult = await rv.RunView<MJAPIApplicationEntity>({
119
119
  EntityName: 'MJ: API Applications',
120
120
  ExtraFilter: `Name='${applicationName}'`,
121
121
  ResultType: 'entity_object'
@@ -222,7 +222,7 @@ export async function CheckAPIKeyScopeAndLog(
222
222
  const rv = new RunView();
223
223
 
224
224
  // Get the API key
225
- const keyResult = await rv.RunView<APIKeyEntity>({
225
+ const keyResult = await rv.RunView<MJAPIKeyEntity>({
226
226
  EntityName: 'MJ: API Keys',
227
227
  ExtraFilter: `ID='${apiKeyId}'`,
228
228
  ResultType: 'entity_object'
@@ -243,7 +243,7 @@ export async function CheckAPIKeyScopeAndLog(
243
243
  const apiKey = keyResult.Results[0];
244
244
 
245
245
  // Get the application
246
- const appResult = await rv.RunView<APIApplicationEntity>({
246
+ const appResult = await rv.RunView<MJAPIApplicationEntity>({
247
247
  EntityName: 'MJ: API Applications',
248
248
  ExtraFilter: `Name='${applicationName}'`,
249
249
  ResultType: 'entity_object'
@@ -3,7 +3,7 @@ import { Metadata, RunView, LogError, EntitySaveOptions } from '@memberjunction/
3
3
  import { NewUserBase } from './newUsers.js';
4
4
  import { UserCache } from '@memberjunction/sqlserver-dataprovider';
5
5
  import { configInfo } from '../config.js';
6
- import { UserEntity } from '@memberjunction/core-entities';
6
+ import { MJUserEntity } from '@memberjunction/core-entities';
7
7
 
8
8
  /**
9
9
  * This example class subclasses the @NewUserBase class and overrides the createNewUser method to create a new person record and then call the base class to create the user record. In this example there is an entity
@@ -14,7 +14,7 @@ import { UserEntity } from '@memberjunction/core-entities';
14
14
  // so that your class is actually used.
15
15
  //@RegisterClass(NewUserBase, undefined, 1) /*by putting 1 into the priority setting, MJGlobal ClassFactory will use this instead of the base class as that registration had no priority*/
16
16
  export class ExampleNewUserSubClass extends NewUserBase {
17
- public override async createNewUser(firstName: string, lastName: string, email: string, linkedRecordType: string = 'None', linkedEntityId?: string, linkedEntityRecordId?: string): Promise<UserEntity | null> {
17
+ public override async createNewUser(firstName: string, lastName: string, email: string, linkedRecordType: string = 'None', linkedEntityId?: string, linkedEntityRecordId?: string): Promise<MJUserEntity | null> {
18
18
  try {
19
19
  const md = new Metadata();
20
20
 
package/src/auth/index.ts CHANGED
@@ -5,7 +5,7 @@ import sql from 'mssql';
5
5
  import { Metadata, RoleInfo, UserInfo } from '@memberjunction/core';
6
6
  import { NewUserBase } from './newUsers.js';
7
7
  import { MJGlobal } from '@memberjunction/global';
8
- import { UserEntity, UserEntityType } from '@memberjunction/core-entities';
8
+ import { MJUserEntity, MJUserEntityType } from '@memberjunction/core-entities';
9
9
  import { AuthProviderFactory } from './AuthProviderFactory.js';
10
10
  import { initializeAuthProviders } from './initializeProviders.js';
11
11
 
@@ -227,13 +227,13 @@ export const verifyUserRecord = async (
227
227
  // we have a domain from the request that matches one of the domains provided by the configuration, so we will create a new user
228
228
  console.warn(`User ${email} not found in cache. Attempting to create a new user...`);
229
229
  const newUserCreator: NewUserBase = MJGlobal.Instance.ClassFactory.CreateInstance<NewUserBase>(NewUserBase); // this will create the object that handles creating the new user for us
230
- const newUser: UserEntity | null = await newUserCreator.createNewUser(firstName, lastName, email);
230
+ const newUser: MJUserEntity | null = await newUserCreator.createNewUser(firstName, lastName, email);
231
231
  if (newUser) {
232
232
  // new user worked! we already have the stuff we need for the cache, so no need to go to the DB now, just create a new UserInfo object and use the return value from the createNewUser method
233
233
  // to init it, including passing in the role list for the user.
234
234
  const md: Metadata = new Metadata();
235
235
 
236
- const initData: UserEntityType & { UserRoles: { UserID: string; RoleName: string; RoleID: string }[] } = newUser.GetAll();
236
+ const initData: MJUserEntityType & { UserRoles: { UserID: string; RoleName: string; RoleID: string }[] } = newUser.GetAll();
237
237
 
238
238
  initData.UserRoles = configInfo.userHandling.newUserRoles.map((role) => {
239
239
  const roleInfo: RoleInfo | undefined = md.Roles.find((r) => r.Name === role);
@@ -2,10 +2,10 @@ import { ApplicationInfo, EntitySaveOptions, LogError, LogStatus, Metadata, RunV
2
2
  import { RegisterClass } from "@memberjunction/global";
3
3
  import { UserCache } from "@memberjunction/sqlserver-dataprovider";
4
4
  import { configInfo } from "../config.js";
5
- import { UserEntity, UserRoleEntity, UserApplicationEntity, UserApplicationEntityEntity, ApplicationEntityType, ApplicationEntityEntityType } from "@memberjunction/core-entities";
5
+ import { MJUserEntity, MJUserRoleEntity, MJUserApplicationEntity, MJUserApplicationEntityEntity, MJApplicationEntityType, MJApplicationEntityEntityType } from "@memberjunction/core-entities";
6
6
 
7
7
  export class NewUserBase {
8
- public async createNewUser(firstName: string, lastName: string, email: string, linkedRecordType: string = 'None', linkedEntityId?: string, linkedEntityRecordId?: string): Promise<UserEntity | null> {
8
+ public async createNewUser(firstName: string, lastName: string, email: string, linkedRecordType: string = 'None', linkedEntityId?: string, linkedEntityRecordId?: string): Promise<MJUserEntity | null> {
9
9
  try {
10
10
  let contextUser: UserInfo | null = null;
11
11
 
@@ -25,7 +25,7 @@ export class NewUserBase {
25
25
  }
26
26
 
27
27
  const md: Metadata = new Metadata();
28
- const user = await md.GetEntityObject<UserEntity>('Users', contextUser) // To-Do - change this to be a different defined user for the user creation process
28
+ const user = await md.GetEntityObject<MJUserEntity>('MJ: Users', contextUser) // To-Do - change this to be a different defined user for the user creation process
29
29
  user.NewRecord();
30
30
  user.Name = email;
31
31
  user.IsActive = true;
@@ -53,7 +53,7 @@ export class NewUserBase {
53
53
  // user created, now create however many roles we need to create for this user based on the config settings
54
54
  LogStatus(`User ${user.Email} created, assigning roles`);
55
55
  for (const role of configInfo.userHandling.newUserRoles) {
56
- const userRoleEntity: UserRoleEntity = await md.GetEntityObject<UserRoleEntity>('User Roles', contextUser);
56
+ const userRoleEntity: MJUserRoleEntity = await md.GetEntityObject<MJUserRoleEntity>('MJ: User Roles', contextUser);
57
57
  userRoleEntity.NewRecord();
58
58
  userRoleEntity.UserID = user.ID;
59
59
  const userRole = md.Roles.find(r => r.Name === role);
@@ -106,7 +106,7 @@ export class NewUserBase {
106
106
 
107
107
  // Create UserApplication records for each application
108
108
  for (const [appIndex, application] of applicationsToCreate.entries()) {
109
- const userApplication: UserApplicationEntity = await md.GetEntityObject<UserApplicationEntity>('User Applications', contextUser);
109
+ const userApplication: MJUserApplicationEntity = await md.GetEntityObject<MJUserApplicationEntity>('MJ: User Applications', contextUser);
110
110
  userApplication.NewRecord();
111
111
  userApplication.UserID = user.ID;
112
112
  userApplication.ApplicationID = application.ID;
@@ -117,10 +117,10 @@ export class NewUserBase {
117
117
  if(userApplicationSaveResult){
118
118
  LogStatus(`Created User Application ${application.Name} for new user ${user.Name}`);
119
119
 
120
- //now create a UserApplicationEntity records for each entity in the application
120
+ //now create a MJUserApplicationEntity records for each entity in the application
121
121
  const rv: RunView = new RunView();
122
- const rvResult: RunViewResult<ApplicationEntityEntityType> = await rv.RunView({
123
- EntityName: 'Application Entities',
122
+ const rvResult: RunViewResult<MJApplicationEntityEntityType> = await rv.RunView({
123
+ EntityName: 'MJ: Application Entities',
124
124
  ExtraFilter: `ApplicationID = '${application.ID}' and DefaultForNewUser = 1`,
125
125
  }, contextUser);
126
126
 
@@ -132,7 +132,7 @@ export class NewUserBase {
132
132
  LogStatus(`Creating ${rvResult.Results.length} User Application Entities for User Application ${application.Name} for new user ${user.Name}`);
133
133
 
134
134
  for(const [index, appEntity] of rvResult.Results.entries()){
135
- const userAppEntity: UserApplicationEntityEntity = await md.GetEntityObject<UserApplicationEntityEntity>('User Application Entities', contextUser);
135
+ const userAppEntity: MJUserApplicationEntityEntity = await md.GetEntityObject<MJUserApplicationEntityEntity>('MJ: User Application Entities', contextUser);
136
136
  userAppEntity.NewRecord();
137
137
  userAppEntity.UserApplicationID = userApplication.ID;
138
138
  userAppEntity.EntityID = appEntity.EntityID;
@@ -1,6 +1,6 @@
1
1
  import { RegisterClass } from '@memberjunction/global';
2
2
  import { BaseEntity, EntityDeleteOptions, EntitySaveOptions } from '@memberjunction/core';
3
- import { EntityPermissionEntity } from '@memberjunction/core-entities';
3
+ import { MJEntityPermissionEntity } from '@memberjunction/core-entities';
4
4
  import axios from 'axios';
5
5
  import { ___codeGenAPIPort, ___codeGenAPISubmissionDelay, ___codeGenAPIURL } from '../config.js';
6
6
 
@@ -11,8 +11,8 @@ import { ___codeGenAPIPort, ___codeGenAPISubmissionDelay, ___codeGenAPIURL } fro
11
11
  * This class is within the memberjunction/server package because it is closely coupled to other aspects of what
12
12
  * happens in the server. That's why it is not in the core-entities-server package.
13
13
  */
14
- @RegisterClass(BaseEntity, 'Entity Permissions')
15
- export class EntityPermissionsEntity_Server extends EntityPermissionEntity {
14
+ @RegisterClass(BaseEntity, 'MJ: Entity Permissions')
15
+ export class EntityPermissionsEntity_Server extends MJEntityPermissionEntity {
16
16
  protected static _entityIDQueue: string[] = [];
17
17
  protected static _lastModifiedTime: Date | null = null;
18
18
  protected static _submissionTimer: NodeJS.Timeout | null = null;