@avakado.ai/schemas 1.0.0 → 1.1.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.
@@ -0,0 +1,197 @@
1
+ import { Schema } from "mongoose";
2
+ import { defineModel, requireDep } from "../runtime.js";
3
+
4
+ const TOKEN_EXPIRY_BUFFER_MS = 60_000;
5
+ const baseOpts = { _id: false };
6
+ const docOpts = { timestamps: true, discriminatorKey: "authType" };
7
+ const credentialOpts = { _id: false, strict: false };
8
+
9
+ const ApiAuthenticationSchema = new Schema({
10
+ provider: { type: Schema.Types.ObjectId, ref: "Providers" },
11
+ accountDetails: Schema.Types.Mixed,
12
+ scope: [String],
13
+ isActive: { type: Boolean, default: true },
14
+ createdBy: { type: Schema.Types.ObjectId, ref: "Users" },
15
+ business: { type: Schema.Types.ObjectId, ref: "Businesses" },
16
+ // Present on host copies that do not use authType discriminators (AvaPhone / socketio).
17
+ credentials: Schema.Types.Mixed,
18
+ config: Schema.Types.Mixed,
19
+ }, docOpts);
20
+
21
+ const oauth2CredentialsSchema = new Schema({
22
+ tokenId: String,
23
+ accessToken: String,
24
+ refreshToken: String,
25
+ expiresAt: Date,
26
+ refreshTokenExpiresAt: Date,
27
+ tokenType: { type: String, default: "Bearer" },
28
+ igUserId: String,
29
+ pageId: String,
30
+ pageAccessToken: String,
31
+ }, credentialOpts);
32
+
33
+ const oauth2Schema = new Schema({
34
+ credentials: oauth2CredentialsSchema,
35
+ config: Schema.Types.Mixed
36
+ }, baseOpts);
37
+
38
+ const apiKeyCredentialsSchema = new Schema({
39
+ apiKey: String,
40
+ apiToken: String,
41
+ accountSid: String,
42
+ subdomain: String,
43
+ }, credentialOpts);
44
+
45
+ const apiKeySchema = new Schema({
46
+ credentials: apiKeyCredentialsSchema,
47
+ config: Schema.Types.Mixed
48
+ }, baseOpts);
49
+
50
+ const basicSchema = new Schema({
51
+ credentials: {
52
+ username: String,
53
+ password: String,
54
+ basicToken: String,
55
+ id: String,
56
+ }
57
+ }, baseOpts);
58
+
59
+ const bearerSchema = new Schema({
60
+ credentials: {
61
+ token: String,
62
+ }
63
+ }, baseOpts);
64
+
65
+ const jwtSchema = new Schema({
66
+ credentials: {
67
+ token: String,
68
+ expiresAt: Date
69
+ },
70
+ config: {
71
+ issuer: String,
72
+ audience: String,
73
+ algorithm: String
74
+ }
75
+ }, baseOpts);
76
+
77
+ const hmacSchema = new Schema({
78
+ credentials: {
79
+ apiKey: String,
80
+ apiSecret: String,
81
+ },
82
+ config: {
83
+ algorithm: { type: String, default: "sha256" },
84
+ header: { type: String, default: "x-signature" }
85
+ }
86
+ }, baseOpts);
87
+
88
+ const customHeaderSchema = new Schema({
89
+ credentials: {
90
+ headers: {
91
+ type: Map,
92
+ of: String
93
+ }
94
+ }
95
+ }, baseOpts);
96
+
97
+ const mtlsSchema = new Schema({
98
+ credentials: {
99
+ cert: String,
100
+ key: String,
101
+ ca: String
102
+ }
103
+ }, baseOpts);
104
+
105
+ const cookieSchema = new Schema({
106
+ credentials: {
107
+ cookies: {
108
+ type: Map,
109
+ of: String
110
+ }
111
+ }
112
+ }, baseOpts);
113
+
114
+ const noAuthSchema = new Schema({}, baseOpts);
115
+
116
+ ApiAuthenticationSchema.discriminator("oauth2", oauth2Schema);
117
+ ApiAuthenticationSchema.discriminator("apiKey", apiKeySchema);
118
+ ApiAuthenticationSchema.discriminator("basic", basicSchema);
119
+ ApiAuthenticationSchema.discriminator("bearer", bearerSchema);
120
+ ApiAuthenticationSchema.discriminator("jwt", jwtSchema);
121
+ ApiAuthenticationSchema.discriminator("hmac", hmacSchema);
122
+ ApiAuthenticationSchema.discriminator("customHeader", customHeaderSchema);
123
+ ApiAuthenticationSchema.discriminator("mtls", mtlsSchema);
124
+ ApiAuthenticationSchema.discriminator("cookie", cookieSchema);
125
+ ApiAuthenticationSchema.discriminator("none", noAuthSchema);
126
+
127
+ ApiAuthenticationSchema.methods.getSecrets = function () {
128
+ return { credentials: this.credentials, config: this.config };
129
+ };
130
+ ApiAuthenticationSchema.methods.getCredentials = async function () {
131
+ return this.credentials;
132
+ };
133
+ ApiAuthenticationSchema.methods._resolveProvider = async function () {
134
+ const getAuthProvider = requireDep("getAuthProvider", "ApiAuthenticators._resolveProvider");
135
+ await this.populate("provider");
136
+ const serviceProvider = getAuthProvider(this.provider?.name);
137
+ if (!serviceProvider) throw new Error(`Unsupported provider: ${this.provider?.name}`);
138
+ return serviceProvider;
139
+ };
140
+ ApiAuthenticationSchema.methods._plain = function (value) {
141
+ return value?.toObject?.() ?? value ?? {};
142
+ };
143
+ ApiAuthenticationSchema.methods._enrichedCredentials = function () {
144
+ const creds = { ...this._plain(this.credentials) };
145
+ const config = this._plain(this.config);
146
+ if (this.authType === "apiKey") {
147
+ creds.accountSid ??= config.AccountSid;
148
+ creds.subdomain ??= config.subdomain;
149
+ }
150
+ return creds;
151
+ };
152
+ ApiAuthenticationSchema.methods._isAccessTokenFresh = function () {
153
+ const { accessToken, expiresAt } = this._enrichedCredentials();
154
+ if (!accessToken || !expiresAt) return false;
155
+ return new Date(expiresAt).getTime() > Date.now() + TOKEN_EXPIRY_BUFFER_MS;
156
+ };
157
+ ApiAuthenticationSchema.methods.validateToken = async function () {
158
+ const serviceProvider = await this._resolveProvider();
159
+ return serviceProvider.validateToken(this._enrichedCredentials());
160
+ };
161
+ ApiAuthenticationSchema.methods.refreshToken = async function () {
162
+ const serviceProvider = await this._resolveProvider();
163
+ const providerSupportsRefresh = requireDep("providerSupportsRefresh", "ApiAuthenticators.refreshToken");
164
+ if (!providerSupportsRefresh(serviceProvider)) {
165
+ throw new Error(`Provider "${this.provider.name}" does not support token refresh`);
166
+ }
167
+ const newTokensRes = await serviceProvider.refreshToken(this._enrichedCredentials());
168
+ if (!newTokensRes.success) throw new Error(newTokensRes.error.message);
169
+ this.credentials = { ...this.credentials, ...newTokensRes.data };
170
+ await this.save();
171
+ return this;
172
+ };
173
+ ApiAuthenticationSchema.methods.ensureValidToken = async function () {
174
+ const serviceProvider = await this._resolveProvider();
175
+ const providerSupportsRefresh = requireDep("providerSupportsRefresh", "ApiAuthenticators.ensureValidToken");
176
+
177
+ if (this._isAccessTokenFresh()) return this;
178
+
179
+ if (await serviceProvider.validateToken(this.credentials)) return this;
180
+
181
+ if (!providerSupportsRefresh(serviceProvider)) {
182
+ throw new Error(`Invalid or expired credentials for ${this.provider.name}; re-authentication required`);
183
+ }
184
+
185
+ return this.refreshToken();
186
+ };
187
+ ApiAuthenticationSchema.methods.hasAllScopes = function (scopes) {
188
+ for (const item of scopes) {
189
+ if (!this.scope.includes(item)) {
190
+ return false;
191
+ }
192
+ }
193
+ return true;
194
+ };
195
+
196
+ export { ApiAuthenticationSchema };
197
+ export const ApiAuthenticators = defineModel("ApiAuthenticators", ApiAuthenticationSchema, "ApiAuthenticators");
@@ -5,3 +5,27 @@ export { UsageLog, UsageLogSchema } from "./UsageLogs.js";
5
5
  export { Conversation, ConversationSchema } from "./Conversations.js";
