@srafis/zsync 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -0
- package/dist/zsync.js +8408 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# zsync
|
|
2
|
+
|
|
3
|
+
An interactive Clockify → Zoho People time-log sync. Choose a period, select
|
|
4
|
+
entries, map projects to jobs, review the changes, and confirm. No scheduler.
|
|
5
|
+
|
|
6
|
+
## Run locally
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
bun install
|
|
10
|
+
bun run dev --help
|
|
11
|
+
bun run dev --demo
|
|
12
|
+
bun run dev
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Develop and test with Bun. The package builds a Node 22+ executable for the planned
|
|
16
|
+
`npx @srafis/zsync` command; Bun is not required to run the published artifact. The package
|
|
17
|
+
has not been published by this implementation.
|
|
18
|
+
|
|
19
|
+
After publication, run `npx @srafis/zsync`, or install with
|
|
20
|
+
`npm i -g @srafis/zsync` and run `zsync`.
|
|
21
|
+
|
|
22
|
+
## Publishing
|
|
23
|
+
|
|
24
|
+
The `publish.yml` GitHub Actions workflow tests and publishes every push to `main`.
|
|
25
|
+
Add a repository Actions secret named `NPM_TOKEN` containing an npm granular
|
|
26
|
+
access token with permission to publish `@srafis/zsync` and bypass 2FA for CI.
|
|
27
|
+
Keep the token in GitHub Secrets, never in this repository.
|
|
28
|
+
|
|
29
|
+
The release patch is the package.json patch plus the GitHub workflow run number
|
|
30
|
+
(starting at `0.1.1`). The version changes only in CI; no release commits are made.
|
|
31
|
+
Rerunning a published version skips publication. Bump the major/minor in
|
|
32
|
+
package.json when needed. The npm scope must belong to your account or organization.
|
|
33
|
+
|
|
34
|
+
The CLI uses the `zsync` state directory and `ZSYNC_*` overrides.
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
bun run typecheck
|
|
38
|
+
bun test
|
|
39
|
+
bun run build
|
|
40
|
+
bun pm pack
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Credentials
|
|
44
|
+
|
|
45
|
+
Use the variables in [.env.example](.env.example). Export them in the shell before
|
|
46
|
+
running the CLI. Exports from `~/.zshrc` work when inherited by the process; the CLI
|
|
47
|
+
never reads or executes your shell configuration. Bun loads a project `.env` during
|
|
48
|
+
development; the built Node executable expects exported environment variables.
|
|
49
|
+
|
|
50
|
+
Clockify uses its global API endpoint; regional Clockify workspaces are not yet
|
|
51
|
+
supported. It requires an API key, workspace ID, and user ID. The configured user must
|
|
52
|
+
match the authenticated account. API keys are available in Clockify profile settings.
|
|
53
|
+
|
|
54
|
+
Only five shell exports are required: `CLOCKIFY_API_KEY`, `CLOCKIFY_USER_ID`,
|
|
55
|
+
`CLOCKIFY_WORKSPACE_ID`, `ZOHO_CLIENT_ID`, and `ZOHO_CLIENT_SECRET`.
|
|
56
|
+
|
|
57
|
+
On first run, browser authorization starts automatically. The default data center
|
|
58
|
+
is `people.zoho.com`; `ZOHO_REGION` remains an optional override.
|
|
59
|
+
Register `http://localhost:8765/callback` in your server-based OAuth client once.
|
|
60
|
+
The CLI starts a temporary loopback listener and opens the consent URL. After
|
|
61
|
+
authorization, the CLI continues automatically. The listener closes after the
|
|
62
|
+
callback, cancellation, or a five-minute timeout. Port 8765 must be available.
|
|
63
|
+
|
|
64
|
+
The CLI requests `ZOHOPEOPLE.timetracker.ALL`, `ZOHOPEOPLE.forms.READ`, and
|
|
65
|
+
`AaaServer.profile.READ`. It exchanges the code, looks up your People employee
|
|
66
|
+
record using your email, and saves the refresh token, region, and employee ID.
|
|
67
|
+
If employee lookup is unavailable, it asks for the numeric employee record ID
|
|
68
|
+
(ERECNO). Later runs reuse the saved authentication without additional exports.
|
|
69
|
+
Run `bun run dev --connect` to reconnect; saved job preferences are preserved.
|
|
70
|
+
|
|
71
|
+
Existing `ZOHO_REFRESH_TOKEN`, `ZOHO_REGION`, and `ZOHO_EMPLOYEE_ID` exports
|
|
72
|
+
remain optional overrides. Set `ZOHO_DATE_FORMAT` when your company returns
|
|
73
|
+
non-ISO dates, for example `dd-MM-yyyy` or `MM/dd/yyyy`.
|
|
74
|
+
|
|
75
|
+
- [Zoho People OAuth setup](https://www.zoho.com/people/api/oauth-steps.html)
|
|
76
|
+
- [Zoho People time-log API](https://www.zoho.com/people/api/timesheet/add-timelogs.html)
|
|
77
|
+
- [Clockify API](https://docs.clockify.me/)
|
|
78
|
+
|
|
79
|
+
The CLI refreshes access tokens in memory. Local preferences contain project/job mappings. A separate account-scoped authentication file stores the refresh token
|
|
80
|
+
with owner-only file permissions (0600); client secrets are never saved. Protect
|
|
81
|
+
the state directory because it now contains authentication and work information.
|
|
82
|
+
|
|
83
|
+
## Selection and mapping
|
|
84
|
+
|
|
85
|
+
The range menu contains Today, Yesterday, This week, Last week, and This month.
|
|
86
|
+
Weeks start on Monday. Current periods stop at the time the CLI starts; completed
|
|
87
|
+
periods use local calendar boundaries. Set `ZSYNC_TIMEZONE` to an IANA timezone if
|
|
88
|
+
the machine's timezone differs from yours.
|
|
89
|
+
|
|
90
|
+
Completed entries are assigned to their **local start date**. An entry beginning
|
|
91
|
+
before midnight and ending afterward is copied whole to its start date. Entries
|
|
92
|
+
longer than 24 hours or rounding to zero minutes are rejected for correction in
|
|
93
|
+
Clockify. Running timers are excluded. Durations round to the nearest minute, and
|
|
94
|
+
the preview shows the duration sent to Zoho. Clockify descriptions become Zoho
|
|
95
|
+
Work Items. Zoho Description stores JSON source metadata: the exact Clockify entry
|
|
96
|
+
ID, project name/ID, tags, original start/end timestamps, and billing flag, followed
|
|
97
|
+
by the existing sync marker. Metadata contains no credentials.
|
|
98
|
+
|
|
99
|
+
Older synced entries remain unchecked. Select one to move its title into Work Item
|
|
100
|
+
and replace its Description with metadata, updating the existing Zoho log. Selected entries overwrite differing destination fields with Clockify values.
|
|
101
|
+
|
|
102
|
+
Unsynced entries start checked. Synced entries, including changed ones, start
|
|
103
|
+
unchecked. Selecting an unchanged entry skips it; selecting a changed entry updates
|
|
104
|
+
its existing Zoho log when safe. If a Clockify project has exactly one matching
|
|
105
|
+
Zoho project/job name, that job is used. Otherwise, select the job explicitly.
|
|
106
|
+
Mappings are remembered per account. No Zoho jobs or projects are created.
|
|
107
|
+
|
|
108
|
+
The entry table fits the terminal width and truncates long cells with an ellipsis.
|
|
109
|
+
Date appears from 90 columns and Tags from 110 columns. The selected rows remain visible above the final confirmation.
|
|
110
|
+
|
|
111
|
+
Use Space to toggle entries and Enter to continue. The final Yes/No prompt requires
|
|
112
|
+
submission even though Yes is initially selected. No and cancellation make no Zoho
|
|
113
|
+
writes; local job mappings may already have been saved.
|
|
114
|
+
|
|
115
|
+
## Reruns and recovery
|
|
116
|
+
|
|
117
|
+
Sync status comes from metadata in Zoho Description, using the exact Clockify
|
|
118
|
+
entry ID. Matching logs start unchecked; selecting a changed entry updates its
|
|
119
|
+
existing log. Deleting a Zoho log makes the Clockify entry new and checked again.
|
|
120
|
+
Duplicate source IDs and locked logs are conflicts. Unmarked manual logs do not
|
|
121
|
+
count as synced, even if their titles and durations match.
|
|
122
|
+
|
|
123
|
+
Only authentication and project/job preferences are stored locally. Existing
|
|
124
|
+
legacy state files supply job preferences only; their ledger, pending writes, and
|
|
125
|
+
lock are ignored. New writes store preferences in `zsync-preferences-*.json`.
|
|
126
|
+
Legacy marker-only logs are recognized with their original account scope; logs
|
|
127
|
+
containing the exact entry ID work across machines and OAuth clients.
|
|
128
|
+
|
|
129
|
+
The CLI rechecks Zoho before committing and verifies each write. A timed-out write
|
|
130
|
+
is reconciled using remote metadata, never blindly retried in the same run. If
|
|
131
|
+
verification remains uncertain, inspect Zoho before rerunning. No persistent pending
|
|
132
|
+
queue or concurrent-execution protection is provided.
|
|
133
|
+
|
|
134
|
+
Lookup covers the selected entries' date span. If a previously synced entry moves
|
|
135
|
+
to a different date outside that span, reconcile the old Zoho log before syncing
|
|
136
|
+
again. Do not run syncs simultaneously on multiple machines.
|
|
137
|
+
|
|
138
|
+
Clockify remains the source of truth. This tool does not delete destination logs,
|
|
139
|
+
submit or approve timesheets, or synchronize Zoho edits back to Clockify. Zoho
|
|
140
|
+
workspace rules can reject time outside attendance, leave, allowed dates, or job
|
|
141
|
+
permissions. Failures are reported per entry and cause a nonzero exit status.
|
|
142
|
+
|
|
143
|
+
## Before first real sync
|
|
144
|
+
|
|
145
|
+
Run `--demo` to inspect the flow without credentials or network calls. Then use a
|
|
146
|
+
small authorized selection and verify its destination in Zoho People. Live API
|
|
147
|
+
behavior and organization policies must be checked in your own account; automated
|
|
148
|
+
tests use fictional responses and never create actual time logs.
|
|
149
|
+
|
|
150
|
+
Default state directories are `~/.local/share/zsync` on Linux (or under
|
|
151
|
+
`XDG_DATA_HOME`), `~/Library/Application Support/zsync` on macOS, and
|
|
152
|
+
`%APPDATA%/zsync` on Windows. Changing the OAuth client or employee changes the
|
|
153
|
+
account scope for local preferences. Exact entry IDs in remote metadata still
|
|
154
|
+
identify synced entries across OAuth clients. Supported Zoho region codes are `com`, `eu`, `in`, `au`, `cn`, `jp`,
|
|
155
|
+
`ca`, `sa`, and `uk`; availability and permissions depend on your People account.
|