fraim-framework 2.0.179 → 2.0.180

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 (59) hide show
  1. package/dist/src/ai-hub/desktop-main.js +2 -2
  2. package/dist/src/api/admin/payments.js +33 -0
  3. package/dist/src/api/admin/sales-leads.js +21 -0
  4. package/dist/src/api/payment/create-session.js +338 -0
  5. package/dist/src/api/payment/dashboard-link.js +149 -0
  6. package/dist/src/api/payment/session-details.js +31 -0
  7. package/dist/src/api/payment/webhook.js +587 -0
  8. package/dist/src/api/personas/me.js +29 -0
  9. package/dist/src/api/pricing/get-config.js +25 -0
  10. package/dist/src/api/sales/contact.js +44 -0
  11. package/dist/src/cli/distribution/marketplace-bundles.js +5 -1
  12. package/dist/src/db/payment-repository.js +61 -0
  13. package/dist/src/fraim/config-loader.js +11 -0
  14. package/dist/src/fraim/db-service.js +2387 -0
  15. package/dist/src/fraim/issues.js +152 -0
  16. package/dist/src/fraim/template-processor.js +184 -0
  17. package/dist/src/fraim/utils/request-utils.js +23 -0
  18. package/dist/src/middleware/auth.js +266 -0
  19. package/dist/src/middleware/cors-config.js +111 -0
  20. package/dist/src/middleware/logger.js +116 -0
  21. package/dist/src/middleware/rate-limit.js +110 -0
  22. package/dist/src/middleware/reject-query-api-key.js +45 -0
  23. package/dist/src/middleware/security-headers.js +41 -0
  24. package/dist/src/middleware/telemetry.js +134 -0
  25. package/dist/src/models/payment.js +2 -0
  26. package/dist/src/routes/analytics.js +1447 -0
  27. package/dist/src/routes/app-routes.js +32 -0
  28. package/dist/src/routes/auth-routes.js +505 -0
  29. package/dist/src/routes/oauth-routes.js +325 -0
  30. package/dist/src/routes/payment-routes.js +186 -0
  31. package/dist/src/routes/persona-catalog-routes.js +84 -0
  32. package/dist/src/services/admin-service.js +229 -0
  33. package/dist/src/services/audit-log-persistence.js +60 -0
  34. package/dist/src/services/audit-log.js +69 -0
  35. package/dist/src/services/cookie-service.js +129 -0
  36. package/dist/src/services/dashboard-access.js +27 -0
  37. package/dist/src/services/demo-seed-service.js +139 -0
  38. package/dist/src/services/email-code.js +23 -0
  39. package/dist/src/services/email-service-clean.js +782 -0
  40. package/dist/src/services/email-service.js +951 -0
  41. package/dist/src/services/installer-service.js +131 -0
  42. package/dist/src/services/mcp-oauth-store.js +33 -0
  43. package/dist/src/services/mcp-service.js +823 -0
  44. package/dist/src/services/oauth-helpers.js +127 -0
  45. package/dist/src/services/org-service.js +89 -0
  46. package/dist/src/services/persona-entitlement-service.js +288 -0
  47. package/dist/src/services/provider-service.js +215 -0
  48. package/dist/src/services/registry-service.js +628 -0
  49. package/dist/src/services/session-service.js +86 -0
  50. package/dist/src/services/trial-reminder-service.js +120 -0
  51. package/dist/src/services/usage-analytics-service.js +419 -0
  52. package/dist/src/services/workspace-identity.js +21 -0
  53. package/dist/src/types/analytics.js +2 -0
  54. package/dist/src/utils/payment-calculator.js +52 -0
  55. package/extensions/office-word/favicon.ico +0 -0
  56. package/extensions/office-word/icon-64.png +0 -0
  57. package/extensions/office-word/manifest.xml +33 -0
  58. package/extensions/office-word/taskpane.html +242 -0
  59. package/package.json +12 -2
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSalesLead = createSalesLead;
4
+ async function createSalesLead(req, res, dbService) {
5
+ try {
6
+ const { name, email, company, teamSize, useCase, projectDetails, timeline, budget } = req.body;
7
+ // Validation
8
+ if (!email || !email.includes('@')) {
9
+ return res.status(400).json({ error: 'Valid email is required' });
10
+ }
11
+ if (!company || company.trim().length === 0) {
12
+ return res.status(400).json({ error: 'Company is required' });
13
+ }
14
+ const validTeamSizes = ['1-10', '11-50', '51-200', '201-500', '500+'];
15
+ if (!teamSize || !validTeamSizes.includes(teamSize)) {
16
+ return res.status(400).json({
17
+ error: 'Invalid teamSize. Must be one of: 1-10, 11-50, 51-200, 201-500, 500+'
18
+ });
19
+ }
20
+ // Create sales inquiry using existing collection
21
+ await dbService.createSalesInquiry({
22
+ email: email.trim().toLowerCase(),
23
+ company: company.trim(),
24
+ projectDetails: projectDetails?.trim() || useCase?.trim() || '',
25
+ teamSize,
26
+ timeline: timeline?.trim(),
27
+ budget: budget?.trim(),
28
+ source: 'fraim-website-payment',
29
+ timestamp: new Date(),
30
+ ipAddress: req.ip,
31
+ userAgent: req.get('user-agent'),
32
+ });
33
+ console.log(`✅ Sales inquiry created: ${email}`);
34
+ // TODO: Send notification emails
35
+ res.json({
36
+ success: true,
37
+ message: 'Thank you for your interest! Our sales team will contact you within 24 hours.',
38
+ });
39
+ }
40
+ catch (error) {
41
+ console.error('❌ Error creating sales inquiry:', error);
42
+ res.status(500).json({ error: 'Failed to create sales inquiry', details: error.message });
43
+ }
44
+ }
@@ -22,7 +22,7 @@ const REQUIRED_TARGET_IDS = [
22
22
  'vscode-copilot-agent-plugin',
23
23
  'gemini-cli-extension'
24
24
  ];