6
6
  export { Campaign, CampaignSchema, Task, TaskSchema } from "./Campaign.js";
7
7
  export { Trigger, TriggerSchema } from "./Triggers.js";
8
+ export { User, ScopesEnum, RoleScopes } from "./User.js";
9
+ export { AgentModel } from "./Agent.js";
10
+ export { Channel, ChannelCapabilityDefaults } from "./Channels.js";
11
+ export { CallSession } from "./CallSessions.js";
12
+ export { Plan } from "./Plans.js";
13
+ export { Api, Providers } from "./ExternalServiceProviders.js";
14
+ export { Template } from "./market.js";
15
+ export { Message, MessageSession } from "./Messages.js";
16
+ export { Lead, LeadTemplate } from "./Leads.js";
17
+ export { Log } from "./Log.js";
18
+ export { BillingLog } from "./BillingLogs.js";
19
+ export { ApiAuthenticators, ApiAuthenticationSchema } from "./apiAuthenticator.js";
20
+ export { DemonstrationModel } from "./Demonstarations.js";
21
+ export { Action } from "./Action.js";
22
+ export { Collection } from "./Collection.js";
23
+ export { Node, NodeModel } from "./InbuiltNodes.js";
24
+ export { Integration } from "./Integrations.js";
25
+ export { Job } from "./Job.js";
26
+ export { Notification } from "./notifications.js";
27
+ export { Ticket } from "./Tickets.js";
28
+ export { Document } from "./Document.js";
29
+ export { Data } from "./Data.js";
30
+ export { Workflow, WorkflowSchema } from "./Workflow.js";
31
+ export { WorkflowLogs } from "./WorkflowLogs.js";
@@ -0,0 +1,66 @@
1
+ // models/channel.js
2
+ import { Schema } from "mongoose";
3
+ import { defineModel } from "../runtime.js";
4
+
5
+ const baseOpts = { _id: false }; // subdocs don’t need their own _id
6
+ const docOpts = { timestamps: true, discriminatorKey: 'type' };
7
+
8
+ /* ───────────────────────────── Base Channel ───────────────────────────── */
9
+ const TemplateBaseSchema = new Schema(
10
+ {
11
+ name: { type: String, required: true, trim: true },
12
+ createdBy: { type: Schema.Types.ObjectId, ref: "Users" },
13
+ type: { type: String, enum: ['agent', 'action'], required: true },
14
+ status: { type: String, default: 'disabled' }, // enabled | disabled | error
15
+ description: String, //can be removed as tool already has it
16
+ imageUrl: String,
17
+ tags: [String],
18
+ version: String,
19
+ applicableSectors: [String], //business sectors the tool is applicable for, useful for filtering in marketplace
20
+ isPublic: { type: Boolean, default: false },
21
+ UIElements: Schema.Types.Mixed,
22
+ isFeatured: { type: Boolean, default: false },
23
+ },
24
+ docOpts
25
+ );
26
+ export const Template = defineModel('StandardProduct', TemplateBaseSchema, 'StandardProduct');
27
+
28
+ /* ───────────────────────────── Agent Template ──────────────────────────── */
29
+ const AgentData = new Schema(
30
+ {
31
+ personalInfo: {
32
+ name: String,
33
+ systemPrompt: {
34
+ role: String,
35
+ objective: String,
36
+ instructionsAndWorkflow: String,
37
+ constraintsAndRules: String
38
+ },
39
+ model: { type: String, default: 'gpt-4.1-mini' },
40
+ temperature: { type: Number, default: 0.5 },
41
+ },
42
+ collections: [{ type: Schema.Types.ObjectId, ref: 'Collection' }],
43
+ actions: [{ type: Schema.Types.ObjectId, ref: 'StandardProduct' }],
44
+ facets: [String],
45
+ },
46
+ baseOpts
47
+ );
48
+ Template.discriminator('agent', new Schema({ data: AgentData, config: Schema.Types.Mixed }, docOpts));
49
+ /* ─────────────────────────── Action Template ─────────────────────────── */
50
+ const ActionData = new Schema(
51
+ {
52
+ name: String,
53
+ description: String,
54
+ async: { type: Boolean, default: true },
55
+ needsApproval: Boolean, // Knowledge fetching doesn't need approval
56
+ parameters: Schema.Types.Mixed,
57
+ functionString: String,
58
+ errorFunction: String,
59
+ UI: Schema.Types.Mixed,
60
+ },
61
+ baseOpts
62
+ );
63
+ const ActionConfig = new Schema({
64
+ orgDefinedParams: Schema.Types.Mixed,
65
+ }, baseOpts);
66
+ Template.discriminator('action', new Schema({ data: ActionData, config: ActionConfig }, docOpts));
@@ -0,0 +1,15 @@
1
+ // mongodb schema for notificatiosn that contains the following fields => head, body,type,attachments, status timestamps
2
+ import { Schema, Types } from "mongoose";
3
+ import { defineModel } from "../runtime.js";
4
+ const NotificationSchema = new Schema(
5
+ {
6
+ business: { type: Types.ObjectId, ref: 'Businesses' },
7
+ head: String,
8
+ body: String,
9
+ type: String,
10
+ attachments: Schema.Types.Mixed,
11
+ status: { type: String, default: "unseen" },
12
+ },
13
+ { timestamps: true }
14
+ );
15
+ export const Notification = defineModel('Notification', NotificationSchema, 'Notification');
package/src/runtime.js CHANGED
@@ -19,6 +19,10 @@ export function defineModel(name, schema, collection) {
19
19
  const deps = {
20
20
  /** ({ topic, message, acks }) => Promise<void> — the service's Kafka producer. */
21
21
  sendKafkaMessage: null,
22
+ /** (providerName) => host OAuth/API provider instance. */
23
+ getAuthProvider: null,
24
+ /** (provider) => boolean — whether the host provider implements refreshToken. */
25
+ providerSupportsRefresh: null,
22
26
  };
23
27
 
24
28
  export function configureSchemas(next = {}) {