@baack-software/baack-ts-tasks 0.0.0-stage → 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.
- package/LICENSE +201 -0
- package/README.md +158 -2
- package/dist/activity.d.ts +20 -0
- package/dist/activity.d.ts.map +1 -0
- package/dist/activity.js +75 -0
- package/dist/activity.js.map +1 -0
- package/dist/blockers.d.ts +28 -0
- package/dist/blockers.d.ts.map +1 -0
- package/dist/blockers.js +134 -0
- package/dist/blockers.js.map +1 -0
- package/dist/conflicts.d.ts +50 -0
- package/dist/conflicts.d.ts.map +1 -0
- package/dist/conflicts.js +73 -0
- package/dist/conflicts.js.map +1 -0
- package/dist/draft.d.ts +45 -0
- package/dist/draft.d.ts.map +1 -0
- package/dist/draft.js +155 -0
- package/dist/draft.js.map +1 -0
- package/dist/errors.d.ts +30 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +37 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/react/TaskActivity.d.ts +15 -0
- package/dist/react/TaskActivity.d.ts.map +1 -0
- package/dist/react/TaskActivity.js +60 -0
- package/dist/react/TaskActivity.js.map +1 -0
- package/dist/react/TaskBoard.d.ts +38 -0
- package/dist/react/TaskBoard.d.ts.map +1 -0
- package/dist/react/TaskBoard.js +85 -0
- package/dist/react/TaskBoard.js.map +1 -0
- package/dist/react/TaskConflicts.d.ts +26 -0
- package/dist/react/TaskConflicts.d.ts.map +1 -0
- package/dist/react/TaskConflicts.js +87 -0
- package/dist/react/TaskConflicts.js.map +1 -0
- package/dist/react/TaskCreateForm.d.ts +13 -0
- package/dist/react/TaskCreateForm.d.ts.map +1 -0
- package/dist/react/TaskCreateForm.js +68 -0
- package/dist/react/TaskCreateForm.js.map +1 -0
- package/dist/react/TaskEditor.d.ts +33 -0
- package/dist/react/TaskEditor.d.ts.map +1 -0
- package/dist/react/TaskEditor.js +172 -0
- package/dist/react/TaskEditor.js.map +1 -0
- package/dist/react/TaskFilters.d.ts +15 -0
- package/dist/react/TaskFilters.d.ts.map +1 -0
- package/dist/react/TaskFilters.js +48 -0
- package/dist/react/TaskFilters.js.map +1 -0
- package/dist/react/TaskView.d.ts +30 -0
- package/dist/react/TaskView.d.ts.map +1 -0
- package/dist/react/TaskView.js +108 -0
- package/dist/react/TaskView.js.map +1 -0
- package/dist/react/TasksAbout.d.ts +24 -0
- package/dist/react/TasksAbout.d.ts.map +1 -0
- package/dist/react/TasksAbout.js +82 -0
- package/dist/react/TasksAbout.js.map +1 -0
- package/dist/react/copy.d.ts +154 -0
- package/dist/react/copy.d.ts.map +1 -0
- package/dist/react/copy.js +173 -0
- package/dist/react/copy.js.map +1 -0
- package/dist/react/fields.d.ts +36 -0
- package/dist/react/fields.d.ts.map +1 -0
- package/dist/react/fields.js +21 -0
- package/dist/react/fields.js.map +1 -0
- package/dist/react/hooks.d.ts +9 -0
- package/dist/react/hooks.d.ts.map +1 -0
- package/dist/react/hooks.js +31 -0
- package/dist/react/hooks.js.map +1 -0
- package/dist/react/index.d.ts +13 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +13 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/parts.d.ts +55 -0
- package/dist/react/parts.d.ts.map +1 -0
- package/dist/react/parts.js +92 -0
- package/dist/react/parts.js.map +1 -0
- package/dist/react/ui/alert.d.ts +11 -0
- package/dist/react/ui/alert.d.ts.map +1 -0
- package/dist/react/ui/alert.js +29 -0
- package/dist/react/ui/alert.js.map +1 -0
- package/dist/react/ui/avatar.d.ts +12 -0
- package/dist/react/ui/avatar.d.ts.map +1 -0
- package/dist/react/ui/avatar.js +24 -0
- package/dist/react/ui/avatar.js.map +1 -0
- package/dist/react/ui/badge.d.ts +10 -0
- package/dist/react/ui/badge.d.ts.map +1 -0
- package/dist/react/ui/badge.js +26 -0
- package/dist/react/ui/badge.js.map +1 -0
- package/dist/react/ui/button.d.ts +11 -0
- package/dist/react/ui/button.d.ts.map +1 -0
- package/dist/react/ui/button.js +37 -0
- package/dist/react/ui/button.js.map +1 -0
- package/dist/react/ui/card.d.ts +12 -0
- package/dist/react/ui/card.d.ts.map +1 -0
- package/dist/react/ui/card.js +26 -0
- package/dist/react/ui/card.js.map +1 -0
- package/dist/react/ui/input.d.ts +4 -0
- package/dist/react/ui/input.d.ts.map +1 -0
- package/dist/react/ui/input.js +8 -0
- package/dist/react/ui/input.js.map +1 -0
- package/dist/react/ui/label.d.ts +5 -0
- package/dist/react/ui/label.d.ts.map +1 -0
- package/dist/react/ui/label.js +10 -0
- package/dist/react/ui/label.js.map +1 -0
- package/dist/react/ui/radio-group.d.ts +6 -0
- package/dist/react/ui/radio-group.d.ts.map +1 -0
- package/dist/react/ui/radio-group.js +12 -0
- package/dist/react/ui/radio-group.js.map +1 -0
- package/dist/react/ui/select.d.ts +16 -0
- package/dist/react/ui/select.d.ts.map +1 -0
- package/dist/react/ui/select.js +37 -0
- package/dist/react/ui/select.js.map +1 -0
- package/dist/react/ui/separator.d.ts +5 -0
- package/dist/react/ui/separator.d.ts.map +1 -0
- package/dist/react/ui/separator.js +10 -0
- package/dist/react/ui/separator.js.map +1 -0
- package/dist/react/ui/sheet.d.ts +15 -0
- package/dist/react/ui/sheet.d.ts.map +1 -0
- package/dist/react/ui/sheet.js +38 -0
- package/dist/react/ui/sheet.js.map +1 -0
- package/dist/react/ui/skeleton.d.ts +3 -0
- package/dist/react/ui/skeleton.d.ts.map +1 -0
- package/dist/react/ui/skeleton.js +7 -0
- package/dist/react/ui/skeleton.js.map +1 -0
- package/dist/react/ui/table.d.ts +11 -0
- package/dist/react/ui/table.d.ts.map +1 -0
- package/dist/react/ui/table.js +29 -0
- package/dist/react/ui/table.js.map +1 -0
- package/dist/react/ui/tabs.d.ts +12 -0
- package/dist/react/ui/tabs.d.ts.map +1 -0
- package/dist/react/ui/tabs.js +31 -0
- package/dist/react/ui/tabs.js.map +1 -0
- package/dist/react/ui/textarea.d.ts +4 -0
- package/dist/react/ui/textarea.d.ts.map +1 -0
- package/dist/react/ui/textarea.js +8 -0
- package/dist/react/ui/textarea.js.map +1 -0
- package/dist/react/ui/toggle-group.d.ts +11 -0
- package/dist/react/ui/toggle-group.d.ts.map +1 -0
- package/dist/react/ui/toggle-group.js +25 -0
- package/dist/react/ui/toggle-group.js.map +1 -0
- package/dist/react/ui/toggle.d.ts +10 -0
- package/dist/react/ui/toggle.d.ts.map +1 -0
- package/dist/react/ui/toggle.js +27 -0
- package/dist/react/ui/toggle.js.map +1 -0
- package/dist/refs.d.ts +16 -0
- package/dist/refs.d.ts.map +1 -0
- package/dist/refs.js +43 -0
- package/dist/refs.js.map +1 -0
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +4 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/recipes.d.ts +39 -0
- package/dist/server/recipes.d.ts.map +1 -0
- package/dist/server/recipes.js +81 -0
- package/dist/server/recipes.js.map +1 -0
- package/dist/server/webhooks.d.ts +135 -0
- package/dist/server/webhooks.d.ts.map +1 -0
- package/dist/server/webhooks.js +243 -0
- package/dist/server/webhooks.js.map +1 -0
- package/dist/store.d.ts +124 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +443 -0
- package/dist/store.js.map +1 -0
- package/dist/task-client.d.ts +137 -0
- package/dist/task-client.d.ts.map +1 -0
- package/dist/task-client.js +271 -0
- package/dist/task-client.js.map +1 -0
- package/dist/tasks.d.ts +84 -0
- package/dist/tasks.d.ts.map +1 -0
- package/dist/tasks.js +208 -0
- package/dist/tasks.js.map +1 -0
- package/dist/time.d.ts +15 -0
- package/dist/time.d.ts.map +1 -0
- package/dist/time.js +34 -0
- package/dist/time.js.map +1 -0
- package/dist/types.d.ts +74 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/package.json +101 -4
- package/src/activity.ts +86 -0
- package/src/blockers.ts +134 -0
- package/src/conflicts.ts +115 -0
- package/src/draft.ts +162 -0
- package/src/errors.ts +40 -0
- package/src/index.ts +10 -0
- package/src/react/TaskActivity.tsx +187 -0
- package/src/react/TaskBoard.tsx +264 -0
- package/src/react/TaskConflicts.tsx +217 -0
- package/src/react/TaskCreateForm.tsx +165 -0
- package/src/react/TaskEditor.tsx +485 -0
- package/src/react/TaskFilters.tsx +122 -0
- package/src/react/TaskView.tsx +291 -0
- package/src/react/TasksAbout.tsx +226 -0
- package/src/react/copy.tsx +253 -0
- package/src/react/fields.tsx +104 -0
- package/src/react/hooks.ts +41 -0
- package/src/react/index.ts +12 -0
- package/src/react/parts.tsx +176 -0
- package/src/react/ui/README.md +6 -0
- package/src/react/ui/alert.tsx +75 -0
- package/src/react/ui/avatar.tsx +109 -0
- package/src/react/ui/badge.tsx +48 -0
- package/src/react/ui/button.tsx +66 -0
- package/src/react/ui/card.tsx +102 -0
- package/src/react/ui/input.tsx +18 -0
- package/src/react/ui/label.tsx +23 -0
- package/src/react/ui/radio-group.tsx +41 -0
- package/src/react/ui/select.tsx +189 -0
- package/src/react/ui/separator.tsx +27 -0
- package/src/react/ui/sheet.tsx +145 -0
- package/src/react/ui/skeleton.tsx +13 -0
- package/src/react/ui/table.tsx +113 -0
- package/src/react/ui/tabs.tsx +89 -0
- package/src/react/ui/textarea.tsx +17 -0
- package/src/react/ui/toggle-group.tsx +89 -0
- package/src/react/ui/toggle.tsx +44 -0
- package/src/refs.ts +49 -0
- package/src/server/index.ts +3 -0
- package/src/server/recipes.ts +107 -0
- package/src/server/webhooks.ts +369 -0
- package/src/store.ts +538 -0
- package/src/task-client.ts +373 -0
- package/src/tasks.ts +263 -0
- package/src/time.ts +35 -0
- package/src/types.ts +101 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textarea.js","sourceRoot":"","sources":["../../../src/react/ui/textarea.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,EAAE,EAAE,MAAM,IAAI,CAAA;AAEvB,SAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAoC;IACzE,OAAO,CACL,gCACY,UAAU,EACpB,SAAS,EAAE,EAAE,CACX,whBAAwhB,EACxhB,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type VariantProps } from "class-variance-authority";
|
|
3
|
+
import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui";
|
|
4
|
+
import { toggleVariants } from "./toggle.tsx";
|
|
5
|
+
declare function ToggleGroup({ className, variant, size, spacing, orientation, children, ...props }: React.ComponentProps<typeof ToggleGroupPrimitive.Root> & VariantProps<typeof toggleVariants> & {
|
|
6
|
+
spacing?: number;
|
|
7
|
+
orientation?: "horizontal" | "vertical";
|
|
8
|
+
}): React.JSX.Element;
|
|
9
|
+
declare function ToggleGroupItem({ className, children, variant, size, ...props }: React.ComponentProps<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>): React.JSX.Element;
|
|
10
|
+
export { ToggleGroup, ToggleGroupItem };
|
|
11
|
+
//# sourceMappingURL=toggle-group.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toggle-group.d.ts","sourceRoot":"","sources":["../../../src/react/ui/toggle-group.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAE5D,OAAO,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAc7C,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,OAAO,EACP,IAAI,EACJ,OAAW,EACX,WAA0B,EAC1B,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,IAAI,CAAC,GACvD,YAAY,CAAC,OAAO,cAAc,CAAC,GAAG;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAA;CACxC,qBAsBF;AAED,iBAAS,eAAe,CAAC,EACvB,SAAS,EACT,QAAQ,EACR,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,IAAI,CAAC,GACvD,YAAY,CAAC,OAAO,cAAc,CAAC,qBAsBpC;AAED,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import {} from "class-variance-authority";
|
|
5
|
+
import { cn } from "cn";
|
|
6
|
+
import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui";
|
|
7
|
+
import { toggleVariants } from "./toggle.js";
|
|
8
|
+
const ToggleGroupContext = React.createContext({
|
|
9
|
+
size: "default",
|
|
10
|
+
variant: "default",
|
|
11
|
+
spacing: 2,
|
|
12
|
+
orientation: "horizontal",
|
|
13
|
+
});
|
|
14
|
+
function ToggleGroup({ className, variant, size, spacing = 2, orientation = "horizontal", children, ...props }) {
|
|
15
|
+
return (_jsx(ToggleGroupPrimitive.Root, { "data-slot": "toggle-group", "data-variant": variant, "data-size": size, "data-spacing": spacing, "data-orientation": orientation, style: { "--gap": spacing }, className: cn("group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-lg data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-vertical:flex-col data-vertical:items-stretch", className), ...props, children: _jsx(ToggleGroupContext.Provider, { value: { variant, size, spacing, orientation }, children: children }) }));
|
|
16
|
+
}
|
|
17
|
+
function ToggleGroupItem({ className, children, variant = "default", size = "default", ...props }) {
|
|
18
|
+
const context = React.useContext(ToggleGroupContext);
|
|
19
|
+
return (_jsx(ToggleGroupPrimitive.Item, { "data-slot": "toggle-group-item", "data-variant": context.variant || variant, "data-size": context.size || size, "data-spacing": context.spacing, className: cn("shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-1.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-1.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t", toggleVariants({
|
|
20
|
+
variant: context.variant || variant,
|
|
21
|
+
size: context.size || size,
|
|
22
|
+
}), className), ...props, children: children }));
|
|
23
|
+
}
|
|
24
|
+
export { ToggleGroup, ToggleGroupItem };
|
|
25
|
+
//# sourceMappingURL=toggle-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toggle-group.js","sourceRoot":"","sources":["../../../src/react/ui/toggle-group.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAqB,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,EAAE,EAAE,MAAM,IAAI,CAAA;AACvB,OAAO,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,aAAc,CAAA;AAE7C,MAAM,kBAAkB,GAAG,KAAK,CAAC,aAAa,CAK5C;IACA,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,CAAC;IACV,WAAW,EAAE,YAAY;CAC1B,CAAC,CAAA;AAEF,SAAS,WAAW,CAAC,EACnB,SAAS,EACT,OAAO,EACP,IAAI,EACJ,OAAO,GAAG,CAAC,EACX,WAAW,GAAG,YAAY,EAC1B,QAAQ,EACR,GAAG,KAAK,EAKP;IACD,OAAO,CACL,KAAC,oBAAoB,CAAC,IAAI,iBACd,cAAc,kBACV,OAAO,eACV,IAAI,kBACD,OAAO,sBACH,WAAW,EAC7B,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAyB,EAClD,SAAS,EAAE,EAAE,CACX,mMAAmM,EACnM,SAAS,CACV,KACG,KAAK,YAET,KAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,YAE7C,QAAQ,GACmB,GACJ,CAC7B,CAAA;AACH,CAAC;AAED,SAAS,eAAe,CAAC,EACvB,SAAS,EACT,QAAQ,EACR,OAAO,GAAG,SAAS,EACnB,IAAI,GAAG,SAAS,EAChB,GAAG,KAAK,EAE2B;IACnC,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;IAEpD,OAAO,CACL,KAAC,oBAAoB,CAAC,IAAI,iBACd,mBAAmB,kBACf,OAAO,CAAC,OAAO,IAAI,OAAO,eAC7B,OAAO,CAAC,IAAI,IAAI,IAAI,kBACjB,OAAO,CAAC,OAAO,EAC7B,SAAS,EAAE,EAAE,CACX,k4BAAk4B,EACl4B,cAAc,CAAC;YACb,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO;YACnC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI;SAC3B,CAAC,EACF,SAAS,CACV,KACG,KAAK,YAER,QAAQ,GACiB,CAC7B,CAAA;AACH,CAAC;AAED,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type VariantProps } from "class-variance-authority";
|
|
3
|
+
import { Toggle as TogglePrimitive } from "radix-ui";
|
|
4
|
+
declare const toggleVariants: (props?: ({
|
|
5
|
+
variant?: "default" | "outline" | null | undefined;
|
|
6
|
+
size?: "default" | "sm" | "lg" | null | undefined;
|
|
7
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
8
|
+
declare function Toggle({ className, variant, size, ...props }: React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>): React.JSX.Element;
|
|
9
|
+
export { Toggle, toggleVariants };
|
|
10
|
+
//# sourceMappingURL=toggle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toggle.d.ts","sourceRoot":"","sources":["../../../src/react/ui/toggle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAEjE,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,UAAU,CAAA;AAEpD,QAAA,MAAM,cAAc;;;8EAoBnB,CAAA;AAED,iBAAS,MAAM,CAAC,EACd,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,GAClD,YAAY,CAAC,OAAO,cAAc,CAAC,qBAQpC;AAED,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cva } from "class-variance-authority";
|
|
4
|
+
import { cn } from "cn";
|
|
5
|
+
import { Toggle as TogglePrimitive } from "radix-ui";
|
|
6
|
+
const toggleVariants = cva("group/toggle inline-flex items-center justify-center gap-1 rounded-lg text-sm font-medium whitespace-nowrap transition-all outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted data-[state=on]:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
7
|
+
variants: {
|
|
8
|
+
variant: {
|
|
9
|
+
default: "bg-transparent",
|
|
10
|
+
outline: "border border-input bg-transparent hover:bg-muted",
|
|
11
|
+
},
|
|
12
|
+
size: {
|
|
13
|
+
default: "h-8 min-w-8 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
14
|
+
sm: "h-7 min-w-7 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
|
15
|
+
lg: "h-9 min-w-9 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
defaultVariants: {
|
|
19
|
+
variant: "default",
|
|
20
|
+
size: "default",
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
function Toggle({ className, variant = "default", size = "default", ...props }) {
|
|
24
|
+
return (_jsx(TogglePrimitive.Root, { "data-slot": "toggle", className: cn(toggleVariants({ variant, size, className })), ...props }));
|
|
25
|
+
}
|
|
26
|
+
export { Toggle, toggleVariants };
|
|
27
|
+
//# sourceMappingURL=toggle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toggle.js","sourceRoot":"","sources":["../../../src/react/ui/toggle.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,GAAG,EAAqB,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAE,EAAE,EAAE,MAAM,IAAI,CAAA;AACvB,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,UAAU,CAAA;AAEpD,MAAM,cAAc,GAAG,GAAG,CACxB,qhBAAqhB,EACrhB;IACE,QAAQ,EAAE;QACR,OAAO,EAAE;YACP,OAAO,EAAE,gBAAgB;YACzB,OAAO,EAAE,mDAAmD;SAC7D;QACD,IAAI,EAAE;YACJ,OAAO,EACL,sFAAsF;YACxF,EAAE,EAAE,oLAAoL;YACxL,EAAE,EAAE,sFAAsF;SAC3F;KACF;IACD,eAAe,EAAE;QACf,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE,SAAS;KAChB;CACF,CACF,CAAA;AAED,SAAS,MAAM,CAAC,EACd,SAAS,EACT,OAAO,GAAG,SAAS,EACnB,IAAI,GAAG,SAAS,EAChB,GAAG,KAAK,EAE2B;IACnC,OAAO,CACL,KAAC,eAAe,CAAC,IAAI,iBACT,QAAQ,EAClB,SAAS,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,KACvD,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA"}
|
package/dist/refs.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Ref, RefLike } from './types.ts';
|
|
2
|
+
/** The URN of a reference or a URN string. */
|
|
3
|
+
export declare function urnOf(value: RefLike): string;
|
|
4
|
+
/** A bare `{ urn }` reference, dropping any other fields of a read representation. */
|
|
5
|
+
export declare function ref(value: RefLike): Ref;
|
|
6
|
+
/** Bare references for a list, without duplicates, in their original order. */
|
|
7
|
+
export declare function refs(values: readonly RefLike[] | null | undefined): Ref[];
|
|
8
|
+
/** Whether two references point at the same representation. Absent references are equal to each other. */
|
|
9
|
+
export declare function sameRef(a: RefLike | null | undefined, b: RefLike | null | undefined): boolean;
|
|
10
|
+
/** Whether two lists hold the same references, ignoring order and duplicates. */
|
|
11
|
+
export declare function sameRefs(a: readonly RefLike[] | null | undefined, b: readonly RefLike[] | null | undefined): boolean;
|
|
12
|
+
/** A copy of `list` with `value` added, unless it is already there. */
|
|
13
|
+
export declare function withRef(list: readonly RefLike[] | null | undefined, value: RefLike): Ref[];
|
|
14
|
+
/** A copy of `list` without `value`. */
|
|
15
|
+
export declare function withoutRef(list: readonly RefLike[] | null | undefined, value: RefLike): Ref[];
|
|
16
|
+
//# sourceMappingURL=refs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refs.d.ts","sourceRoot":"","sources":["../src/refs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE/C,8CAA8C;AAC9C,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE5C;AAED,sFAAsF;AACtF,wBAAgB,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAEvC;AAED,+EAA+E;AAC/E,wBAAgB,IAAI,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,GAAG,SAAS,GAAG,GAAG,EAAE,CAWzE;AAED,0GAA0G;AAC1G,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,EAAE,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAG7F;AAED,iFAAiF;AACjF,wBAAgB,QAAQ,CAAC,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,GAAG,SAAS,EAAE,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAIpH;AAED,uEAAuE;AACvE,wBAAgB,OAAO,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,GAAG,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,GAAG,EAAE,CAE1F;AAED,wCAAwC;AACxC,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,GAAG,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,GAAG,EAAE,CAG7F"}
|
package/dist/refs.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** The URN of a reference or a URN string. */
|
|
2
|
+
export function urnOf(value) {
|
|
3
|
+
return typeof value === 'string' ? value : value.urn;
|
|
4
|
+
}
|
|
5
|
+
/** A bare `{ urn }` reference, dropping any other fields of a read representation. */
|
|
6
|
+
export function ref(value) {
|
|
7
|
+
return { urn: urnOf(value) };
|
|
8
|
+
}
|
|
9
|
+
/** Bare references for a list, without duplicates, in their original order. */
|
|
10
|
+
export function refs(values) {
|
|
11
|
+
const seen = new Set();
|
|
12
|
+
const result = [];
|
|
13
|
+
for (const value of values ?? []) {
|
|
14
|
+
const urn = urnOf(value);
|
|
15
|
+
if (!seen.has(urn)) {
|
|
16
|
+
seen.add(urn);
|
|
17
|
+
result.push({ urn });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
/** Whether two references point at the same representation. Absent references are equal to each other. */
|
|
23
|
+
export function sameRef(a, b) {
|
|
24
|
+
if (a == null || b == null)
|
|
25
|
+
return a == null && b == null;
|
|
26
|
+
return urnOf(a) === urnOf(b);
|
|
27
|
+
}
|
|
28
|
+
/** Whether two lists hold the same references, ignoring order and duplicates. */
|
|
29
|
+
export function sameRefs(a, b) {
|
|
30
|
+
const left = new Set((a ?? []).map(urnOf));
|
|
31
|
+
const right = new Set((b ?? []).map(urnOf));
|
|
32
|
+
return left.size === right.size && [...left].every((urn) => right.has(urn));
|
|
33
|
+
}
|
|
34
|
+
/** A copy of `list` with `value` added, unless it is already there. */
|
|
35
|
+
export function withRef(list, value) {
|
|
36
|
+
return refs([...(list ?? []), value]);
|
|
37
|
+
}
|
|
38
|
+
/** A copy of `list` without `value`. */
|
|
39
|
+
export function withoutRef(list, value) {
|
|
40
|
+
const urn = urnOf(value);
|
|
41
|
+
return refs(list).filter((item) => item.urn !== urn);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=refs.js.map
|
package/dist/refs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refs.js","sourceRoot":"","sources":["../src/refs.ts"],"names":[],"mappings":"AAEA,8CAA8C;AAC9C,MAAM,UAAU,KAAK,CAAC,KAAc;IAClC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;AACvD,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,GAAG,CAAC,KAAc;IAChC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;AAC/B,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,IAAI,CAAC,MAA6C;IAChE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAU,EAAE,CAAC;IACzB,KAAK,MAAM,KAAK,IAAI,MAAM,IAAI,EAAE,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,0GAA0G;AAC1G,MAAM,UAAU,OAAO,CAAC,CAA6B,EAAE,CAA6B;IAClF,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC;IAC1D,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,QAAQ,CAAC,CAAwC,EAAE,CAAwC;IACzG,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5C,OAAO,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,OAAO,CAAC,IAA2C,EAAE,KAAc;IACjF,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,UAAU,CAAC,IAA2C,EAAE,KAAc;IACpF,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACzB,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,kIAAkI;AAClI,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,kIAAkI;AAClI,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type Task, type TaskStatus } from '@baack-software/baack-ts-client';
|
|
2
|
+
import type { DraftInput } from '../draft.ts';
|
|
3
|
+
import type { ChangeOptions, TaskClient } from '../task-client.ts';
|
|
4
|
+
import type { RefLike } from '../types.ts';
|
|
5
|
+
import { type WebhookEvent } from './webhooks.ts';
|
|
6
|
+
/**
|
|
7
|
+
* Automations built from the client and helpers, for webhook handlers and scheduled jobs. Each takes what it needs
|
|
8
|
+
* and returns what it did, so callers can log it or notify someone.
|
|
9
|
+
*/
|
|
10
|
+
export interface WelcomeOptions extends ChangeOptions {
|
|
11
|
+
/** The company that owns the new task: usually yours, the one the webhook subscription belongs to. */
|
|
12
|
+
owner: RefLike;
|
|
13
|
+
/** The task to create, given the new company's URN. Default "Welcome your new customer", priority HIGH. */
|
|
14
|
+
task?: (company: string) => Omit<DraftInput, 'owner'>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* On a company being created, creates a task to welcome it, related to the new company. Returns the task, or
|
|
18
|
+
* `undefined` for any other event.
|
|
19
|
+
*/
|
|
20
|
+
export declare function welcomeNewCompany(event: WebhookEvent, tasks: TaskClient, { owner, task, ...options }: WelcomeOptions): Promise<Task | undefined>;
|
|
21
|
+
export interface UnblockOptions extends ChangeOptions {
|
|
22
|
+
/** The status a task moves to once nothing blocks it. Default `PENDING`. */
|
|
23
|
+
status?: TaskStatus;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* When `done` is finished, moves each task it was blocking out of `BLOCKED` if no other open task still blocks it.
|
|
27
|
+
* Reads the dependants and their other blockers fresh. Returns the tasks moved. Does nothing while `done` is open.
|
|
28
|
+
*/
|
|
29
|
+
export declare function unblockDependants(done: Task, tasks: TaskClient, { status, ...options }?: UnblockOptions): Promise<Task[]>;
|
|
30
|
+
/**
|
|
31
|
+
* The webhook side of `unblockDependants`: on a task update, reads the task and unblocks its dependants once it is
|
|
32
|
+
* finished. Returns the tasks moved.
|
|
33
|
+
*/
|
|
34
|
+
export declare function unblockOnCompletion(event: WebhookEvent, tasks: TaskClient, options?: UnblockOptions): Promise<Task[]>;
|
|
35
|
+
/** A company's open tasks past their due date, most urgent first. For a nightly job that notifies their assignees. */
|
|
36
|
+
export declare function overdueTasks(tasks: TaskClient, owner: RefLike, now?: Date): Promise<Task[]>;
|
|
37
|
+
/** Groups tasks by assignee URN, for one message per person. Unassigned tasks are under `''`. */
|
|
38
|
+
export declare function byAssignee(tasks: readonly Task[]): Map<string, Task[]>;
|
|
39
|
+
//# sourceMappingURL=recipes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipes.d.ts","sourceRoot":"","sources":["../../src/server/recipes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,IAAI,EAAE,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE9F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEnE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjE;;;GAGG;AAEH,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,sGAAsG;IACtG,KAAK,EAAE,OAAO,CAAC;IACf,2GAA2G;IAC3G,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;CACvD;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,UAAU,EACjB,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,EAAE,cAAc,GAC1C,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC,CAS3B;AAED,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,4EAA4E;IAC5E,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,UAAU,EACjB,EAAE,MAAkB,EAAE,GAAG,OAAO,EAAE,GAAE,cAAmB,GACtD,OAAO,CAAC,IAAI,EAAE,CAAC,CAiBjB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAK3H;AAED,sHAAsH;AACtH,wBAAsB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,GAAE,IAAiB,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAG7G;AAED,iGAAiG;AACjG,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAOtE"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { isBaackApiError } from '@baack-software/baack-ts-client';
|
|
2
|
+
import { openBlockers } from "../blockers.js";
|
|
3
|
+
import { urnOf } from "../refs.js";
|
|
4
|
+
import { byUrgency, isOpen, isOverdue } from "../tasks.js";
|
|
5
|
+
import { webhookTarget } from "./webhooks.js";
|
|
6
|
+
/**
|
|
7
|
+
* On a company being created, creates a task to welcome it, related to the new company. Returns the task, or
|
|
8
|
+
* `undefined` for any other event.
|
|
9
|
+
*/
|
|
10
|
+
export async function welcomeNewCompany(event, tasks, { owner, task, ...options }) {
|
|
11
|
+
if (event.trigger.subject !== 'COMPANY' || event.trigger.event !== 'CREATE')
|
|
12
|
+
return undefined;
|
|
13
|
+
const company = webhookTarget(event);
|
|
14
|
+
if (!company)
|
|
15
|
+
return undefined;
|
|
16
|
+
const fields = task?.(company) ?? { title: 'Welcome your new customer', priority: 'HIGH' };
|
|
17
|
+
return tasks.create({ owner, ...fields, associatedCompanies: [...(fields.associatedCompanies ?? []), { urn: company }] }, options);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* When `done` is finished, moves each task it was blocking out of `BLOCKED` if no other open task still blocks it.
|
|
21
|
+
* Reads the dependants and their other blockers fresh. Returns the tasks moved. Does nothing while `done` is open.
|
|
22
|
+
*/
|
|
23
|
+
export async function unblockDependants(done, tasks, { status = 'PENDING', ...options } = {}) {
|
|
24
|
+
if (isOpen(done))
|
|
25
|
+
return [];
|
|
26
|
+
const moved = [];
|
|
27
|
+
for (const ref of done.blocking ?? []) {
|
|
28
|
+
const dependant = await readOrSkip(tasks, ref.urn);
|
|
29
|
+
if (!dependant || dependant.status !== 'BLOCKED')
|
|
30
|
+
continue;
|
|
31
|
+
const blockers = new Map([[done.urn, done]]);
|
|
32
|
+
for (const blocker of dependant.blockedBy ?? []) {
|
|
33
|
+
if (blockers.has(blocker.urn))
|
|
34
|
+
continue;
|
|
35
|
+
const read = await readOrSkip(tasks, blocker.urn);
|
|
36
|
+
if (read)
|
|
37
|
+
blockers.set(read.urn, read);
|
|
38
|
+
}
|
|
39
|
+
// A blocker that can't be read (deleted, or out of reach) counts as open, so nothing moves on a guess.
|
|
40
|
+
if (openBlockers(dependant, (urn) => blockers.get(urn)).length > 0)
|
|
41
|
+
continue;
|
|
42
|
+
moved.push(await tasks.setStatus(dependant, status, options));
|
|
43
|
+
}
|
|
44
|
+
return moved;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The webhook side of `unblockDependants`: on a task update, reads the task and unblocks its dependants once it is
|
|
48
|
+
* finished. Returns the tasks moved.
|
|
49
|
+
*/
|
|
50
|
+
export async function unblockOnCompletion(event, tasks, options) {
|
|
51
|
+
if (event.trigger.subject !== 'TASK' || event.trigger.event !== 'UPDATE')
|
|
52
|
+
return [];
|
|
53
|
+
const urn = webhookTarget(event);
|
|
54
|
+
const task = urn ? await readOrSkip(tasks, urn) : undefined;
|
|
55
|
+
return task ? unblockDependants(task, tasks, options) : [];
|
|
56
|
+
}
|
|
57
|
+
/** A company's open tasks past their due date, most urgent first. For a nightly job that notifies their assignees. */
|
|
58
|
+
export async function overdueTasks(tasks, owner, now = new Date()) {
|
|
59
|
+
const { tasks: all } = await tasks.list({ owner, includeRelated: false });
|
|
60
|
+
return all.filter((task) => isOverdue(task, now)).sort(byUrgency);
|
|
61
|
+
}
|
|
62
|
+
/** Groups tasks by assignee URN, for one message per person. Unassigned tasks are under `''`. */
|
|
63
|
+
export function byAssignee(tasks) {
|
|
64
|
+
const groups = new Map();
|
|
65
|
+
for (const task of tasks) {
|
|
66
|
+
const key = task.assignee ? urnOf(task.assignee) : '';
|
|
67
|
+
groups.set(key, [...(groups.get(key) ?? []), task]);
|
|
68
|
+
}
|
|
69
|
+
return groups;
|
|
70
|
+
}
|
|
71
|
+
async function readOrSkip(tasks, urn) {
|
|
72
|
+
try {
|
|
73
|
+
return await tasks.get(urn);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
if (isBaackApiError(error) && error.isNotFound)
|
|
77
|
+
return undefined;
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=recipes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipes.js","sourceRoot":"","sources":["../../src/server/recipes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAA8B,MAAM,iCAAiC,CAAC;AAC9F,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAqB,MAAM,eAAe,CAAC;AAcjE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAmB,EACnB,KAAiB,EACjB,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,EAAkB;IAE3C,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC9F,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,2BAA2B,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAC3F,OAAO,KAAK,CAAC,MAAM,CACjB,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,mBAAmB,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,mBAAmB,IAAI,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,EACpG,OAAO,CACR,CAAC;AACJ,CAAC;AAOD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAU,EACV,KAAiB,EACjB,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,OAAO,KAAqB,EAAE;IAEvD,IAAI,MAAM,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAW,EAAE,CAAC;IACzB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACnD,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS;YAAE,SAAS;QAC3D,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAe,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3D,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;YAChD,IAAI,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC;gBAAE,SAAS;YACxC,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;YAClD,IAAI,IAAI;gBAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACzC,CAAC;QACD,uGAAuG;QACvG,IAAI,YAAY,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC7E,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAAmB,EAAE,KAAiB,EAAE,OAAwB;IACxG,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,KAAK,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACpF,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5D,OAAO,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED,sHAAsH;AACtH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAiB,EAAE,KAAc,EAAE,MAAY,IAAI,IAAI,EAAE;IAC1F,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACpE,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,KAAiB,EAAE,GAAW;IACtD,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,eAAe,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,UAAU;YAAE,OAAO,SAAS,CAAC;QACjE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { type Task } from '@baack-software/baack-ts-client';
|
|
2
|
+
import type { TaskClient } from '../task-client.ts';
|
|
3
|
+
import type { Ref } from '../types.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Receiving Baack webhooks: verifying a delivery's signature, reading its event, and fetching the task it is about.
|
|
6
|
+
* Uses Web Crypto and the Fetch API types only, so it runs on Node 20+, Deno, Bun and edge runtimes.
|
|
7
|
+
*
|
|
8
|
+
* A delivery is a POST whose body is a webhook event, an envelope naming what changed (`trigger`) and where it is
|
|
9
|
+
* (`v1`), without the changed representation itself; read it from the API. Its headers:
|
|
10
|
+
*
|
|
11
|
+
* - `Signature`: base64 HMAC-SHA256, keyed with the subscription's secret, over the UTF-8 bytes of the parts
|
|
12
|
+
* `Signed-Headers` lists, in that order and without separators. Today that is the body, then `Last-Modified`, then
|
|
13
|
+
* `Idempotency-Key`.
|
|
14
|
+
* - `Last-Modified`: when the trigger happened, an ISO local date-time (UTC, without a zone, like other Baack
|
|
15
|
+
* timestamps), signed as sent.
|
|
16
|
+
* - `Idempotency-Key`: the trigger's URN. Retries carry the same key, so handle each key once.
|
|
17
|
+
* - `X-Attempt-Number` and `X-Attempts-Remaining`: where a delivery is in its retries.
|
|
18
|
+
*/
|
|
19
|
+
/** Header names, lower case as the Fetch API's `Headers` and Node's `IncomingMessage` give them. */
|
|
20
|
+
export declare const WEBHOOK_HEADERS: {
|
|
21
|
+
readonly signature: "signature";
|
|
22
|
+
readonly signedHeaders: "signed-headers";
|
|
23
|
+
readonly timestamp: "last-modified";
|
|
24
|
+
readonly idempotencyKey: "idempotency-key";
|
|
25
|
+
readonly attempt: "x-attempt-number";
|
|
26
|
+
readonly attemptsRemaining: "x-attempts-remaining";
|
|
27
|
+
};
|
|
28
|
+
/** What a delivery signs when it doesn't say, the order the API uses. */
|
|
29
|
+
export declare const DEFAULT_SIGNED_PARTS: readonly ["body", "last-modified", "idempotency-key"];
|
|
30
|
+
/** The kinds of representation a trigger can be about. */
|
|
31
|
+
export type WebhookSubject = 'UNKNOWN' | 'ADDRESS' | 'API_CLIENT' | 'BEARER_TOKEN' | 'BOOLEAN_ITEM' | 'CLIENT_IDENTIFIER' | 'COMPANY' | 'DATETIME_ITEM' | 'DOUBLE_ITEM' | 'EMAIL' | 'ENTITY' | 'ENTITY_LIST' | 'GROUP' | 'GROUP_MEMBERSHIP' | 'IDENTITY' | 'JSON_ITEM' | 'LINK_ITEM' | 'REFERENCE_ITEM' | 'IMAGE_ITEM' | 'LATLONG_ITEM' | 'LONG_ITEM' | 'MARKDOWN_ITEM' | 'MESSAGE_THREAD' | 'MESSAGE_THREAD_NOTIFICATION' | 'MONEY_ITEM' | 'OAUTH_TOKEN' | 'PERMISSION' | 'PERSON' | 'PERSON_NAME' | 'PROJECT' | 'ROLE' | 'TASK' | 'TELEPHONE' | 'TEMPLATE_ITEM' | 'TEXT_ITEM' | 'THREAD_POST' | 'WEBHOOK_SUBSCRIPTION' | 'WORKFLOW';
|
|
32
|
+
export type WebhookEventKind = 'CREATE' | 'UPDATE' | 'DELETE';
|
|
33
|
+
/** What happened: a representation of `subject` was created, updated or deleted. */
|
|
34
|
+
export interface WebhookTrigger {
|
|
35
|
+
urn: string;
|
|
36
|
+
owner?: Ref;
|
|
37
|
+
subject: WebhookSubject;
|
|
38
|
+
event: WebhookEventKind;
|
|
39
|
+
/** The URN of the representation that changed. */
|
|
40
|
+
targetUrn?: string;
|
|
41
|
+
timestamp?: string;
|
|
42
|
+
}
|
|
43
|
+
/** A webhook delivery's body. */
|
|
44
|
+
export interface WebhookEvent {
|
|
45
|
+
trigger: WebhookTrigger;
|
|
46
|
+
subscription?: {
|
|
47
|
+
urn: string;
|
|
48
|
+
[field: string]: unknown;
|
|
49
|
+
};
|
|
50
|
+
/** Where the changed representation is. */
|
|
51
|
+
v1?: {
|
|
52
|
+
urn: string;
|
|
53
|
+
url?: string;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** A delivery that passed verification. */
|
|
57
|
+
export interface WebhookDelivery {
|
|
58
|
+
event: WebhookEvent;
|
|
59
|
+
/** The trigger's URN; the same on every retry of this delivery. */
|
|
60
|
+
idempotencyKey: string;
|
|
61
|
+
/** `Last-Modified`, as sent. */
|
|
62
|
+
timestamp: string;
|
|
63
|
+
attempt?: number;
|
|
64
|
+
attemptsRemaining?: number;
|
|
65
|
+
}
|
|
66
|
+
export type WebhookRejection = 'missing-signature' | 'missing-header' | 'unsigned-body' | 'bad-signature' | 'stale' | 'malformed-event';
|
|
67
|
+
/** Thrown when a delivery can't be trusted or read. Answer 401 (or 400 for `malformed-event`) and don't act on it. */
|
|
68
|
+
export declare class WebhookVerificationError extends Error {
|
|
69
|
+
readonly reason: WebhookRejection;
|
|
70
|
+
readonly name = "WebhookVerificationError";
|
|
71
|
+
constructor(reason: WebhookRejection, message: string);
|
|
72
|
+
}
|
|
73
|
+
/** Header lookups from the Fetch API's `Headers`, or a plain object such as Node's `req.headers`. */
|
|
74
|
+
export type HeaderSource = Headers | Readonly<Record<string, string | readonly string[] | undefined>>;
|
|
75
|
+
export interface VerifyOptions {
|
|
76
|
+
/**
|
|
77
|
+
* Refuse deliveries whose `Last-Modified` is older than this. Off by default: retries keep the trigger's time, so a
|
|
78
|
+
* late retry is still genuine. Use the idempotency key against replays instead.
|
|
79
|
+
*/
|
|
80
|
+
maxAgeMs?: number;
|
|
81
|
+
now?: Date;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Checks a delivery's signature and returns its event. `body` must be the raw bytes or text as received: parsing and
|
|
85
|
+
* re-serialising the JSON changes the bytes and the signature won't match. Throws `WebhookVerificationError`.
|
|
86
|
+
*/
|
|
87
|
+
export declare function verifyWebhook(delivery: {
|
|
88
|
+
body: string | Uint8Array;
|
|
89
|
+
headers: HeaderSource;
|
|
90
|
+
}, secret: string, options?: VerifyOptions): Promise<WebhookDelivery>;
|
|
91
|
+
/** `verifyWebhook` for a Fetch API `Request`, reading its body. */
|
|
92
|
+
export declare function verifyWebhookRequest(request: Request, secret: string, options?: VerifyOptions): Promise<WebhookDelivery>;
|
|
93
|
+
/** Reads a delivery's body as a webhook event, checking the parts handlers rely on. Throws `WebhookVerificationError`. */
|
|
94
|
+
export declare function parseWebhookEvent(body: string): WebhookEvent;
|
|
95
|
+
/** The URN of the representation an event is about. */
|
|
96
|
+
export declare function webhookTarget(event: WebhookEvent): string | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Signs a delivery the way the API does, returning the headers to send with `body`. For tests and for replaying or
|
|
99
|
+
* simulating deliveries locally.
|
|
100
|
+
*/
|
|
101
|
+
export declare function signWebhook(body: string, secret: string, { timestamp, idempotencyKey }: {
|
|
102
|
+
timestamp: string;
|
|
103
|
+
idempotencyKey: string;
|
|
104
|
+
}): Promise<Record<string, string>>;
|
|
105
|
+
/**
|
|
106
|
+
* The task an event is about, read fresh, since events don't carry it. `null` when the task was deleted, by the event
|
|
107
|
+
* or since. Throws for events about anything but a task.
|
|
108
|
+
*/
|
|
109
|
+
export declare function taskFromWebhook(event: WebhookEvent, tasks: TaskClient): Promise<Task | null>;
|
|
110
|
+
/** Remembers which deliveries were handled, so a retry isn't acted on twice. */
|
|
111
|
+
export interface IdempotencyStore {
|
|
112
|
+
/** Records the key and returns true the first time it is seen, false after. */
|
|
113
|
+
claim(key: string): Promise<boolean> | boolean;
|
|
114
|
+
/** Forgets a key whose handling failed, so a retry runs it. */
|
|
115
|
+
release?(key: string): Promise<void> | void;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Keys held in memory for `ttlMs` (default a day). Enough for one process; use a shared store (a database row with
|
|
119
|
+
* a unique key, Redis `SET NX`) when several handle deliveries.
|
|
120
|
+
*/
|
|
121
|
+
export declare function memoryIdempotencyStore(ttlMs?: number): IdempotencyStore;
|
|
122
|
+
export interface WebhookHandlerOptions {
|
|
123
|
+
secret: string;
|
|
124
|
+
/** Acts on a verified delivery seen for the first time. A throw answers 500, so the API retries. */
|
|
125
|
+
onEvent: (delivery: WebhookDelivery) => Promise<void> | void;
|
|
126
|
+
/** Default: in memory, per process. */
|
|
127
|
+
idempotency?: IdempotencyStore;
|
|
128
|
+
verify?: VerifyOptions;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* A Fetch API handler (`(request) => Response`) for a webhook endpoint: verifies, skips repeats, and runs `onEvent`.
|
|
132
|
+
* Answers 401 to an untrusted delivery, 400 to an unreadable one, 200 once handled or already handled.
|
|
133
|
+
*/
|
|
134
|
+
export declare function webhookHandler(options: WebhookHandlerOptions): (request: Request) => Promise<Response>;
|
|
135
|
+
//# sourceMappingURL=webhooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/server/webhooks.ts"],"names":[],"mappings":"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"}
|