25
- const ACCEPTED_LOCAL_STATUSES = new Set(['package-prepared', 'submission-ready', 'submitted']);
25
+ const ACCEPTED_LOCAL_STATUSES = new Set(['package-prepared', 'submission-ready', 'submitted', 'accepted']);
26
26
  const TEXT_EXTENSIONS = new Set(['.json', '.md', '.txt', '.toml', '.yaml', '.yml']);
27
27
  const SECRET_PATTERNS = [
28
28
  { label: 'OpenAI-style API key', pattern: /sk-[A-Za-z0-9_-]{20,}/ },
@@ -432,6 +432,10 @@ function validateMcpRegistryPackage(repoRoot, result, targetDetails) {
432
432
  requireHttpsUrl(serverJson.$schema, serverRelPath, '$schema', result);
433
433
  assertEqual(serverJson.name, 'io.github.mathursrus/fraim', serverRelPath, 'name', result);
434
434
  assertEqual(serverJson.title, 'FRAIM', serverRelPath, 'title', result);
435
+ const description = stringValue(serverJson.description);
436
+ if (!description || description.length > 100) {
437
+ addIssue(result.errors, serverRelPath, 'description must be a non-empty string of at most 100 characters');
438
+ }
435
439
  assertEqual(serverJson.version, targetDetails.productVersion, serverRelPath, 'version', result);
436
440
  requireHttpsUrl(serverJson.websiteUrl, serverRelPath, 'websiteUrl', result);
437
441
  const repository = asObject(serverJson.repository);
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PaymentRepository = void 0;
4
+ const COLLECTION_NAME = 'fraim_payments';
5
+ class PaymentRepository {
6
+ constructor(client, dbName = 'fraim') {
7
+ this.db = client.db(dbName);
8
+ this.collection = this.db.collection(COLLECTION_NAME);
9
+ }
10
+ async ensureIndexes() {
11
+ await this.collection.createIndex({ email: 1 });
12
+ await this.collection.createIndex({ timestamp: -1 });
13
+ await this.collection.createIndex({ status: 1 });
14
+ await this.collection.createIndex({ stripeCustomerId: 1 });
15
+ }
16
+ async createPayment(payment) {
17
+ const result = await this.collection.insertOne(payment);
18
+ return { ...payment, _id: result.insertedId.toString() };
19
+ }
20
+ async updatePaymentStatus(stripePaymentIntentId, status, metadata) {
21
+ const result = await this.collection.updateOne({ stripePaymentIntentId }, {
22
+ $set: {
23
+ status,
24
+ ...(metadata && { metadata })
25
+ }
26
+ });
27
+ return result.modifiedCount > 0;
28
+ }
29
+ async getPaymentById(id) {
30
+ return await this.collection.findOne({ _id: id });
31
+ }
32
+ async getPaymentByStripePaymentIntent(stripePaymentIntentId) {
33
+ return await this.collection.findOne({ stripePaymentIntentId });
34
+ }
35
+ async getPaymentsByEmail(email) {
36
+ return await this.collection.find({ email }).sort({ timestamp: -1 }).toArray();
37
+ }
38
+ async listPayments(filters) {
39
+ const query = {};
40
+ if (filters.plan)
41
+ query.plan = filters.plan;
42
+ if (filters.status)
43
+ query.status = filters.status;
44
+ if (filters.startDate || filters.endDate) {
45
+ query.timestamp = {};
46
+ if (filters.startDate)
47
+ query.timestamp.$gte = filters.startDate;
48
+ if (filters.endDate)
49
+ query.timestamp.$lte = filters.endDate;
50
+ }
51
+ const total = await this.collection.countDocuments(query);
52
+ const payments = await this.collection
53
+ .find(query)
54
+ .sort({ timestamp: -1 })
55
+ .skip(filters.offset || 0)
56
+ .limit(filters.limit || 50)
57
+ .toArray();
58
+ return { payments, total };
59
+ }
60
+ }
61
+ exports.PaymentRepository = PaymentRepository;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRepositoryInfo = exports.getConfigValue = exports.loadFraimConfig = void 0;
4
+ /**
5
+ * Backward-compatible re-export.
6
+ * Canonical config loader lives in src/core/config-loader.ts.
7
+ */
8
+ var config_loader_1 = require("../core/config-loader");
9
+ Object.defineProperty(exports, "loadFraimConfig", { enumerable: true, get: function () { return config_loader_1.loadFraimConfig; } });
10
+ Object.defineProperty(exports, "getConfigValue", { enumerable: true, get: function () { return config_loader_1.getConfigValue; } });
11
+ Object.defineProperty(exports, "getRepositoryInfo", { enumerable: true, get: function () { return config_loader_1.getRepositoryInfo; } });