convex-linear 0.0.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.
Files changed (52) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +438 -0
  3. package/dist/client/_generated/_ignore.d.ts +1 -0
  4. package/dist/client/_generated/_ignore.d.ts.map +1 -0
  5. package/dist/client/_generated/_ignore.js +3 -0
  6. package/dist/client/_generated/_ignore.js.map +1 -0
  7. package/dist/client/index.d.ts +163 -0
  8. package/dist/client/index.d.ts.map +1 -0
  9. package/dist/client/index.js +316 -0
  10. package/dist/client/index.js.map +1 -0
  11. package/dist/component/_generated/api.d.ts +34 -0
  12. package/dist/component/_generated/api.d.ts.map +1 -0
  13. package/dist/component/_generated/api.js +31 -0
  14. package/dist/component/_generated/api.js.map +1 -0
  15. package/dist/component/_generated/component.d.ts +170 -0
  16. package/dist/component/_generated/component.d.ts.map +1 -0
  17. package/dist/component/_generated/component.js +11 -0
  18. package/dist/component/_generated/component.js.map +1 -0
  19. package/dist/component/_generated/dataModel.d.ts +46 -0
  20. package/dist/component/_generated/dataModel.d.ts.map +1 -0
  21. package/dist/component/_generated/dataModel.js +11 -0
  22. package/dist/component/_generated/dataModel.js.map +1 -0
  23. package/dist/component/_generated/server.d.ts +133 -0
  24. package/dist/component/_generated/server.d.ts.map +1 -0
  25. package/dist/component/_generated/server.js +80 -0
  26. package/dist/component/_generated/server.js.map +1 -0
  27. package/dist/component/convex.config.d.ts +3 -0
  28. package/dist/component/convex.config.d.ts.map +1 -0
  29. package/dist/component/convex.config.js +4 -0
  30. package/dist/component/convex.config.js.map +1 -0
  31. package/dist/component/lib.d.ts +146 -0
  32. package/dist/component/lib.d.ts.map +1 -0
  33. package/dist/component/lib.js +258 -0
  34. package/dist/component/lib.js.map +1 -0
  35. package/dist/component/schema.d.ts +75 -0
  36. package/dist/component/schema.d.ts.map +1 -0
  37. package/dist/component/schema.js +51 -0
  38. package/dist/component/schema.js.map +1 -0
  39. package/package.json +105 -0
  40. package/src/client/_generated/_ignore.ts +1 -0
  41. package/src/client/index.ts +460 -0
  42. package/src/client/setup.test.ts +26 -0
  43. package/src/component/_generated/api.ts +50 -0
  44. package/src/component/_generated/component.ts +224 -0
  45. package/src/component/_generated/dataModel.ts +60 -0
  46. package/src/component/_generated/server.ts +169 -0
  47. package/src/component/convex.config.ts +5 -0
  48. package/src/component/lib.test.ts +191 -0
  49. package/src/component/lib.ts +280 -0
  50. package/src/component/schema.ts +53 -0
  51. package/src/component/setup.test.ts +11 -0
  52. package/src/test.ts +18 -0
