@useairfoil/producer-linear 0.0.1 → 0.0.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.
Files changed (50) hide show
  1. package/README.md +71 -0
  2. package/dist/index.d.mts +4027 -0
  3. package/dist/index.mjs +3 -0
  4. package/dist/main.d.mts +1 -0
  5. package/dist/main.mjs +1303 -0
  6. package/dist/main.mjs.map +1 -0
  7. package/dist/manifest.d.mts +114 -0
  8. package/dist/manifest.mjs +161 -0
  9. package/dist/manifest.mjs.map +1 -0
  10. package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
  11. package/dist/src-Ci3_ltan.mjs +1691 -0
  12. package/dist/src-Ci3_ltan.mjs.map +1 -0
  13. package/package.json +45 -7
  14. package/src/client/client.ts +200 -0
  15. package/src/connector.ts +151 -0
  16. package/src/create-table.ts +5 -0
  17. package/src/demo/index.ts +137 -0
  18. package/src/demo/initiatives.ts +116 -0
  19. package/src/demo/issues.ts +320 -0
  20. package/src/demo/projects.ts +215 -0
  21. package/src/demo/setup.ts +151 -0
  22. package/src/demo/shared.ts +122 -0
  23. package/src/demo/teams.ts +173 -0
  24. package/src/index.ts +83 -0
  25. package/src/main.ts +22 -0
  26. package/src/manifest.ts +58 -0
  27. package/src/resources/comments.ts +32 -0
  28. package/src/resources/customers.ts +105 -0
  29. package/src/resources/documents.ts +31 -0
  30. package/src/resources/initiatives.ts +136 -0
  31. package/src/resources/issue-history.ts +119 -0
  32. package/src/resources/issues.ts +131 -0
  33. package/src/resources/pages.ts +264 -0
  34. package/src/resources/projects.ts +161 -0
  35. package/src/resources/releases.ts +114 -0
  36. package/src/resources/teams.ts +140 -0
  37. package/src/sandbox.ts +35 -0
  38. package/src/schemas/comments.ts +32 -0
  39. package/src/schemas/customers.ts +80 -0
  40. package/src/schemas/documents.ts +32 -0
  41. package/src/schemas/initiatives.ts +119 -0
  42. package/src/schemas/issues.ts +180 -0
  43. package/src/schemas/projects.ts +154 -0
  44. package/src/schemas/releases.ts +119 -0
  45. package/src/schemas/shared.ts +66 -0
  46. package/src/schemas/teams.ts +144 -0
  47. package/src/start.ts +47 -0
  48. package/src/tables.ts +83 -0
  49. package/src/webhook/route.ts +50 -0
  50. package/src/webhook/signature.ts +28 -0
