@happyvertical/smrt-profiles 0.30.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/AGENTS.md +53 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +7 -0
- package/README.md +176 -0
- package/dist/chunks/ApiKey-B2LKEaP8.js +143 -0
- package/dist/chunks/ApiKey-B2LKEaP8.js.map +1 -0
- package/dist/chunks/ApiKeyCollection-B6Op817e.js +91 -0
- package/dist/chunks/ApiKeyCollection-B6Op817e.js.map +1 -0
- package/dist/chunks/AuditLogCollection-BYqCj0uE.js +195 -0
- package/dist/chunks/AuditLogCollection-BYqCj0uE.js.map +1 -0
- package/dist/chunks/NostrIdentityCollection-DadQBHWy.js +3065 -0
- package/dist/chunks/NostrIdentityCollection-DadQBHWy.js.map +1 -0
- package/dist/chunks/ProfileAssetCollection-D_tk1kKG.js +122 -0
- package/dist/chunks/ProfileAssetCollection-D_tk1kKG.js.map +1 -0
- package/dist/chunks/ProfileCollection-DU6wUJTO.js +782 -0
- package/dist/chunks/ProfileCollection-DU6wUJTO.js.map +1 -0
- package/dist/chunks/ProfileMetadataCollection-DEhmljMY.js +120 -0
- package/dist/chunks/ProfileMetadataCollection-DEhmljMY.js.map +1 -0
- package/dist/chunks/ProfileMetafieldCollection-DMKhSHXX.js +184 -0
- package/dist/chunks/ProfileMetafieldCollection-DMKhSHXX.js.map +1 -0
- package/dist/chunks/ProfileRelationshipCollection-C0IM8UQR.js +177 -0
- package/dist/chunks/ProfileRelationshipCollection-C0IM8UQR.js.map +1 -0
- package/dist/chunks/ProfileRelationshipTermCollection-CXem_qT-.js +117 -0
- package/dist/chunks/ProfileRelationshipTermCollection-CXem_qT-.js.map +1 -0
- package/dist/chunks/ProfileRelationshipType-BXBLldea.js +103 -0
- package/dist/chunks/ProfileRelationshipType-BXBLldea.js.map +1 -0
- package/dist/chunks/ProfileRelationshipTypeCollection-CF8YvLTV.js +48 -0
- package/dist/chunks/ProfileRelationshipTypeCollection-CF8YvLTV.js.map +1 -0
- package/dist/chunks/index-jFtOWsAV.js +1014 -0
- package/dist/chunks/index-jFtOWsAV.js.map +1 -0
- package/dist/index.d.ts +1848 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.json +11829 -0
- package/dist/smrt-knowledge.json +3846 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +61 -0
- package/dist/utils.js +49 -0
- package/dist/utils.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { foreignKey, smrt, SmrtObject, SmrtCollection } from "@happyvertical/smrt-core";
|
|
2
|
+
import { tenantId, TenantScoped } from "@happyvertical/smrt-tenancy";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
6
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
7
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
8
|
+
if (decorator = decorators[i])
|
|
9
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
10
|
+
if (kind && result) __defProp(target, key, result);
|
|
11
|
+
return result;
|
|
12
|
+
};
|
|
13
|
+
let AuditLog = class extends SmrtObject {
|
|
14
|
+
tenantId = null;
|
|
15
|
+
profileId;
|
|
16
|
+
/**
|
|
17
|
+
* Action performed (e.g., 'issue.update', 'feedback.incorporate')
|
|
18
|
+
*/
|
|
19
|
+
action = "";
|
|
20
|
+
/**
|
|
21
|
+
* Type of resource affected (e.g., 'Issue', 'Repository')
|
|
22
|
+
*/
|
|
23
|
+
resourceType = "";
|
|
24
|
+
/**
|
|
25
|
+
* ID of the affected resource
|
|
26
|
+
*/
|
|
27
|
+
resourceId = "";
|
|
28
|
+
/**
|
|
29
|
+
* Source of the action
|
|
30
|
+
*/
|
|
31
|
+
source = "web";
|
|
32
|
+
/**
|
|
33
|
+
* Additional context (CI run ID, request ID, etc.)
|
|
34
|
+
*/
|
|
35
|
+
metadata = {};
|
|
36
|
+
onBehalfOfId;
|
|
37
|
+
constructor(options = {}) {
|
|
38
|
+
super(options);
|
|
39
|
+
if (options.profileId) this.profileId = options.profileId;
|
|
40
|
+
if (options.action) this.action = options.action;
|
|
41
|
+
if (options.resourceType) this.resourceType = options.resourceType;
|
|
42
|
+
if (options.resourceId) this.resourceId = options.resourceId;
|
|
43
|
+
if (options.source) this.source = options.source;
|
|
44
|
+
if (options.metadata) this.metadata = options.metadata;
|
|
45
|
+
if (options.onBehalfOfId !== void 0)
|
|
46
|
+
this.onBehalfOfId = options.onBehalfOfId;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get the profile who performed the action
|
|
50
|
+
*/
|
|
51
|
+
async getProfile() {
|
|
52
|
+
return await this.getRelated("profileId");
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get the profile on whose behalf the action was performed (if any)
|
|
56
|
+
*/
|
|
57
|
+
async getOnBehalfOf() {
|
|
58
|
+
if (!this.onBehalfOfId) return null;
|
|
59
|
+
return await this.getRelated("onBehalfOfId");
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get the effective actor (onBehalfOf if set, otherwise profile)
|
|
63
|
+
*/
|
|
64
|
+
async getEffectiveActor() {
|
|
65
|
+
const onBehalfOf = await this.getOnBehalfOf();
|
|
66
|
+
if (onBehalfOf) return onBehalfOf;
|
|
67
|
+
return await this.getProfile();
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Create an audit log entry
|
|
71
|
+
*/
|
|
72
|
+
static async record(options) {
|
|
73
|
+
const log = new AuditLog({
|
|
74
|
+
...options,
|
|
75
|
+
profileId: options.profile.id,
|
|
76
|
+
onBehalfOfId: options.onBehalfOf?.id
|
|
77
|
+
});
|
|
78
|
+
await log.initialize();
|
|
79
|
+
await log.save();
|
|
80
|
+
return log;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
__decorateClass([
|
|
84
|
+
tenantId({ nullable: true })
|
|
85
|
+
], AuditLog.prototype, "tenantId", 2);
|
|
86
|
+
__decorateClass([
|
|
87
|
+
foreignKey("Profile", { required: true })
|
|
88
|
+
], AuditLog.prototype, "profileId", 2);
|
|
89
|
+
__decorateClass([
|
|
90
|
+
foreignKey("Profile", { nullable: true })
|
|
91
|
+
], AuditLog.prototype, "onBehalfOfId", 2);
|
|
92
|
+
AuditLog = __decorateClass([
|
|
93
|
+
TenantScoped({ mode: "optional", allowSuperAdminBypass: true }),
|
|
94
|
+
smrt({
|
|
95
|
+
tableName: "audit_logs",
|
|
96
|
+
api: { include: ["list", "get"] },
|
|
97
|
+
mcp: { include: ["list", "get"] },
|
|
98
|
+
cli: { include: ["list"] }
|
|
99
|
+
})
|
|
100
|
+
], AuditLog);
|
|
101
|
+
class AuditLogCollection extends SmrtCollection {
|
|
102
|
+
static _itemClass = AuditLog;
|
|
103
|
+
/**
|
|
104
|
+
* Find logs for a profile (actions they performed)
|
|
105
|
+
*/
|
|
106
|
+
async findByProfile(profileId) {
|
|
107
|
+
return await this.list({
|
|
108
|
+
where: { profileId },
|
|
109
|
+
orderBy: "createdAt DESC"
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Find logs for a resource
|
|
114
|
+
*/
|
|
115
|
+
async findByResource(resourceType, resourceId) {
|
|
116
|
+
return await this.list({
|
|
117
|
+
where: { resourceType, resourceId },
|
|
118
|
+
orderBy: "createdAt DESC"
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Find logs by action type
|
|
123
|
+
*/
|
|
124
|
+
async findByAction(action) {
|
|
125
|
+
return await this.list({
|
|
126
|
+
where: { action },
|
|
127
|
+
orderBy: "createdAt DESC"
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Find logs by source
|
|
132
|
+
*/
|
|
133
|
+
async findBySource(source) {
|
|
134
|
+
return await this.list({
|
|
135
|
+
where: { source },
|
|
136
|
+
orderBy: "createdAt DESC"
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Find logs where actions were performed on behalf of someone
|
|
141
|
+
*/
|
|
142
|
+
async findOnBehalfOf(profileId) {
|
|
143
|
+
return await this.list({
|
|
144
|
+
where: { onBehalfOfId: profileId },
|
|
145
|
+
orderBy: "createdAt DESC"
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Record a new audit log entry
|
|
150
|
+
*/
|
|
151
|
+
async record(options) {
|
|
152
|
+
const log = new AuditLog({
|
|
153
|
+
...this.options,
|
|
154
|
+
profileId: options.profile.id,
|
|
155
|
+
action: options.action,
|
|
156
|
+
resourceType: options.resourceType,
|
|
157
|
+
resourceId: options.resourceId,
|
|
158
|
+
source: options.source || "web",
|
|
159
|
+
metadata: options.metadata || {},
|
|
160
|
+
onBehalfOfId: options.onBehalfOf?.id
|
|
161
|
+
});
|
|
162
|
+
await log.initialize();
|
|
163
|
+
await log.save();
|
|
164
|
+
return log;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Get recent activity for a profile
|
|
168
|
+
*/
|
|
169
|
+
async getRecentActivity(profileId, limit = 50) {
|
|
170
|
+
return await this.list({
|
|
171
|
+
where: { profileId },
|
|
172
|
+
orderBy: "createdAt DESC",
|
|
173
|
+
limit
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Get activity timeline for a resource
|
|
178
|
+
*/
|
|
179
|
+
async getResourceTimeline(resourceType, resourceId) {
|
|
180
|
+
return await this.list({
|
|
181
|
+
where: { resourceType, resourceId },
|
|
182
|
+
orderBy: "createdAt ASC"
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const AuditLogCollection$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
187
|
+
__proto__: null,
|
|
188
|
+
AuditLogCollection
|
|
189
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
190
|
+
export {
|
|
191
|
+
AuditLog as A,
|
|
192
|
+
AuditLogCollection as a,
|
|
193
|
+
AuditLogCollection$1 as b
|
|
194
|
+
};
|
|
195
|
+
//# sourceMappingURL=AuditLogCollection-BYqCj0uE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuditLogCollection-BYqCj0uE.js","sources":["../../src/models/AuditLog.ts","../../src/collections/AuditLogCollection.ts"],"sourcesContent":["/**\n * AuditLog - Tracks all actions for full audit trail\n *\n * Records who did what, when, and how (web, CLI, CI, webhook, MCP).\n * Supports pass-through identity for CI workflows.\n */\n\nimport {\n foreignKey,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport type { Profile } from './Profile';\n\nexport type AuditSource = 'web' | 'cli' | 'ci' | 'webhook' | 'mcp';\n\nexport interface AuditLogOptions extends SmrtObjectOptions {\n profileId?: string;\n action?: string;\n resourceType?: string;\n resourceId?: string;\n source?: AuditSource;\n metadata?: Record<string, any>;\n onBehalfOfId?: string | null;\n tenantId?: string | null;\n}\n\n@TenantScoped({ mode: 'optional', allowSuperAdminBypass: true })\n@smrt({\n tableName: 'audit_logs',\n api: { include: ['list', 'get'] },\n mcp: { include: ['list', 'get'] },\n cli: { include: ['list'] },\n})\nexport class AuditLog extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /**\n * The profile who performed the action\n */\n @foreignKey('Profile', { required: true })\n profileId?: string;\n\n /**\n * Action performed (e.g., 'issue.update', 'feedback.incorporate')\n */\n action: string = '';\n\n /**\n * Type of resource affected (e.g., 'Issue', 'Repository')\n */\n resourceType: string = '';\n\n /**\n * ID of the affected resource\n */\n resourceId: string = '';\n\n /**\n * Source of the action\n */\n source: AuditSource = 'web';\n\n /**\n * Additional context (CI run ID, request ID, etc.)\n */\n metadata: Record<string, any> = {};\n\n /**\n * For pass-through identity in CI - the actual person who triggered\n */\n @foreignKey('Profile', { nullable: true })\n onBehalfOfId?: string | null;\n\n constructor(options: AuditLogOptions = {}) {\n super(options);\n if (options.profileId) this.profileId = options.profileId;\n if (options.action) this.action = options.action;\n if (options.resourceType) this.resourceType = options.resourceType;\n if (options.resourceId) this.resourceId = options.resourceId;\n if (options.source) this.source = options.source;\n if (options.metadata) this.metadata = options.metadata;\n if (options.onBehalfOfId !== undefined)\n this.onBehalfOfId = options.onBehalfOfId;\n }\n\n /**\n * Get the profile who performed the action\n */\n async getProfile(): Promise<Profile | null> {\n return (await this.getRelated('profileId')) as Profile | null;\n }\n\n /**\n * Get the profile on whose behalf the action was performed (if any)\n */\n async getOnBehalfOf(): Promise<Profile | null> {\n if (!this.onBehalfOfId) return null;\n return (await this.getRelated('onBehalfOfId')) as Profile | null;\n }\n\n /**\n * Get the effective actor (onBehalfOf if set, otherwise profile)\n */\n async getEffectiveActor(): Promise<Profile | null> {\n const onBehalfOf = await this.getOnBehalfOf();\n if (onBehalfOf) return onBehalfOf;\n return await this.getProfile();\n }\n\n /**\n * Create an audit log entry\n */\n static async record(\n options: AuditLogOptions & {\n profile: Profile;\n onBehalfOf?: Profile | null;\n },\n ): Promise<AuditLog> {\n const log = new AuditLog({\n ...options,\n profileId: options.profile.id as string,\n onBehalfOfId: options.onBehalfOf?.id as string | undefined,\n });\n await log.initialize();\n await log.save();\n return log;\n }\n}\n","/**\n * AuditLogCollection - Collection for querying audit logs\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { AuditLog, type AuditSource } from '../models/AuditLog';\nimport type { Profile } from '../models/Profile';\n\nexport class AuditLogCollection extends SmrtCollection<AuditLog> {\n static readonly _itemClass = AuditLog;\n\n /**\n * Find logs for a profile (actions they performed)\n */\n async findByProfile(profileId: string): Promise<AuditLog[]> {\n return await this.list({\n where: { profileId },\n orderBy: 'createdAt DESC',\n });\n }\n\n /**\n * Find logs for a resource\n */\n async findByResource(\n resourceType: string,\n resourceId: string,\n ): Promise<AuditLog[]> {\n return await this.list({\n where: { resourceType, resourceId },\n orderBy: 'createdAt DESC',\n });\n }\n\n /**\n * Find logs by action type\n */\n async findByAction(action: string): Promise<AuditLog[]> {\n return await this.list({\n where: { action },\n orderBy: 'createdAt DESC',\n });\n }\n\n /**\n * Find logs by source\n */\n async findBySource(source: AuditSource): Promise<AuditLog[]> {\n return await this.list({\n where: { source },\n orderBy: 'createdAt DESC',\n });\n }\n\n /**\n * Find logs where actions were performed on behalf of someone\n */\n async findOnBehalfOf(profileId: string): Promise<AuditLog[]> {\n return await this.list({\n where: { onBehalfOfId: profileId },\n orderBy: 'createdAt DESC',\n });\n }\n\n /**\n * Record a new audit log entry\n */\n async record(options: {\n profile: Profile;\n action: string;\n resourceType: string;\n resourceId: string;\n source?: AuditSource;\n metadata?: Record<string, any>;\n onBehalfOf?: Profile | null;\n }): Promise<AuditLog> {\n const log = new AuditLog({\n ...this.options,\n profileId: options.profile.id as string,\n action: options.action,\n resourceType: options.resourceType,\n resourceId: options.resourceId,\n source: options.source || 'web',\n metadata: options.metadata || {},\n onBehalfOfId: options.onBehalfOf?.id as string | undefined,\n });\n await log.initialize();\n await log.save();\n return log;\n }\n\n /**\n * Get recent activity for a profile\n */\n async getRecentActivity(\n profileId: string,\n limit: number = 50,\n ): Promise<AuditLog[]> {\n return await this.list({\n where: { profileId },\n orderBy: 'createdAt DESC',\n limit,\n });\n }\n\n /**\n * Get activity timeline for a resource\n */\n async getResourceTimeline(\n resourceType: string,\n resourceId: string,\n ): Promise<AuditLog[]> {\n return await this.list({\n where: { resourceType, resourceId },\n orderBy: 'createdAt ASC',\n });\n }\n}\n"],"names":[],"mappings":"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"}
|