@timesheet/plugin-outlook-calendar 1.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/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # Outlook Calendar Sync
2
+
3
+ > Intended integration between Timesheet tasks and Outlook (Microsoft 365) calendar events. Early scaffold, not yet functional.
4
+
5
+ This package is an early scaffold. The handlers are wired into the plugin runtime and return placeholder results (for example, `testConnection` reports OK and `syncTaskToExternal` echoes the task id), but no calls are made to the Microsoft Graph or Outlook Calendar API yet. The manifest below describes the intended shape of the integration rather than working behavior.
6
+
7
+ - Package: `@timesheet/plugin-outlook-calendar`
8
+ - Manifest id: `outlook-calendar-sync`
9
+ - Category: calendar
10
+ - Status: scaffold (no Outlook Calendar API integration implemented)
11
+
12
+ ## Authentication
13
+
14
+ OAuth 2.0. Scopes are placeholders (`read`, `write`) and will be replaced with the real Microsoft Graph scopes when the integration is implemented.
15
+
16
+ ## Configuration
17
+
18
+ | Option | Required | Default | Description |
19
+ | --- | --- | --- | --- |
20
+ | `syncDirection` | yes | `bidirectional` | One of `bidirectional`, `timesheet-to-external`, `external-to-timesheet`. |
21
+
22
+ ## Mappings
23
+
24
+ - **Project mapping**: Timesheet project to Outlook calendar (placeholder, not yet wired to real Outlook entities).
25
+
26
+ ## Triggers
27
+
28
+ - **Task Created** (event): scaffolded handler for new Timesheet tasks.
29
+ - **Outlook Calendar Webhook** (webhook): scaffolded inbound endpoint.
30
+ - **Scheduled Full Sync** (daily at 02:00 UTC): scaffolded background sync.
31
+ - **Manual Sync** (user action): scaffolded sync from the integration settings page.
32
+
33
+ ## Development
34
+
35
+ ```bash
36
+ npm install # or: npm ci
37
+ npm run build # compile TypeScript into dist/
38
+ npm run typecheck
39
+ ```
40
+
41
+ The package ships `dist/` and `manifest.json`; the sandboxed plugin runtime loads it by package name, version, and integrity. Shared tests live in `integrations/tests/` and run from the `integrations/` root with `npm test`.
@@ -0,0 +1,5 @@
1
+ import { WebhookInput } from '@timesheet/integration-sdk';
2
+ export declare const handleWebhook: import("@timesheet/integration-sdk").IntegrationHandler<WebhookInput, {
3
+ system: string;
4
+ handled: boolean;
5
+ }, Record<string, unknown>>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleWebhook = void 0;
4
+ const integration_sdk_1 = require("@timesheet/integration-sdk");
5
+ const SYSTEM = 'outlook-calendar';
6
+ exports.handleWebhook = (0, integration_sdk_1.defineHandler)(async (input, context) => {
7
+ context.logger.info('Handling webhook', {
8
+ system: SYSTEM,
9
+ method: input.method,
10
+ installationId: context.installationId
11
+ });
12
+ return {
13
+ system: SYSTEM,
14
+ handled: true
15
+ };
16
+ });
@@ -0,0 +1,2 @@
1
+ import { ExternalEntity } from '@timesheet/integration-sdk';
2
+ export declare const listExternalProjects: import("@timesheet/integration-sdk").IntegrationHandler<void, ExternalEntity[], Record<string, unknown>>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listExternalProjects = void 0;
4
+ const integration_sdk_1 = require("@timesheet/integration-sdk");
5
+ const SYSTEM = 'outlook-calendar';
6
+ exports.listExternalProjects = (0, integration_sdk_1.defineHandler)(async (_input, context) => {
7
+ context.logger.info('Listing external projects', {
8
+ system: SYSTEM,
9
+ installationId: context.installationId
10
+ });
11
+ return [
12
+ { id: 'outlook-calendar-project-1', name: 'Outlook Calendar Sync Project 1' },
13
+ { id: 'outlook-calendar-project-2', name: 'Outlook Calendar Sync Project 2' }
14
+ ];
15
+ });
@@ -0,0 +1,5 @@
1
+ export declare const runFullSync: import("@timesheet/integration-sdk").IntegrationHandler<void, {
2
+ system: string;
3
+ status: string;
4
+ syncedCount: number;
5
+ }, Record<string, unknown>>;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runFullSync = void 0;
4
+ const integration_sdk_1 = require("@timesheet/integration-sdk");
5
+ const SYSTEM = 'outlook-calendar';
6
+ exports.runFullSync = (0, integration_sdk_1.defineHandler)(async (_input, context) => {
7
+ context.logger.info('Running full sync', {
8
+ system: SYSTEM,
9
+ installationId: context.installationId,
10
+ syncDirection: context.config?.syncDirection ?? 'bidirectional'
11
+ });
12
+ return {
13
+ system: SYSTEM,
14
+ status: 'completed',
15
+ syncedCount: 0
16
+ };
17
+ });
@@ -0,0 +1,5 @@
1
+ import { WebhookInput } from '@timesheet/integration-sdk';
2
+ export declare const syncTaskFromExternal: import("@timesheet/integration-sdk").IntegrationHandler<WebhookInput, {
3
+ system: string;
4
+ accepted: boolean;
5
+ }, Record<string, unknown>>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.syncTaskFromExternal = void 0;
4
+ const integration_sdk_1 = require("@timesheet/integration-sdk");
5
+ const SYSTEM = 'outlook-calendar';
6
+ exports.syncTaskFromExternal = (0, integration_sdk_1.defineHandler)(async (input, context) => {
7
+ context.logger.info('Syncing task from external payload', {
8
+ system: SYSTEM,
9
+ method: input.method,
10
+ installationId: context.installationId
11
+ });
12
+ return {
13
+ system: SYSTEM,
14
+ accepted: true
15
+ };
16
+ });
@@ -0,0 +1,6 @@
1
+ import { TaskCreatedInput } from '@timesheet/integration-sdk';
2
+ export declare const syncTaskToExternal: import("@timesheet/integration-sdk").IntegrationHandler<TaskCreatedInput, {
3
+ system: string;
4
+ taskId: string;
5
+ direction: string;
6
+ }, Record<string, unknown>>;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.syncTaskToExternal = void 0;
4
+ const integration_sdk_1 = require("@timesheet/integration-sdk");
5
+ const SYSTEM = 'outlook-calendar';
6
+ exports.syncTaskToExternal = (0, integration_sdk_1.defineHandler)(async (input, context) => {
7
+ context.logger.info('Syncing task to external system', {
8
+ system: SYSTEM,
9
+ taskId: input.taskId,
10
+ installationId: context.installationId
11
+ });
12
+ return {
13
+ system: SYSTEM,
14
+ taskId: input.taskId,
15
+ direction: 'timesheet-to-external'
16
+ };
17
+ });
@@ -0,0 +1,5 @@
1
+ export declare const testConnection: import("@timesheet/integration-sdk").IntegrationHandler<void, {
2
+ system: string;
3
+ ok: boolean;
4
+ installationId: string;
5
+ }, Record<string, unknown>>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.testConnection = void 0;
4
+ const integration_sdk_1 = require("@timesheet/integration-sdk");
5
+ const SYSTEM = 'outlook-calendar';
6
+ exports.testConnection = (0, integration_sdk_1.defineHandler)(async (_input, context) => {
7
+ context.logger.info('Testing integration connection', {
8
+ system: SYSTEM,
9
+ installationId: context.installationId
10
+ });
11
+ return {
12
+ system: SYSTEM,
13
+ ok: true,
14
+ installationId: context.installationId
15
+ };
16
+ });
@@ -0,0 +1,8 @@
1
+ export { syncTaskToExternal } from './handlers/syncTaskToExternal';
2
+ export { syncTaskFromExternal } from './handlers/syncTaskFromExternal';
3
+ export { handleWebhook } from './handlers/handleWebhook';
4
+ export { runFullSync } from './handlers/runFullSync';
5
+ export { testConnection } from './handlers/testConnection';
6
+ export { listExternalProjects } from './handlers/listExternalProjects';
7
+ export declare const PLUGIN_SYSTEM = "outlook-calendar";
8
+ export declare const PLUGIN_NAME = "Outlook Calendar Sync";
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PLUGIN_NAME = exports.PLUGIN_SYSTEM = exports.listExternalProjects = exports.testConnection = exports.runFullSync = exports.handleWebhook = exports.syncTaskFromExternal = exports.syncTaskToExternal = void 0;
4
+ var syncTaskToExternal_1 = require("./handlers/syncTaskToExternal");
5
+ Object.defineProperty(exports, "syncTaskToExternal", { enumerable: true, get: function () { return syncTaskToExternal_1.syncTaskToExternal; } });
6
+ var syncTaskFromExternal_1 = require("./handlers/syncTaskFromExternal");
7
+ Object.defineProperty(exports, "syncTaskFromExternal", { enumerable: true, get: function () { return syncTaskFromExternal_1.syncTaskFromExternal; } });
8
+ var handleWebhook_1 = require("./handlers/handleWebhook");
9
+ Object.defineProperty(exports, "handleWebhook", { enumerable: true, get: function () { return handleWebhook_1.handleWebhook; } });
10
+ var runFullSync_1 = require("./handlers/runFullSync");
11
+ Object.defineProperty(exports, "runFullSync", { enumerable: true, get: function () { return runFullSync_1.runFullSync; } });
12
+ var testConnection_1 = require("./handlers/testConnection");
13
+ Object.defineProperty(exports, "testConnection", { enumerable: true, get: function () { return testConnection_1.testConnection; } });
14
+ var listExternalProjects_1 = require("./handlers/listExternalProjects");
15
+ Object.defineProperty(exports, "listExternalProjects", { enumerable: true, get: function () { return listExternalProjects_1.listExternalProjects; } });
16
+ exports.PLUGIN_SYSTEM = 'outlook-calendar';
17
+ exports.PLUGIN_NAME = 'Outlook Calendar Sync';
package/manifest.json ADDED
@@ -0,0 +1,150 @@
1
+ {
2
+ "id": "outlook-calendar-sync",
3
+ "name": "Outlook Calendar Sync",
4
+ "version": "1.0.1",
5
+ "description": "Timesheet Outlook Calendar Sync plugin integration",
6
+ "category": "calendar",
7
+ "tags": ["sync", "timesheet", "outlook-calendar"],
8
+ "dataAccess": ["projects", "tasks", "colleagues", "settings"],
9
+ "externalAuth": [
10
+ {
11
+ "id": "outlook",
12
+ "type": "oauth2",
13
+ "oauth": {
14
+ "authorizeUrl": "https://example.com/oauth/authorize",
15
+ "tokenUrl": "https://example.com/oauth/token",
16
+ "scopes": ["read", "write"]
17
+ }
18
+ }
19
+ ],
20
+ "configSchema": {
21
+ "type": "object",
22
+ "properties": {
23
+ "syncDirection": {
24
+ "type": "string",
25
+ "title": "Sync Direction",
26
+ "enum": ["bidirectional", "timesheet-to-external", "external-to-timesheet"],
27
+ "default": "bidirectional",
28
+ "x-ui-widget": "radio"
29
+ }
30
+ },
31
+ "required": ["syncDirection"]
32
+ },
33
+ "mappingSchema": {
34
+ "system": "outlook-calendar",
35
+ "mappings": [
36
+ {
37
+ "id": "projects",
38
+ "title": "Project Mapping",
39
+ "description": "Map Timesheet projects to Outlook Calendar Sync projects",
40
+ "localEntity": {
41
+ "type": "project",
42
+ "label": "Timesheet Project",
43
+ "display": "{{title}}"
44
+ },
45
+ "externalEntity": {
46
+ "type": "project",
47
+ "label": "Outlook Calendar Sync Project",
48
+ "fetchAction": "list-external-projects"
49
+ },
50
+ "required": true,
51
+ "minMappings": 1
52
+ }
53
+ ]
54
+ },
55
+ "triggers": [
56
+ {
57
+ "id": "task-created",
58
+ "type": "event",
59
+ "name": "Task Created",
60
+ "description": "Sync when a new task is created",
61
+ "events": ["task.create"],
62
+ "configurable": true
63
+ },
64
+ {
65
+ "id": "integration-webhook",
66
+ "type": "webhook",
67
+ "name": "Outlook Calendar Sync Webhook",
68
+ "description": "Receive inbound changes from Outlook Calendar Sync",
69
+ "configurable": false,
70
+ "webhook": {
71
+ "signature": {
72
+ "header": "x-timesheet-signature",
73
+ "algorithm": "hmac-sha256",
74
+ "secretConfigKey": "webhookSecret"
75
+ }
76
+ }
77
+ },
78
+ {
79
+ "id": "full-sync",
80
+ "type": "schedule",
81
+ "name": "Scheduled Full Sync",
82
+ "description": "Run background synchronization",
83
+ "schedule": "0 2 * * *",
84
+ "timezone": "UTC",
85
+ "configurable": true
86
+ },
87
+ {
88
+ "id": "manual-sync",
89
+ "type": "user_action",
90
+ "name": "Manual Sync",
91
+ "description": "Trigger a sync from settings",
92
+ "userAction": {
93
+ "label": "Sync Now",
94
+ "placement": "settings"
95
+ }
96
+ }
97
+ ],
98
+ "actions": [
99
+ {
100
+ "id": "sync-task-to-external",
101
+ "name": "Sync task to Outlook Calendar Sync",
102
+ "handler": "syncTaskToExternal"
103
+ },
104
+ {
105
+ "id": "sync-task-from-external",
106
+ "name": "Sync task from Outlook Calendar Sync",
107
+ "handler": "syncTaskFromExternal"
108
+ },
109
+ {
110
+ "id": "handle-webhook",
111
+ "handler": "handleWebhook",
112
+ "internal": true
113
+ },
114
+ {
115
+ "id": "run-full-sync",
116
+ "name": "Run full sync",
117
+ "handler": "runFullSync"
118
+ },
119
+ {
120
+ "id": "test-connection",
121
+ "name": "Test connection",
122
+ "handler": "testConnection"
123
+ },
124
+ {
125
+ "id": "list-external-projects",
126
+ "handler": "listExternalProjects",
127
+ "internal": true
128
+ }
129
+ ],
130
+ "pages": [
131
+ {
132
+ "id": "dashboard",
133
+ "title": "Sync Dashboard",
134
+ "icon": "chart-bar",
135
+ "layout": "dashboard",
136
+ "widgets": [
137
+ {
138
+ "id": "manual-sync-btn",
139
+ "type": "action_button",
140
+ "title": "Manual Sync",
141
+ "config": {
142
+ "actionId": "run-full-sync",
143
+ "label": "Run Full Sync",
144
+ "variant": "primary"
145
+ }
146
+ }
147
+ ]
148
+ }
149
+ ]
150
+ }
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@timesheet/plugin-outlook-calendar",
3
+ "version": "1.0.1",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "files": [
7
+ "dist",
8
+ "manifest.json"
9
+ ],
10
+ "scripts": {
11
+ "build": "rm -rf dist && tsc -p tsconfig.json",
12
+ "typecheck": "tsc --noEmit",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "dependencies": {
16
+ "@timesheet/integration-sdk": "^0.5.0"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^20.19.43",
20
+ "typescript": "^5.9.3"
21
+ }
22
+ }