clivly 0.2.1 → 0.2.2
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 +7 -5
- package/{adapter-nLfZpgIG.d.cts → adapter-Cd6D_3JD.d.mts} +7 -1
- package/{adapter-xs04z0KX.d.mts → adapter-Cy4q2CLs.d.cts} +7 -1
- package/{auth-adapter-FEOR1nx-.d.mts → auth-adapter-CRBW4elj.d.mts} +1 -1
- package/{auth-adapter-wvfGKsOJ.d.cts → auth-adapter-CdLODn2p.d.cts} +1 -1
- package/auth-better-auth.d.cts +1 -1
- package/auth-better-auth.d.mts +1 -1
- package/auth-clerk.d.cts +1 -1
- package/auth-clerk.d.mts +1 -1
- package/auth-workos.d.cts +1 -1
- package/auth-workos.d.mts +1 -1
- package/core-adapter.d.cts +1 -1
- package/core-adapter.d.mts +1 -1
- package/core-auth-adapter.d.cts +1 -1
- package/core-auth-adapter.d.mts +1 -1
- package/core-types.d.cts +1 -1
- package/core-types.d.mts +1 -1
- package/core.d.cts +3 -3
- package/core.d.mts +3 -3
- package/index.cjs +53 -18
- package/index.d.cts +1 -0
- package/index.d.mts +1 -0
- package/index.mjs +53 -18
- package/package.json +30 -4
- package/{types-C4POUcvk.d.mts → types-BpsKVccL.d.cts} +1 -0
- package/{types-LJTBhkcN.d.cts → types-_qbJXMt_.d.mts} +1 -0
package/README.md
CHANGED
|
@@ -4,8 +4,8 @@ Configure and integrate [Clivly](https://clivly.com) — the CRM that lives insi
|
|
|
4
4
|
your app.
|
|
5
5
|
|
|
6
6
|
For the full integration path, including when to use `start()` versus
|
|
7
|
-
`runScheduled()` / `createClivlyHandler()`, see
|
|
8
|
-
[
|
|
7
|
+
`runScheduled()` / `createClivlyHandler()`, see the
|
|
8
|
+
[connecting to Clivly Cloud guide](https://github.com/amani-joseph/clivly.com/blob/master/docs/guides/connecting-to-clivly-cloud.md).
|
|
9
9
|
|
|
10
10
|
## Usage
|
|
11
11
|
|
|
@@ -67,9 +67,11 @@ npx clivly doctor --config ./apps/web/clivly.config.ts
|
|
|
67
67
|
## More docs
|
|
68
68
|
|
|
69
69
|
- Onboarding guide:
|
|
70
|
-
[
|
|
71
|
-
- SDK docs:
|
|
72
|
-
|
|
70
|
+
[connecting to Clivly Cloud](https://github.com/amani-joseph/clivly.com/blob/master/docs/guides/connecting-to-clivly-cloud.md)
|
|
71
|
+
- SDK docs:
|
|
72
|
+
[`@clivly/sdk` README](https://github.com/amani-joseph/clivly.com/blob/master/packages/sdk/README.md)
|
|
73
|
+
- Release notes:
|
|
74
|
+
[CHANGELOG](https://github.com/amani-joseph/clivly.com/blob/master/CHANGELOG.md)
|
|
73
75
|
|
|
74
76
|
## License
|
|
75
77
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, c as CreateCompanyInput, d as CreateTaskInput, g as RecordSource, i as Contact, l as CreateContactInput, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, w as UpdateTaskInput, y as TaskFilters } from "./types-
|
|
1
|
+
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, c as CreateCompanyInput, d as CreateTaskInput, g as RecordSource, i as Contact, l as CreateContactInput, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, w as UpdateTaskInput, y as TaskFilters } from "./types-_qbJXMt_.mjs";
|
|
2
2
|
|
|
3
3
|
//#region ../core/src/adapter.d.ts
|
|
4
4
|
/**
|
|
@@ -31,6 +31,12 @@ interface CRMAdapter {
|
|
|
31
31
|
getTasks(orgId: string, filters?: TaskFilters): Promise<Task[]>;
|
|
32
32
|
reopenTask(orgId: string, id: string): Promise<Task>;
|
|
33
33
|
updateContact(orgId: string, id: string, data: UpdateContactInput): Promise<Contact>;
|
|
34
|
+
/**
|
|
35
|
+
* Move a deal to `stage` and reorder it directly after `afterId` (null = top
|
|
36
|
+
* of the column). The adapter computes the fractional `position` from the
|
|
37
|
+
* target column's current order; callers never pass a numeric position.
|
|
38
|
+
*/
|
|
39
|
+
moveDeal(orgId: string, id: string, stage: Deal["stage"], afterId: string | null): Promise<Deal>;
|
|
34
40
|
updateDeal(orgId: string, id: string, data: UpdateDealInput): Promise<Deal>;
|
|
35
41
|
updateDealStage(orgId: string, id: string, stage: Deal["stage"]): Promise<Deal>;
|
|
36
42
|
updateTask(orgId: string, id: string, data: UpdateTaskInput): Promise<Task>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, c as CreateCompanyInput, d as CreateTaskInput, g as RecordSource, i as Contact, l as CreateContactInput, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, w as UpdateTaskInput, y as TaskFilters } from "./types-
|
|
1
|
+
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, c as CreateCompanyInput, d as CreateTaskInput, g as RecordSource, i as Contact, l as CreateContactInput, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, w as UpdateTaskInput, y as TaskFilters } from "./types-BpsKVccL.cjs";
|
|
2
2
|
|
|
3
3
|
//#region ../core/src/adapter.d.ts
|
|
4
4
|
/**
|
|
@@ -31,6 +31,12 @@ interface CRMAdapter {
|
|
|
31
31
|
getTasks(orgId: string, filters?: TaskFilters): Promise<Task[]>;
|
|
32
32
|
reopenTask(orgId: string, id: string): Promise<Task>;
|
|
33
33
|
updateContact(orgId: string, id: string, data: UpdateContactInput): Promise<Contact>;
|
|
34
|
+
/**
|
|
35
|
+
* Move a deal to `stage` and reorder it directly after `afterId` (null = top
|
|
36
|
+
* of the column). The adapter computes the fractional `position` from the
|
|
37
|
+
* target column's current order; callers never pass a numeric position.
|
|
38
|
+
*/
|
|
39
|
+
moveDeal(orgId: string, id: string, stage: Deal["stage"], afterId: string | null): Promise<Deal>;
|
|
34
40
|
updateDeal(orgId: string, id: string, data: UpdateDealInput): Promise<Deal>;
|
|
35
41
|
updateDealStage(orgId: string, id: string, stage: Deal["stage"]): Promise<Deal>;
|
|
36
42
|
updateTask(orgId: string, id: string, data: UpdateTaskInput): Promise<Task>;
|
package/auth-better-auth.d.cts
CHANGED
package/auth-better-auth.d.mts
CHANGED
package/auth-clerk.d.cts
CHANGED
package/auth-clerk.d.mts
CHANGED
package/auth-workos.d.cts
CHANGED
package/auth-workos.d.mts
CHANGED
package/core-adapter.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as CRMAdapter } from "./adapter-
|
|
1
|
+
import { t as CRMAdapter } from "./adapter-Cy4q2CLs.cjs";
|
|
2
2
|
export { CRMAdapter };
|
package/core-adapter.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as CRMAdapter } from "./adapter-
|
|
1
|
+
import { t as CRMAdapter } from "./adapter-Cd6D_3JD.mjs";
|
|
2
2
|
export { CRMAdapter };
|
package/core-auth-adapter.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-
|
|
1
|
+
import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-CdLODn2p.cjs";
|
|
2
2
|
export { ClivlyAuthAdapter, ClivlyUser, CrmMembership, MembershipResolver, authCustom };
|
package/core-auth-adapter.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-
|
|
1
|
+
import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-CRBW4elj.mjs";
|
|
2
2
|
export { ClivlyAuthAdapter, ClivlyUser, CrmMembership, MembershipResolver, authCustom };
|
package/core-types.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-
|
|
1
|
+
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-BpsKVccL.cjs";
|
|
2
2
|
export { Activity, ActivityType, Company, Contact, ContactFilters, ContactStatus, CreateActivityInput, CreateCompanyInput, CreateContactInput, CreateDealInput, CreateTaskInput, CrmRole, Deal, DealStage, Note, RecordSource, Task, TaskEntityType, TaskFilters, TaskPriority, TaskStatus, UpdateContactInput, UpdateDealInput, UpdateTaskInput };
|
package/core-types.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-
|
|
1
|
+
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-_qbJXMt_.mjs";
|
|
2
2
|
export { Activity, ActivityType, Company, Contact, ContactFilters, ContactStatus, CreateActivityInput, CreateCompanyInput, CreateContactInput, CreateDealInput, CreateTaskInput, CrmRole, Deal, DealStage, Note, RecordSource, Task, TaskEntityType, TaskFilters, TaskPriority, TaskStatus, UpdateContactInput, UpdateDealInput, UpdateTaskInput };
|
package/core.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-
|
|
2
|
-
import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-
|
|
3
|
-
import { t as CRMAdapter } from "./adapter-
|
|
1
|
+
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-BpsKVccL.cjs";
|
|
2
|
+
import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-CdLODn2p.cjs";
|
|
3
|
+
import { t as CRMAdapter } from "./adapter-Cy4q2CLs.cjs";
|
|
4
4
|
import { C as validateEntitiesConfig, S as relationshipsSchema, _ as RelationshipsMap, a as ClivlyEntitiesConfig, b as filterSchema, c as ConfigValidationResult, d as FilterExpr, f as FilterValue, g as RelationshipVia, h as RelationshipSpec, i as ClivlyConfigError, l as CrmConcept, m as MaterializingConcept, n as CRM_CONCEPTS, o as ClivlyEntityConfig, p as MATERIALIZING_CONCEPTS, s as ConfigValidationError, t as CANONICAL_FIELDS, u as DiscoveredSchemaTable, v as defineClivlyConfig, x as relationshipSchema, y as entitiesConfigSchema } from "./entity-config-GczjD3y8.cjs";
|
|
5
5
|
import { i as relationshipViaSignature, n as buildFilterFromDiscriminator, r as buildRelationships, t as RelationshipCandidate } from "./mapping-form-CUlFVfG8.cjs";
|
|
6
6
|
import { n as mappingsToEntitiesConfig, t as EntityMappingRow } from "./mappings-config-DjRLCb2Q.cjs";
|
package/core.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-
|
|
2
|
-
import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-
|
|
3
|
-
import { t as CRMAdapter } from "./adapter-
|
|
1
|
+
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-_qbJXMt_.mjs";
|
|
2
|
+
import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-CRBW4elj.mjs";
|
|
3
|
+
import { t as CRMAdapter } from "./adapter-Cd6D_3JD.mjs";
|
|
4
4
|
import { C as validateEntitiesConfig, S as relationshipsSchema, _ as RelationshipsMap, a as ClivlyEntitiesConfig, b as filterSchema, c as ConfigValidationResult, d as FilterExpr, f as FilterValue, g as RelationshipVia, h as RelationshipSpec, i as ClivlyConfigError, l as CrmConcept, m as MaterializingConcept, n as CRM_CONCEPTS, o as ClivlyEntityConfig, p as MATERIALIZING_CONCEPTS, s as ConfigValidationError, t as CANONICAL_FIELDS, u as DiscoveredSchemaTable, v as defineClivlyConfig, x as relationshipSchema, y as entitiesConfigSchema } from "./entity-config-D1DFyeUp.mjs";
|
|
5
5
|
import { i as relationshipViaSignature, n as buildFilterFromDiscriminator, r as buildRelationships, t as RelationshipCandidate } from "./mapping-form-kjSiJaCX.mjs";
|
|
6
6
|
import { n as mappingsToEntitiesConfig, t as EntityMappingRow } from "./mappings-config-GxiYsSBQ.mjs";
|
package/index.cjs
CHANGED
|
@@ -5,6 +5,7 @@ const require_entity_config = require("./entity-config-Cvjo1cpv.cjs");
|
|
|
5
5
|
require("./mapping-score-D9gfhtRu.cjs");
|
|
6
6
|
const require_core_entity_heuristics = require("./core-entity-heuristics.cjs");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
|
+
let node_module = require("node:module");
|
|
8
9
|
let node_path = require("node:path");
|
|
9
10
|
let jiti = require("jiti");
|
|
10
11
|
let node_url = require("node:url");
|
|
@@ -315,6 +316,16 @@ const defaultRun = (command, args, cwd) => new Promise((resolvePromise, reject)
|
|
|
315
316
|
child.on("error", reject);
|
|
316
317
|
child.on("close", (code) => resolvePromise(code ?? 0));
|
|
317
318
|
});
|
|
319
|
+
const QUIET_FLAGS = {
|
|
320
|
+
npm: [
|
|
321
|
+
"--no-audit",
|
|
322
|
+
"--no-fund",
|
|
323
|
+
"--loglevel=error"
|
|
324
|
+
],
|
|
325
|
+
pnpm: ["--reporter=silent"],
|
|
326
|
+
yarn: [],
|
|
327
|
+
bun: []
|
|
328
|
+
};
|
|
318
329
|
/**
|
|
319
330
|
* Best-effort install: run `<pm> add <packages>`. Never throws — returns
|
|
320
331
|
* `{ ok, command }` so the caller can print the exact command on failure and
|
|
@@ -322,11 +333,12 @@ const defaultRun = (command, args, cwd) => new Promise((resolvePromise, reject)
|
|
|
322
333
|
*/
|
|
323
334
|
async function installPackages(options) {
|
|
324
335
|
const { command, args } = addCommand(options.pm, options.packages);
|
|
325
|
-
const
|
|
336
|
+
const fullArgs = [...args, ...QUIET_FLAGS[options.pm]];
|
|
337
|
+
const printable = `${command} ${fullArgs.join(" ")}`;
|
|
326
338
|
const run = options.run ?? defaultRun;
|
|
327
339
|
try {
|
|
328
340
|
return {
|
|
329
|
-
ok: await run(command,
|
|
341
|
+
ok: await run(command, fullArgs, options.cwd) === 0,
|
|
330
342
|
command: printable
|
|
331
343
|
};
|
|
332
344
|
} catch {
|
|
@@ -545,29 +557,39 @@ function renderEntity(key, entity) {
|
|
|
545
557
|
fields: ${renderFields(entity.fields)}${renderRelationships(entity)},
|
|
546
558
|
}`;
|
|
547
559
|
}
|
|
548
|
-
function renderSource(role, entity) {
|
|
560
|
+
function renderSource(role, entity, dbExpr) {
|
|
549
561
|
const opts = entity.idField === null ? `{ entity: "${entity.tableName}", cursorField: "${entity.cursorField}" }` : `{ entity: "${entity.tableName}", cursorField: "${entity.cursorField}", idField: "${entity.idField}" }`;
|
|
550
|
-
return ` ${role}: fromDrizzle(
|
|
551
|
-
}
|
|
552
|
-
function
|
|
553
|
-
const
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
562
|
+
return ` ${role}: fromDrizzle(${dbExpr}, schema.${entity.moduleKey}, ${opts})`;
|
|
563
|
+
}
|
|
564
|
+
function fallbackDbImportPath(schemaImportPath) {
|
|
565
|
+
const slash = schemaImportPath.lastIndexOf("/");
|
|
566
|
+
return `${slash >= 0 ? schemaImportPath.slice(0, slash) : "."}/db`;
|
|
567
|
+
}
|
|
568
|
+
function renderDbExpr(plan) {
|
|
569
|
+
return plan.db ? `schema.${plan.db.moduleKey}` : "db";
|
|
570
|
+
}
|
|
571
|
+
function renderImports(plan) {
|
|
572
|
+
const lines = [
|
|
573
|
+
"import { createClivlySDK } from \"clivly/sdk\";",
|
|
574
|
+
"import { fromDrizzle } from \"clivly/drizzle\";",
|
|
575
|
+
"import { defineClivlyConfig } from \"clivly/core\";",
|
|
576
|
+
"import { discoverFromDrizzle } from \"clivly/core/drizzle\";",
|
|
577
|
+
`import * as schema from "${plan.importPath}";`
|
|
578
|
+
];
|
|
579
|
+
if (!plan.db) lines.push(`import { db } from "${fallbackDbImportPath(plan.importPath)}"; // TODO: point at your Drizzle instance`);
|
|
580
|
+
return lines.join("\n");
|
|
557
581
|
}
|
|
558
582
|
function renderTodoHeader(todos) {
|
|
559
583
|
if (todos.length === 0) return "";
|
|
560
584
|
return `// TODO(clivly): review before running \`clivly doctor\`:\n${todos.map((t) => `// - ${t}`).join("\n")}\n\n`;
|
|
561
585
|
}
|
|
562
586
|
function renderInitConfig(plan) {
|
|
587
|
+
const dbExpr = renderDbExpr(plan);
|
|
563
588
|
const entities = [renderEntity(plan.contact.moduleKey, plan.contact)];
|
|
564
589
|
if (plan.company) entities.push(renderEntity(plan.company.moduleKey, plan.company));
|
|
565
|
-
const sources = [renderSource("contacts", plan.contact)];
|
|
566
|
-
if (plan.company) sources.push(renderSource("companies", plan.company));
|
|
567
|
-
return `${renderTodoHeader(plan.todos)}
|
|
568
|
-
import { fromDrizzle } from "@clivly/sdk/drizzle";
|
|
569
|
-
import { defineClivlyConfig } from "@clivly/core";
|
|
570
|
-
${renderTableImport(plan)}
|
|
590
|
+
const sources = [renderSource("contacts", plan.contact, dbExpr)];
|
|
591
|
+
if (plan.company) sources.push(renderSource("companies", plan.company, dbExpr));
|
|
592
|
+
return `${renderTodoHeader(plan.todos)}${renderImports(plan)}
|
|
571
593
|
|
|
572
594
|
const entities = defineClivlyConfig({
|
|
573
595
|
entities: {
|
|
@@ -578,6 +600,9 @@ ${entities.join(",\n")},
|
|
|
578
600
|
export default createClivlySDK({
|
|
579
601
|
apiKey: process.env.CLIVLY_API_KEY!,
|
|
580
602
|
entities,
|
|
603
|
+
// Every table in your Drizzle schema, so the Clivly dashboard can offer them
|
|
604
|
+
// all when you add a mapping — not just the ones wired up as sources below.
|
|
605
|
+
schema: discoverFromDrizzle(schema),
|
|
581
606
|
source: {
|
|
582
607
|
${sources.join(",\n")},
|
|
583
608
|
},
|
|
@@ -753,6 +778,13 @@ function readDeps(cwd) {
|
|
|
753
778
|
return {};
|
|
754
779
|
}
|
|
755
780
|
}
|
|
781
|
+
function readOwnVersion() {
|
|
782
|
+
const req = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
783
|
+
for (const rel of ["./package.json", "../package.json"]) try {
|
|
784
|
+
const pkg = req(rel);
|
|
785
|
+
if (pkg.name === "clivly" && pkg.version) return pkg.version;
|
|
786
|
+
} catch {}
|
|
787
|
+
}
|
|
756
788
|
function defaultReadEnv(cwd) {
|
|
757
789
|
const path = (0, node_path.join)(cwd, ".env");
|
|
758
790
|
return (0, node_fs.existsSync)(path) ? (0, node_fs.readFileSync)(path, "utf8") : "";
|
|
@@ -780,6 +812,7 @@ function resolveInitDeps(options) {
|
|
|
780
812
|
detectPackageManager: options.detectPackageManager ?? detectPackageManager,
|
|
781
813
|
install: options.installPackages ?? installPackages,
|
|
782
814
|
readEnv: options.readEnv ?? defaultReadEnv,
|
|
815
|
+
readOwnVersion: options.readOwnVersion ?? readOwnVersion,
|
|
783
816
|
writeEnv: options.writeEnv ?? defaultWriteEnv,
|
|
784
817
|
framework: "unknown"
|
|
785
818
|
};
|
|
@@ -867,12 +900,14 @@ function printNextSteps(out) {
|
|
|
867
900
|
async function scaffold(options, deps, plan) {
|
|
868
901
|
const { out } = deps;
|
|
869
902
|
const pm = deps.detectPackageManager(options.cwd);
|
|
903
|
+
const version = deps.readOwnVersion();
|
|
904
|
+
const spec = version ? `clivly@${version}` : "clivly";
|
|
870
905
|
const result = await deps.install({
|
|
871
906
|
cwd: options.cwd,
|
|
872
907
|
pm,
|
|
873
|
-
packages: [
|
|
908
|
+
packages: [spec]
|
|
874
909
|
});
|
|
875
|
-
if (result.ok) out(`Installed
|
|
910
|
+
if (result.ok) out(`Installed clivly (${pm})\n`);
|
|
876
911
|
else out(`Could not install automatically — run:\n ${result.command}\n`);
|
|
877
912
|
writeScaffoldFiles(options, deps, plan);
|
|
878
913
|
writeEnvFile(options, deps);
|
package/index.d.cts
CHANGED
|
@@ -46,6 +46,7 @@ interface RunInitOptions {
|
|
|
46
46
|
out?: (line: string) => void;
|
|
47
47
|
readDeps?: (cwd: string) => Record<string, string>;
|
|
48
48
|
readEnv?: (cwd: string) => string;
|
|
49
|
+
readOwnVersion?: () => string | undefined;
|
|
49
50
|
resolveSchemaPath?: (cwd: string) => string | null;
|
|
50
51
|
schemaFlag?: string;
|
|
51
52
|
writeConfig?: (path: string, contents: string) => void;
|
package/index.d.mts
CHANGED
|
@@ -46,6 +46,7 @@ interface RunInitOptions {
|
|
|
46
46
|
out?: (line: string) => void;
|
|
47
47
|
readDeps?: (cwd: string) => Record<string, string>;
|
|
48
48
|
readEnv?: (cwd: string) => string;
|
|
49
|
+
readOwnVersion?: () => string | undefined;
|
|
49
50
|
resolveSchemaPath?: (cwd: string) => string | null;
|
|
50
51
|
schemaFlag?: string;
|
|
51
52
|
writeConfig?: (path: string, contents: string) => void;
|
package/index.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { t as createClivlySDK } from "./sdk-BZUn6wzs.mjs";
|
|
|
3
3
|
import { t as CANONICAL_FIELDS } from "./entity-config-DoR0khce.mjs";
|
|
4
4
|
import "./mapping-score-BJNe0lFn.mjs";
|
|
5
5
|
import { matchesConcept, requiredFieldsFor, scoreFieldMap, scoreRelationships, suggestCursorField, toFieldMap } from "./core-entity-heuristics.mjs";
|
|
6
|
+
import { createRequire } from "node:module";
|
|
6
7
|
import { existsSync, mkdirSync, readFileSync, realpathSync, statSync, writeFileSync } from "node:fs";
|
|
7
8
|
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
8
9
|
import { createJiti } from "jiti";
|
|
@@ -314,6 +315,16 @@ const defaultRun = (command, args, cwd) => new Promise((resolvePromise, reject)
|
|
|
314
315
|
child.on("error", reject);
|
|
315
316
|
child.on("close", (code) => resolvePromise(code ?? 0));
|
|
316
317
|
});
|
|
318
|
+
const QUIET_FLAGS = {
|
|
319
|
+
npm: [
|
|
320
|
+
"--no-audit",
|
|
321
|
+
"--no-fund",
|
|
322
|
+
"--loglevel=error"
|
|
323
|
+
],
|
|
324
|
+
pnpm: ["--reporter=silent"],
|
|
325
|
+
yarn: [],
|
|
326
|
+
bun: []
|
|
327
|
+
};
|
|
317
328
|
/**
|
|
318
329
|
* Best-effort install: run `<pm> add <packages>`. Never throws — returns
|
|
319
330
|
* `{ ok, command }` so the caller can print the exact command on failure and
|
|
@@ -321,11 +332,12 @@ const defaultRun = (command, args, cwd) => new Promise((resolvePromise, reject)
|
|
|
321
332
|
*/
|
|
322
333
|
async function installPackages(options) {
|
|
323
334
|
const { command, args } = addCommand(options.pm, options.packages);
|
|
324
|
-
const
|
|
335
|
+
const fullArgs = [...args, ...QUIET_FLAGS[options.pm]];
|
|
336
|
+
const printable = `${command} ${fullArgs.join(" ")}`;
|
|
325
337
|
const run = options.run ?? defaultRun;
|
|
326
338
|
try {
|
|
327
339
|
return {
|
|
328
|
-
ok: await run(command,
|
|
340
|
+
ok: await run(command, fullArgs, options.cwd) === 0,
|
|
329
341
|
command: printable
|
|
330
342
|
};
|
|
331
343
|
} catch {
|
|
@@ -544,29 +556,39 @@ function renderEntity(key, entity) {
|
|
|
544
556
|
fields: ${renderFields(entity.fields)}${renderRelationships(entity)},
|
|
545
557
|
}`;
|
|
546
558
|
}
|
|
547
|
-
function renderSource(role, entity) {
|
|
559
|
+
function renderSource(role, entity, dbExpr) {
|
|
548
560
|
const opts = entity.idField === null ? `{ entity: "${entity.tableName}", cursorField: "${entity.cursorField}" }` : `{ entity: "${entity.tableName}", cursorField: "${entity.cursorField}", idField: "${entity.idField}" }`;
|
|
549
|
-
return ` ${role}: fromDrizzle(
|
|
550
|
-
}
|
|
551
|
-
function
|
|
552
|
-
const
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
561
|
+
return ` ${role}: fromDrizzle(${dbExpr}, schema.${entity.moduleKey}, ${opts})`;
|
|
562
|
+
}
|
|
563
|
+
function fallbackDbImportPath(schemaImportPath) {
|
|
564
|
+
const slash = schemaImportPath.lastIndexOf("/");
|
|
565
|
+
return `${slash >= 0 ? schemaImportPath.slice(0, slash) : "."}/db`;
|
|
566
|
+
}
|
|
567
|
+
function renderDbExpr(plan) {
|
|
568
|
+
return plan.db ? `schema.${plan.db.moduleKey}` : "db";
|
|
569
|
+
}
|
|
570
|
+
function renderImports(plan) {
|
|
571
|
+
const lines = [
|
|
572
|
+
"import { createClivlySDK } from \"clivly/sdk\";",
|
|
573
|
+
"import { fromDrizzle } from \"clivly/drizzle\";",
|
|
574
|
+
"import { defineClivlyConfig } from \"clivly/core\";",
|
|
575
|
+
"import { discoverFromDrizzle } from \"clivly/core/drizzle\";",
|
|
576
|
+
`import * as schema from "${plan.importPath}";`
|
|
577
|
+
];
|
|
578
|
+
if (!plan.db) lines.push(`import { db } from "${fallbackDbImportPath(plan.importPath)}"; // TODO: point at your Drizzle instance`);
|
|
579
|
+
return lines.join("\n");
|
|
556
580
|
}
|
|
557
581
|
function renderTodoHeader(todos) {
|
|
558
582
|
if (todos.length === 0) return "";
|
|
559
583
|
return `// TODO(clivly): review before running \`clivly doctor\`:\n${todos.map((t) => `// - ${t}`).join("\n")}\n\n`;
|
|
560
584
|
}
|
|
561
585
|
function renderInitConfig(plan) {
|
|
586
|
+
const dbExpr = renderDbExpr(plan);
|
|
562
587
|
const entities = [renderEntity(plan.contact.moduleKey, plan.contact)];
|
|
563
588
|
if (plan.company) entities.push(renderEntity(plan.company.moduleKey, plan.company));
|
|
564
|
-
const sources = [renderSource("contacts", plan.contact)];
|
|
565
|
-
if (plan.company) sources.push(renderSource("companies", plan.company));
|
|
566
|
-
return `${renderTodoHeader(plan.todos)}
|
|
567
|
-
import { fromDrizzle } from "@clivly/sdk/drizzle";
|
|
568
|
-
import { defineClivlyConfig } from "@clivly/core";
|
|
569
|
-
${renderTableImport(plan)}
|
|
589
|
+
const sources = [renderSource("contacts", plan.contact, dbExpr)];
|
|
590
|
+
if (plan.company) sources.push(renderSource("companies", plan.company, dbExpr));
|
|
591
|
+
return `${renderTodoHeader(plan.todos)}${renderImports(plan)}
|
|
570
592
|
|
|
571
593
|
const entities = defineClivlyConfig({
|
|
572
594
|
entities: {
|
|
@@ -577,6 +599,9 @@ ${entities.join(",\n")},
|
|
|
577
599
|
export default createClivlySDK({
|
|
578
600
|
apiKey: process.env.CLIVLY_API_KEY!,
|
|
579
601
|
entities,
|
|
602
|
+
// Every table in your Drizzle schema, so the Clivly dashboard can offer them
|
|
603
|
+
// all when you add a mapping — not just the ones wired up as sources below.
|
|
604
|
+
schema: discoverFromDrizzle(schema),
|
|
580
605
|
source: {
|
|
581
606
|
${sources.join(",\n")},
|
|
582
607
|
},
|
|
@@ -752,6 +777,13 @@ function readDeps(cwd) {
|
|
|
752
777
|
return {};
|
|
753
778
|
}
|
|
754
779
|
}
|
|
780
|
+
function readOwnVersion() {
|
|
781
|
+
const req = createRequire(import.meta.url);
|
|
782
|
+
for (const rel of ["./package.json", "../package.json"]) try {
|
|
783
|
+
const pkg = req(rel);
|
|
784
|
+
if (pkg.name === "clivly" && pkg.version) return pkg.version;
|
|
785
|
+
} catch {}
|
|
786
|
+
}
|
|
755
787
|
function defaultReadEnv(cwd) {
|
|
756
788
|
const path = join(cwd, ".env");
|
|
757
789
|
return existsSync(path) ? readFileSync(path, "utf8") : "";
|
|
@@ -779,6 +811,7 @@ function resolveInitDeps(options) {
|
|
|
779
811
|
detectPackageManager: options.detectPackageManager ?? detectPackageManager,
|
|
780
812
|
install: options.installPackages ?? installPackages,
|
|
781
813
|
readEnv: options.readEnv ?? defaultReadEnv,
|
|
814
|
+
readOwnVersion: options.readOwnVersion ?? readOwnVersion,
|
|
782
815
|
writeEnv: options.writeEnv ?? defaultWriteEnv,
|
|
783
816
|
framework: "unknown"
|
|
784
817
|
};
|
|
@@ -866,12 +899,14 @@ function printNextSteps(out) {
|
|
|
866
899
|
async function scaffold(options, deps, plan) {
|
|
867
900
|
const { out } = deps;
|
|
868
901
|
const pm = deps.detectPackageManager(options.cwd);
|
|
902
|
+
const version = deps.readOwnVersion();
|
|
903
|
+
const spec = version ? `clivly@${version}` : "clivly";
|
|
869
904
|
const result = await deps.install({
|
|
870
905
|
cwd: options.cwd,
|
|
871
906
|
pm,
|
|
872
|
-
packages: [
|
|
907
|
+
packages: [spec]
|
|
873
908
|
});
|
|
874
|
-
if (result.ok) out(`Installed
|
|
909
|
+
if (result.ok) out(`Installed clivly (${pm})\n`);
|
|
875
910
|
else out(`Could not install automatically — run:\n ${result.command}\n`);
|
|
876
911
|
writeScaffoldFiles(options, deps, plan);
|
|
877
912
|
writeEnvFile(options, deps);
|
package/package.json
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clivly",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Clivly CLI — scaffold a CRM into your app (clivly init).",
|
|
7
7
|
"license": "MIT",
|
|
8
|
-
"bin":
|
|
8
|
+
"bin": {
|
|
9
|
+
"clivly": "index.mjs"
|
|
10
|
+
},
|
|
9
11
|
"main": "./index.cjs",
|
|
10
12
|
"module": "./index.mjs",
|
|
11
13
|
"types": "./index.d.mts",
|
|
@@ -232,5 +234,29 @@
|
|
|
232
234
|
"vite": {
|
|
233
235
|
"optional": true
|
|
234
236
|
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
+
},
|
|
238
|
+
"author": "Joseph Amani",
|
|
239
|
+
"engines": {
|
|
240
|
+
"node": ">=18"
|
|
241
|
+
},
|
|
242
|
+
"repository": {
|
|
243
|
+
"type": "git",
|
|
244
|
+
"url": "git+https://github.com/amani-joseph/clivly.com.git",
|
|
245
|
+
"directory": "packages/cli"
|
|
246
|
+
},
|
|
247
|
+
"homepage": "https://clivly.com",
|
|
248
|
+
"bugs": {
|
|
249
|
+
"url": "https://github.com/amani-joseph/clivly.com/issues"
|
|
250
|
+
},
|
|
251
|
+
"keywords": [
|
|
252
|
+
"crm",
|
|
253
|
+
"cli",
|
|
254
|
+
"drizzle",
|
|
255
|
+
"typescript",
|
|
256
|
+
"tanstack-start",
|
|
257
|
+
"nextjs",
|
|
258
|
+
"self-hosted",
|
|
259
|
+
"embedded-crm",
|
|
260
|
+
"postgres"
|
|
261
|
+
]
|
|
262
|
+
}
|