@@ -0,0 +1,258 @@
1
+ import { v } from "convex/values";
2
+ import { mutation, query } from "./_generated/server.js";
3
+ const issueValidator = v.object({
4
+ _id: v.id("issues"),
5
+ _creationTime: v.number(),
6
+ issueId: v.string(),
7
+ identifier: v.string(),
8
+ teamId: v.string(),
9
+ title: v.string(),
10
+ description: v.optional(v.string()),
11
+ state: v.string(),
12
+ priority: v.optional(v.number()),
13
+ assigneeId: v.optional(v.string()),
14
+ assigneeName: v.optional(v.string()),
15
+ labels: v.optional(v.array(v.string())),
16
+ url: v.string(),
17
+ archivedAt: v.optional(v.number()),
18
+ trashed: v.optional(v.boolean()),
19
+ createdAt: v.number(),
20
+ updatedAt: v.number(),
21
+ });
22
+ const commentValidator = v.object({
23
+ _id: v.id("comments"),
24
+ _creationTime: v.number(),
25
+ commentId: v.string(),
26
+ issueId: v.string(),
27
+ body: v.string(),
28
+ userId: v.optional(v.string()),
29
+ userName: v.optional(v.string()),
30
+ createdAt: v.number(),
31
+ updatedAt: v.number(),
32
+ });
33
+ // ─── Queries ────────────────────────────────────────────────────────────────
34
+ export const getIssue = query({
35
+ args: { issueId: v.string() },
36
+ returns: v.union(v.null(), issueValidator),
37
+ handler: async (ctx, args) => {
38
+ return await ctx.db
39
+ .query("issues")
40
+ .withIndex("by_issueId", (q) => q.eq("issueId", args.issueId))
41
+ .first();
42
+ },
43
+ });
44
+ export const listIssuesByTeam = query({
45
+ args: { teamId: v.string(), limit: v.optional(v.number()) },
46
+ returns: v.array(issueValidator),
47
+ handler: async (ctx, args) => {
48
+ return await ctx.db
49
+ .query("issues")
50
+ .withIndex("by_teamId", (q) => q.eq("teamId", args.teamId))
51
+ .order("desc")
52
+ .take(args.limit ?? 50);
53
+ },
54
+ });
55
+ export const listCommentsByIssue = query({
56
+ args: { issueId: v.string(), limit: v.optional(v.number()) },
57
+ returns: v.array(commentValidator),
58
+ handler: async (ctx, args) => {
59
+ return await ctx.db
60
+ .query("comments")
61
+ .withIndex("by_issueId", (q) => q.eq("issueId", args.issueId))
62
+ .order("desc")
63
+ .take(args.limit ?? 50);
64
+ },
65
+ });
66
+ // ─── Mutations ──────────────────────────────────────────────────────────────
67
+ export const recordIssue = mutation({
68
+ args: {
69
+ issueId: v.string(),
70
+ identifier: v.string(),
71
+ teamId: v.string(),
72
+ title: v.string(),
73
+ description: v.optional(v.string()),
74
+ state: v.string(),
75
+ priority: v.optional(v.number()),
76
+ assigneeId: v.optional(v.string()),
77
+ assigneeName: v.optional(v.string()),
78
+ labels: v.optional(v.array(v.string())),
79
+ url: v.string(),
80
+ archivedAt: v.optional(v.number()),
81
+ trashed: v.optional(v.boolean()),
82
+ },
83
+ returns: v.id("issues"),
84
+ handler: async (ctx, args) => {
85
+ const now = Date.now();
86
+ const existing = await ctx.db
87
+ .query("issues")
88
+ .withIndex("by_issueId", (q) => q.eq("issueId", args.issueId))
89
+ .first();
90
+ if (existing) {
91
+ // recordIssue is always called with a full, fresh snapshot from
92
+ // Linear (see issueRecordFromFragment in client/index.ts) — so every
93
+ // optional field is listed explicitly here, even when its value is
94
+ // undefined. A bare `...args` spread silently keeps whatever was
95
+ // already stored for a field Linear no longer reports (an unassigned
96
+ // issue, a cleared label list, a restored-from-trash issue), because
97
+ // an omitted optional argument never appears as a key on `args` at
98
+ // all — so spreading it into patch() doesn't touch the old value.
99
+ // Naming the field here forces the key to exist, which is what makes
100
+ // Convex's patch() actually clear it.
101
+ await ctx.db.patch(existing._id, {
102
+ identifier: args.identifier,
103
+ teamId: args.teamId,
104
+ title: args.title,
105
+ description: args.description,
106
+ state: args.state,
107
+ priority: args.priority,
108
+ assigneeId: args.assigneeId,
109
+ assigneeName: args.assigneeName,
110
+ labels: args.labels,
111
+ url: args.url,
112
+ archivedAt: args.archivedAt,
113
+ trashed: args.trashed,
114
+ updatedAt: now,
115
+ });
116
+ return existing._id;
117
+ }
118
+ return await ctx.db.insert("issues", { ...args, createdAt: now, updatedAt: now });
119
+ },
120
+ });
121
+ export const recordComment = mutation({
122
+ args: {
123
+ commentId: v.string(),
124
+ issueId: v.string(),
125
+ body: v.string(),
126
+ userId: v.optional(v.string()),
127
+ userName: v.optional(v.string()),
128
+ },
129
+ returns: v.id("comments"),
130
+ handler: async (ctx, args) => {
131
+ const now = Date.now();
132
+ const existing = await ctx.db
133
+ .query("comments")
134
+ .withIndex("by_commentId", (q) => q.eq("commentId", args.commentId))
135
+ .first();
136
+ if (existing) {
137
+ await ctx.db.patch(existing._id, { ...args, updatedAt: now });
138
+ return existing._id;
139
+ }
140
+ return await ctx.db.insert("comments", { ...args, createdAt: now, updatedAt: now });
141
+ },
142
+ });
143
+ export const removeIssue = mutation({
144
+ args: { issueId: v.string() },
145
+ returns: v.null(),
146
+ handler: async (ctx, args) => {
147
+ const existing = await ctx.db
148
+ .query("issues")
149
+ .withIndex("by_issueId", (q) => q.eq("issueId", args.issueId))
150
+ .first();
151
+ if (existing) {
152
+ await ctx.db.delete(existing._id);
153
+ }
154
+ return null;
155
+ },
156
+ });
157
+ // Marks an issue archived (or restores it, when archivedAt is null) without
158
+ // deleting the local row. Linear's own archive is a soft-hide (restorable via
159
+ // issueUnarchive), so the local mirror should reflect that instead of
160
+ // disappearing the issue entirely — removeIssue() stays reserved for Linear's
161
+ // actual delete/remove events.
162
+ export const setIssueArchived = mutation({
163
+ args: { issueId: v.string(), archivedAt: v.union(v.number(), v.null()) },
164
+ returns: v.null(),
165
+ handler: async (ctx, args) => {
166
+ const existing = await ctx.db
167
+ .query("issues")
168
+ .withIndex("by_issueId", (q) => q.eq("issueId", args.issueId))
169
+ .first();
170
+ if (!existing) {
171
+ return null;
172
+ }
173
+ await ctx.db.patch(existing._id, {
174
+ archivedAt: args.archivedAt ?? undefined,
175
+ updatedAt: Date.now(),
176
+ });
177
+ return null;
178
+ },
179
+ });
180
+ // ─── Dashboard queries ──────────────────────────────────────────────────────
181
+ // These do full, un-indexed scans across every issue/comment/event the
182
+ // component has ever recorded, on purpose — they power a demo's stats bar
183
+ // and activity history, not high-volume production use.
184
+ export const getStats = query({
185
+ args: {},
186
+ returns: v.object({
187
+ issueCount: v.number(),
188
+ archivedCount: v.number(),
189
+ commentCount: v.number(),
190
+ webhookEventCount: v.number(),
191
+ }),
192
+ handler: async (ctx) => {
193
+ const [issues, comments, webhookEvents] = await Promise.all([
194
+ ctx.db.query("issues").collect(),
195
+ ctx.db.query("comments").collect(),
196
+ ctx.db.query("webhookEvents").collect(),
197
+ ]);
198
+ return {
199
+ issueCount: issues.length,
200
+ archivedCount: issues.filter((issue) => issue.archivedAt !== undefined).length,
201
+ commentCount: comments.length,
202
+ webhookEventCount: webhookEvents.length,
203
+ };
204
+ },
205
+ });
206
+ export const listRecentIssues = query({
207
+ args: { limit: v.optional(v.number()) },
208
+ returns: v.array(issueValidator),
209
+ handler: async (ctx, args) => {
210
+ const issues = await ctx.db.query("issues").collect();
211
+ return issues.sort((a, b) => b.updatedAt - a.updatedAt).slice(0, args.limit ?? 20);
212
+ },
213
+ });
214
+ export const listRecentComments = query({
215
+ args: { limit: v.optional(v.number()) },
216
+ returns: v.array(commentValidator),
217
+ handler: async (ctx, args) => {
218
+ const comments = await ctx.db.query("comments").collect();
219
+ return comments.sort((a, b) => b.updatedAt - a.updatedAt).slice(0, args.limit ?? 20);
220
+ },
221
+ });
222
+ export const listRecentWebhookEvents = query({
223
+ args: { limit: v.optional(v.number()) },
224
+ returns: v.array(v.object({
225
+ _id: v.id("webhookEvents"),
226
+ _creationTime: v.number(),
227
+ eventId: v.string(),
228
+ eventType: v.string(),
229
+ action: v.optional(v.string()),
230
+ payload: v.string(),
231
+ receivedAt: v.number(),
232
+ })),
233
+ handler: async (ctx, args) => {
234
+ const events = await ctx.db.query("webhookEvents").collect();
235
+ return events.sort((a, b) => b.receivedAt - a.receivedAt).slice(0, args.limit ?? 20);
236
+ },
237
+ });
238
+ export const checkAndRecordEvent = mutation({
239
+ args: {
240
+ eventId: v.string(),
241
+ eventType: v.string(),
242
+ action: v.optional(v.string()),
243
+ payload: v.string(),
244
+ },
245
+ returns: v.object({ alreadyProcessed: v.boolean() }),
246
+ handler: async (ctx, args) => {
247
+ const existing = await ctx.db
248
+ .query("webhookEvents")
249
+ .withIndex("by_eventId", (q) => q.eq("eventId", args.eventId))
250
+ .first();
251
+ if (existing) {
252
+ return { alreadyProcessed: true };
253
+ }
254
+ await ctx.db.insert("webhookEvents", { ...args, receivedAt: Date.now() });
255
+ return { alreadyProcessed: false };
256
+ },
257
+ });
258
+ //# sourceMappingURL=lib.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../../src/component/lib.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ declare const _default: import("convex/server").SchemaDefinition<{
2
+ issues: import("convex/server").TableDefinition<import("convex/values").VObject<{
3
+ archivedAt?: number | undefined;
4
+ assigneeId?: string | undefined;
5
+ assigneeName?: string | undefined;
6
+ description?: string | undefined;
7
+ labels?: string[] | undefined;
8
+ priority?: number | undefined;
9
+ trashed?: boolean | undefined;
10
+ issueId: string;
11
+ teamId: string;
12
+ identifier: string;
13
+ state: string;
14
+ title: string;
15
+ url: string;
16
+ createdAt: number;
17
+ updatedAt: number;
18
+ }, {
19
+ issueId: import("convex/values").VString<string, "required">;
20
+ identifier: import("convex/values").VString<string, "required">;
21
+ teamId: import("convex/values").VString<string, "required">;
22
+ title: import("convex/values").VString<string, "required">;
23
+ description: import("convex/values").VString<string | undefined, "optional">;
24
+ state: import("convex/values").VString<string, "required">;
25
+ priority: import("convex/values").VFloat64<number | undefined, "optional">;
26
+ assigneeId: import("convex/values").VString<string | undefined, "optional">;
27
+ assigneeName: import("convex/values").VString<string | undefined, "optional">;
28
+ labels: import("convex/values").VArray<string[] | undefined, import("convex/values").VString<string, "required">, "optional">;
29
+ url: import("convex/values").VString<string, "required">;
30
+ archivedAt: import("convex/values").VFloat64<number | undefined, "optional">;
31
+ trashed: import("convex/values").VBoolean<boolean | undefined, "optional">;
32
+ createdAt: import("convex/values").VFloat64<number, "required">;
33
+ updatedAt: import("convex/values").VFloat64<number, "required">;
34
+ }, "required", "issueId" | "teamId" | "archivedAt" | "assigneeId" | "assigneeName" | "description" | "identifier" | "labels" | "priority" | "state" | "title" | "trashed" | "url" | "createdAt" | "updatedAt">, {
35
+ by_issueId: ["issueId", "_creationTime"];
36
+ by_teamId: ["teamId", "_creationTime"];
37
+ }, {}, {}>;
38
+ comments: import("convex/server").TableDefinition<import("convex/values").VObject<{
39
+ userId?: string | undefined;
40
+ userName?: string | undefined;
41
+ issueId: string;
42
+ body: string;
43
+ commentId: string;
44
+ createdAt: number;
45
+ updatedAt: number;
46
+ }, {
47
+ commentId: import("convex/values").VString<string, "required">;
48
+ issueId: import("convex/values").VString<string, "required">;
49
+ body: import("convex/values").VString<string, "required">;
50
+ userId: import("convex/values").VString<string | undefined, "optional">;
51
+ userName: import("convex/values").VString<string | undefined, "optional">;
52
+ createdAt: import("convex/values").VFloat64<number, "required">;
53
+ updatedAt: import("convex/values").VFloat64<number, "required">;
54
+ }, "required", "issueId" | "body" | "commentId" | "userId" | "userName" | "createdAt" | "updatedAt">, {
55
+ by_commentId: ["commentId", "_creationTime"];
56
+ by_issueId: ["issueId", "_creationTime"];
57
+ }, {}, {}>;
58
+ webhookEvents: import("convex/server").TableDefinition<import("convex/values").VObject<{
59
+ action?: string | undefined;
60
+ eventId: string;
61
+ eventType: string;
62
+ payload: string;
63
+ receivedAt: number;
64
+ }, {
65
+ eventId: import("convex/values").VString<string, "required">;
66
+ eventType: import("convex/values").VString<string, "required">;
67
+ action: import("convex/values").VString<string | undefined, "optional">;
68
+ payload: import("convex/values").VString<string, "required">;
69
+ receivedAt: import("convex/values").VFloat64<number, "required">;
70
+ }, "required", "action" | "eventId" | "eventType" | "payload" | "receivedAt">, {
71
+ by_eventId: ["eventId", "_creationTime"];
72
+ }, {}, {}>;
73
+ }, true>;
74
+ export default _default;
75
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/component/schema.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,wBAiDG"}
@@ -0,0 +1,51 @@
1
+ import { defineSchema, defineTable } from "convex/server";
2
+ import { v } from "convex/values";
3
+ export default defineSchema({
4
+ issues: defineTable({
5
+ issueId: v.string(), // Linear's UUID
6
+ identifier: v.string(), // e.g. "ENG-123"
7
+ teamId: v.string(),
8
+ title: v.string(),
9
+ description: v.optional(v.string()),
10
+ state: v.string(), // Linear workflow state name (team-defined, not a fixed enum)
11
+ priority: v.optional(v.number()), // Linear's own scale: 0 none, 1 urgent, 2 high, 3 normal, 4 low
12
+ assigneeId: v.optional(v.string()),
13
+ assigneeName: v.optional(v.string()),
14
+ labels: v.optional(v.array(v.string())),
15
+ url: v.string(),
16
+ // Set from Issue.archivedAt when Linear archives the issue (via the webhook or
17
+ // archiveIssue()) — archived issues are kept, not deleted, so a stale local
18
+ // mirror never quietly diverges from what's actually in Linear.
19
+ archivedAt: v.optional(v.number()),
20
+ // Linear's own "moved to trash" flag — distinct from archivedAt. A
21
+ // trashed issue is still recoverable for 30 days (and its own webhook
22
+ // delivery arrives as an "update", not "remove" — see client/index.ts).
23
+ trashed: v.optional(v.boolean()),
24
+ createdAt: v.number(),
25
+ updatedAt: v.number(),
26
+ })
27
+ .index("by_issueId", ["issueId"])
28
+ .index("by_teamId", ["teamId"]),
29
+ comments: defineTable({
30
+ commentId: v.string(), // Linear's UUID
31
+ issueId: v.string(),
32
+ body: v.string(),
33
+ userId: v.optional(v.string()),
34
+ userName: v.optional(v.string()),
35
+ createdAt: v.number(),
36
+ updatedAt: v.number(),
37
+ })
38
+ .index("by_commentId", ["commentId"])
39
+ .index("by_issueId", ["issueId"]),
40
+ webhookEvents: defineTable({
41
+ eventId: v.string(),
42
+ eventType: v.string(), // Linear-Event: "Issue" | "Comment" | ...
43
+ // payload.action: "create" | "update" | "remove" | "restore" — NOTE: for
44
+ // Issue events this does not reliably indicate archived vs trashed vs
45
+ // deleted (see client/index.ts); it's recorded here only for auditing.
46
+ action: v.optional(v.string()),
47
+ payload: v.string(),
48
+ receivedAt: v.number(),
49
+ }).index("by_eventId", ["eventId"]),
50
+ });
51
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/component/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAElC,eAAe,YAAY,CAAC;IAC1B,MAAM,EAAE,WAAW,CAAC;QAClB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,gBAAgB;QACrC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,iBAAiB;QACzC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QACnC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,8DAA8D;QACjF,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,gEAAgE;QAClG,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAClC,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QACpC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACvC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;QACf,+EAA+E;QAC/E,4EAA4E;QAC5E,gEAAgE;QAChE,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAClC,mEAAmE;QACnE,sEAAsE;QACtE,wEAAwE;QACxE,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAChC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;KACtB,CAAC;SACC,KAAK,CAAC,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC;SAChC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC;IAEjC,QAAQ,EAAE,WAAW,CAAC;QACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,gBAAgB;QACvC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC9B,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAChC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;KACtB,CAAC;SACC,KAAK,CAAC,cAAc,EAAE,CAAC,WAAW,CAAC,CAAC;SACpC,KAAK,CAAC,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC;IAEnC,aAAa,EAAE,WAAW,CAAC;QACzB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,0CAA0C;QACjE,yEAAyE;QACzE,sEAAsE;QACtE,uEAAuE;QACvE,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;KACvB,CAAC,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC;CACpC,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "convex-linear",
3
+ "description": "Sync Linear issues into Convex reactively, and create, update, and comment on issues from Convex functions.",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/sholajegede/convex-linear.git"
7
+ },
8
+ "homepage": "https://github.com/sholajegede/convex-linear#readme",
9
+ "bugs": {
10
+ "url": "https://github.com/sholajegede/convex-linear/issues"
11
+ },
12
+ "version": "0.0.1",
13
+ "license": "Apache-2.0",
14
+ "keywords": [
15
+ "convex",
16
+ "component",
17
+ "linear",
18
+ "issues",
19
+ "project-management",
20
+ "webhooks",
21
+ "devtools"
22
+ ],
23
+ "type": "module",
24
+ "scripts": {
25
+ "dev": "run-p -r 'dev:*'",
26
+ "dev:backend": "convex dev --typecheck-components",
27
+ "dev:frontend": "cd example && vite --clearScreen false",
28
+ "dev:build": "chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'npm run build:codegen' --initial",
29
+ "predev": "path-exists .env.local dist || (npm run build && convex dev --once)",
30
+ "build": "tsc --project ./tsconfig.build.json",
31
+ "build:codegen": "npx convex codegen --component-dir ./src/component && npm run build",
32
+ "build:clean": "rm -rf dist *.tsbuildinfo && npm run build:codegen",
33
+ "typecheck": "tsc --noEmit && tsc -p example && tsc -p example/convex",
34
+ "lint": "eslint .",
35
+ "all": "run-p -r 'dev:*' 'test:watch'",
36
+ "test": "vitest run --typecheck",
37
+ "test:watch": "vitest --typecheck --clearScreen false",
38
+ "test:debug": "vitest --inspect-brk --no-file-parallelism",
39
+ "test:coverage": "vitest run --coverage --coverage.reporter=text",
40
+ "preversion": "npm install --legacy-peer-deps && npm run build:clean && run-p test lint typecheck",
41
+ "prepublishOnly": "npm whoami || npm login",
42
+ "alpha": "npm version prerelease --preid alpha && npm publish --tag alpha && git push --follow-tags",
43
+ "release": "npm version patch && npm publish && git push --follow-tags",
44
+ "version": "vim -c 'normal o' -c 'normal o## '$npm_package_version CHANGELOG.md && prettier -w CHANGELOG.md && git add CHANGELOG.md"
45
+ },
46
+ "files": [
47
+ "dist",
48
+ "src"
49
+ ],
50
+ "exports": {
51
+ "./package.json": "./package.json",
52
+ ".": {
53
+ "types": "./dist/client/index.d.ts",
54
+ "default": "./dist/client/index.js"
55
+ },
56
+ "./test": "./src/test.ts",
57
+ "./_generated/component.js": {
58
+ "types": "./dist/component/_generated/component.d.ts"
59
+ },
60
+ "./_generated/component": {
61
+ "types": "./dist/component/_generated/component.d.ts"
62
+ },
63
+ "./convex.config.js": {
64
+ "types": "./dist/component/convex.config.d.ts",
65
+ "default": "./dist/component/convex.config.js"
66
+ },
67
+ "./convex.config": {
68
+ "types": "./dist/component/convex.config.d.ts",
69
+ "default": "./dist/component/convex.config.js"
70
+ }
71
+ },
72
+ "peerDependencies": {
73
+ "convex": "^1.34.1"
74
+ },
75
+ "devDependencies": {
76
+ "@convex-dev/eslint-plugin": "^1.2.0",
77
+ "@edge-runtime/vm": "^5.0.0",
78
+ "@eslint/eslintrc": "^3.3.5",
79
+ "@eslint/js": "9.39.4",
80
+ "@types/node": "^24.12.0",
81
+ "@types/react": "^19.2.14",
82
+ "@types/react-dom": "^19.2.3",
83
+ "@vitejs/plugin-react": "^5.2.0",
84
+ "chokidar-cli": "3.0.0",
85
+ "convex": "1.45.0",
86
+ "convex-test": "0.0.41",
87
+ "eslint": "9.39.4",
88
+ "eslint-plugin-react": "^7.37.5",
89
+ "eslint-plugin-react-hooks": "^7.0.1",
90
+ "eslint-plugin-react-refresh": "^0.5.2",
91
+ "globals": "^17.4.0",
92
+ "npm-run-all2": "8.0.4",
93
+ "path-exists-cli": "2.0.0",
94
+ "pkg-pr-new": "^0.0.66",
95
+ "prettier": "3.8.1",
96
+ "react": "^19.2.4",
97
+ "react-dom": "^19.2.4",
98
+ "typescript": "5.9.3",
99
+ "typescript-eslint": "8.57.1",
100
+ "vite": "7.3.1",
101
+ "vitest": "4.1.0"
102
+ },
103
+ "types": "./dist/client/index.d.ts",
104
+ "module": "./dist/client/index.js"
105
+ }
@@ -0,0 +1 @@
1
+ // This is only here so convex-test can detect a _generated folder