@daeda/mcp-pro 0.1.0 → 0.1.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/dist/index.js +195 -61
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -416,7 +416,6 @@ var saveErrorCsv = (portalId, objectType, csvContent) => pipe2(
|
|
|
416
416
|
);
|
|
417
417
|
|
|
418
418
|
// src/plugins/crm-data.ts
|
|
419
|
-
var PROPERTY_SAMPLE_SIZE = 5;
|
|
420
419
|
var ASSOCIATIONS_TABLE_STATEMENTS = [
|
|
421
420
|
`CREATE TABLE IF NOT EXISTS associations (
|
|
422
421
|
from_object_type TEXT NOT NULL,
|
|
@@ -649,23 +648,18 @@ var crmDataPlugin = {
|
|
|
649
648
|
const count = Number(
|
|
650
649
|
countReader.getRowObjects()[0].count
|
|
651
650
|
);
|
|
652
|
-
let
|
|
651
|
+
let propertyKeyCount = 0;
|
|
653
652
|
if (count > 0) {
|
|
654
653
|
const sampleReader = await conn.runAndReadAll(
|
|
655
|
-
`SELECT properties FROM "${tableName}" LIMIT
|
|
654
|
+
`SELECT properties FROM "${tableName}" LIMIT 1`
|
|
656
655
|
);
|
|
657
656
|
const sampleRows = sampleReader.getRowObjects();
|
|
658
|
-
|
|
659
|
-
for (const row of sampleRows) {
|
|
657
|
+
if (sampleRows[0]) {
|
|
660
658
|
try {
|
|
661
|
-
|
|
662
|
-
for (const key of Object.keys(props)) {
|
|
663
|
-
keySet.add(key);
|
|
664
|
-
}
|
|
659
|
+
propertyKeyCount = Object.keys(JSON.parse(sampleRows[0].properties)).length;
|
|
665
660
|
} catch {
|
|
666
661
|
}
|
|
667
662
|
}
|
|
668
|
-
propertyKeys = Array.from(keySet).sort();
|
|
669
663
|
}
|
|
670
664
|
let lastSynced = null;
|
|
671
665
|
try {
|
|
@@ -680,7 +674,7 @@ var crmDataPlugin = {
|
|
|
680
674
|
return {
|
|
681
675
|
objectType: tableName,
|
|
682
676
|
recordCount: count,
|
|
683
|
-
|
|
677
|
+
propertyKeyCount,
|
|
684
678
|
lastSynced
|
|
685
679
|
};
|
|
686
680
|
})
|
|
@@ -701,11 +695,6 @@ var crmDataPlugin = {
|
|
|
701
695
|
to: group.to_object_type,
|
|
702
696
|
count: Number(group.count)
|
|
703
697
|
}))
|
|
704
|
-
},
|
|
705
|
-
queryHints: {
|
|
706
|
-
accessProperty: "json_extract_string(properties, '$.propertyName')",
|
|
707
|
-
exampleQuery: "SELECT id, json_extract_string(properties, '$.firstname') as first_name FROM contacts LIMIT 10",
|
|
708
|
-
allProperties: "SELECT id, properties FROM <table> LIMIT 1"
|
|
709
698
|
}
|
|
710
699
|
}
|
|
711
700
|
};
|
|
@@ -3182,7 +3171,7 @@ Use "all" to get everything at once.`,
|
|
|
3182
3171
|
result.schema = await buildSchemaSection(deps.getSelectedPortalId, deps.getEncryptionKey);
|
|
3183
3172
|
}
|
|
3184
3173
|
return {
|
|
3185
|
-
content: [{ type: "text", text: JSON.stringify(result
|
|
3174
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
3186
3175
|
};
|
|
3187
3176
|
} catch (e) {
|
|
3188
3177
|
const message = e instanceof Error ? e.message : String(e);
|
|
@@ -5326,6 +5315,18 @@ var updatePropertyHandler = {
|
|
|
5326
5315
|
message: `Property '${op.property_name}' groupName: expected '${op.updates.group_name}', got '${updated.groupName}'`
|
|
5327
5316
|
});
|
|
5328
5317
|
}
|
|
5318
|
+
if (op.updates.options !== void 0) {
|
|
5319
|
+
const expectedValues = new Set(op.updates.options.map((o) => o.value));
|
|
5320
|
+
const actualValues = new Set(updated.options.map((o) => o.value));
|
|
5321
|
+
if (expectedValues.size !== actualValues.size || [...expectedValues].some((v) => !actualValues.has(v))) {
|
|
5322
|
+
issues.push({
|
|
5323
|
+
severity: "warning",
|
|
5324
|
+
operation_index: index,
|
|
5325
|
+
code: "POSTCHECK_OPTIONS_MISMATCH",
|
|
5326
|
+
message: `Property '${op.property_name}' options: expected ${expectedValues.size} options, got ${actualValues.size}`
|
|
5327
|
+
});
|
|
5328
|
+
}
|
|
5329
|
+
}
|
|
5329
5330
|
return issues;
|
|
5330
5331
|
}),
|
|
5331
5332
|
catchAllToWarning(
|
|
@@ -5626,6 +5627,14 @@ var updatePropertyGroupHandler = {
|
|
|
5626
5627
|
message: `Property group '${op.group_name}' label: expected '${op.updates.label}', got '${updated.label}'`
|
|
5627
5628
|
});
|
|
5628
5629
|
}
|
|
5630
|
+
if (op.updates.display_order !== void 0 && updated.displayOrder !== op.updates.display_order) {
|
|
5631
|
+
issues.push({
|
|
5632
|
+
severity: "warning",
|
|
5633
|
+
operation_index: index,
|
|
5634
|
+
code: "POSTCHECK_DISPLAY_ORDER_MISMATCH",
|
|
5635
|
+
message: `Property group '${op.group_name}' displayOrder: expected ${op.updates.display_order}, got ${updated.displayOrder}`
|
|
5636
|
+
});
|
|
5637
|
+
}
|
|
5629
5638
|
return issues;
|
|
5630
5639
|
}),
|
|
5631
5640
|
catchAllToWarning(
|
|
@@ -6080,7 +6089,8 @@ var updatePipelineHandler = {
|
|
|
6080
6089
|
label: op.updates.label,
|
|
6081
6090
|
displayOrder: op.updates.display_order
|
|
6082
6091
|
}),
|
|
6083
|
-
Effect44.
|
|
6092
|
+
Effect44.map(() => ({ label: "update pipeline metadata", ok: true })),
|
|
6093
|
+
Effect44.catchAll(() => Effect44.succeed({ label: "update pipeline metadata", ok: false }))
|
|
6084
6094
|
)
|
|
6085
6095
|
);
|
|
6086
6096
|
}
|
|
@@ -6097,7 +6107,8 @@ var updatePipelineHandler = {
|
|
|
6097
6107
|
}
|
|
6098
6108
|
}
|
|
6099
6109
|
}),
|
|
6100
|
-
Effect44.
|
|
6110
|
+
Effect44.map(() => ({ label: `add stage '${stage.label}'`, ok: true })),
|
|
6111
|
+
Effect44.catchAll(() => Effect44.succeed({ label: `add stage '${stage.label}'`, ok: false }))
|
|
6101
6112
|
)
|
|
6102
6113
|
);
|
|
6103
6114
|
}
|
|
@@ -6114,7 +6125,8 @@ var updatePipelineHandler = {
|
|
|
6114
6125
|
}
|
|
6115
6126
|
}
|
|
6116
6127
|
}),
|
|
6117
|
-
Effect44.
|
|
6128
|
+
Effect44.map(() => ({ label: `update stage '${stageUpdate.stage_id}'`, ok: true })),
|
|
6129
|
+
Effect44.catchAll(() => Effect44.succeed({ label: `update stage '${stageUpdate.stage_id}'`, ok: false }))
|
|
6118
6130
|
)
|
|
6119
6131
|
);
|
|
6120
6132
|
}
|
|
@@ -6122,19 +6134,42 @@ var updatePipelineHandler = {
|
|
|
6122
6134
|
steps.push(
|
|
6123
6135
|
pipe33(
|
|
6124
6136
|
hs.deletePipelineStage(op.object_type, op.pipeline_id, stageId),
|
|
6125
|
-
Effect44.
|
|
6137
|
+
Effect44.map(() => ({ label: `remove stage '${stageId}'`, ok: true })),
|
|
6138
|
+
Effect44.catchAll(() => Effect44.succeed({ label: `remove stage '${stageId}'`, ok: false }))
|
|
6126
6139
|
)
|
|
6127
6140
|
);
|
|
6128
6141
|
}
|
|
6129
6142
|
return pipe33(
|
|
6130
6143
|
Effect44.forEach(steps, (step) => step, { concurrency: 1 }),
|
|
6131
|
-
Effect44.map(() =>
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6144
|
+
Effect44.map((results) => {
|
|
6145
|
+
const failed = results.filter((r) => !r.ok);
|
|
6146
|
+
if (failed.length === results.length) {
|
|
6147
|
+
return {
|
|
6148
|
+
index,
|
|
6149
|
+
type: "update_pipeline",
|
|
6150
|
+
status: "failed",
|
|
6151
|
+
records_affected: 0,
|
|
6152
|
+
error: `All ${failed.length} sub-steps failed: ${failed.map((f) => f.label).join(", ")}`
|
|
6153
|
+
};
|
|
6154
|
+
}
|
|
6155
|
+
if (failed.length > 0) {
|
|
6156
|
+
return {
|
|
6157
|
+
index,
|
|
6158
|
+
type: "update_pipeline",
|
|
6159
|
+
status: "failed",
|
|
6160
|
+
records_affected: 1,
|
|
6161
|
+
affected_ids: [op.pipeline_id],
|
|
6162
|
+
error: `Partial failure: ${failed.length}/${results.length} sub-steps failed (${failed.map((f) => f.label).join(", ")})`
|
|
6163
|
+
};
|
|
6164
|
+
}
|
|
6165
|
+
return {
|
|
6166
|
+
index,
|
|
6167
|
+
type: "update_pipeline",
|
|
6168
|
+
status: "success",
|
|
6169
|
+
records_affected: 1,
|
|
6170
|
+
affected_ids: [op.pipeline_id]
|
|
6171
|
+
};
|
|
6172
|
+
})
|
|
6138
6173
|
);
|
|
6139
6174
|
}),
|
|
6140
6175
|
catchAllToFailed("update_pipeline", index)
|
|
@@ -6174,6 +6209,18 @@ var updatePipelineHandler = {
|
|
|
6174
6209
|
});
|
|
6175
6210
|
}
|
|
6176
6211
|
}
|
|
6212
|
+
for (const stageUpdate of op.stages_to_update ?? []) {
|
|
6213
|
+
const stage = pipeline.stages.find((s) => s.id === stageUpdate.stage_id);
|
|
6214
|
+
if (!stage) continue;
|
|
6215
|
+
if (stageUpdate.label !== void 0 && stage.label !== stageUpdate.label) {
|
|
6216
|
+
issues.push({
|
|
6217
|
+
severity: "warning",
|
|
6218
|
+
operation_index: index,
|
|
6219
|
+
code: "POSTCHECK_STAGE_LABEL_MISMATCH",
|
|
6220
|
+
message: `Stage '${stageUpdate.stage_id}' label: expected '${stageUpdate.label}', got '${stage.label}'`
|
|
6221
|
+
});
|
|
6222
|
+
}
|
|
6223
|
+
}
|
|
6177
6224
|
const stageIds = new Set(pipeline.stages.map((s) => s.id));
|
|
6178
6225
|
for (const removedId of op.stage_ids_to_remove ?? []) {
|
|
6179
6226
|
if (stageIds.has(removedId)) {
|
|
@@ -6685,13 +6732,51 @@ var batchUpdateAssociationsHandler = {
|
|
|
6685
6732
|
}
|
|
6686
6733
|
return [];
|
|
6687
6734
|
},
|
|
6688
|
-
validateEffectful: () =>
|
|
6735
|
+
validateEffectful: (op, index) => pipe38(
|
|
6736
|
+
HubSpotService,
|
|
6737
|
+
Effect49.flatMap((hs) => hs.getAssociationLabels(op.from_object_type, op.to_object_type)),
|
|
6738
|
+
Effect49.map((labels) => {
|
|
6739
|
+
const issues = [];
|
|
6740
|
+
const match = labels.find((l) => l.typeId === op.new_association_type_id);
|
|
6741
|
+
if (!match) {
|
|
6742
|
+
issues.push({
|
|
6743
|
+
severity: "error",
|
|
6744
|
+
operation_index: index,
|
|
6745
|
+
code: "ASSOCIATION_TYPE_NOT_FOUND",
|
|
6746
|
+
message: `Association type ID ${op.new_association_type_id} does not exist between ${op.from_object_type} and ${op.to_object_type}`
|
|
6747
|
+
});
|
|
6748
|
+
}
|
|
6749
|
+
return issues;
|
|
6750
|
+
}),
|
|
6751
|
+
catchAllToWarning(
|
|
6752
|
+
"VALIDATION_API_UNAVAILABLE",
|
|
6753
|
+
index,
|
|
6754
|
+
`Unable to verify association labels between ${op.from_object_type} and ${op.to_object_type} (API error)`
|
|
6755
|
+
)
|
|
6756
|
+
),
|
|
6689
6757
|
preCheck: () => Effect49.succeed([]),
|
|
6690
6758
|
execute: (op, index) => pipe38(
|
|
6691
6759
|
HubSpotService,
|
|
6692
|
-
Effect49.flatMap(
|
|
6693
|
-
|
|
6694
|
-
|
|
6760
|
+
Effect49.flatMap((hs) => {
|
|
6761
|
+
const deleteInputs = {
|
|
6762
|
+
fromObjectType: op.from_object_type,
|
|
6763
|
+
toObjectType: op.to_object_type,
|
|
6764
|
+
inputs: op.associations.map((a) => ({
|
|
6765
|
+
fromId: a.from_id,
|
|
6766
|
+
toId: a.to_id
|
|
6767
|
+
}))
|
|
6768
|
+
};
|
|
6769
|
+
const createWithType = (typeId) => hs.batchCreateAssociations({
|
|
6770
|
+
fromObjectType: op.from_object_type,
|
|
6771
|
+
toObjectType: op.to_object_type,
|
|
6772
|
+
inputs: op.associations.map((a) => ({
|
|
6773
|
+
fromId: a.from_id,
|
|
6774
|
+
toId: a.to_id,
|
|
6775
|
+
associationTypeId: typeId
|
|
6776
|
+
}))
|
|
6777
|
+
});
|
|
6778
|
+
const recreateUnlabeled = pipe38(
|
|
6779
|
+
hs.batchCreateAssociations({
|
|
6695
6780
|
fromObjectType: op.from_object_type,
|
|
6696
6781
|
toObjectType: op.to_object_type,
|
|
6697
6782
|
inputs: op.associations.map((a) => ({
|
|
@@ -6699,19 +6784,23 @@ var batchUpdateAssociationsHandler = {
|
|
|
6699
6784
|
toId: a.to_id
|
|
6700
6785
|
}))
|
|
6701
6786
|
}),
|
|
6787
|
+
Effect49.catchAll(() => Effect49.succeed(void 0))
|
|
6788
|
+
);
|
|
6789
|
+
return pipe38(
|
|
6790
|
+
hs.batchDeleteAssociations(deleteInputs),
|
|
6702
6791
|
Effect49.flatMap(
|
|
6703
|
-
() =>
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6792
|
+
() => pipe38(
|
|
6793
|
+
createWithType(op.new_association_type_id),
|
|
6794
|
+
Effect49.catchAll(
|
|
6795
|
+
(createError) => pipe38(
|
|
6796
|
+
recreateUnlabeled,
|
|
6797
|
+
Effect49.flatMap(() => Effect49.fail(createError))
|
|
6798
|
+
)
|
|
6799
|
+
)
|
|
6800
|
+
)
|
|
6712
6801
|
)
|
|
6713
|
-
)
|
|
6714
|
-
),
|
|
6802
|
+
);
|
|
6803
|
+
}),
|
|
6715
6804
|
Effect49.map(() => ({
|
|
6716
6805
|
index,
|
|
6717
6806
|
type: "batch_update_associations",
|
|
@@ -7283,20 +7372,33 @@ var updateCustomObjectHandler = {
|
|
|
7283
7372
|
execute: (op, index) => pipe45(
|
|
7284
7373
|
HubSpotService,
|
|
7285
7374
|
Effect56.flatMap((hs) => {
|
|
7286
|
-
const
|
|
7287
|
-
|
|
7288
|
-
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
|
|
7294
|
-
|
|
7295
|
-
|
|
7296
|
-
|
|
7297
|
-
|
|
7298
|
-
|
|
7299
|
-
|
|
7375
|
+
const needsLabelMerge = (op.new_singular_label !== void 0 || op.new_plural_label !== void 0) && !(op.new_singular_label !== void 0 && op.new_plural_label !== void 0);
|
|
7376
|
+
const getExistingLabels = needsLabelMerge ? pipe45(
|
|
7377
|
+
hs.getCustomObjectSchemas,
|
|
7378
|
+
Effect56.map((schemas) => {
|
|
7379
|
+
const schema = schemas.find((s) => s.name === op.object_type || s.objectTypeId === op.object_type);
|
|
7380
|
+
return schema?.labels ?? { singular: "", plural: "" };
|
|
7381
|
+
})
|
|
7382
|
+
) : Effect56.succeed({ singular: "", plural: "" });
|
|
7383
|
+
return pipe45(
|
|
7384
|
+
getExistingLabels,
|
|
7385
|
+
Effect56.flatMap((existingLabels) => {
|
|
7386
|
+
const updates = {};
|
|
7387
|
+
if (op.new_singular_label !== void 0 || op.new_plural_label !== void 0) {
|
|
7388
|
+
updates.labels = {
|
|
7389
|
+
singular: op.new_singular_label ?? existingLabels.singular,
|
|
7390
|
+
plural: op.new_plural_label ?? existingLabels.plural
|
|
7391
|
+
};
|
|
7392
|
+
}
|
|
7393
|
+
if (op.new_primary_display_property !== void 0) {
|
|
7394
|
+
updates.primaryDisplayProperty = op.new_primary_display_property;
|
|
7395
|
+
}
|
|
7396
|
+
if (op.new_required_properties !== void 0) {
|
|
7397
|
+
updates.requiredProperties = [...op.new_required_properties];
|
|
7398
|
+
}
|
|
7399
|
+
return hs.updateCustomObject(op.object_type, updates);
|
|
7400
|
+
})
|
|
7401
|
+
);
|
|
7300
7402
|
}),
|
|
7301
7403
|
Effect56.map((result) => ({
|
|
7302
7404
|
index,
|
|
@@ -7808,7 +7910,27 @@ var batchAssignOwnerHandler = {
|
|
|
7808
7910
|
}
|
|
7809
7911
|
return issues;
|
|
7810
7912
|
},
|
|
7811
|
-
validateEffectful: () =>
|
|
7913
|
+
validateEffectful: (op, index) => pipe53(
|
|
7914
|
+
HubSpotService,
|
|
7915
|
+
Effect64.flatMap((hs) => hs.getOwners),
|
|
7916
|
+
Effect64.map((owners) => {
|
|
7917
|
+
const issues = [];
|
|
7918
|
+
if (!owners.find((o) => o.id === op.owner_id)) {
|
|
7919
|
+
issues.push({
|
|
7920
|
+
severity: "error",
|
|
7921
|
+
operation_index: index,
|
|
7922
|
+
code: "OWNER_NOT_FOUND",
|
|
7923
|
+
message: `Owner ID '${op.owner_id}' does not exist in this portal \u2014 use the query tool to find valid owner IDs`
|
|
7924
|
+
});
|
|
7925
|
+
}
|
|
7926
|
+
return issues;
|
|
7927
|
+
}),
|
|
7928
|
+
catchAllToWarning(
|
|
7929
|
+
"VALIDATION_API_UNAVAILABLE",
|
|
7930
|
+
index,
|
|
7931
|
+
"Unable to verify owner ID during validation (API error)"
|
|
7932
|
+
)
|
|
7933
|
+
),
|
|
7812
7934
|
preCheck: () => Effect64.succeed([]),
|
|
7813
7935
|
execute: (op, index) => pipe53(
|
|
7814
7936
|
HubSpotService,
|
|
@@ -8100,7 +8222,15 @@ var formatPlanView = () => {
|
|
|
8100
8222
|
};
|
|
8101
8223
|
function registerBuildPlanTool(server2) {
|
|
8102
8224
|
server2.registerTool("build_plan", {
|
|
8103
|
-
description: `
|
|
8225
|
+
description: `Use this tool whenever the user wants to make changes to their HubSpot CRM configuration or data. This is the ONLY way to modify HubSpot \u2014 there is no direct API access. All CRM write operations must go through a plan.
|
|
8226
|
+
|
|
8227
|
+
Supports 28 operation types across these categories:
|
|
8228
|
+
- Properties & groups: create, update, or delete custom properties and property groups
|
|
8229
|
+
- Pipelines & stages: create, update, or delete deal/ticket pipelines with stages
|
|
8230
|
+
- Records: batch create, update, delete, merge, or reassign owners for CRM records
|
|
8231
|
+
- Associations: create, update, or delete associations and labels between object types
|
|
8232
|
+
- Lists: create, update, delete lists, or add/remove members
|
|
8233
|
+
- Custom objects: create, update, or delete custom object schemas
|
|
8104
8234
|
|
|
8105
8235
|
CREATING A PLAN:
|
|
8106
8236
|
Provide title + description (+ optional operations) to start a new draft.
|
|
@@ -8122,7 +8252,7 @@ VIEWING THE PLAN:
|
|
|
8122
8252
|
IMPORTANT: After building the plan, present it to the user and ask for confirmation before calling submit_plan.
|
|
8123
8253
|
|
|
8124
8254
|
WORKFLOW:
|
|
8125
|
-
1. describe_operations - Discover available operation types
|
|
8255
|
+
1. describe_operations - Discover available operation types and their required fields
|
|
8126
8256
|
2. build_plan - Create draft with title, description, and operations
|
|
8127
8257
|
3. Present the plan to the user for review
|
|
8128
8258
|
4. submit_plan (dry_run: true) - Validate without saving (optional)
|
|
@@ -8258,7 +8388,11 @@ ${formatPlanView()}`
|
|
|
8258
8388
|
import { z as z43 } from "zod";
|
|
8259
8389
|
function registerDescribeOperationsTool(server2) {
|
|
8260
8390
|
server2.registerTool("describe_operations", {
|
|
8261
|
-
description: `Discover
|
|
8391
|
+
description: `Discover what CRM modifications are available and what fields they require. Call this tool when the user asks about making changes to HubSpot, or before using build_plan to check operation schemas.
|
|
8392
|
+
|
|
8393
|
+
Use cases:
|
|
8394
|
+
- User asks "can I delete custom properties?" or "what can you do with pipelines?" \u2014 call with no arguments to list all 28 operation types.
|
|
8395
|
+
- User wants to build a plan \u2014 call with specific types to see their full field schemas and examples (e.g. ['delete_property', 'create_pipeline']).
|
|
8262
8396
|
|
|
8263
8397
|
- Call with no arguments to list all available operation types.
|
|
8264
8398
|
- Call with specific types to see their full field schemas and examples.`,
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@daeda/mcp-pro",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "MCP server for HubSpot CRM — sync, query, and manage your portal data",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"mcp-pro": "
|
|
7
|
+
"mcp-pro": "dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"main": "./dist/index.js",
|
|
10
10
|
"exports": {
|
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
"dev": "bun run --watch src/index.ts",
|
|
22
22
|
"start": "bun run src/index.ts",
|
|
23
23
|
"prepublishOnly": "bun run build",
|
|
24
|
+
"release:patch": "npm version patch && npm publish --access public",
|
|
25
|
+
"release:minor": "npm version minor && npm publish --access public",
|
|
26
|
+
"release:major": "npm version major && npm publish --access public",
|
|
24
27
|
"db:stats": "bun run scripts/db-stats.ts",
|
|
25
28
|
"db:query": "bun run scripts/db-query.ts",
|
|
26
29
|
"db:schema": "bun run scripts/db-schema.ts",
|