@fleox-agent-crm/agentcrm 0.3.0 → 0.3.1
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/README.md +16 -16
- package/changelog.json +19 -0
- package/dist/admin/admin-files.json +8 -8
- package/dist/admin/assets/{chartsImpl-CE2akJat.js → chartsImpl-B45AAqnr.js} +30 -30
- package/dist/admin/assets/{firebase-BHSUggRo.js → firebase-C1x_l9P9.js} +2 -2
- package/dist/admin/assets/{gitJson-BulGh2KV.js → gitJson-CAUSxl8d.js} +1 -1
- package/dist/admin/assets/{index-DidVVK7L.js → index-ChFauO8y.js} +265 -265
- package/dist/admin/assets/{index-hMXwHSvN.css → index-TcjySLVg.css} +1 -1
- package/dist/admin/assets/{lucide-react.min-DEDlHCPj.js → lucide-react.min--rznIkmQ.js} +1 -1
- package/dist/admin/assets/{sdk-CnrLnlRo.js → sdk-DgzLACmL.js} +1 -1
- package/dist/admin/index.html +2 -2
- package/dist/agent/agentcrm.mjs +267 -142
- package/dist/agent/chunks/{api-B6OqNVWp.mjs → api-Cz0Ubj-B.mjs} +4 -3
- package/dist/agent/chunks/{appearance-BaShelzt.mjs → appearance-BloHbiLA.mjs} +1 -1
- package/dist/agent/chunks/{automations-BWrvLqP6.mjs → automations-DwWruxmu.mjs} +3 -3
- package/dist/agent/chunks/{backup-ClSmxmFZ.mjs → backup-W3CjgkAJ.mjs} +16 -3
- package/dist/agent/chunks/{compact-CsFPaAAq.mjs → compact-BGHI92tm.mjs} +2 -2
- package/dist/agent/chunks/{exportCsv-B5hRvkNm.mjs → exportCsv-C6e6XEmB.mjs} +38 -3
- package/dist/agent/chunks/{extCheck--7lmVvl7.mjs → extCheck-GgHG1dYB.mjs} +16 -9
- package/dist/agent/chunks/{extPackage-BGl5Oqs8.mjs → extPackage-DuZ6GZhp.mjs} +2 -2
- package/dist/agent/chunks/{extScaffold-DqxI7R1e.mjs → extScaffold-Aqyjf1nr.mjs} +3 -3
- package/dist/agent/chunks/{extensions-BP1k60md.mjs → extensions-Bp72uZ9a.mjs} +19 -6
- package/dist/agent/chunks/{featureRegistry-C9nbVShp.mjs → featureRegistry-DSsZbhrh.mjs} +3 -3
- package/dist/agent/chunks/{files-q8Xu5bft.mjs → files-D1daDgY0.mjs} +1 -1
- package/dist/agent/chunks/{forms-BKU5F9WF.mjs → forms-BfuWaQjA.mjs} +1 -1
- package/dist/agent/chunks/{importCsv-DmE_sBch.mjs → importCsv-LVmMTaWU.mjs} +2 -2
- package/dist/agent/chunks/{install-CpHoUFtL.mjs → install-CbpD_7gd.mjs} +3 -3
- package/dist/agent/chunks/{loader-C9nm3iwx.mjs → loader-MPD9iAvh.mjs} +20 -20
- package/dist/agent/chunks/{modules-CqdVQVJb.mjs → modules-clWdE-K2.mjs} +27 -2
- package/dist/agent/chunks/{nodeImport-BPCt5uMu.mjs → nodeImport-ylfRDvqt.mjs} +2 -2
- package/dist/agent/chunks/{package-DWbn3t2R.mjs → package-B7mI6HGi.mjs} +1 -1
- package/dist/agent/chunks/{papaparse-DjBYnQM2.mjs → papaparse-Df7i1dHr.mjs} +31 -7
- package/dist/agent/chunks/{pipelines-DCdRBNBV.mjs → pipelines-BAKpPk1w.mjs} +1 -1
- package/dist/agent/chunks/{plan-C0TBrU92.mjs → plan-BmTat6-T.mjs} +1 -1
- package/dist/agent/chunks/{records-DoqiT9xR.mjs → records-DcHFelq5.mjs} +5 -1
- package/dist/agent/chunks/{registry-Ceexawxl.mjs → registry-COfJrSmg.mjs} +18 -18
- package/dist/agent/chunks/{reports-BB59N6ke.mjs → reports-BACHGccj.mjs} +3 -3
- package/dist/agent/chunks/{runtime-DHo7ZEEO.mjs → runtime-C0Xf0Axi.mjs} +53 -32
- package/dist/agent/chunks/{schema-DlHt2PxI.mjs → schema-C4lSslXv.mjs} +10 -4
- package/dist/agent/chunks/{schema-7-4-qtSS.mjs → schema-DnLj8dUO.mjs} +10 -0
- package/dist/agent/chunks/{seed-CugPGYZL.mjs → seed-6MRmQQBR.mjs} +26 -8
- package/dist/agent/chunks/{server-ISwlDRCN.mjs → server-DC3t8r30.mjs} +5 -5
- package/dist/agent/chunks/{settings-BtvR_jdm.mjs → settings-Di8nzNEL.mjs} +35 -0
- package/dist/agent/chunks/{stats-CfeJssSS.mjs → stats-BfuLWhVV.mjs} +2 -2
- package/dist/agent/chunks/{tools-Bew8lxKx.mjs → tools-iSH-yMpl.mjs} +59 -19
- package/dist/agent/chunks/{views-fO_BM5U_.mjs → views-DH1n9Lrt.mjs} +1 -1
- package/dist/version.json +1 -1
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/skills/agentcrm-admin/SKILL.md +67 -67
- package/plugin/skills/agentcrm-admin/references/appearance.md +1 -1
- package/plugin/skills/agentcrm-admin/references/records.md +5 -5
- package/plugin/skills/agentcrm-admin/references/schema.md +20 -20
- package/plugin/skills/agentcrm-extensions/SKILL.md +9 -9
- package/plugin/skills/agentcrm-extensions/references/module-recipes.md +2 -2
- package/plugin/skills/agentcrm-extensions/references/testing.md +16 -14
- package/plugin/skills/agentcrm-extensions/references/theme-recipes.md +3 -3
- package/plugin/skills/agentcrm-install/SKILL.md +13 -13
- package/plugin/skills/agentcrm-install/references/firebase.md +1 -1
- package/plugin/skills/agentcrm-install/references/github.md +1 -1
- package/plugin/skills/agentcrm-install/references/mcp.md +3 -3
- package/plugin/skills/agentcrm-install/references/plans.md +1 -1
- package/plugin/skills/agentcrm-install/references/s3.md +1 -1
- package/plugin/skills/agentcrm-manage/SKILL.md +15 -15
- package/plugin/skills/agentcrm-sales/SKILL.md +18 -18
|
@@ -8,7 +8,7 @@ import { dateValueToMs, colorAt } from "./fields-B0bitgmr.mjs";
|
|
|
8
8
|
import { s as slugId } from "./ids-CvnmrMJX.mjs";
|
|
9
9
|
import { s as stageOptions, p as pipelineOptions } from "./standardObjects-CheqfDqa.mjs";
|
|
10
10
|
import { assertCan, OpsError } from "./context-CxFfqS4D.mjs";
|
|
11
|
-
import { updateRecord } from "./records-
|
|
11
|
+
import { updateRecord } from "./records-DcHFelq5.mjs";
|
|
12
12
|
import { requireRecord, pipelinesOf, requireObject, requirePipeline, recordsOf, asDoc, thaw } from "./store-5gqRSKXg.mjs";
|
|
13
13
|
import "./pluginRegistry-DyHtlkcr.mjs";
|
|
14
14
|
import "./query-C5nJB_3C.mjs";
|
|
@@ -6,7 +6,7 @@ const __filename = __acrmPath(import.meta.url);
|
|
|
6
6
|
const __dirname = __acrmDirname(__filename);
|
|
7
7
|
import { isAbsolute, resolve } from "node:path";
|
|
8
8
|
import { splitSecretSettings } from "./runtimeConfig-CCOFg1RM.mjs";
|
|
9
|
-
import { v as validateAlias, f as findBackend,
|
|
9
|
+
import { v as validateAlias, f as findBackend, b as parseAccount, g as getCredential, c as requireCredential, C as CliError, d as findLocation, L as LOCATIONS, e as findHosting, H as HOSTINGS } from "../agentcrm.mjs";
|
|
10
10
|
import "node:util";
|
|
11
11
|
import "node:fs";
|
|
12
12
|
import "node:url";
|
|
@@ -6,7 +6,7 @@ const __filename = __acrmPath(import.meta.url);
|
|
|
6
6
|
const __dirname = __acrmDirname(__filename);
|
|
7
7
|
import { normalizeDomain, recordLabel, validateRecordFields, defaultFieldValues, isEmptyFieldValue, FieldValidationError, normalizeEmail } from "./fields-B0bitgmr.mjs";
|
|
8
8
|
import { n as newId } from "./ids-CvnmrMJX.mjs";
|
|
9
|
-
import { b as applyFilters, a as applySorts, p as paginate } from "./query-C5nJB_3C.mjs";
|
|
9
|
+
import { r as resolveField, b as applyFilters, a as applySorts, p as paginate } from "./query-C5nJB_3C.mjs";
|
|
10
10
|
import { n as normalizeStandardFields } from "./standardObjects-CheqfDqa.mjs";
|
|
11
11
|
import { assertCan, OpsError, actorId, emit } from "./context-CxFfqS4D.mjs";
|
|
12
12
|
import { i as inverseRelations, j as expandRelations, l as labelOf, v as validateRelationValue, c as rewriteReferences, b as fileCleanupMutations } from "./relations-B9TynBmA.mjs";
|
|
@@ -1933,6 +1933,10 @@ function queryContext(ctx, object) {
|
|
|
1933
1933
|
function listRecords(ctx, objectId, opts = {}) {
|
|
1934
1934
|
assertCan(ctx, "records.read");
|
|
1935
1935
|
const object = requireObject(ctx.store, objectId);
|
|
1936
|
+
const unknown = [...opts.filters ?? [], ...opts.sorts ?? []].map((f) => f.field).filter((f) => !resolveField(object, f));
|
|
1937
|
+
if (unknown.length) {
|
|
1938
|
+
throw new OpsError("validation", `Unknown field${unknown.length > 1 ? "s" : ""} ${[...new Set(unknown)].map((f) => `"${f}"`).join(", ")} on ${object.labelPlural}. Fields: ${object.fields.map((f) => f.id).join(", ")}, id, ownerId, createdAt, updatedAt.`);
|
|
1939
|
+
}
|
|
1936
1940
|
let filters = opts.filters ?? [];
|
|
1937
1941
|
let sorts = opts.sorts ?? [];
|
|
1938
1942
|
if (opts.viewId) {
|
|
@@ -4,18 +4,18 @@ import { dirname as __acrmDirname } from "node:path";
|
|
|
4
4
|
const require2 = __acrmRequire(import.meta.url);
|
|
5
5
|
const __filename = __acrmPath(import.meta.url);
|
|
6
6
|
const __dirname = __acrmDirname(__filename);
|
|
7
|
-
import { i as isCompatibleApiVersion } from "./api-
|
|
8
|
-
import { registerExternalFeature } from "./featureRegistry-
|
|
9
|
-
import { registerAiTool } from "./tools-
|
|
7
|
+
import { i as isCompatibleApiVersion } from "./api-Cz0Ubj-B.mjs";
|
|
8
|
+
import { registerExternalFeature } from "./featureRegistry-DSsZbhrh.mjs";
|
|
9
|
+
import { registerAiTool } from "./tools-iSH-yMpl.mjs";
|
|
10
10
|
import { registerAutomationAction } from "./extensionActions-D2HtpQz4.mjs";
|
|
11
11
|
import { plugins } from "./pluginRegistry-DyHtlkcr.mjs";
|
|
12
12
|
import { registerExternalTheme } from "./themes-DPZFv3yc.mjs";
|
|
13
13
|
import "./index-Bnmav-Oh.mjs";
|
|
14
14
|
import "./_commonjsHelpers-ClciMIcB.mjs";
|
|
15
15
|
import "./index-BM8qeGOb.mjs";
|
|
16
|
-
import "./modules-
|
|
16
|
+
import "./modules-clWdE-K2.mjs";
|
|
17
17
|
import "./context-CxFfqS4D.mjs";
|
|
18
|
-
import "./settings-
|
|
18
|
+
import "./settings-Di8nzNEL.mjs";
|
|
19
19
|
import "./store-5gqRSKXg.mjs";
|
|
20
20
|
import "./runtimeConfig-CCOFg1RM.mjs";
|
|
21
21
|
import "./fields-B0bitgmr.mjs";
|
|
@@ -33,27 +33,27 @@ import "./activities-Cj_SIOay.mjs";
|
|
|
33
33
|
import "./ids-CvnmrMJX.mjs";
|
|
34
34
|
import "./relations-B9TynBmA.mjs";
|
|
35
35
|
import "./dedupe-BepmsaHv.mjs";
|
|
36
|
-
import "./importCsv-
|
|
37
|
-
import "./papaparse-
|
|
36
|
+
import "./importCsv-LVmMTaWU.mjs";
|
|
37
|
+
import "./papaparse-Df7i1dHr.mjs";
|
|
38
38
|
import "stream";
|
|
39
39
|
import "./utils-DmI8FtXP.mjs";
|
|
40
|
-
import "./records-
|
|
40
|
+
import "./records-DcHFelq5.mjs";
|
|
41
41
|
import "./standardObjects-CheqfDqa.mjs";
|
|
42
|
-
import "./pipelines-
|
|
43
|
-
import "./reports-
|
|
44
|
-
import "./schema-
|
|
45
|
-
import "./automations-
|
|
46
|
-
import "./forms-
|
|
47
|
-
import "./schema-
|
|
48
|
-
import "./appearance-
|
|
49
|
-
import "./extensions-
|
|
50
|
-
import "./package-
|
|
42
|
+
import "./pipelines-BAKpPk1w.mjs";
|
|
43
|
+
import "./reports-BACHGccj.mjs";
|
|
44
|
+
import "./schema-C4lSslXv.mjs";
|
|
45
|
+
import "./automations-DwWruxmu.mjs";
|
|
46
|
+
import "./forms-BfuWaQjA.mjs";
|
|
47
|
+
import "./schema-DnLj8dUO.mjs";
|
|
48
|
+
import "./appearance-BloHbiLA.mjs";
|
|
49
|
+
import "./extensions-Bp72uZ9a.mjs";
|
|
50
|
+
import "./package-B7mI6HGi.mjs";
|
|
51
51
|
import "./index-w03ReRs4.mjs";
|
|
52
52
|
import "events";
|
|
53
53
|
import "buffer";
|
|
54
54
|
import "util";
|
|
55
55
|
import "./files-CjsPJSR6.mjs";
|
|
56
|
-
import "./files-
|
|
56
|
+
import "./files-D1daDgY0.mjs";
|
|
57
57
|
import "./index-RCmo-uld.mjs";
|
|
58
58
|
import "./http-Bk9ICb7I.mjs";
|
|
59
59
|
const entries = /* @__PURE__ */ new Map();
|
|
@@ -9,8 +9,8 @@ import { L as LIFECYCLE_OPTIONS } from "./standardObjects-CheqfDqa.mjs";
|
|
|
9
9
|
import { A as ACTIVITY_TYPES } from "../agentcrm.mjs";
|
|
10
10
|
import { lastActivityAt } from "./activities-Cj_SIOay.mjs";
|
|
11
11
|
import { OpsError, assertCan } from "./context-CxFfqS4D.mjs";
|
|
12
|
-
import { forecast, pipelineOfRecord } from "./pipelines-
|
|
13
|
-
import { getSettings } from "./settings-
|
|
12
|
+
import { forecast, pipelineOfRecord } from "./pipelines-BAKpPk1w.mjs";
|
|
13
|
+
import { getSettings } from "./settings-Di8nzNEL.mjs";
|
|
14
14
|
import { objectOf, recordsOf, pipelinesOf, usersOf, activitiesOf, requirePipeline } from "./store-5gqRSKXg.mjs";
|
|
15
15
|
import "node:util";
|
|
16
16
|
import "node:fs";
|
|
@@ -24,7 +24,7 @@ import "./ids-CvnmrMJX.mjs";
|
|
|
24
24
|
import "./query-C5nJB_3C.mjs";
|
|
25
25
|
import "./relations-B9TynBmA.mjs";
|
|
26
26
|
import "./pluginRegistry-DyHtlkcr.mjs";
|
|
27
|
-
import "./records-
|
|
27
|
+
import "./records-DcHFelq5.mjs";
|
|
28
28
|
import "./runtimeConfig-CCOFg1RM.mjs";
|
|
29
29
|
const DAY = 864e5;
|
|
30
30
|
function defaultPipelineId(ctx, pipelineId) {
|
|
@@ -8,42 +8,42 @@ import { a as requireReact, r as reactExports, R as React } from "./index-Bnmav-
|
|
|
8
8
|
import { j as jsxRuntimeExports, R as ReactJsxRuntime } from "./jsx-runtime-Ca2uwGDr.mjs";
|
|
9
9
|
import { g as getDefaultExportFromCjs } from "./_commonjsHelpers-ClciMIcB.mjs";
|
|
10
10
|
import { OpsError, PERMISSIONS, actorId, assertCan, can, createOpsContext, emit } from "./context-CxFfqS4D.mjs";
|
|
11
|
-
import { bulkDelete, bulkUpdate, createRecord, deleteRecord, getRecord, getRecordDetails, hardDeleteMutations, listRecords, prepareRecordFields, queryContext, recordPatchMutation, restoreRecord, searchRecords, setRecordOwner, updateRecord } from "./records-
|
|
11
|
+
import { bulkDelete, bulkUpdate, createRecord, deleteRecord, getRecord, getRecordDetails, hardDeleteMutations, listRecords, prepareRecordFields, queryContext, recordPatchMutation, restoreRecord, searchRecords, setRecordOwner, updateRecord } from "./records-DcHFelq5.mjs";
|
|
12
12
|
import { j as expandRelations, b as fileCleanupMutations, e as fileFieldIds, g as fileIdsIn, d as fileMergeMutations, f as fileTargetPatch, i as inverseRelations, l as labelOf, k as linkRecords, h as referencedFileIds, m as relatedRecords, r as relationFields, a as relationIds, c as rewriteReferences, s as sameTarget, t as toRef, u as unlinkRecords, v as validateRelationValue } from "./relations-B9TynBmA.mjs";
|
|
13
13
|
import { addActivity, addNote, completeTask, createTask, deleteActivity, getActivity, lastActivityAt, listActivities, listTasks, timelineScope, updateActivity } from "./activities-Cj_SIOay.mjs";
|
|
14
|
-
import { createPipeline, deletePipeline, forecast, getPipeline, listPipelines, moveStage, pipelineOfRecord, syncPipelineOptions, updatePipeline } from "./pipelines-
|
|
15
|
-
import { addOption, changeFieldType, createField, createObject, deleteField, deleteObject, describeSchema, getObject, listObjects, removeOption, reorderFields, updateField, updateObject, updateOption } from "./schema-
|
|
16
|
-
import { createView, deleteView, duplicateView, getView, listViews, runView, updateView } from "./views-
|
|
14
|
+
import { createPipeline, deletePipeline, forecast, getPipeline, listPipelines, moveStage, pipelineOfRecord, syncPipelineOptions, updatePipeline } from "./pipelines-BAKpPk1w.mjs";
|
|
15
|
+
import { addOption, changeFieldType, createField, createObject, deleteField, deleteObject, describeSchema, getObject, listObjects, removeOption, reorderFields, updateField, updateObject, updateOption } from "./schema-C4lSslXv.mjs";
|
|
16
|
+
import { createView, deleteView, duplicateView, getView, listViews, runView, updateView } from "./views-DH1n9Lrt.mjs";
|
|
17
17
|
import { createUser, deleteUser, findUserByEmail, getUser, listUsers, setUserRole, updateUser } from "./users-DI1BvS0f.mjs";
|
|
18
|
-
import { DEFAULT_SETTINGS, assertNoSecrets, getConfigDoc, getSettings, setConfigDoc, updateSettings } from "./settings-
|
|
19
|
-
import { MAPPING_ID, MAPPING_OWNER, MAPPING_SKIP, importCsv, parseCsv, suggestMapping } from "./importCsv-
|
|
20
|
-
import { exportCsv, exportJson, importJson } from "./exportCsv-
|
|
18
|
+
import { DEFAULT_SETTINGS, SETTINGS_KEYS, assertNoSecrets, getConfigDoc, getSettings, setConfigDoc, updateSettings } from "./settings-Di8nzNEL.mjs";
|
|
19
|
+
import { MAPPING_ID, MAPPING_OWNER, MAPPING_SKIP, importCsv, parseCsv, suggestMapping } from "./importCsv-LVmMTaWU.mjs";
|
|
20
|
+
import { exportCsv, exportJson, importJson, planImportJson } from "./exportCsv-C6e6XEmB.mjs";
|
|
21
21
|
import { findDuplicates, mergeRecords } from "./dedupe-BepmsaHv.mjs";
|
|
22
|
-
import { REPORTS, activityByUser, conversion, leadSources, pipelineByStage, runReport, staleDeals, wonLost } from "./reports-
|
|
23
|
-
import { getStats } from "./stats-
|
|
24
|
-
import { DEFAULT_ADMIN_ID, seedCrm, seedDemoData } from "./seed-
|
|
25
|
-
import { compactData } from "./compact-
|
|
26
|
-
import { ACTION_TYPES, AUTOMATION_TEMPLATES, EVENT_TRIGGERS, MAX_AUTOMATION_DEPTH, MAX_AUTOMATION_RUNS, SCHEDULED_TRIGGERS, TRIGGER_TYPES, automationAssignees, clearAutomationRuns, createAutomation, createAutomationFromTemplate, deleteAutomation, duplicateAutomation, findAutomationTemplate, getAutomation, installAutomations, lastTouchedAt, listAutomationRuns, listAutomations, pruneAutomationRuns, renderTemplate, runAutomationEvent, runScheduled, scheduledCandidates, setAutomationEnabled, setAutomationFetch, templatePlaceholders, testAutomation, triggerMatches, updateAutomation, validateAutomation } from "./automations-
|
|
27
|
-
import { DEFAULT_FIREBASE_INBOX, DEFAULT_FORM_TEXTS, DEFAULT_INBOX_PREFIX, FORM_FIELD_TYPES, FREE_MAIL_DOMAINS, HONEYPOT_NAME, INBOX_KINDS, MIN_FILL_MS, buildFormArtifacts, buildFormHtml, companyDomainOfEmail, connectorInboxSource, createForm, defaultFormPath, deleteForm, escapeHtml, firestoreInboxSource, getForm, ingestInbox, ingestSubmissions, isFormFieldType, listForms, listInbox, memoryInboxSource, parseSubmission, publishForm, resolveInboxSource, setInboxSourceResolver, suggestFormFields, updateForm, validateForm } from "./forms-
|
|
28
|
-
import { disabledObjectIds, getModule, getModuleConfig, isModuleEnabled, listModules, moduleStates, setModuleConfig, setModuleEnabled } from "./modules-
|
|
29
|
-
import { getExtension, getExtensionPackage, installExtension, listExtensions, setExtensionEnabled, summarizeExtension, uninstallExtension } from "./extensions-
|
|
30
|
-
import { applyPreset, getAppearance, getAppearanceDoc, listPresets, resetAppearance, setAppearance, setLogo } from "./appearance-
|
|
31
|
-
import { ORPHAN_GRACE_MS, attachFile, clearRecordImage, deleteFile, detachFile, fileUsage, getFile, getFileBytes, listFiles, maxUploadBytes, purgeFiles, recordImageId, renameFile, restoreFile, setRecordImage, uploadFile } from "./files-
|
|
22
|
+
import { REPORTS, activityByUser, conversion, leadSources, pipelineByStage, runReport, staleDeals, wonLost } from "./reports-BACHGccj.mjs";
|
|
23
|
+
import { getStats } from "./stats-BfuLWhVV.mjs";
|
|
24
|
+
import { DEFAULT_ADMIN_ID, seedCrm, seedDemoData } from "./seed-6MRmQQBR.mjs";
|
|
25
|
+
import { compactData } from "./compact-BGHI92tm.mjs";
|
|
26
|
+
import { ACTION_TYPES, AUTOMATION_TEMPLATES, EVENT_TRIGGERS, MAX_AUTOMATION_DEPTH, MAX_AUTOMATION_RUNS, SCHEDULED_TRIGGERS, TRIGGER_TYPES, automationAssignees, clearAutomationRuns, createAutomation, createAutomationFromTemplate, deleteAutomation, duplicateAutomation, findAutomationTemplate, getAutomation, installAutomations, lastTouchedAt, listAutomationRuns, listAutomations, pruneAutomationRuns, renderTemplate, runAutomationEvent, runScheduled, scheduledCandidates, setAutomationEnabled, setAutomationFetch, templatePlaceholders, testAutomation, triggerMatches, updateAutomation, validateAutomation } from "./automations-DwWruxmu.mjs";
|
|
27
|
+
import { DEFAULT_FIREBASE_INBOX, DEFAULT_FORM_TEXTS, DEFAULT_INBOX_PREFIX, FORM_FIELD_TYPES, FREE_MAIL_DOMAINS, HONEYPOT_NAME, INBOX_KINDS, MIN_FILL_MS, buildFormArtifacts, buildFormHtml, companyDomainOfEmail, connectorInboxSource, createForm, defaultFormPath, deleteForm, escapeHtml, firestoreInboxSource, getForm, ingestInbox, ingestSubmissions, isFormFieldType, listForms, listInbox, memoryInboxSource, parseSubmission, publishForm, resolveInboxSource, setInboxSourceResolver, suggestFormFields, updateForm, validateForm } from "./forms-BfuWaQjA.mjs";
|
|
28
|
+
import { disabledObjectIds, getModule, getModuleConfig, isModuleEnabled, listModules, moduleStates, setModuleConfig, setModuleEnabled } from "./modules-clWdE-K2.mjs";
|
|
29
|
+
import { getExtension, getExtensionPackage, installExtension, listExtensions, setExtensionEnabled, summarizeExtension, uninstallExtension } from "./extensions-Bp72uZ9a.mjs";
|
|
30
|
+
import { applyPreset, getAppearance, getAppearanceDoc, listPresets, resetAppearance, setAppearance, setLogo } from "./appearance-BloHbiLA.mjs";
|
|
31
|
+
import { ORPHAN_GRACE_MS, attachFile, clearRecordImage, deleteFile, detachFile, fileUsage, getFile, getFileBytes, listFiles, maxUploadBytes, purgeFiles, recordImageId, renameFile, restoreFile, setRecordImage, uploadFile } from "./files-D1daDgY0.mjs";
|
|
32
32
|
import { S as SCHEMA_MIGRATIONS, m as migrateSchema, s as schemaMigrationMutations } from "./migrate-CsClnnN8.mjs";
|
|
33
|
-
import { BACKUP_DATA_FILE, BACKUP_FILES_DIR, exportBackupZip, importBackupZip, readBackupZipInfo } from "./backup-
|
|
33
|
+
import { BACKUP_DATA_FILE, BACKUP_FILES_DIR, exportBackupZip, importBackupZip, planBackupZip, readBackupZipInfo } from "./backup-W3CjgkAJ.mjs";
|
|
34
34
|
import { getAutomationAction, listAutomationActions, registerAutomationAction, subscribeAutomationActions } from "./extensionActions-D2HtpQz4.mjs";
|
|
35
35
|
import { a as intlLocale, b as activeLocale, i as instance, r as registerI18nNamespace } from "./index-BM8qeGOb.mjs";
|
|
36
36
|
import "./standardObjects-CheqfDqa.mjs";
|
|
37
|
-
import { useModuleStates, useModuleEnabled } from "./featureRegistry-
|
|
37
|
+
import { useModuleStates, useModuleEnabled } from "./featureRegistry-DSsZbhrh.mjs";
|
|
38
38
|
import { a as cn, i as initials, f as formatRelative, b as formatDateTime, d as formatDate } from "./utils-DmI8FtXP.mjs";
|
|
39
39
|
import { t as toast } from "./http-Bk9ICb7I.mjs";
|
|
40
40
|
import { isEmptyFieldValue, formatFieldValue, formatAddress, dateValueToMs, formatNumber, formatCurrency, toIsoDate, parseNumber, coerceFieldValue, recordLabel } from "./fields-B0bitgmr.mjs";
|
|
41
41
|
import { fileKind, isPreviewable, formatBytes } from "./files-CjsPJSR6.mjs";
|
|
42
42
|
import { plugins } from "./pluginRegistry-DyHtlkcr.mjs";
|
|
43
43
|
import { n as newId } from "./ids-CvnmrMJX.mjs";
|
|
44
|
-
import { registerAiTool } from "./tools-
|
|
45
|
-
import { a as DEFAULT_APPEARANCE } from "./schema-
|
|
46
|
-
import { b as EXTENSION_MIN_API_VERSION, E as EXTENSION_API_VERSION,
|
|
44
|
+
import { registerAiTool } from "./tools-iSH-yMpl.mjs";
|
|
45
|
+
import { a as DEFAULT_APPEARANCE } from "./schema-DnLj8dUO.mjs";
|
|
46
|
+
import { b as EXTENSION_MIN_API_VERSION, E as EXTENSION_API_VERSION, k as RUNTIME_GLOBAL } from "./api-Cz0Ubj-B.mjs";
|
|
47
47
|
import "./query-C5nJB_3C.mjs";
|
|
48
48
|
import "./store-5gqRSKXg.mjs";
|
|
49
49
|
import "../agentcrm.mjs";
|
|
@@ -56,11 +56,11 @@ import "node:os";
|
|
|
56
56
|
import "node:child_process";
|
|
57
57
|
import "node:http";
|
|
58
58
|
import "./runtimeConfig-CCOFg1RM.mjs";
|
|
59
|
-
import "./papaparse-
|
|
59
|
+
import "./papaparse-Df7i1dHr.mjs";
|
|
60
60
|
import "stream";
|
|
61
61
|
import "./types-BOy9PUl7.mjs";
|
|
62
62
|
import "./index-RCmo-uld.mjs";
|
|
63
|
-
import "./package-
|
|
63
|
+
import "./package-B7mI6HGi.mjs";
|
|
64
64
|
import "./index-w03ReRs4.mjs";
|
|
65
65
|
import "events";
|
|
66
66
|
import "buffer";
|
|
@@ -8396,6 +8396,7 @@ const opsModule = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePro
|
|
|
8396
8396
|
REPORTS,
|
|
8397
8397
|
SCHEDULED_TRIGGERS,
|
|
8398
8398
|
SCHEMA_MIGRATIONS,
|
|
8399
|
+
SETTINGS_KEYS,
|
|
8399
8400
|
TRIGGER_TYPES,
|
|
8400
8401
|
activityByUser,
|
|
8401
8402
|
actorId,
|
|
@@ -8527,6 +8528,8 @@ const opsModule = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePro
|
|
|
8527
8528
|
parseSubmission,
|
|
8528
8529
|
pipelineByStage,
|
|
8529
8530
|
pipelineOfRecord,
|
|
8531
|
+
planBackupZip,
|
|
8532
|
+
planImportJson,
|
|
8530
8533
|
prepareRecordFields,
|
|
8531
8534
|
pruneAutomationRuns,
|
|
8532
8535
|
publishForm,
|
|
@@ -9706,7 +9709,7 @@ const Button = reactExports.forwardRef(function Button2({ variant = "outline", s
|
|
|
9706
9709
|
),
|
|
9707
9710
|
...rest,
|
|
9708
9711
|
children: [
|
|
9709
|
-
hasIcon && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex h-4 w-4 shrink-0 items-center justify-center [
|
|
9712
|
+
hasIcon && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex h-4 w-4 shrink-0 items-center justify-center [&_svg]:h-4 [&_svg]:w-4", children: [
|
|
9710
9713
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("inline-flex", loading && "hidden"), children: icon }),
|
|
9711
9714
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("inline-flex", !loading && "hidden"), children: /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" }) })
|
|
9712
9715
|
] }),
|
|
@@ -9794,7 +9797,7 @@ const Checkbox = reactExports.forwardRef(function Checkbox2({ label, indetermina
|
|
|
9794
9797
|
}
|
|
9795
9798
|
);
|
|
9796
9799
|
if (!label) return input;
|
|
9797
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: cn("inline-flex cursor-pointer items-center gap-2 text-sm text-surface-700 dark:text-surface-200", className), children: [
|
|
9800
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: cn("relative inline-flex cursor-pointer items-center gap-2 text-sm text-surface-700 dark:text-surface-200", className), children: [
|
|
9798
9801
|
input,
|
|
9799
9802
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: label })
|
|
9800
9803
|
] });
|
|
@@ -9821,7 +9824,7 @@ function Switch({ checked, onChange, label, disabled, size = "md", className, id
|
|
|
9821
9824
|
}
|
|
9822
9825
|
);
|
|
9823
9826
|
if (!label) return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className, children: button });
|
|
9824
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: cn("inline-flex cursor-pointer items-center gap-2 text-sm text-surface-700 dark:text-surface-200", className), children: [
|
|
9827
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: cn("relative inline-flex cursor-pointer items-center gap-2 text-sm text-surface-700 dark:text-surface-200", className), children: [
|
|
9825
9828
|
button,
|
|
9826
9829
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: label })
|
|
9827
9830
|
] });
|
|
@@ -9910,8 +9913,23 @@ function Drawer({ open, onClose, title, children, footer, width = "md", side = "
|
|
|
9910
9913
|
)
|
|
9911
9914
|
] }) });
|
|
9912
9915
|
}
|
|
9916
|
+
const PopoverParent = reactExports.createContext(null);
|
|
9917
|
+
function isInsidePopover(target, id) {
|
|
9918
|
+
let el = target instanceof Element ? target : target?.parentElement ?? null;
|
|
9919
|
+
let panel = el?.closest("[data-popover-id]") ?? null;
|
|
9920
|
+
while (panel) {
|
|
9921
|
+
if (panel.getAttribute("data-popover-id") === id) return true;
|
|
9922
|
+
const parent = panel.getAttribute("data-popover-parent");
|
|
9923
|
+
if (!parent) return false;
|
|
9924
|
+
el = document.querySelector(`[data-popover-id="${CSS.escape(parent)}"]`);
|
|
9925
|
+
panel = el;
|
|
9926
|
+
}
|
|
9927
|
+
return false;
|
|
9928
|
+
}
|
|
9913
9929
|
function Popover({ open, onClose, anchor, children, align = "start", matchWidth, className, offset = 4 }) {
|
|
9914
9930
|
const panel = reactExports.useRef(null);
|
|
9931
|
+
const id = reactExports.useId();
|
|
9932
|
+
const parentId = reactExports.useContext(PopoverParent);
|
|
9915
9933
|
const [pos, setPos] = reactExports.useState(null);
|
|
9916
9934
|
const place = reactExports.useCallback(() => {
|
|
9917
9935
|
if (!anchor) return;
|
|
@@ -9931,11 +9949,12 @@ function Popover({ open, onClose, anchor, children, align = "start", matchWidth,
|
|
|
9931
9949
|
if (!open) return;
|
|
9932
9950
|
const onDown = (e2) => {
|
|
9933
9951
|
const t2 = e2.target;
|
|
9934
|
-
if (panel.current?.contains(t2) || anchor?.contains(t2)) return;
|
|
9952
|
+
if (panel.current?.contains(t2) || anchor?.contains(t2) || isInsidePopover(t2, id)) return;
|
|
9935
9953
|
onClose();
|
|
9936
9954
|
};
|
|
9937
9955
|
const onKey = (e2) => {
|
|
9938
9956
|
if (e2.key === "Escape") {
|
|
9957
|
+
if (document.querySelector(`[data-popover-parent="${CSS.escape(id)}"]`)) return;
|
|
9939
9958
|
e2.stopPropagation();
|
|
9940
9959
|
onClose();
|
|
9941
9960
|
}
|
|
@@ -9953,18 +9972,20 @@ function Popover({ open, onClose, anchor, children, align = "start", matchWidth,
|
|
|
9953
9972
|
window.removeEventListener("resize", onMove);
|
|
9954
9973
|
window.removeEventListener("scroll", onMove, true);
|
|
9955
9974
|
};
|
|
9956
|
-
}, [open, onClose, anchor, place]);
|
|
9975
|
+
}, [open, onClose, anchor, place, id]);
|
|
9957
9976
|
if (!open || !anchor) return null;
|
|
9958
9977
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9959
9978
|
"div",
|
|
9960
9979
|
{
|
|
9961
9980
|
ref: panel,
|
|
9981
|
+
"data-popover-id": id,
|
|
9982
|
+
"data-popover-parent": parentId ?? void 0,
|
|
9962
9983
|
style: { top: pos?.top ?? -9999, left: pos?.left ?? -9999, ...matchWidth && pos ? { minWidth: pos.width } : {} },
|
|
9963
9984
|
className: cn(
|
|
9964
9985
|
"fixed z-[60] animate-scale-in overflow-hidden rounded-lg border border-surface-200 bg-white shadow-pop dark:border-surface-700 dark:bg-surface-900",
|
|
9965
9986
|
className
|
|
9966
9987
|
),
|
|
9967
|
-
children
|
|
9988
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverParent.Provider, { value: id, children })
|
|
9968
9989
|
}
|
|
9969
9990
|
) });
|
|
9970
9991
|
}
|
|
@@ -13541,11 +13562,11 @@ function createDOMPurify() {
|
|
|
13541
13562
|
const originalDocument = document2;
|
|
13542
13563
|
const currentScript = originalDocument.currentScript;
|
|
13543
13564
|
window2.DocumentFragment;
|
|
13544
|
-
const HTMLTemplateElement = window2.HTMLTemplateElement, Node = window2.Node,
|
|
13565
|
+
const HTMLTemplateElement = window2.HTMLTemplateElement, Node = window2.Node, Element2 = window2.Element, NodeFilter = window2.NodeFilter;
|
|
13545
13566
|
window2.NamedNodeMap === void 0 && (window2.NamedNodeMap || window2.MozNamedAttrMap);
|
|
13546
13567
|
window2.HTMLFormElement;
|
|
13547
13568
|
const DOMParser = window2.DOMParser, trustedTypes = window2.trustedTypes;
|
|
13548
|
-
const ElementPrototype =
|
|
13569
|
+
const ElementPrototype = Element2.prototype;
|
|
13549
13570
|
const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
|
|
13550
13571
|
const remove = lookupGetter(ElementPrototype, "remove");
|
|
13551
13572
|
const removeAttributeNode = lookupGetter(ElementPrototype, "removeAttributeNode");
|
|
@@ -8,10 +8,10 @@ import { c as camelId } from "./utils-DmI8FtXP.mjs";
|
|
|
8
8
|
import { colorAt, canConvertType, isEmptyFieldValue, convertValue } from "./fields-B0bitgmr.mjs";
|
|
9
9
|
import { s as slugId } from "./ids-CvnmrMJX.mjs";
|
|
10
10
|
import { d as defaultViewFor } from "./standardObjects-CheqfDqa.mjs";
|
|
11
|
-
import {
|
|
11
|
+
import { a as FIELD_TYPES } from "../agentcrm.mjs";
|
|
12
12
|
import { assertCan, OpsError } from "./context-CxFfqS4D.mjs";
|
|
13
|
-
import { hardDeleteMutations } from "./records-
|
|
14
|
-
import { requireObject, objectsOf, pipelinesOf, recordsOf,
|
|
13
|
+
import { hardDeleteMutations } from "./records-DcHFelq5.mjs";
|
|
14
|
+
import { requireObject, objectsOf, pipelinesOf, recordsOf, viewsOf, asDoc, thaw } from "./store-5gqRSKXg.mjs";
|
|
15
15
|
import "node:util";
|
|
16
16
|
import "node:fs";
|
|
17
17
|
import "node:path";
|
|
@@ -183,9 +183,15 @@ async function createField(ctx, objectId, input) {
|
|
|
183
183
|
const object = requireObject(ctx.store, objectId);
|
|
184
184
|
const field = buildField(ctx, object, input);
|
|
185
185
|
const imageField = object.imageField ?? (field.type === "image" ? field.id : void 0);
|
|
186
|
-
|
|
186
|
+
const mutations = [saveObject(ctx, { ...object, ...imageField ? { imageField } : {}, fields: [...object.fields, field] })];
|
|
187
|
+
const defaultView = viewsOf(ctx.store, objectId).find((v) => v.id === defaultViewFor(object).id);
|
|
188
|
+
if (defaultView && defaultView.type === "table" && !field.hidden && field.type !== "image" && !defaultView.columns.includes(field.id) && defaultView.columns.length < DEFAULT_VIEW_MAX_COLUMNS) {
|
|
189
|
+
mutations.push({ op: "patch", collection: "views", id: defaultView.id, fields: { columns: [...defaultView.columns, field.id] } });
|
|
190
|
+
}
|
|
191
|
+
await ctx.store.write(mutations, { message: `Add field ${field.label}` });
|
|
187
192
|
return field;
|
|
188
193
|
}
|
|
194
|
+
const DEFAULT_VIEW_MAX_COLUMNS = 7;
|
|
189
195
|
function requireField(object, fieldId) {
|
|
190
196
|
const f = object.fields.find((x) => x.id === fieldId);
|
|
191
197
|
if (!f) throw new OpsError("notFound", `Field "${fieldId}" not found on ${object.labelPlural}.`);
|
|
@@ -87,6 +87,15 @@ const ENUMS = {
|
|
|
87
87
|
};
|
|
88
88
|
const IMAGE_RE = /^data:image\/(png|jpeg|gif|webp|svg\+xml|x-icon|vnd\.microsoft\.icon);base64,[A-Za-z0-9+/]+=*$/;
|
|
89
89
|
const ID_RE = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
90
|
+
function svgHasActiveContent(dataUrl) {
|
|
91
|
+
let text;
|
|
92
|
+
try {
|
|
93
|
+
text = atob(dataUrl.slice(dataUrl.indexOf(",") + 1));
|
|
94
|
+
} catch {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
return /<script[\s>/]|<foreignObject[\s>/]|\son[a-z]+\s*=|javascript:/i.test(text);
|
|
98
|
+
}
|
|
90
99
|
function dataUrlBytes(url) {
|
|
91
100
|
const b64 = url.slice(url.indexOf(",") + 1);
|
|
92
101
|
const pad = b64.endsWith("==") ? 2 : b64.endsWith("=") ? 1 : 0;
|
|
@@ -96,6 +105,7 @@ function validateImageDataUrl(value, label = "image") {
|
|
|
96
105
|
if (typeof value !== "string" || !IMAGE_RE.test(value)) return `The ${label} must be a base64 image data URL (PNG, JPEG, GIF, WebP, SVG or ICO).`;
|
|
97
106
|
const bytes = dataUrlBytes(value);
|
|
98
107
|
if (bytes > MAX_IMAGE_BYTES) return `The ${label} is ${Math.round(bytes / 1024)} KB — the limit is ${MAX_IMAGE_BYTES / 1024} KB.`;
|
|
108
|
+
if (/^data:image\/svg\+xml/i.test(value) && svgHasActiveContent(value)) return `The ${label} SVG contains scripts or event handlers — export it as a plain SVG (or a PNG).`;
|
|
99
109
|
return null;
|
|
100
110
|
}
|
|
101
111
|
function validateAppearancePatch(patch) {
|
|
@@ -11,7 +11,7 @@ import { a as standardObjects, b as defaultPipeline, c as defaultViews } from ".
|
|
|
11
11
|
import { assertCan } from "./context-CxFfqS4D.mjs";
|
|
12
12
|
import { sha256Hex } from "./files-CjsPJSR6.mjs";
|
|
13
13
|
import { asDoc, objectOf, usersOf, settingsDoc } from "./store-5gqRSKXg.mjs";
|
|
14
|
-
import { DEFAULT_SETTINGS } from "./settings-
|
|
14
|
+
import { DEFAULT_SETTINGS } from "./settings-Di8nzNEL.mjs";
|
|
15
15
|
import "./pluginRegistry-DyHtlkcr.mjs";
|
|
16
16
|
import "./runtimeConfig-CCOFg1RM.mjs";
|
|
17
17
|
const PALETTES = [
|
|
@@ -362,6 +362,20 @@ const FIRST = ["Ada", "Alan", "Grace", "Linus", "Margaret", "Dennis", "Barbara",
|
|
|
362
362
|
const LAST = ["Lovelace", "Turing", "Hopper", "Torvalds", "Hamilton", "Ritchie", "Liskov", "Thompson", "Allen", "Berners-Lee", "Perlman", "Cerf", "Lamarr", "McCarthy", "Johnson", "van Rossum", "Martin", "Bernard", "Dubois", "Durand", "Lefebvre", "Moreau", "Laurent", "Simon", "Michel", "Garcia", "Roux", "Fournier", "Girard", "Bonnet", "Smith", "Brown", "Wilson", "Taylor", "Clark", "Lewis", "Walker", "Young", "King", "Wright"];
|
|
363
363
|
const TITLES = ["CEO", "CTO", "VP Sales", "Head of Marketing", "Procurement Manager", "Operations Director", "Product Manager", "Engineering Manager", "CFO", "Office Manager", "Account Executive", "Data Analyst"];
|
|
364
364
|
const CITIES = ["Paris", "London", "New York", "Berlin", "Lyon", "Madrid", "Amsterdam", "Montréal", "San Francisco", "Lisbon", "Brussels", "Toronto"];
|
|
365
|
+
const CITY_COUNTRY = {
|
|
366
|
+
Paris: ["France", "+33 1"],
|
|
367
|
+
London: ["United Kingdom", "+44 20"],
|
|
368
|
+
"New York": ["United States", "+1 212"],
|
|
369
|
+
Berlin: ["Germany", "+49 30"],
|
|
370
|
+
Lyon: ["France", "+33 4"],
|
|
371
|
+
Madrid: ["Spain", "+34 91"],
|
|
372
|
+
Amsterdam: ["Netherlands", "+31 20"],
|
|
373
|
+
Montréal: ["Canada", "+1 514"],
|
|
374
|
+
"San Francisco": ["United States", "+1 415"],
|
|
375
|
+
Lisbon: ["Portugal", "+351 21"],
|
|
376
|
+
Brussels: ["Belgium", "+32 2"],
|
|
377
|
+
Toronto: ["Canada", "+1 416"]
|
|
378
|
+
};
|
|
365
379
|
const DEAL_KINDS = ["Annual license", "Pilot", "Expansion", "Renewal", "Onboarding package", "Enterprise plan", "Support contract", "Consulting retainer"];
|
|
366
380
|
const LIFECYCLE = ["subscriber", "lead", "lead", "mql", "sql", "opportunity", "customer", "customer", "evangelist"];
|
|
367
381
|
const SOURCES = ["website", "referral", "event", "outbound", "partner", "ads", "social"];
|
|
@@ -405,19 +419,23 @@ async function seedDemoData(ctx, opts = {}) {
|
|
|
405
419
|
updatedAt: stamp(Math.max(0, daysAgo - rand() * daysAgo)),
|
|
406
420
|
...opts.ownerId ? { createdBy: opts.ownerId } : {}
|
|
407
421
|
});
|
|
408
|
-
const companies = COMPANIES.map(
|
|
409
|
-
|
|
422
|
+
const companies = COMPANIES.map(([name, domain, industry, employees], i) => {
|
|
423
|
+
const annualRevenue = Math.round(employees * (6e4 + rand() * 14e4) / 1e3) * 1e3;
|
|
424
|
+
const city = pick(CITIES);
|
|
425
|
+
rand();
|
|
426
|
+
const [country, dial] = CITY_COUNTRY[city];
|
|
427
|
+
return rec(seededId(`demo:company:${i}`), "companies", {
|
|
410
428
|
name,
|
|
411
429
|
domain: `https://${domain}`,
|
|
412
430
|
industry,
|
|
413
431
|
employees,
|
|
414
|
-
annualRevenue
|
|
415
|
-
address: { city
|
|
432
|
+
annualRevenue,
|
|
433
|
+
address: { city, country },
|
|
416
434
|
linkedin: `https://www.linkedin.com/company/${domain.split(".")[0]}`,
|
|
417
|
-
phone:
|
|
435
|
+
phone: `${dial} ${String(10 + i).padStart(2, "0")} ${String(Math.floor(rand() * 90) + 10)} ${String(Math.floor(rand() * 90) + 10)} ${String(Math.floor(rand() * 90) + 10)}`,
|
|
418
436
|
...rand() < 0.3 ? { tags: [pick(["vip", "partner", "strategic", "smb", "enterprise"])] } : {}
|
|
419
|
-
}, i, 30 + rand() * 300)
|
|
420
|
-
);
|
|
437
|
+
}, i, 30 + rand() * 300);
|
|
438
|
+
});
|
|
421
439
|
const people = [];
|
|
422
440
|
for (let i = 0; i < 80; i++) {
|
|
423
441
|
const firstName = FIRST[i % FIRST.length];
|
|
@@ -97,7 +97,7 @@ function createMcpServer(opts) {
|
|
|
97
97
|
try {
|
|
98
98
|
const run = async () => {
|
|
99
99
|
const ctx = await opts.backend.context();
|
|
100
|
-
const { callTool: call } = await import("./tools-
|
|
100
|
+
const { callTool: call } = await import("./tools-iSH-yMpl.mjs");
|
|
101
101
|
return call(ctx, name, args);
|
|
102
102
|
};
|
|
103
103
|
const result = tool.mutating ? await opts.backend.withWrite(run) : await run();
|
|
@@ -112,15 +112,15 @@ function createMcpServer(opts) {
|
|
|
112
112
|
async function readResource(id, uri) {
|
|
113
113
|
const ctx = await opts.backend.context();
|
|
114
114
|
let value;
|
|
115
|
-
if (uri === "agentcrm://schema") value = (await import("./schema-
|
|
115
|
+
if (uri === "agentcrm://schema") value = (await import("./schema-C4lSslXv.mjs")).describeSchema(ctx);
|
|
116
116
|
else if (uri === "agentcrm://pipelines") {
|
|
117
|
-
const { listPipelines, forecast } = await import("./pipelines-
|
|
117
|
+
const { listPipelines, forecast } = await import("./pipelines-BAKpPk1w.mjs");
|
|
118
118
|
value = listPipelines(ctx).map((p) => ({ ...p, forecast: forecast(ctx, { pipelineId: p.id }) }));
|
|
119
119
|
} else if (uri === "agentcrm://modules") {
|
|
120
|
-
const [{ listModules }, { listExtensions }] = await Promise.all([import("./modules-
|
|
120
|
+
const [{ listModules }, { listExtensions }] = await Promise.all([import("./modules-clWdE-K2.mjs"), import("./extensions-Bp72uZ9a.mjs")]);
|
|
121
121
|
value = { modules: listModules(ctx), extensions: listExtensions(ctx) };
|
|
122
122
|
} else if (uri === "agentcrm://appearance") {
|
|
123
|
-
const { getAppearance, listPresets } = await import("./appearance-
|
|
123
|
+
const { getAppearance, listPresets } = await import("./appearance-BloHbiLA.mjs");
|
|
124
124
|
const { logo, favicon, customCss, ...rest } = getAppearance(ctx);
|
|
125
125
|
value = { appearance: { ...rest, hasLogo: !!logo, hasFavicon: !!favicon, customCss: customCss ?? null }, presets: listPresets(ctx).map((p) => ({ id: p.id, name: p.name, source: p.source, description: p.description, ...p.enabled !== void 0 ? { enabled: p.enabled } : {} })) };
|
|
126
126
|
} else return fail(id, -32002, `Resource not found: ${uri}`, { uri });
|
|
@@ -20,8 +20,25 @@ function getSettings(ctx) {
|
|
|
20
20
|
assertCan(ctx, "settings.read");
|
|
21
21
|
return { ...DEFAULT_SETTINGS, ...settingsDoc(ctx.store) ?? {} };
|
|
22
22
|
}
|
|
23
|
+
const SETTINGS_KEYS = ["name", "defaultCurrency", "locale", "timezone", "weekStartsOn", "staleDealDays", "ownerUserId", "maxUploadMb"];
|
|
23
24
|
async function updateSettings(ctx, patch) {
|
|
24
25
|
assertCan(ctx, "settings.write");
|
|
26
|
+
const unknown = Object.keys(patch).filter((k) => !SETTINGS_KEYS.includes(k) && k !== "createdAt" && k !== "updatedAt" && k !== "id");
|
|
27
|
+
if (unknown.length) {
|
|
28
|
+
throw new OpsError("validation", `Unknown setting${unknown.length > 1 ? "s" : ""} ${unknown.map((k) => `"${k}"`).join(", ")}. Settings: ${SETTINGS_KEYS.join(", ")}.`);
|
|
29
|
+
}
|
|
30
|
+
if (patch.name !== void 0 && (typeof patch.name !== "string" || !patch.name.trim())) {
|
|
31
|
+
throw new OpsError("validation", "The CRM name can't be empty.");
|
|
32
|
+
}
|
|
33
|
+
if (patch.weekStartsOn !== void 0 && patch.weekStartsOn !== 0 && patch.weekStartsOn !== 1) {
|
|
34
|
+
throw new OpsError("validation", "Week start must be 0 (Sunday) or 1 (Monday).");
|
|
35
|
+
}
|
|
36
|
+
if (patch.locale !== void 0 && !validLocale(patch.locale)) {
|
|
37
|
+
throw new OpsError("validation", `"${String(patch.locale)}" is not a valid locale (BCP-47, e.g. en-US, fr-FR).`);
|
|
38
|
+
}
|
|
39
|
+
if (patch.timezone !== void 0 && patch.timezone !== null && !validTimeZone(patch.timezone)) {
|
|
40
|
+
throw new OpsError("validation", `"${String(patch.timezone)}" is not a valid time zone (IANA, e.g. Europe/Paris).`);
|
|
41
|
+
}
|
|
25
42
|
if (patch.defaultCurrency !== void 0 && !/^[A-Z]{3}$/.test(patch.defaultCurrency.toUpperCase())) {
|
|
26
43
|
throw new OpsError("validation", `"${patch.defaultCurrency}" is not an ISO 4217 currency code.`);
|
|
27
44
|
}
|
|
@@ -43,6 +60,23 @@ async function updateSettings(ctx, patch) {
|
|
|
43
60
|
await ctx.store.write([{ op: "set", collection: "settings", doc: asDoc(next) }], { message: "Update settings" });
|
|
44
61
|
return getSettings(ctx);
|
|
45
62
|
}
|
|
63
|
+
function validLocale(value) {
|
|
64
|
+
if (typeof value !== "string" || !value) return false;
|
|
65
|
+
try {
|
|
66
|
+
return Intl.getCanonicalLocales(value).length === 1;
|
|
67
|
+
} catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function validTimeZone(value) {
|
|
72
|
+
if (typeof value !== "string" || !value) return false;
|
|
73
|
+
try {
|
|
74
|
+
new Intl.DateTimeFormat("en-US", { timeZone: value });
|
|
75
|
+
return true;
|
|
76
|
+
} catch {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
46
80
|
function assertNoSecrets(value, path = "") {
|
|
47
81
|
if (!value || typeof value !== "object") return;
|
|
48
82
|
for (const [k, v] of Object.entries(value)) {
|
|
@@ -68,6 +102,7 @@ async function setConfigDoc(ctx, id, value) {
|
|
|
68
102
|
}
|
|
69
103
|
export {
|
|
70
104
|
DEFAULT_SETTINGS,
|
|
105
|
+
SETTINGS_KEYS,
|
|
71
106
|
assertNoSecrets,
|
|
72
107
|
getConfigDoc,
|
|
73
108
|
getSettings,
|
|
@@ -6,7 +6,7 @@ const __filename = __acrmPath(import.meta.url);
|
|
|
6
6
|
const __dirname = __acrmDirname(__filename);
|
|
7
7
|
import { A as ACTIVITY_TYPES } from "../agentcrm.mjs";
|
|
8
8
|
import { assertCan } from "./context-CxFfqS4D.mjs";
|
|
9
|
-
import { forecast } from "./pipelines-
|
|
9
|
+
import { forecast } from "./pipelines-BAKpPk1w.mjs";
|
|
10
10
|
import { activitiesOf, pipelinesOf, usersOf, objectsOf, recordsOf } from "./store-5gqRSKXg.mjs";
|
|
11
11
|
import "node:util";
|
|
12
12
|
import "node:fs";
|
|
@@ -20,7 +20,7 @@ import "./pluginRegistry-DyHtlkcr.mjs";
|
|
|
20
20
|
import "./fields-B0bitgmr.mjs";
|
|
21
21
|
import "./ids-CvnmrMJX.mjs";
|
|
22
22
|
import "./standardObjects-CheqfDqa.mjs";
|
|
23
|
-
import "./records-
|
|
23
|
+
import "./records-DcHFelq5.mjs";
|
|
24
24
|
import "./query-C5nJB_3C.mjs";
|
|
25
25
|
import "./relations-B9TynBmA.mjs";
|
|
26
26
|
function getStats(ctx) {
|