dsh-simple-usage-info 0.1.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 +21 -0
- package/README.md +269 -0
- package/cordis.patch.yml +35 -0
- package/lib/client.d.ts +85 -0
- package/lib/client.js +620 -0
- package/lib/holiday-source.d.ts +54 -0
- package/lib/holiday-source.js +154 -0
- package/lib/holidays.d.ts +19 -0
- package/lib/holidays.js +109 -0
- package/lib/index.d.ts +46 -0
- package/lib/index.js +263 -0
- package/lib/pricing.d.ts +105 -0
- package/lib/pricing.js +225 -0
- package/package.json +88 -0
package/lib/pricing.d.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-simple-usage-info — peak / off-peak pricing schedule types.
|
|
3
|
+
* @module dsh-simple-usage-info/pricing
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** Peak-rate window name. */
|
|
7
|
+
export declare const PEAK = 'peak'
|
|
8
|
+
/** Off-peak (discounted) window name. */
|
|
9
|
+
export declare const OFF_PEAK = 'off-peak'
|
|
10
|
+
|
|
11
|
+
/** Which window applies. */
|
|
12
|
+
export type PricingWindow = typeof PEAK | typeof OFF_PEAK
|
|
13
|
+
/**
|
|
14
|
+
* Why a window applies: a Chinese public holiday, a non-peak weekday, the peak
|
|
15
|
+
* clock windows, or none of them.
|
|
16
|
+
*/
|
|
17
|
+
export type PricingReason = 'holiday' | 'non-peak-day' | 'peak-hours' | 'outside-peak-hours'
|
|
18
|
+
|
|
19
|
+
/** Raw schedule configuration, as it arrives from the Cordis patch. */
|
|
20
|
+
export interface PricingScheduleInput {
|
|
21
|
+
readonly peakWindows?: readonly string[]
|
|
22
|
+
readonly peakDays?: readonly number[]
|
|
23
|
+
readonly holidays?: readonly string[]
|
|
24
|
+
readonly makeupWorkdays?: readonly string[]
|
|
25
|
+
readonly makeupWorkdaysArePeak?: boolean
|
|
26
|
+
readonly useBundledHolidays?: boolean
|
|
27
|
+
readonly offPeakDiscountPercent?: number
|
|
28
|
+
}
|
|
29
|
+
/** A validated schedule. */
|
|
30
|
+
export interface NormalizedSchedule {
|
|
31
|
+
readonly windows: readonly { readonly label: string; readonly start: number; readonly end: number }[]
|
|
32
|
+
readonly peakDays: ReadonlySet<number>
|
|
33
|
+
/** The bundled State Council table, before any fetched data replaces it. */
|
|
34
|
+
readonly bundledHolidays: readonly string[]
|
|
35
|
+
readonly bundledMakeupWorkdays: readonly string[]
|
|
36
|
+
/** Dates the operator added; always additive, even over fetched data. */
|
|
37
|
+
readonly configuredHolidays: readonly string[]
|
|
38
|
+
readonly configuredMakeupWorkdays: readonly string[]
|
|
39
|
+
/** The effective holiday set. */
|
|
40
|
+
readonly holidays: ReadonlySet<string>
|
|
41
|
+
readonly makeupWorkdays: ReadonlySet<string>
|
|
42
|
+
readonly makeupWorkdaysArePeak: boolean
|
|
43
|
+
readonly offPeakDiscountPercent: number
|
|
44
|
+
/** The years the effective holiday data covers. */
|
|
45
|
+
readonly coveredYears: readonly number[]
|
|
46
|
+
/** Where the holiday dates came from: fetched, bundled, or none. */
|
|
47
|
+
readonly holidayData: 'remote' | 'bundled' | 'none'
|
|
48
|
+
/** The State Council papers the data was scraped from, when fetched. */
|
|
49
|
+
readonly holidayPapers: readonly string[]
|
|
50
|
+
readonly label: string
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Validate raw configuration, seeding the holiday sets from the bundled table.
|
|
55
|
+
* @throws TypeError when a window, day, holiday, or discount is malformed.
|
|
56
|
+
*/
|
|
57
|
+
export declare function normalizeSchedule(raw: PricingScheduleInput): NormalizedSchedule
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Swap the bundled holiday table for a fetched snapshot, keeping configured
|
|
61
|
+
* dates additive. Returns the input unchanged when `remote` is undefined.
|
|
62
|
+
*/
|
|
63
|
+
export declare function withHolidayData(
|
|
64
|
+
schedule: NormalizedSchedule,
|
|
65
|
+
remote: import('./holiday-source.js').HolidaySnapshot | undefined
|
|
66
|
+
): NormalizedSchedule
|
|
67
|
+
|
|
68
|
+
/** The plain-JSON schedule the browser half repeats the rule from. */
|
|
69
|
+
export interface SerializedSchedule {
|
|
70
|
+
readonly peakWindows: readonly { readonly start: number; readonly end: number; readonly label: string }[]
|
|
71
|
+
readonly peakDays: readonly number[]
|
|
72
|
+
readonly holidays: readonly string[]
|
|
73
|
+
readonly makeupWorkdays: readonly string[]
|
|
74
|
+
readonly makeupWorkdaysArePeak: boolean
|
|
75
|
+
readonly offPeakDiscountPercent: number
|
|
76
|
+
readonly coveredYears: readonly number[]
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Project a schedule into plain JSON for the browser half. */
|
|
80
|
+
export declare function serializeSchedule(schedule: NormalizedSchedule): SerializedSchedule
|
|
81
|
+
|
|
82
|
+
/** The pricing block the route returns. */
|
|
83
|
+
export interface PricingReading {
|
|
84
|
+
readonly window: PricingWindow
|
|
85
|
+
readonly reason: PricingReason
|
|
86
|
+
readonly discountPercent: number
|
|
87
|
+
readonly nextChangeAt?: number
|
|
88
|
+
readonly nextWindow?: PricingWindow
|
|
89
|
+
/** Human-readable UTC summary, e.g. `01:00-04:00, 06:00-10:00 UTC, Mon/Tue/...`. */
|
|
90
|
+
readonly schedule: string
|
|
91
|
+
/** The UTC year the reading was evaluated in. */
|
|
92
|
+
readonly holidayYear: number
|
|
93
|
+
/** Whether the effective holiday data covers `holidayYear`. */
|
|
94
|
+
readonly holidayCovered: boolean
|
|
95
|
+
/** The State Council paper or bundled notice for `holidayYear`, when known. */
|
|
96
|
+
readonly holidayNotice?: string
|
|
97
|
+
/** Where the holiday dates came from: fetched, bundled, or none. */
|
|
98
|
+
readonly holidayData: 'remote' | 'bundled' | 'none'
|
|
99
|
+
readonly now: number
|
|
100
|
+
/** The serializable schedule the browser half evaluates from. */
|
|
101
|
+
readonly windows: SerializedSchedule
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Describe the pricing window in force at one instant. */
|
|
105
|
+
export declare function readPricing(schedule: NormalizedSchedule, instant: number): PricingReading
|
package/lib/pricing.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSeek peak / off-peak pricing windows.
|
|
3
|
+
*
|
|
4
|
+
* Policy, per https://api-docs.deepseek.com/quick_start/pricing :
|
|
5
|
+
*
|
|
6
|
+
* "Off-peak rates are half of the peak rates. Peak hours are 01:00 - 04:00 and
|
|
7
|
+
* 06:00 - 10:00 UTC, Monday through Friday, excluding Chinese public holidays.
|
|
8
|
+
* All other hours are off-peak, including weekends and Chinese public holidays
|
|
9
|
+
* in full."
|
|
10
|
+
*
|
|
11
|
+
* The windows are defined in UTC, so the price of a given instant is the same
|
|
12
|
+
* everywhere; only the clock the user reads it on differs. Everything here is
|
|
13
|
+
* therefore absolute-instant arithmetic, and the browser half repeats the same
|
|
14
|
+
* small rule to stay live between polls and to render the windows in the user's
|
|
15
|
+
* own timezone.
|
|
16
|
+
*
|
|
17
|
+
* Chinese public holidays come from `lib/holidays.js`, merged with any dates the
|
|
18
|
+
* operator adds in config.
|
|
19
|
+
*
|
|
20
|
+
* @module dsh-simple-usage-info/pricing
|
|
21
|
+
*/
|
|
22
|
+
import { COVERED_YEARS, bundledHolidays, bundledMakeupWorkdays, noticeFor } from './holidays.js'
|
|
23
|
+
|
|
24
|
+
/** Peak-rate window name. */
|
|
25
|
+
export const PEAK = 'peak'
|
|
26
|
+
/** Off-peak (discounted) window name. */
|
|
27
|
+
export const OFF_PEAK = 'off-peak'
|
|
28
|
+
|
|
29
|
+
/** `HH:MM` -> minutes since UTC midnight. */
|
|
30
|
+
const CLOCK = /^([01]\d|2[0-3]):([0-5]\d)$/
|
|
31
|
+
/** `HH:MM-HH:MM` -> one window. */
|
|
32
|
+
const WINDOW = /^([01]\d|2[0-3]):([0-5]\d)-([01]\d|2[0-3]):([0-5]\d)$/
|
|
33
|
+
|
|
34
|
+
/** Minutes since UTC midnight for one `HH:MM`. */
|
|
35
|
+
function clockMinutes(text) {
|
|
36
|
+
const match = CLOCK.exec(text)
|
|
37
|
+
if (match === null) throw new TypeError(`clock "${text}" must be HH:MM in 24-hour UTC`)
|
|
38
|
+
return Number(match[1]) * 60 + Number(match[2])
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** `YYYY-MM-DD` for one instant's UTC date. */
|
|
42
|
+
function utcDayKey(instant) {
|
|
43
|
+
const date = new Date(instant)
|
|
44
|
+
const pad = (value) => String(value).padStart(2, '0')
|
|
45
|
+
return `${date.getUTCFullYear()}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())}`
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Weekday names, indexed by `Date#getUTCDay`. */
|
|
49
|
+
const DAY_NAMES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Validate raw configuration into the shape the readers below consume.
|
|
53
|
+
* Bundled Chinese public holidays are merged in unless `useBundledHolidays` is
|
|
54
|
+
* false; `holidays` is always additive, so it covers years the table does not.
|
|
55
|
+
* @param raw - the plugin's pricing configuration.
|
|
56
|
+
* @returns a detached, validated schedule.
|
|
57
|
+
* @throws TypeError when a window, day, holiday, or discount is malformed.
|
|
58
|
+
*/
|
|
59
|
+
export function normalizeSchedule(raw) {
|
|
60
|
+
const windows = (raw.peakWindows ?? []).map((text) => {
|
|
61
|
+
const match = WINDOW.exec(text)
|
|
62
|
+
if (match === null) throw new TypeError(`peak window "${text}" must be HH:MM-HH:MM in 24-hour UTC`)
|
|
63
|
+
const start = clockMinutes(`${match[1]}:${match[2]}`)
|
|
64
|
+
const end = clockMinutes(`${match[3]}:${match[4]}`)
|
|
65
|
+
if (end <= start) throw new TypeError(`peak window "${text}" must not wrap past midnight; write overnight coverage as two windows`)
|
|
66
|
+
return { label: text, start, end }
|
|
67
|
+
})
|
|
68
|
+
const days = (raw.peakDays ?? []).map((day) => {
|
|
69
|
+
if (!Number.isInteger(day) || day < 0 || day > 6) throw new TypeError(`peak day ${String(day)} must be 0 (Sunday) through 6 (Saturday)`)
|
|
70
|
+
return day
|
|
71
|
+
})
|
|
72
|
+
const asDates = (values, label) =>
|
|
73
|
+
(values ?? []).map((day) => {
|
|
74
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(day)) throw new TypeError(`${label} "${day}" must be YYYY-MM-DD`)
|
|
75
|
+
return day
|
|
76
|
+
})
|
|
77
|
+
const discount = raw.offPeakDiscountPercent ?? 50
|
|
78
|
+
if (typeof discount !== 'number' || discount < 0 || discount > 100) throw new TypeError(`offPeakDiscountPercent ${String(discount)} must be between 0 and 100`)
|
|
79
|
+
|
|
80
|
+
const useBundled = raw.useBundledHolidays !== false
|
|
81
|
+
// The bundled and configured dates are kept apart from the effective sets so
|
|
82
|
+
// `withHolidayData` can swap the bundled half for fetched data while leaving
|
|
83
|
+
// the operator's own additions in place.
|
|
84
|
+
const bundled = useBundled ? bundledHolidays() : []
|
|
85
|
+
const bundledMakeup = useBundled ? bundledMakeupWorkdays() : []
|
|
86
|
+
const configured = asDates(raw.holidays, 'holiday')
|
|
87
|
+
const configuredMakeup = asDates(raw.makeupWorkdays, 'makeup workday')
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
windows,
|
|
91
|
+
peakDays: new Set(days),
|
|
92
|
+
bundledHolidays: bundled,
|
|
93
|
+
bundledMakeupWorkdays: bundledMakeup,
|
|
94
|
+
configuredHolidays: configured,
|
|
95
|
+
configuredMakeupWorkdays: configuredMakeup,
|
|
96
|
+
holidays: new Set([...bundled, ...configured]),
|
|
97
|
+
makeupWorkdays: new Set([...bundledMakeup, ...configuredMakeup]),
|
|
98
|
+
makeupWorkdaysArePeak: raw.makeupWorkdaysArePeak === true,
|
|
99
|
+
offPeakDiscountPercent: discount,
|
|
100
|
+
coveredYears: useBundled ? COVERED_YEARS : [],
|
|
101
|
+
holidayData: useBundled ? 'bundled' : 'none',
|
|
102
|
+
holidayPapers: [],
|
|
103
|
+
label: `${windows.map((window) => window.label).join(', ')} UTC, ${days.length === 0 ? 'no' : days.map((day) => DAY_NAMES[day]).join('/')}`
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Swap the bundled holiday table for fetched data.
|
|
109
|
+
*
|
|
110
|
+
* The fetched snapshot (see `lib/holiday-source.js`) replaces the bundled half
|
|
111
|
+
* entirely; dates the operator configured are always additive on top, so a
|
|
112
|
+
* private calendar can extend the official one.
|
|
113
|
+
* @param schedule - a normalized schedule.
|
|
114
|
+
* @param remote - the source's snapshot, or undefined to keep the bundled table.
|
|
115
|
+
* @returns a derived schedule; the input is not mutated.
|
|
116
|
+
*/
|
|
117
|
+
export function withHolidayData(schedule, remote) {
|
|
118
|
+
if (remote === undefined) return schedule
|
|
119
|
+
return {
|
|
120
|
+
...schedule,
|
|
121
|
+
holidays: new Set([...remote.holidays, ...schedule.configuredHolidays]),
|
|
122
|
+
makeupWorkdays: new Set([...remote.makeupWorkdays, ...schedule.configuredMakeupWorkdays]),
|
|
123
|
+
coveredYears: remote.years,
|
|
124
|
+
holidayData: 'remote',
|
|
125
|
+
holidayPapers: remote.papers
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Project a schedule into plain JSON for the browser half, which repeats the
|
|
131
|
+
* rule locally so the badge can flip on time and render in the user's timezone.
|
|
132
|
+
* @param schedule - a normalized schedule.
|
|
133
|
+
* @returns a serializable copy.
|
|
134
|
+
*/
|
|
135
|
+
export function serializeSchedule(schedule) {
|
|
136
|
+
return {
|
|
137
|
+
peakWindows: schedule.windows.map((window) => ({ start: window.start, end: window.end, label: window.label })),
|
|
138
|
+
peakDays: [...schedule.peakDays].sort((left, right) => left - right),
|
|
139
|
+
holidays: [...schedule.holidays].sort(),
|
|
140
|
+
makeupWorkdays: [...schedule.makeupWorkdays].sort(),
|
|
141
|
+
makeupWorkdaysArePeak: schedule.makeupWorkdaysArePeak,
|
|
142
|
+
offPeakDiscountPercent: schedule.offPeakDiscountPercent,
|
|
143
|
+
coveredYears: [...schedule.coveredYears]
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Which window one instant falls in.
|
|
149
|
+
* @param schedule - a normalized schedule.
|
|
150
|
+
* @param instant - epoch milliseconds.
|
|
151
|
+
* @returns the window and why it applies.
|
|
152
|
+
*/
|
|
153
|
+
function stateAt(schedule, instant) {
|
|
154
|
+
const date = new Date(instant)
|
|
155
|
+
const key = utcDayKey(instant)
|
|
156
|
+
if (schedule.holidays.has(key)) return { window: OFF_PEAK, reason: 'holiday' }
|
|
157
|
+
// The published rule says "Monday through Friday", so a 调休 makeup workday is
|
|
158
|
+
// off-peak unless the operator opts into treating it as a working day.
|
|
159
|
+
const makesUp = schedule.makeupWorkdaysArePeak && schedule.makeupWorkdays.has(key)
|
|
160
|
+
if (!makesUp && !schedule.peakDays.has(date.getUTCDay())) return { window: OFF_PEAK, reason: 'non-peak-day' }
|
|
161
|
+
const minutes = date.getUTCHours() * 60 + date.getUTCMinutes()
|
|
162
|
+
for (const window of schedule.windows) {
|
|
163
|
+
if (minutes >= window.start && minutes < window.end) return { window: PEAK, reason: 'peak-hours' }
|
|
164
|
+
}
|
|
165
|
+
return { window: OFF_PEAK, reason: 'outside-peak-hours' }
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* The first instant after `instant` whose window differs from the current one.
|
|
170
|
+
* Walks the candidate boundaries (UTC midnight plus every window edge) over the
|
|
171
|
+
* next eight days, which is enough to cross any weekend or holiday run.
|
|
172
|
+
* @param schedule - a normalized schedule.
|
|
173
|
+
* @param instant - epoch milliseconds.
|
|
174
|
+
* @returns the next boundary, or `undefined` when none is found.
|
|
175
|
+
*/
|
|
176
|
+
function nextChange(schedule, instant) {
|
|
177
|
+
const base = new Date(instant)
|
|
178
|
+
const year = base.getUTCFullYear()
|
|
179
|
+
const month = base.getUTCMonth()
|
|
180
|
+
const day = base.getUTCDate()
|
|
181
|
+
const current = stateAt(schedule, instant).window
|
|
182
|
+
const candidates = []
|
|
183
|
+
for (let offset = 0; offset <= 8; offset += 1) {
|
|
184
|
+
const midnight = Date.UTC(year, month, day + offset, 0, 0, 0, 0)
|
|
185
|
+
candidates.push(midnight)
|
|
186
|
+
for (const window of schedule.windows) {
|
|
187
|
+
candidates.push(midnight + window.start * 60000)
|
|
188
|
+
candidates.push(midnight + window.end * 60000)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
for (const candidate of candidates.filter((value) => value > instant).sort((left, right) => left - right)) {
|
|
192
|
+
const state = stateAt(schedule, candidate)
|
|
193
|
+
if (state.window !== current) return { at: candidate, window: state.window }
|
|
194
|
+
}
|
|
195
|
+
return { at: undefined, window: undefined }
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Describe the pricing window in force at one instant.
|
|
200
|
+
* @param schedule - a normalized schedule.
|
|
201
|
+
* @param instant - epoch milliseconds to evaluate.
|
|
202
|
+
* @returns the window, its reason, the discount, the next transition, and the
|
|
203
|
+
* serializable schedule the browser half repeats the rule from.
|
|
204
|
+
*/
|
|
205
|
+
export function readPricing(schedule, instant) {
|
|
206
|
+
const state = stateAt(schedule, instant)
|
|
207
|
+
const next = nextChange(schedule, instant)
|
|
208
|
+
const year = new Date(instant).getUTCFullYear()
|
|
209
|
+
return {
|
|
210
|
+
window: state.window,
|
|
211
|
+
reason: state.reason,
|
|
212
|
+
discountPercent: state.window === OFF_PEAK ? schedule.offPeakDiscountPercent : 0,
|
|
213
|
+
nextChangeAt: next.at,
|
|
214
|
+
nextWindow: next.window,
|
|
215
|
+
schedule: schedule.label,
|
|
216
|
+
holidayYear: year,
|
|
217
|
+
holidayCovered: schedule.coveredYears.includes(year),
|
|
218
|
+
// A fetched year cites the State Council paper; the bundled table cites its
|
|
219
|
+
// own notice. Either way the operator can see where the dates came from.
|
|
220
|
+
holidayNotice: schedule.holidayPapers?.[0] ?? noticeFor(year),
|
|
221
|
+
holidayData: schedule.holidayData,
|
|
222
|
+
now: instant,
|
|
223
|
+
windows: serializeSchedule(schedule)
|
|
224
|
+
}
|
|
225
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-simple-usage-info",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "DeepSeek Harness plugin: your DeepSeek API balance and the current peak/off-peak billing window, below the message input.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"dsh",
|
|
7
|
+
"deepseek-harness",
|
|
8
|
+
"deepseek",
|
|
9
|
+
"plugin",
|
|
10
|
+
"cordis",
|
|
11
|
+
"balance",
|
|
12
|
+
"usage",
|
|
13
|
+
"pricing",
|
|
14
|
+
"peak",
|
|
15
|
+
"off-peak",
|
|
16
|
+
"dsh-plugin"
|
|
17
|
+
],
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"author": "Marjose Darang",
|
|
20
|
+
"homepage": "https://github.com/MarJose123/dsh-simple-usage-info#readme",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/MarJose123/dsh-simple-usage-info.git"
|
|
24
|
+
},
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/MarJose123/dsh-simple-usage-info/issues"
|
|
27
|
+
},
|
|
28
|
+
"type": "module",
|
|
29
|
+
"main": "lib/index.js",
|
|
30
|
+
"types": "lib/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./lib/index.d.ts",
|
|
34
|
+
"default": "./lib/index.js"
|
|
35
|
+
},
|
|
36
|
+
"./client": {
|
|
37
|
+
"types": "./lib/client.d.ts",
|
|
38
|
+
"default": "./lib/client.js"
|
|
39
|
+
},
|
|
40
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
41
|
+
"./package.json": "./package.json"
|
|
42
|
+
},
|
|
43
|
+
"files": [
|
|
44
|
+
"lib",
|
|
45
|
+
"cordis.patch.yml"
|
|
46
|
+
],
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=20"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"preflight": "node test/preflight-host.mjs && node test/preflight-pricing.mjs && node test/preflight-holidays.mjs && node test/preflight-client.mjs",
|
|
55
|
+
"preflight:host": "node test/preflight-host.mjs",
|
|
56
|
+
"preflight:pricing": "node test/preflight-pricing.mjs",
|
|
57
|
+
"preflight:holidays": "node test/preflight-holidays.mjs",
|
|
58
|
+
"preflight:client": "node test/preflight-client.mjs",
|
|
59
|
+
"preflight:live": "node test/preflight-live.mjs",
|
|
60
|
+
"preview:panel": "node test/preview-panel.mjs",
|
|
61
|
+
"verify:compose": "sh test/make-probe-home.sh && DSH_HOME=$PWD/tmp/probe-home dsh --profile web --dump-config | grep -A4 usage-info"
|
|
62
|
+
},
|
|
63
|
+
"dsh": {
|
|
64
|
+
"bundle": {
|
|
65
|
+
"patch": "./cordis.patch.yml"
|
|
66
|
+
},
|
|
67
|
+
"client": {
|
|
68
|
+
"inject": [
|
|
69
|
+
"@deepseek-ai/dsh-client-ui-conversation"
|
|
70
|
+
],
|
|
71
|
+
"platform": "web"
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"@deepseek-ai/cordis": "~4.0.4",
|
|
76
|
+
"@deepseek-ai/dsh-credentials": "0.2.0-rc.2",
|
|
77
|
+
"@deepseek-ai/dsh-launch-environment": "0.2.0-rc.2",
|
|
78
|
+
"@deepseek-ai/schemastery": "~3.18.4"
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"@deepseek-ai/cordis": "~4.0.4",
|
|
82
|
+
"@deepseek-ai/dsh-credentials": "0.2.0-rc.2",
|
|
83
|
+
"@deepseek-ai/dsh-launch-environment": "0.2.0-rc.2",
|
|
84
|
+
"@deepseek-ai/schemastery": "~3.18.4",
|
|
85
|
+
"react": "^18.3.1",
|
|
86
|
+
"react-dom": "^18.3.1"
|
|
87
|
+
}
|
|
88
|
+
}
|