@murumets-ee/yhikas-sync 0.38.0
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 +94 -0
- package/README.md +192 -0
- package/dist/config-CHVLiXZf.d.mts +77 -0
- package/dist/config-CHVLiXZf.d.mts.map +1 -0
- package/dist/index.d.mts +1026 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1 -0
- package/dist/jobs-D2perJoW.mjs +2 -0
- package/dist/jobs-D2perJoW.mjs.map +1 -0
- package/dist/plugin.d.mts +25 -0
- package/dist/plugin.d.mts.map +1 -0
- package/dist/plugin.mjs +2 -0
- package/dist/plugin.mjs.map +1 -0
- package/dist/sync-state-table-CYl_DVX9.mjs +2 -0
- package/dist/sync-state-table-CYl_DVX9.mjs.map +1 -0
- package/dist/watchdog-CNsiJMUR.mjs +2 -0
- package/dist/watchdog-CNsiJMUR.mjs.map +1 -0
- package/package.json +44 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Elastic License 2.0 (ELv2)
|
|
2
|
+
|
|
3
|
+
URL: https://www.elastic.co/licensing/elastic-license
|
|
4
|
+
|
|
5
|
+
## Acceptance
|
|
6
|
+
|
|
7
|
+
By using the software, you agree to all of the terms and conditions below.
|
|
8
|
+
|
|
9
|
+
## Copyright License
|
|
10
|
+
|
|
11
|
+
The licensor grants you a non-exclusive, royalty-free, worldwide,
|
|
12
|
+
non-sublicensable, non-transferable license to use, copy, distribute, make
|
|
13
|
+
available, and prepare derivative works of the software, in each case subject
|
|
14
|
+
to the limitations and conditions below.
|
|
15
|
+
|
|
16
|
+
## Limitations
|
|
17
|
+
|
|
18
|
+
You may not provide the software to third parties as a hosted or managed
|
|
19
|
+
service, where the service provides users with access to any substantial set
|
|
20
|
+
of the features or functionality of the software.
|
|
21
|
+
|
|
22
|
+
You may not move, change, disable, or circumvent the license key functionality
|
|
23
|
+
in the software, and you may not remove or obscure any functionality in the
|
|
24
|
+
software that is protected by the license key.
|
|
25
|
+
|
|
26
|
+
You may not alter, remove, or obscure any licensing, copyright, or other
|
|
27
|
+
notices of the licensor in the software. Any use of the licensor's trademarks
|
|
28
|
+
is subject to applicable law.
|
|
29
|
+
|
|
30
|
+
## Patents
|
|
31
|
+
|
|
32
|
+
The licensor grants you a license, under any patent claims the licensor can
|
|
33
|
+
license, or becomes able to license, to make, have made, use, sell, offer for
|
|
34
|
+
sale, import and have imported the software, in each case subject to the
|
|
35
|
+
limitations and conditions in this license. This license does not cover any
|
|
36
|
+
patent claims that you cause to be infringed by modifications or additions to
|
|
37
|
+
the software. If you or your company make any written claim that the software
|
|
38
|
+
infringes or contributes to infringement of any patent, your patent license
|
|
39
|
+
for the software granted under these terms ends immediately. If your company
|
|
40
|
+
makes such a claim, your patent license ends immediately for work on behalf
|
|
41
|
+
of your company.
|
|
42
|
+
|
|
43
|
+
## Notices
|
|
44
|
+
|
|
45
|
+
You must ensure that anyone who gets a copy of any part of the software from
|
|
46
|
+
you also gets a copy of these terms.
|
|
47
|
+
|
|
48
|
+
If you modify the software, you must include in any modified copies of the
|
|
49
|
+
software prominent notices stating that you have modified the software.
|
|
50
|
+
|
|
51
|
+
## No Other Rights
|
|
52
|
+
|
|
53
|
+
These terms do not imply any licenses other than those expressly granted in
|
|
54
|
+
these terms.
|
|
55
|
+
|
|
56
|
+
## Termination
|
|
57
|
+
|
|
58
|
+
If you use the software in violation of these terms, such use is not licensed,
|
|
59
|
+
and your licenses will automatically terminate. If the licensor provides you
|
|
60
|
+
with a notice of your violation, and you cease all violation of this license
|
|
61
|
+
no later than 30 days after you receive that notice, your licenses will be
|
|
62
|
+
reinstated retroactively. However, if you violate these terms after such
|
|
63
|
+
reinstatement, any additional violation of these terms will cause your
|
|
64
|
+
licenses to terminate automatically and permanently.
|
|
65
|
+
|
|
66
|
+
## No Liability
|
|
67
|
+
|
|
68
|
+
As far as the law allows, the software comes as is, without any warranty or
|
|
69
|
+
condition, and the licensor will not be liable to you for any damages arising
|
|
70
|
+
out of these terms or the use or nature of the software, under any kind of
|
|
71
|
+
legal claim.
|
|
72
|
+
|
|
73
|
+
## Definitions
|
|
74
|
+
|
|
75
|
+
The **licensor** is the entity offering these terms, and the **software** is
|
|
76
|
+
the software the licensor makes available under these terms, including any
|
|
77
|
+
portion of it.
|
|
78
|
+
|
|
79
|
+
**you** refers to the individual or entity agreeing to these terms.
|
|
80
|
+
|
|
81
|
+
**your company** is any legal entity, sole proprietorship, or other kind of
|
|
82
|
+
organization that you work for, plus all organizations that have control over,
|
|
83
|
+
are under the control of, or are under common control with that organization.
|
|
84
|
+
**control** means ownership of substantially all the assets of an entity, or
|
|
85
|
+
the power to direct the management and policies of an entity (for example, by
|
|
86
|
+
voting right, contract, or otherwise). Control can be direct or indirect.
|
|
87
|
+
|
|
88
|
+
**your licenses** are all the licenses granted to you for the software under
|
|
89
|
+
these terms.
|
|
90
|
+
|
|
91
|
+
**use** means anything you do with the software requiring one of your
|
|
92
|
+
licenses.
|
|
93
|
+
|
|
94
|
+
**trademark** means trademarks, service marks, and similar rights.
|
package/README.md
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# `@murumets-ee/yhikas-sync`
|
|
2
|
+
|
|
3
|
+
A scheduled, one-directional pull of yhikas-admin's **room types** and **legal
|
|
4
|
+
documents** into lumi-cms content, so the yhikas public site reads exactly one
|
|
5
|
+
origin — its own content-api — and never learns that yhikas-admin exists.
|
|
6
|
+
|
|
7
|
+
Part of the `frontend-delivery` plan, phase 05 (D014).
|
|
8
|
+
|
|
9
|
+
## Why a pull and not a push
|
|
10
|
+
|
|
11
|
+
Three independent facts, each of which would decide it alone:
|
|
12
|
+
|
|
13
|
+
- **There is nothing to push with.** yhikas-admin has no webhook dispatch, no
|
|
14
|
+
outbound content HTTP, no content queue and no DB triggers. Its ~30
|
|
15
|
+
`revalidatePath`/`revalidateTag` calls all target admin pages — in-process
|
|
16
|
+
Next cache invalidation that never crosses a process boundary.
|
|
17
|
+
- **Its own rules discourage building one.** That app's CLAUDE.md rule 5 is
|
|
18
|
+
"NEVER create API routes for internal data operations", with rule 6 carving
|
|
19
|
+
out third-party integrations needing HTTP endpoints. A pull-only reader of
|
|
20
|
+
`/api/public/*` sits in the carve-out; a push dispatcher does not.
|
|
21
|
+
- **Nothing needs pushing.** `git log -S "monthlyRent" -- src/db/schema.ts`
|
|
22
|
+
returns one commit — the initial one, 2025-05-14 — against a repo whose HEAD
|
|
23
|
+
is 2026-08-03. This is a fee schedule revised at most yearly.
|
|
24
|
+
|
|
25
|
+
The diff is **full-snapshot**, and that is forced rather than chosen:
|
|
26
|
+
`room_type` carries no timestamp of any kind, and `legal_document`'s
|
|
27
|
+
`updated_at` is not in the API response. There is no cursor and no change feed.
|
|
28
|
+
|
|
29
|
+
## Wiring
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
// lumi.config.ts
|
|
33
|
+
import { content } from '@murumets-ee/content/plugin'
|
|
34
|
+
import { queue } from '@murumets-ee/queue/plugin'
|
|
35
|
+
import { yhikasSync } from '@murumets-ee/yhikas-sync/plugin'
|
|
36
|
+
|
|
37
|
+
export default defineLumiConfig({
|
|
38
|
+
plugins: [content({ /* … */ }), queue(), yhikasSync()],
|
|
39
|
+
})
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Both `@murumets-ee/content` and `@murumets-ee/queue` are declared in
|
|
43
|
+
`Plugin.requires`, so a misconfigured install fails at boot rather than at the
|
|
44
|
+
first sync — see "Per-locale publish" below for why content in particular is a
|
|
45
|
+
hard requirement rather than a nicety.
|
|
46
|
+
|
|
47
|
+
### Environment
|
|
48
|
+
|
|
49
|
+
| Variable | Purpose |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `YHIKAS_ADMIN_BASE_URL` | Origin of the yhikas-admin deployment, e.g. the Docker-internal `http://yhikas-admin:3000`. |
|
|
52
|
+
| `YHIKAS_SYNC_API_KEY` | The sync's **own** bearer credential. |
|
|
53
|
+
|
|
54
|
+
The credential is deliberately **not** the site's `PUBLIC_SITE_API_KEY`.
|
|
55
|
+
Upstream's rate limiter buckets on `sha256(key).slice(0,16)` rather than on the
|
|
56
|
+
caller IP — over the Docker-internal path there is no `x-forwarded-for` and
|
|
57
|
+
every caller resolves to `'unknown'` — so a shared key means a shared 60/min
|
|
58
|
+
bucket, and revoking one credential would blind both consumers.
|
|
59
|
+
|
|
60
|
+
The key is never part of the plugin's declared config: resolved config lands in
|
|
61
|
+
the framework's `PluginConfigRegistry`, a process-global any plugin can read,
|
|
62
|
+
and a secret does not belong there. It is read from the environment at job-run
|
|
63
|
+
time.
|
|
64
|
+
|
|
65
|
+
## What it does, and what it refuses to do
|
|
66
|
+
|
|
67
|
+
### Identity is the business key
|
|
68
|
+
|
|
69
|
+
`room_type.code` and `legal_document.type` — never the serial `id`, which is an
|
|
70
|
+
implementation detail of the other system and would make this system's content
|
|
71
|
+
depend on the other's insert order.
|
|
72
|
+
|
|
73
|
+
### Semantics this side declares
|
|
74
|
+
|
|
75
|
+
There is no currency column, no VAT column and no period column upstream;
|
|
76
|
+
EUR-net-per-month is a convention held in column *naming*. So `currency` and
|
|
77
|
+
`vatTreatment` are real columns here, written with constants, which means a
|
|
78
|
+
mis-entered source value renders as a **visibly wrong number against a declared
|
|
79
|
+
unit** rather than as a plausible one. Period stays in the field name
|
|
80
|
+
(`monthlyRent` / `dailyRent`) because one row carries two different periods.
|
|
81
|
+
|
|
82
|
+
Decimals stay **strings** end to end. `pg` returns `numeric` as a string and
|
|
83
|
+
upstream passes it through; parsing to a float would put rounding into a price.
|
|
84
|
+
Nulls likewise pass through untouched — a missing price is data, not a zero.
|
|
85
|
+
|
|
86
|
+
### Per-locale publish, and why `content` is required
|
|
87
|
+
|
|
88
|
+
One upstream row becomes one entity row with a translation per locale. When the
|
|
89
|
+
English text is empty — both columns are `notNull` upstream but nothing
|
|
90
|
+
validates non-emptiness, so `""` is the expected state of a half-filled row —
|
|
91
|
+
the English locale is set to `draft` and its translation row deleted. No empty
|
|
92
|
+
string is ever written as a translation value, and the English page cannot
|
|
93
|
+
render rather than rendering Estonian text under an English URL.
|
|
94
|
+
|
|
95
|
+
That mechanism is `AdminClient.updateForLocale`, which routes a non-default
|
|
96
|
+
locale's `status` into `<entity>_locale_status`. Two of its preconditions are
|
|
97
|
+
load-bearing, and both fail SILENTLY rather than loudly:
|
|
98
|
+
|
|
99
|
+
- **The locale-status writer must exist.** Without it `updateForLocale` falls
|
|
100
|
+
back to the base row's `status` column, so a request to unpublish English
|
|
101
|
+
would unpublish Estonian. The writer is installed by
|
|
102
|
+
`@murumets-ee/content`'s `init`, for entities that are `publishable()` with
|
|
103
|
+
at least one translatable field — which both entities here satisfy by
|
|
104
|
+
construction. `Plugin.requires` guarantees content is *configured*; the
|
|
105
|
+
*ordering* half is bought by constructing the AdminClients inside the job
|
|
106
|
+
handler rather than in `init`, because `createAdminClient` reads the writer
|
|
107
|
+
once, at construction. Hoisting that into `init` would reintroduce the hazard
|
|
108
|
+
while leaving the declaration green.
|
|
109
|
+
- **The default locale must be resolvable.** `updateForLocale` throws when it
|
|
110
|
+
can find one in neither its options nor the request context — and
|
|
111
|
+
`elevateRequestContext`, which the sync runs under, deliberately strips
|
|
112
|
+
`locale`/`defaultLocale`. So the adapter passes it explicitly on every call,
|
|
113
|
+
and it is read from `resolveI18nConfig(app)` rather than configured: a
|
|
114
|
+
configured copy could disagree with the app's real default, and that
|
|
115
|
+
disagreement writes the wrong language to the base row without failing.
|
|
116
|
+
|
|
117
|
+
### Deletion is a decision
|
|
118
|
+
|
|
119
|
+
A row that is published locally and absent upstream is **unpublished, never
|
|
120
|
+
deleted**. The row and its audit trail survive, and a wrongly-retired row heals
|
|
121
|
+
automatically on the next successful run. Two guards, both of which abort the
|
|
122
|
+
whole run before a single write:
|
|
123
|
+
|
|
124
|
+
1. **Nothing acts on an absence from a response that did not fully succeed.**
|
|
125
|
+
Every upstream failure path sets `success: false` (401, 429, 500), and the
|
|
126
|
+
wire schema pins `success: z.literal(true)` — so a refusal can never be
|
|
127
|
+
mistaken for an authoritative empty snapshot.
|
|
128
|
+
2. **A sanity floor.** An empty snapshot against non-empty local content is
|
|
129
|
+
refused at any size; a run retiring more than half of at least three
|
|
130
|
+
published rows is refused. Both are needed: the fraction rule is blind at the
|
|
131
|
+
two-row size a freshly seeded install lives at, and the empty-snapshot rule
|
|
132
|
+
is blind to the half-truncated response a partial failure actually produces.
|
|
133
|
+
|
|
134
|
+
An **oversized** snapshot is also refused rather than truncated — capping at N
|
|
135
|
+
and processing the first N would turn the dropped tail into apparent absences,
|
|
136
|
+
and therefore into mass retirement.
|
|
137
|
+
|
|
138
|
+
### Synced content is not editor-writable
|
|
139
|
+
|
|
140
|
+
An editable field the next run silently overwrites is a worse affordance than a
|
|
141
|
+
read-only one, because it looks like it worked. A `machineWritten` behavior
|
|
142
|
+
refuses every create/update/delete on the BASE row whose actor is not
|
|
143
|
+
`yhikas-sync`, including an administrator in the generic CRUD UI. (`access`
|
|
144
|
+
metadata and `admin.hidden` cannot do this — neither is read by the firewall.)
|
|
145
|
+
|
|
146
|
+
**The boundary, stated because a guard documented as total but actually partial
|
|
147
|
+
is worse than one whose limit is written down:** `saveTranslation` and
|
|
148
|
+
`deleteTranslation` run no behaviour hooks, so an edit made through the admin
|
|
149
|
+
*locale switcher* is not refused — and, because it does not change
|
|
150
|
+
`sourceHash`, the sync will not revert it either. Closing that needs a hook
|
|
151
|
+
seam on the translation write path, which is a framework change; tracked as
|
|
152
|
+
finding 12 on the plan.
|
|
153
|
+
|
|
154
|
+
## Observability
|
|
155
|
+
|
|
156
|
+
`yhikas_sync_state` holds one row per resource: when it last attempted, when it
|
|
157
|
+
last **succeeded**, the last error, and the counts from the last successful run.
|
|
158
|
+
|
|
159
|
+
A second scheduled job — the watchdog — alerts when the newest success is older
|
|
160
|
+
than the window, including the case where a sync has never succeeded at all.
|
|
161
|
+
This is new code because nothing shipped can detect it: the queue's heartbeat is
|
|
162
|
+
keyed on `workerId` and answers "is any worker alive", and its alerter fires
|
|
163
|
+
only from `failJob`'s dead-letter branch, i.e. only on a job that ran and
|
|
164
|
+
*threw*. A job that never starts produces no error at all. The watchdog throws,
|
|
165
|
+
and the throw reaches the shipped dedupe/digest/email path — so the detection is
|
|
166
|
+
new, the delivery is not.
|
|
167
|
+
|
|
168
|
+
Known limit, stated rather than papered over: the watchdog is itself a scheduled
|
|
169
|
+
job, so a worker that is entirely dead runs neither it nor the sync. That case
|
|
170
|
+
is what the queue's worker heartbeat *does* see. The two are complementary.
|
|
171
|
+
|
|
172
|
+
## Defaults
|
|
173
|
+
|
|
174
|
+
| Setting | Default | Why |
|
|
175
|
+
|---|---|---|
|
|
176
|
+
| `schedule` | `@every 6h` | Four successes a day against an annually-revised fee schedule. The interval form rather than cron: the queue's cron parser is UTC-only with no DST awareness, so a wall-clock schedule would shift twice a year. |
|
|
177
|
+
| `watchdogSchedule` | `@every 1h` | |
|
|
178
|
+
| `staleAfterMs` | 24h | Four consecutive failures before anyone is woken. |
|
|
179
|
+
| `requestTimeoutMs` | 15s | The queue has **no** per-job timeout; without a deadline a hung fetch holds a slot until lease recovery re-claims it and runs the handler twice, concurrently. |
|
|
180
|
+
| `maxRowsPerResource` | 500 | ~25 room types today. |
|
|
181
|
+
| `maxRetireFraction` | 0.5 | |
|
|
182
|
+
|
|
183
|
+
## Scope
|
|
184
|
+
|
|
185
|
+
**In:** room types and legal documents.
|
|
186
|
+
|
|
187
|
+
**Out:** `site_info` / `site_notice` — they have no write path anywhere in
|
|
188
|
+
yhikas-admin (no admin UI, no server action, no seed), so a sync would pull the
|
|
189
|
+
route's designed-empty fallback. Recorded as Q1, not dropped. Deposits, which
|
|
190
|
+
ship upstream as hardcoded `null` with no backing column. And any write path
|
|
191
|
+
back into yhikas-admin: the client exposes two methods and both are GETs, so
|
|
192
|
+
one-directionality is a property of the type rather than a rule to remember.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//#region src/config.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Plugin configuration — pure resolution, no I/O, no `server-only`.
|
|
4
|
+
*
|
|
5
|
+
* There is deliberately no `defaultLocale` knob either. The default locale is
|
|
6
|
+
* read from `@murumets-ee/content`'s `resolveI18nConfig(app)` at job-run time,
|
|
7
|
+
* because a configured copy could silently disagree with the app's actual
|
|
8
|
+
* default — and the consequences run both ways: `updateForLocale` would take
|
|
9
|
+
* its default-locale branch for what this package believed was the secondary
|
|
10
|
+
* locale and overwrite the base row with the wrong language, while no
|
|
11
|
+
* translation was written for the real one. Neither write fails. A knob whose
|
|
12
|
+
* only reachable states are "correct but redundant" and "wrong and silent" is a
|
|
13
|
+
* trap, not a setting.
|
|
14
|
+
*
|
|
15
|
+
* The bearer credential is deliberately NOT part of this object. Resolved
|
|
16
|
+
* config is stored in the framework's `PluginConfigRegistry`, which is a
|
|
17
|
+
* process-global any plugin can read; a secret belongs in the environment and
|
|
18
|
+
* is read at job-run time instead (`resolveCredential`). This mirrors
|
|
19
|
+
* `@murumets-ee/merit` D003 — the key never lands in a registry or the DB.
|
|
20
|
+
*/
|
|
21
|
+
interface YhikasSyncConfig {
|
|
22
|
+
/**
|
|
23
|
+
* Origin of the yhikas-admin deployment, e.g. `http://yhikas-admin:3000`
|
|
24
|
+
* over the Docker-internal network. Falls back to `YHIKAS_ADMIN_BASE_URL`.
|
|
25
|
+
*/
|
|
26
|
+
baseUrl?: string;
|
|
27
|
+
/** Cron/interval expression for the pull. Default `@every 6h` (D017). */
|
|
28
|
+
schedule?: string;
|
|
29
|
+
/** Cron/interval expression for the staleness watchdog. Default `@every 1h`. */
|
|
30
|
+
watchdogSchedule?: string;
|
|
31
|
+
/** Alert when the newest successful sync is older than this. Default 24h. */
|
|
32
|
+
staleAfterMs?: number;
|
|
33
|
+
/** Per-request deadline. The queue has NO per-job timeout (R012 §3). Default 15s. */
|
|
34
|
+
requestTimeoutMs?: number;
|
|
35
|
+
/** Refuse a snapshot larger than this rather than truncating it (D016). */
|
|
36
|
+
maxRowsPerResource?: number;
|
|
37
|
+
/** Refuse a run retiring more than this fraction of published rows. Default 0.5. */
|
|
38
|
+
maxRetireFraction?: number;
|
|
39
|
+
/** The fraction rule only applies once at least this many rows are published. Default 3. */
|
|
40
|
+
minRowsForRetireFloor?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Explicit opt-out. An unconfigured sync is a BROKEN sync, and a broken sync
|
|
43
|
+
* must be visibly broken (S7) — so an absent credential fails the job loudly
|
|
44
|
+
* rather than quietly skipping registration. Set this to `false` when the
|
|
45
|
+
* install genuinely has no yhikas-admin to talk to.
|
|
46
|
+
*/
|
|
47
|
+
enabled?: boolean;
|
|
48
|
+
}
|
|
49
|
+
interface ResolvedYhikasSyncConfig {
|
|
50
|
+
readonly baseUrl: string | undefined;
|
|
51
|
+
readonly schedule: string;
|
|
52
|
+
readonly watchdogSchedule: string;
|
|
53
|
+
readonly staleAfterMs: number;
|
|
54
|
+
readonly requestTimeoutMs: number;
|
|
55
|
+
readonly maxRowsPerResource: number;
|
|
56
|
+
readonly maxRetireFraction: number;
|
|
57
|
+
readonly minRowsForRetireFloor: number;
|
|
58
|
+
readonly enabled: boolean;
|
|
59
|
+
}
|
|
60
|
+
/** Thrown at plugin construction for a structurally invalid config. */
|
|
61
|
+
declare class YhikasSyncConfigError extends Error {
|
|
62
|
+
constructor(message: string);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Resolve config + environment into the frozen object the plugin declares.
|
|
66
|
+
*
|
|
67
|
+
* Throws only on a STRUCTURALLY invalid config — a nonsensical number. It never
|
|
68
|
+
* throws for a missing credential or a missing base URL: `lumi.config.ts` is
|
|
69
|
+
* loaded at build time by the CLI, and throwing there breaks every `lumi`
|
|
70
|
+
* command on a machine that simply has no secrets (see
|
|
71
|
+
* `gotcha_lumi_config_throw_at_build_time`). A missing credential surfaces at
|
|
72
|
+
* job-run time, where it becomes an alert.
|
|
73
|
+
*/
|
|
74
|
+
declare function resolveYhikasSyncConfig(config?: YhikasSyncConfig, env?: NodeJS.ProcessEnv): ResolvedYhikasSyncConfig;
|
|
75
|
+
//#endregion
|
|
76
|
+
export { resolveYhikasSyncConfig as i, YhikasSyncConfig as n, YhikasSyncConfigError as r, ResolvedYhikasSyncConfig as t };
|
|
77
|
+
//# sourceMappingURL=config-CHVLiXZf.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-CHVLiXZf.d.mts","names":[],"sources":["../src/config.ts"],"mappings":";;AA+BA;;;;;;;;;;;;;;AA0BS;AAGT;;;UA7BiB,gBAAA;EA8BN;;;;EAzBT,OAAA;EA8BS;EA5BT,QAAA;EA8BS;EA5BT,gBAAA;EA6BgB;EA3BhB,YAAA;EA+BW;EA7BX,gBAAA;;EAEA,kBAAA;EA2ByC;EAzBzC,iBAAA;EA0BY;EAxBZ,qBAAA;EAwB2B;AAoC7B;;;;;EArDE,OAAA;AAAA;AAAA,UAGe,wBAAA;EAAA,SACN,OAAA;EAAA,SACA,QAAA;EAAA,SACA,gBAAA;EAAA,SACA,YAAA;EAAA,SACA,gBAAA;EAAA,SACA,kBAAA;EAAA,SACA,iBAAA;EAAA,SACA,qBAAA;EAAA,SACA,OAAA;AAAA;;cAIE,qBAAA,SAA8B,KAAK;cAClC,OAAA;AAAA;;;;;;;;;;;iBAoCE,uBAAA,CACd,MAAA,GAAQ,gBAAA,EACR,GAAA,GAAK,MAAA,CAAO,UAAA,GACX,wBAAA"}
|