@@ -0,0 +1,151 @@
1
+ import { Connector, type ResourceDefinition } from "@useairfoil/connector-kit";
2
+ import { Config, Context, Effect, Layer, Redacted } from "effect";
3
+
4
+ import type { LinearConfig } from "./manifest";
5
+
6
+ import * as LinearClient from "./client/client";
7
+ import { makeComments } from "./resources/comments";
8
+ import {
9
+ makeCustomerNeeds,
10
+ makeCustomerStatuses,
11
+ makeCustomerTiers,
12
+ makeCustomers,
13
+ } from "./resources/customers";
14
+ import { makeDocuments } from "./resources/documents";
15
+ import {
16
+ makeInitiativeLabels,
17
+ makeInitiativeRelations,
18
+ makeInitiativeToProjects,
19
+ makeInitiativeUpdates,
20
+ makeInitiatives,
21
+ } from "./resources/initiatives";
22
+ import { makeIssueHistory } from "./resources/issue-history";
23
+ import {
24
+ makeAttachments,
25
+ makeIssueLabels,
26
+ makeIssueRelations,
27
+ makeIssues,
28
+ } from "./resources/issues";
29
+ import {
30
+ makeProjectLabels,
31
+ makeProjectMilestones,
32
+ makeProjectRelations,
33
+ makeProjectStatuses,
34
+ makeProjectUpdates,
35
+ makeProjects,
36
+ } from "./resources/projects";
37
+ import {
38
+ makeIssueToReleases,
39
+ makeReleaseNotes,
40
+ makeReleasePipelines,
41
+ makeReleaseStages,
42
+ makeReleases,
43
+ } from "./resources/releases";
44
+ import {
45
+ makeCycles,
46
+ makeExternalUsers,
47
+ makeTeamMemberships,
48
+ makeTeams,
49
+ makeUsers,
50
+ makeWorkflowStates,
51
+ } from "./resources/teams";
52
+ import { makeWebhookRoute } from "./webhook/route";
53
+ export { LinearConfigDef, manifest } from "./manifest";
54
+ export type { LinearConfig } from "./manifest";
55
+
56
+ export const make = Effect.fnUntraced(function* (config: LinearConfig) {
57
+ const client = yield* LinearClient.LinearClient;
58
+
59
+ const Issues = makeIssues(client);
60
+ const IssueHistory = makeIssueHistory(client);
61
+ const Comments = makeComments(client);
62
+ const Attachments = makeAttachments(client);
63
+ const IssueLabels = makeIssueLabels(client);
64
+ const Users = makeUsers(client);
65
+ const Cycles = makeCycles(client);
66
+ const Projects = makeProjects(client);
67
+ const ProjectUpdates = makeProjectUpdates(client);
68
+ const ProjectLabels = makeProjectLabels(client);
69
+ const Initiatives = makeInitiatives(client);
70
+ const InitiativeUpdates = makeInitiativeUpdates(client);
71
+ const Documents = makeDocuments(client);
72
+ const Customers = makeCustomers(client);
73
+ const CustomerNeeds = makeCustomerNeeds(client);
74
+
75
+ return Connector.define({
76
+ name: "producer-linear",
77
+ title: "Linear",
78
+ resources: [
79
+ Issues,
80
+ IssueHistory,
81
+ Comments,
82
+ makeIssueRelations(client),
83
+ Attachments,
84
+ IssueLabels,
85
+ makeWorkflowStates(client),
86
+ makeTeams(client),
87
+ makeTeamMemberships(client),
88
+ Users,
89
+ makeExternalUsers(client),
90
+ Cycles,
91
+ Projects,
92
+ makeProjectMilestones(client),
93
+ ProjectUpdates,
94
+ makeProjectStatuses(client),
95
+ ProjectLabels,
96
+ makeProjectRelations(client),
97
+ Initiatives,
98
+ InitiativeUpdates,
99
+ makeInitiativeLabels(client),
100
+ makeInitiativeRelations(client),
101
+ makeInitiativeToProjects(client),
102
+ Documents,
103
+ Customers,
104
+ CustomerNeeds,
105
+ makeCustomerStatuses(client),
106
+ makeCustomerTiers(client),
107
+ makeReleases(client),
108
+ makeReleaseNotes(client),
109
+ makeReleasePipelines(client),
110
+ makeReleaseStages(client),
111
+ makeIssueToReleases(client),
112
+ ],
113
+ webhooks: [
114
+ makeWebhookRoute({
115
+ secret: Redacted.value(config.webhookSecret),
116
+ issueHistory: IssueHistory,
117
+ // Release webhooks need the Business plan.
118
+ targets: new Map<string, ResourceDefinition>([
119
+ ["Issue", Issues],
120
+ ["Comment", Comments],
121
+ ["Attachment", Attachments],
122
+ ["IssueLabel", IssueLabels],
123
+ ["User", Users],
124
+ ["Cycle", Cycles],
125
+ ["Project", Projects],
126
+ ["ProjectUpdate", ProjectUpdates],
127
+ ["ProjectLabel", ProjectLabels],
128
+ ["Initiative", Initiatives],
129
+ ["InitiativeUpdate", InitiativeUpdates],
130
+ ["Document", Documents],
131
+ ["Customer", Customers],
132
+ ["CustomerNeed", CustomerNeeds],
133
+ ]),
134
+ }),
135
+ ],
136
+ });
137
+ });
138
+
139
+ export type LinearConnectorRuntime = Effect.Success<ReturnType<typeof make>>;
140
+
141
+ export class LinearConnector extends Context.Service<LinearConnector, LinearConnectorRuntime>()(
142
+ "@useairfoil/producer-linear/LinearConnector",
143
+ ) {}
144
+
145
+ export const layer = (config: LinearConfig) =>
146
+ Layer.effect(LinearConnector)(
147
+ make(config).pipe(Effect.annotateLogs({ component: "linear" })),
148
+ ).pipe(Layer.provide(LinearClient.layer(config)));
149
+
150
+ export const layerConfig = (config: Config.Wrap<LinearConfig>) =>
151
+ Layer.unwrap(Config.unwrap(config).pipe(Effect.map(layer)));
@@ -0,0 +1,5 @@
1
+ import { ConnectorApp } from "@useairfoil/connector-kit";
2
+
3
+ import { tableSchemas } from "./tables";
4
+
5
+ export const createTableCommand = ConnectorApp.makeCreateTableCommand(tableSchemas);
@@ -0,0 +1,137 @@
1
+ import { ConnectorApp, Demo, RuntimeConfig } from "@useairfoil/connector-kit";
2
+ import { Command } from "effect/cli";
3
+
4
+ import { CommentSchema } from "../schemas/comments";
5
+ import {
6
+ CustomerNeedSchema,
7
+ CustomerSchema,
8
+ CustomerStatusSchema,
9
+ CustomerTierSchema,
10
+ } from "../schemas/customers";
11
+ import { DocumentSchema } from "../schemas/documents";
12
+ import {
13
+ InitiativeLabelSchema,
14
+ InitiativeRelationSchema,
15
+ InitiativeSchema,
16
+ InitiativeToProjectSchema,
17
+ InitiativeUpdateSchema,
18
+ } from "../schemas/initiatives";
19
+ import {
20
+ AttachmentSchema,
21
+ IssueHistorySchema,
22
+ IssueLabelSchema,
23
+ IssueRelationSchema,
24
+ IssueSchema,
25
+ } from "../schemas/issues";
26
+ import {
27
+ ProjectLabelSchema,
28
+ ProjectMilestoneSchema,
29
+ ProjectRelationSchema,
30
+ ProjectSchema,
31
+ ProjectStatusSchema,
32
+ ProjectUpdateSchema,
33
+ } from "../schemas/projects";
34
+ import {
35
+ IssueToReleaseSchema,
36
+ ReleaseNoteSchema,
37
+ ReleasePipelineSchema,
38
+ ReleaseSchema,
39
+ ReleaseStageSchema,
40
+ } from "../schemas/releases";
41
+ import {
42
+ CycleSchema,
43
+ ExternalUserSchema,
44
+ TeamMembershipSchema,
45
+ TeamSchema,
46
+ UserSchema,
47
+ WorkflowStateSchema,
48
+ } from "../schemas/teams";
49
+ import { issueRows } from "./issues";
50
+ import { setupRows } from "./setup";
51
+
52
+ export const demo = Demo.define({
53
+ name: "producer-linear",
54
+ setup: {
55
+ tables: [
56
+ Demo.table({ name: "teams", rowSchema: TeamSchema, version: "version" }),
57
+ Demo.table({ name: "workflow_states", rowSchema: WorkflowStateSchema, version: "version" }),
58
+ Demo.table({ name: "users", rowSchema: UserSchema, version: "version" }),
59
+ Demo.table({ name: "team_memberships", rowSchema: TeamMembershipSchema, version: "version" }),
60
+ Demo.table({ name: "external_users", rowSchema: ExternalUserSchema, version: "version" }),
61
+ Demo.table({ name: "issue_labels", rowSchema: IssueLabelSchema, version: "version" }),
62
+ Demo.table({ name: "cycles", rowSchema: CycleSchema, version: "version" }),
63
+ Demo.table({ name: "project_statuses", rowSchema: ProjectStatusSchema, version: "version" }),
64
+ Demo.table({ name: "project_labels", rowSchema: ProjectLabelSchema, version: "version" }),
65
+ Demo.table({ name: "projects", rowSchema: ProjectSchema, version: "version" }),
66
+ Demo.table({
67
+ name: "project_milestones",
68
+ rowSchema: ProjectMilestoneSchema,
69
+ version: "version",
70
+ }),
71
+ Demo.table({ name: "project_updates", rowSchema: ProjectUpdateSchema, version: "version" }),
72
+ Demo.table({
73
+ name: "project_relations",
74
+ rowSchema: ProjectRelationSchema,
75
+ version: "version",
76
+ }),
77
+ Demo.table({ name: "documents", rowSchema: DocumentSchema, version: "version" }),
78
+ Demo.table({ name: "initiatives", rowSchema: InitiativeSchema, version: "version" }),
79
+ Demo.table({
80
+ name: "initiative_labels",
81
+ rowSchema: InitiativeLabelSchema,
82
+ version: "version",
83
+ }),
84
+ Demo.table({
85
+ name: "initiative_updates",
86
+ rowSchema: InitiativeUpdateSchema,
87
+ version: "version",
88
+ }),
89
+ Demo.table({
90
+ name: "initiative_relations",
91
+ rowSchema: InitiativeRelationSchema,
92
+ version: "version",
93
+ }),
94
+ Demo.table({
95
+ name: "initiative_to_projects",
96
+ rowSchema: InitiativeToProjectSchema,
97
+ version: "version",
98
+ }),
99
+ Demo.table({
100
+ name: "customer_statuses",
101
+ rowSchema: CustomerStatusSchema,
102
+ version: "version",
103
+ }),
104
+ Demo.table({ name: "customer_tiers", rowSchema: CustomerTierSchema, version: "version" }),
105
+ Demo.table({ name: "customers", rowSchema: CustomerSchema, version: "version" }),
106
+ Demo.table({
107
+ name: "release_pipelines",
108
+ rowSchema: ReleasePipelineSchema,
109
+ version: "version",
110
+ }),
111
+ Demo.table({ name: "release_stages", rowSchema: ReleaseStageSchema, version: "version" }),
112
+ Demo.table({ name: "releases", rowSchema: ReleaseSchema, version: "version" }),
113
+ Demo.table({ name: "release_notes", rowSchema: ReleaseNoteSchema, version: "version" }),
114
+ ],
115
+ rows: setupRows,
116
+ },
117
+ group: {
118
+ tables: [
119
+ Demo.table({ name: "issues", rowSchema: IssueSchema, version: "version" }),
120
+ Demo.table({ name: "issue_history", rowSchema: IssueHistorySchema, version: "version" }),
121
+ Demo.table({ name: "comments", rowSchema: CommentSchema, version: "version" }),
122
+ Demo.table({ name: "issue_relations", rowSchema: IssueRelationSchema, version: "version" }),
123
+ Demo.table({ name: "attachments", rowSchema: AttachmentSchema, version: "version" }),
124
+ Demo.table({ name: "customer_needs", rowSchema: CustomerNeedSchema, version: "version" }),
125
+ Demo.table({
126
+ name: "issue_to_releases",
127
+ rowSchema: IssueToReleaseSchema,
128
+ version: "version",
129
+ }),
130
+ ],
131
+ rows: issueRows,
132
+ },
133
+ });
134
+
135
+ export const demoCommand = ConnectorApp.makeDemoCommand(demo).pipe(
136
+ Command.provide(RuntimeConfig.layerHosted()),
137
+ );
@@ -0,0 +1,116 @@
1
+ import type { Demo } from "@useairfoil/connector-kit";
2
+
3
+ import type {
4
+ Initiative,
5
+ InitiativeLabel,
6
+ InitiativeRelation,
7
+ InitiativeToProject,
8
+ InitiativeUpdate,
9
+ } from "../schemas/initiatives";
10
+
11
+ import {
12
+ dateOnly,
13
+ day,
14
+ initiativeId,
15
+ projectId,
16
+ projects,
17
+ stamp,
18
+ userId,
19
+ uuid,
20
+ workspace,
21
+ } from "./shared";
22
+
23
+ /** Initiatives with their labels, updates, relations, and projects. */
24
+ export const initiativeTables = ({ now }: Demo.DemoContext, founded: Date) => {
25
+ const set = stamp(founded, founded);
26
+
27
+ const initiatives = [
28
+ "Enterprise readiness",
29
+ "Self-serve growth",
30
+ "Platform reliability",
31
+ ] as const;
32
+
33
+ const initiativeRows: Array<Initiative> = initiatives.map((name, i) => ({
34
+ id: initiativeId(i),
35
+ ...stamp(founded, now),
36
+ _deleted: false,
37
+ name,
38
+ description: `${name} for this year`,
39
+ content: null,
40
+ url: `${workspace}/initiative/${name.toLowerCase().replaceAll(" ", "-")}`,
41
+ icon: null,
42
+ color: null,
43
+ status: "Active",
44
+ health: "onTrack",
45
+ health_updated_at: new Date(now.getTime() - 7 * day),
46
+ priority: BigInt(i + 1),
47
+ owner_id: userId(i),
48
+ creator_id: userId(0),
49
+ parent_initiative_id: null,
50
+ target_date: dateOnly(new Date(now.getTime() + 90 * day)),
51
+ started_at: founded,
52
+ completed_at: null,
53
+ canceled_at: null,
54
+ label_ids: [uuid(20, i % 2)],
55
+ visibility: "workspace",
56
+ trashed: false,
57
+ }));
58
+
59
+ const initiativeLabels: Array<InitiativeLabel> = ["Company goal", "Team goal"].map((name, l) => ({
60
+ id: uuid(20, l),
61
+ ...set,
62
+ name,
63
+ description: null,
64
+ color: "#5E6AD2",
65
+ is_group: false,
66
+ parent_id: null,
67
+ creator_id: userId(0),
68
+ retired_at: null,
69
+ }));
70
+
71
+ const initiativeUpdates: Array<InitiativeUpdate> = initiatives.flatMap((_, i) =>
72
+ Array.from({ length: 6 }, (_, k) => {
73
+ const posted = new Date(now.getTime() - (6 - k) * 30 * day);
74
+
75
+ return {
76
+ id: uuid(21, i, k),
77
+ ...stamp(posted, posted),
78
+ _deleted: false,
79
+ initiative_id: initiativeId(i),
80
+ user_id: userId(i),
81
+ body: "Monthly check-in: projects are moving and the main risks are covered.",
82
+ health: "onTrack",
83
+ url: `${workspace}/initiative/${i}/updates#${k}`,
84
+ edited_at: null,
85
+ comment_count: 0n,
86
+ };
87
+ }),
88
+ );
89
+
90
+ const initiativeRelations: Array<InitiativeRelation> = [
91
+ {
92
+ id: uuid(22, 0),
93
+ ...set,
94
+ initiative_id: initiativeId(0),
95
+ related_initiative_id: initiativeId(2),
96
+ sort_order: 0,
97
+ user_id: userId(0),
98
+ },
99
+ ];
100
+
101
+ const initiativeProjects: Array<InitiativeToProject> = projects.map((_, p) => ({
102
+ id: uuid(23, p),
103
+ ...set,
104
+ initiative_id: initiativeId(p % initiatives.length),
105
+ project_id: projectId(p),
106
+ sort_order: String(p),
107
+ }));
108
+
109
+ return {
110
+ initiatives: initiativeRows,
111
+ initiative_labels: initiativeLabels,
112
+ initiative_updates: initiativeUpdates,
113
+ initiative_relations: initiativeRelations,
114
+ initiative_to_projects: initiativeProjects,
115
+ };
116
+ };