@wat-toolbox/wat 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 +62 -0
- package/dist/cli/commands/availability.d.ts +10 -0
- package/dist/cli/commands/availability.d.ts.map +1 -0
- package/dist/cli/commands/availability.js +83 -0
- package/dist/cli/commands/availability.js.map +1 -0
- package/dist/cli/commands/bookings.d.ts +12 -0
- package/dist/cli/commands/bookings.d.ts.map +1 -0
- package/dist/cli/commands/bookings.js +195 -0
- package/dist/cli/commands/bookings.js.map +1 -0
- package/dist/cli/commands/config.d.ts +7 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +59 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/login.d.ts +11 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/login.js +127 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/logout.d.ts +8 -0
- package/dist/cli/commands/logout.d.ts.map +1 -0
- package/dist/cli/commands/logout.js +38 -0
- package/dist/cli/commands/logout.js.map +1 -0
- package/dist/cli/commands/rooms.d.ts +22 -0
- package/dist/cli/commands/rooms.d.ts.map +1 -0
- package/dist/cli/commands/rooms.js +76 -0
- package/dist/cli/commands/rooms.js.map +1 -0
- package/dist/cli/commands/whoami.d.ts +6 -0
- package/dist/cli/commands/whoami.d.ts.map +1 -0
- package/dist/cli/commands/whoami.js +37 -0
- package/dist/cli/commands/whoami.js.map +1 -0
- package/dist/cli/index.d.ts +22 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +61 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/output.d.ts +28 -0
- package/dist/cli/utils/output.d.ts.map +1 -0
- package/dist/cli/utils/output.js +40 -0
- package/dist/cli/utils/output.js.map +1 -0
- package/dist/cli/utils/require-key.d.ts +6 -0
- package/dist/cli/utils/require-key.d.ts.map +1 -0
- package/dist/cli/utils/require-key.js +18 -0
- package/dist/cli/utils/require-key.js.map +1 -0
- package/dist/utils/api-client.d.ts +35 -0
- package/dist/utils/api-client.d.ts.map +1 -0
- package/dist/utils/api-client.js +98 -0
- package/dist/utils/api-client.js.map +1 -0
- package/dist/utils/auth-flow-client.d.ts +60 -0
- package/dist/utils/auth-flow-client.d.ts.map +1 -0
- package/dist/utils/auth-flow-client.js +28 -0
- package/dist/utils/auth-flow-client.js.map +1 -0
- package/dist/utils/config.d.ts +95 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +246 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/rooms-client.d.ts +70 -0
- package/dist/utils/rooms-client.d.ts.map +1 -0
- package/dist/utils/rooms-client.js +59 -0
- package/dist/utils/rooms-client.js.map +1 -0
- package/dist/utils/time.d.ts +37 -0
- package/dist/utils/time.d.ts.map +1 -0
- package/dist/utils/time.js +130 -0
- package/dist/utils/time.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin wrappers around `apiCall` for the CLI login flow + key verification.
|
|
3
|
+
*/
|
|
4
|
+
import { type ApiResult } from './api-client.js';
|
|
5
|
+
export interface RequestLoginOtpOutput {
|
|
6
|
+
email: string;
|
|
7
|
+
expiresInSeconds: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function requestLoginOtp(input: {
|
|
10
|
+
email: string;
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
}): Promise<ApiResult<RequestLoginOtpOutput>>;
|
|
13
|
+
export interface CompleteLoginOutput {
|
|
14
|
+
organizationId: string;
|
|
15
|
+
organizationName: string;
|
|
16
|
+
created: boolean;
|
|
17
|
+
member: {
|
|
18
|
+
id: string;
|
|
19
|
+
email: string;
|
|
20
|
+
name: string | null;
|
|
21
|
+
role: string;
|
|
22
|
+
};
|
|
23
|
+
apiKey: {
|
|
24
|
+
keyId: string;
|
|
25
|
+
raw: string;
|
|
26
|
+
keyPrefix: string;
|
|
27
|
+
name: string;
|
|
28
|
+
scopes: string[];
|
|
29
|
+
createdAt: string;
|
|
30
|
+
expiresAt?: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export declare function completeLogin(input: {
|
|
34
|
+
email: string;
|
|
35
|
+
code: string;
|
|
36
|
+
signupCode?: string;
|
|
37
|
+
apiKey?: {
|
|
38
|
+
name?: string;
|
|
39
|
+
expiresInDays?: number;
|
|
40
|
+
};
|
|
41
|
+
baseUrl?: string;
|
|
42
|
+
}): Promise<ApiResult<CompleteLoginOutput>>;
|
|
43
|
+
export interface VerifyApiKeyOutput {
|
|
44
|
+
organizationId: string;
|
|
45
|
+
organizationName: string;
|
|
46
|
+
memberId: string;
|
|
47
|
+
role: string;
|
|
48
|
+
email: string;
|
|
49
|
+
name: string | null;
|
|
50
|
+
keyId: string;
|
|
51
|
+
keyName: string;
|
|
52
|
+
keyPrefix: string;
|
|
53
|
+
scopes: string[];
|
|
54
|
+
expiresAt?: string;
|
|
55
|
+
}
|
|
56
|
+
export declare function verifyApiKey(input: {
|
|
57
|
+
apiKey: string;
|
|
58
|
+
baseUrl?: string;
|
|
59
|
+
}): Promise<ApiResult<VerifyApiKeyOutput>>;
|
|
60
|
+
//# sourceMappingURL=auth-flow-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-flow-client.d.ts","sourceRoot":"","sources":["../../src/utils/auth-flow-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG1D,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAM5C;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACzE,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAO1C;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAMzC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin wrappers around `apiCall` for the CLI login flow + key verification.
|
|
3
|
+
*/
|
|
4
|
+
import { apiCall } from './api-client.js';
|
|
5
|
+
import { ENDPOINTS, resolveBaseUrl } from './config.js';
|
|
6
|
+
export async function requestLoginOtp(input) {
|
|
7
|
+
return apiCall({
|
|
8
|
+
url: resolveBaseUrl(input.baseUrl) + ENDPOINTS.cliRequestLoginOtp,
|
|
9
|
+
method: 'POST',
|
|
10
|
+
body: { email: input.email }
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export async function completeLogin(input) {
|
|
14
|
+
const { baseUrl, ...body } = input;
|
|
15
|
+
return apiCall({
|
|
16
|
+
url: resolveBaseUrl(baseUrl) + ENDPOINTS.cliCompleteLogin,
|
|
17
|
+
method: 'POST',
|
|
18
|
+
body
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export async function verifyApiKey(input) {
|
|
22
|
+
return apiCall({
|
|
23
|
+
url: resolveBaseUrl(input.baseUrl) + ENDPOINTS.verifyApiKey,
|
|
24
|
+
method: 'POST',
|
|
25
|
+
apiKey: input.apiKey
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=auth-flow-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-flow-client.js","sourceRoot":"","sources":["../../src/utils/auth-flow-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAkB,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAOxD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAGrC;IACC,OAAO,OAAO,CAAwB;QACpC,GAAG,EAAE,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,kBAAkB;QACjE,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;KAC7B,CAAC,CAAC;AACL,CAAC;AAkBD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAMnC;IACC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IACnC,OAAO,OAAO,CAAsB;QAClC,GAAG,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,gBAAgB;QACzD,MAAM,EAAE,MAAM;QACd,IAAI;KACL,CAAC,CAAC;AACL,CAAC;AAgBD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAGlC;IACC,OAAO,OAAO,CAAqB;QACjC,GAAG,EAAE,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,YAAY;QAC3D,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration module.
|
|
3
|
+
*
|
|
4
|
+
* Persists CLI config in ~/.config/wat/config.json (mode 0600). Supports multiple
|
|
5
|
+
* named profiles (an API key + metadata each) and an active profile.
|
|
6
|
+
*
|
|
7
|
+
* Base-URL resolution precedence (highest first), per the plan §8:
|
|
8
|
+
* --api-url flag
|
|
9
|
+
* > WAT_CLI_API_BASE_URL env
|
|
10
|
+
* > active/named profile baseUrl
|
|
11
|
+
* > --env dev|prod (or WAT_CLI_ENV)
|
|
12
|
+
* > prod default (PRODUCTION_BASE_URL)
|
|
13
|
+
*
|
|
14
|
+
* API-key resolution: --api-key flag > WAT_CLI_API_KEY env > profile.
|
|
15
|
+
*/
|
|
16
|
+
/** Directory name under ~/.config/ (or $XDG_CONFIG_HOME/). */
|
|
17
|
+
export declare const CONFIG_DIR_NAME = "wat";
|
|
18
|
+
/** The terminal command / program name. */
|
|
19
|
+
export declare const PROGRAM_NAME = "wat";
|
|
20
|
+
/** Env var holding the API key. */
|
|
21
|
+
export declare const ENV_API_KEY = "WAT_CLI_API_KEY";
|
|
22
|
+
/** Env var holding a base-URL override. */
|
|
23
|
+
export declare const ENV_BASE_URL = "WAT_CLI_API_BASE_URL";
|
|
24
|
+
/** Env var selecting the env target (`dev` | `prod`). */
|
|
25
|
+
export declare const ENV_TARGET = "WAT_CLI_ENV";
|
|
26
|
+
/** Production base URL — the `prod` branch of the wat-app Vercel project. */
|
|
27
|
+
export declare const PRODUCTION_BASE_URL = "https://wat-app.vercel.app";
|
|
28
|
+
/** Dev base URL — the `stag` branch Preview (APP_DEFAULT_MODE=dev, dev Neon). */
|
|
29
|
+
export declare const DEV_BASE_URL = "https://wat-app-git-stag-codika.vercel.app";
|
|
30
|
+
/** Valid env-target values for the global `--env` flag / WAT_CLI_ENV. */
|
|
31
|
+
export type EnvTarget = 'dev' | 'prod';
|
|
32
|
+
/** Record the env target chosen via the global `--env` flag. */
|
|
33
|
+
export declare function setEnvTarget(env: EnvTarget | null): void;
|
|
34
|
+
/** Normalize an arbitrary string to a valid EnvTarget, or null. */
|
|
35
|
+
export declare function parseEnvTarget(value: string | undefined | null): EnvTarget | null;
|
|
36
|
+
/** Base URL for an explicit env target. */
|
|
37
|
+
export declare function baseUrlForEnv(env: EnvTarget): string;
|
|
38
|
+
export interface ProfileData {
|
|
39
|
+
apiKey: string;
|
|
40
|
+
email?: string | null;
|
|
41
|
+
role?: string | null;
|
|
42
|
+
keyName?: string | null;
|
|
43
|
+
keyPrefix?: string | null;
|
|
44
|
+
createdAt?: string | null;
|
|
45
|
+
expiresAt?: string | null;
|
|
46
|
+
baseUrl?: string | null;
|
|
47
|
+
}
|
|
48
|
+
export interface CliConfig {
|
|
49
|
+
activeProfile: string | null;
|
|
50
|
+
profiles: Record<string, ProfileData>;
|
|
51
|
+
}
|
|
52
|
+
export type EndpointName = keyof typeof ENDPOINTS;
|
|
53
|
+
/**
|
|
54
|
+
* Endpoint paths, relative to the resolved base URL. The CLI hits the SAME
|
|
55
|
+
* /api/rooms, /api/availability, /api/bookings the browser uses (Bearer-gated by
|
|
56
|
+
* the app's hooks); only the login + key-verify routes are CLI-specific.
|
|
57
|
+
*/
|
|
58
|
+
export declare const ENDPOINTS: {
|
|
59
|
+
readonly cliRequestLoginOtp: "/api/cli/requestLoginOtp";
|
|
60
|
+
readonly cliCompleteLogin: "/api/cli/completeLogin";
|
|
61
|
+
readonly verifyApiKey: "/api/cli/verifyApiKey";
|
|
62
|
+
readonly rooms: "/api/rooms";
|
|
63
|
+
readonly availability: "/api/availability";
|
|
64
|
+
readonly bookings: "/api/bookings";
|
|
65
|
+
};
|
|
66
|
+
export declare function getConfigPath(): string;
|
|
67
|
+
export declare function readConfig(): CliConfig;
|
|
68
|
+
export declare function writeConfig(config: CliConfig): void;
|
|
69
|
+
export declare function clearConfig(): void;
|
|
70
|
+
export declare function getActiveProfile(): {
|
|
71
|
+
name: string;
|
|
72
|
+
profile: ProfileData;
|
|
73
|
+
} | null;
|
|
74
|
+
export declare function listProfiles(): Array<{
|
|
75
|
+
name: string;
|
|
76
|
+
profile: ProfileData;
|
|
77
|
+
active: boolean;
|
|
78
|
+
}>;
|
|
79
|
+
export declare function setActiveProfile(name: string): void;
|
|
80
|
+
export declare function upsertProfile(name: string, data: ProfileData): void;
|
|
81
|
+
export declare function removeProfile(name: string): void;
|
|
82
|
+
export declare function getProfileByName(name: string): ProfileData | null;
|
|
83
|
+
export declare function deriveProfileName(data: {
|
|
84
|
+
email?: string | null;
|
|
85
|
+
keyName?: string | null;
|
|
86
|
+
keyPrefix?: string | null;
|
|
87
|
+
}, existingNames: Set<string>): string;
|
|
88
|
+
export declare function resolveApiKey(flagValue?: string, profileName?: string): string | undefined;
|
|
89
|
+
export declare function resolveBaseUrl(flagValue?: string, profileName?: string): string;
|
|
90
|
+
export declare function resolveEndpointUrl(endpoint: EndpointName, baseUrlOverride?: string, profileName?: string): string;
|
|
91
|
+
export declare function describeApiKeySource(flagValue?: string): string;
|
|
92
|
+
export declare function describeBaseUrlSource(flagValue?: string): string;
|
|
93
|
+
export declare function maskApiKey(key: string): string;
|
|
94
|
+
export declare const API_KEY_MISSING_MESSAGE = "Not logged in. Either:\n 1. Run 'wat login' to authenticate\n 2. Set WAT_CLI_API_KEY environment variable\n 3. Pass --api-key <key>";
|
|
95
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration module.
|
|
3
|
+
*
|
|
4
|
+
* Persists CLI config in ~/.config/wat/config.json (mode 0600). Supports multiple
|
|
5
|
+
* named profiles (an API key + metadata each) and an active profile.
|
|
6
|
+
*
|
|
7
|
+
* Base-URL resolution precedence (highest first), per the plan §8:
|
|
8
|
+
* --api-url flag
|
|
9
|
+
* > WAT_CLI_API_BASE_URL env
|
|
10
|
+
* > active/named profile baseUrl
|
|
11
|
+
* > --env dev|prod (or WAT_CLI_ENV)
|
|
12
|
+
* > prod default (PRODUCTION_BASE_URL)
|
|
13
|
+
*
|
|
14
|
+
* API-key resolution: --api-key flag > WAT_CLI_API_KEY env > profile.
|
|
15
|
+
*/
|
|
16
|
+
import { readFileSync, writeFileSync, mkdirSync, unlinkSync, existsSync } from 'fs';
|
|
17
|
+
import { join } from 'path';
|
|
18
|
+
import { homedir } from 'os';
|
|
19
|
+
// ── Service identity ─────────────────────────────────────
|
|
20
|
+
/** Directory name under ~/.config/ (or $XDG_CONFIG_HOME/). */
|
|
21
|
+
export const CONFIG_DIR_NAME = 'wat';
|
|
22
|
+
/** The terminal command / program name. */
|
|
23
|
+
export const PROGRAM_NAME = 'wat';
|
|
24
|
+
/** Env var holding the API key. */
|
|
25
|
+
export const ENV_API_KEY = 'WAT_CLI_API_KEY';
|
|
26
|
+
/** Env var holding a base-URL override. */
|
|
27
|
+
export const ENV_BASE_URL = 'WAT_CLI_API_BASE_URL';
|
|
28
|
+
/** Env var selecting the env target (`dev` | `prod`). */
|
|
29
|
+
export const ENV_TARGET = 'WAT_CLI_ENV';
|
|
30
|
+
/** Production base URL — the `prod` branch of the wat-app Vercel project. */
|
|
31
|
+
export const PRODUCTION_BASE_URL = 'https://wat-app.vercel.app';
|
|
32
|
+
/** Dev base URL — the `stag` branch Preview (APP_DEFAULT_MODE=dev, dev Neon). */
|
|
33
|
+
export const DEV_BASE_URL = 'https://wat-app-git-stag-codika.vercel.app';
|
|
34
|
+
/**
|
|
35
|
+
* Process-wide env target, set once from the global `--env` flag (the CLI's
|
|
36
|
+
* preAction hook). `null` means "not explicitly selected"; resolution then falls
|
|
37
|
+
* back to WAT_CLI_ENV, and finally the prod default.
|
|
38
|
+
*/
|
|
39
|
+
let envTargetOverride = null;
|
|
40
|
+
/** Record the env target chosen via the global `--env` flag. */
|
|
41
|
+
export function setEnvTarget(env) {
|
|
42
|
+
envTargetOverride = env;
|
|
43
|
+
}
|
|
44
|
+
/** Normalize an arbitrary string to a valid EnvTarget, or null. */
|
|
45
|
+
export function parseEnvTarget(value) {
|
|
46
|
+
if (!value)
|
|
47
|
+
return null;
|
|
48
|
+
const v = value.trim().toLowerCase();
|
|
49
|
+
return v === 'dev' || v === 'prod' ? v : null;
|
|
50
|
+
}
|
|
51
|
+
/** The effective env target: `--env` override, else WAT_CLI_ENV, else null. */
|
|
52
|
+
function effectiveEnvTarget() {
|
|
53
|
+
return envTargetOverride ?? parseEnvTarget(process.env[ENV_TARGET]);
|
|
54
|
+
}
|
|
55
|
+
/** Base URL for an explicit env target. */
|
|
56
|
+
export function baseUrlForEnv(env) {
|
|
57
|
+
return env === 'dev' ? DEV_BASE_URL : PRODUCTION_BASE_URL;
|
|
58
|
+
}
|
|
59
|
+
// ── Endpoints ────────────────────────────────────────────
|
|
60
|
+
/**
|
|
61
|
+
* Endpoint paths, relative to the resolved base URL. The CLI hits the SAME
|
|
62
|
+
* /api/rooms, /api/availability, /api/bookings the browser uses (Bearer-gated by
|
|
63
|
+
* the app's hooks); only the login + key-verify routes are CLI-specific.
|
|
64
|
+
*/
|
|
65
|
+
export const ENDPOINTS = {
|
|
66
|
+
// ── Auth (the OTP login + key-verify flow) ──
|
|
67
|
+
cliRequestLoginOtp: '/api/cli/requestLoginOtp',
|
|
68
|
+
cliCompleteLogin: '/api/cli/completeLogin',
|
|
69
|
+
verifyApiKey: '/api/cli/verifyApiKey',
|
|
70
|
+
// ── Shared domain surface (Bearer; same paths the web UI calls) ──
|
|
71
|
+
rooms: '/api/rooms',
|
|
72
|
+
availability: '/api/availability',
|
|
73
|
+
bookings: '/api/bookings'
|
|
74
|
+
};
|
|
75
|
+
// ── Config file path ─────────────────────────────────────
|
|
76
|
+
function getConfigDir() {
|
|
77
|
+
const xdg = process.env.XDG_CONFIG_HOME;
|
|
78
|
+
const base = xdg || join(homedir(), '.config');
|
|
79
|
+
return join(base, CONFIG_DIR_NAME);
|
|
80
|
+
}
|
|
81
|
+
export function getConfigPath() {
|
|
82
|
+
return join(getConfigDir(), 'config.json');
|
|
83
|
+
}
|
|
84
|
+
// ── Read / Write / Clear ─────────────────────────────────
|
|
85
|
+
const EMPTY_CONFIG = { activeProfile: null, profiles: {} };
|
|
86
|
+
export function readConfig() {
|
|
87
|
+
const path = getConfigPath();
|
|
88
|
+
if (!existsSync(path))
|
|
89
|
+
return { ...EMPTY_CONFIG, profiles: {} };
|
|
90
|
+
try {
|
|
91
|
+
const parsed = JSON.parse(readFileSync(path, 'utf-8'));
|
|
92
|
+
if (parsed && typeof parsed.profiles === 'object')
|
|
93
|
+
return parsed;
|
|
94
|
+
return { ...EMPTY_CONFIG, profiles: {} };
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return { ...EMPTY_CONFIG, profiles: {} };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
export function writeConfig(config) {
|
|
101
|
+
const dir = getConfigDir();
|
|
102
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
103
|
+
// mode 0600: the file holds a raw API key (a secret).
|
|
104
|
+
writeFileSync(getConfigPath(), JSON.stringify(config, null, 2) + '\n', { mode: 0o600 });
|
|
105
|
+
}
|
|
106
|
+
export function clearConfig() {
|
|
107
|
+
const path = getConfigPath();
|
|
108
|
+
if (existsSync(path))
|
|
109
|
+
unlinkSync(path);
|
|
110
|
+
}
|
|
111
|
+
// ── Profile management ───────────────────────────────────
|
|
112
|
+
export function getActiveProfile() {
|
|
113
|
+
const config = readConfig();
|
|
114
|
+
if (!config.activeProfile || !config.profiles[config.activeProfile])
|
|
115
|
+
return null;
|
|
116
|
+
return { name: config.activeProfile, profile: config.profiles[config.activeProfile] };
|
|
117
|
+
}
|
|
118
|
+
export function listProfiles() {
|
|
119
|
+
const config = readConfig();
|
|
120
|
+
return Object.entries(config.profiles).map(([name, profile]) => ({
|
|
121
|
+
name,
|
|
122
|
+
profile,
|
|
123
|
+
active: name === config.activeProfile
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
export function setActiveProfile(name) {
|
|
127
|
+
const config = readConfig();
|
|
128
|
+
if (!config.profiles[name])
|
|
129
|
+
throw new Error(`Profile "${name}" does not exist.`);
|
|
130
|
+
config.activeProfile = name;
|
|
131
|
+
writeConfig(config);
|
|
132
|
+
}
|
|
133
|
+
export function upsertProfile(name, data) {
|
|
134
|
+
const config = readConfig();
|
|
135
|
+
config.profiles[name] = data;
|
|
136
|
+
if (!config.activeProfile || !config.profiles[config.activeProfile]) {
|
|
137
|
+
config.activeProfile = name;
|
|
138
|
+
}
|
|
139
|
+
writeConfig(config);
|
|
140
|
+
}
|
|
141
|
+
export function removeProfile(name) {
|
|
142
|
+
const config = readConfig();
|
|
143
|
+
if (!config.profiles[name])
|
|
144
|
+
throw new Error(`Profile "${name}" does not exist.`);
|
|
145
|
+
delete config.profiles[name];
|
|
146
|
+
if (config.activeProfile === name) {
|
|
147
|
+
const remaining = Object.keys(config.profiles);
|
|
148
|
+
config.activeProfile = remaining.length > 0 ? remaining[0] : null;
|
|
149
|
+
}
|
|
150
|
+
writeConfig(config);
|
|
151
|
+
}
|
|
152
|
+
export function getProfileByName(name) {
|
|
153
|
+
return readConfig().profiles[name] || null;
|
|
154
|
+
}
|
|
155
|
+
// ── Profile name derivation ──────────────────────────────
|
|
156
|
+
export function deriveProfileName(data, existingNames) {
|
|
157
|
+
let base = '';
|
|
158
|
+
if (data.email)
|
|
159
|
+
base = slugify(data.email.split('@')[0]);
|
|
160
|
+
else if (data.keyName)
|
|
161
|
+
base = slugify(data.keyName);
|
|
162
|
+
else if (data.keyPrefix)
|
|
163
|
+
base = data.keyPrefix;
|
|
164
|
+
if (!base)
|
|
165
|
+
base = 'default';
|
|
166
|
+
let name = base;
|
|
167
|
+
let i = 2;
|
|
168
|
+
while (existingNames.has(name)) {
|
|
169
|
+
name = `${base}-${i}`;
|
|
170
|
+
i++;
|
|
171
|
+
}
|
|
172
|
+
return name;
|
|
173
|
+
}
|
|
174
|
+
function slugify(str) {
|
|
175
|
+
return str
|
|
176
|
+
.toLowerCase()
|
|
177
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
178
|
+
.replace(/^-|-$/g, '');
|
|
179
|
+
}
|
|
180
|
+
// ── Resolution chains ────────────────────────────────────
|
|
181
|
+
export function resolveApiKey(flagValue, profileName) {
|
|
182
|
+
if (flagValue)
|
|
183
|
+
return flagValue;
|
|
184
|
+
if (process.env[ENV_API_KEY])
|
|
185
|
+
return process.env[ENV_API_KEY];
|
|
186
|
+
if (profileName)
|
|
187
|
+
return getProfileByName(profileName)?.apiKey;
|
|
188
|
+
return getActiveProfile()?.profile.apiKey;
|
|
189
|
+
}
|
|
190
|
+
export function resolveBaseUrl(flagValue, profileName) {
|
|
191
|
+
// Precedence: --api-url > WAT_CLI_API_BASE_URL > profile baseUrl
|
|
192
|
+
// > --env / WAT_CLI_ENV > prod default.
|
|
193
|
+
if (flagValue)
|
|
194
|
+
return flagValue;
|
|
195
|
+
if (process.env[ENV_BASE_URL])
|
|
196
|
+
return process.env[ENV_BASE_URL];
|
|
197
|
+
if (profileName) {
|
|
198
|
+
const profile = getProfileByName(profileName);
|
|
199
|
+
if (profile?.baseUrl)
|
|
200
|
+
return profile.baseUrl;
|
|
201
|
+
}
|
|
202
|
+
const active = getActiveProfile();
|
|
203
|
+
if (active?.profile.baseUrl)
|
|
204
|
+
return active.profile.baseUrl;
|
|
205
|
+
const env = effectiveEnvTarget();
|
|
206
|
+
if (env)
|
|
207
|
+
return baseUrlForEnv(env);
|
|
208
|
+
return PRODUCTION_BASE_URL;
|
|
209
|
+
}
|
|
210
|
+
export function resolveEndpointUrl(endpoint, baseUrlOverride, profileName) {
|
|
211
|
+
return resolveBaseUrl(baseUrlOverride, profileName) + ENDPOINTS[endpoint];
|
|
212
|
+
}
|
|
213
|
+
// ── Source descriptions (for `config show`) ──────────────
|
|
214
|
+
export function describeApiKeySource(flagValue) {
|
|
215
|
+
if (flagValue)
|
|
216
|
+
return 'flag';
|
|
217
|
+
if (process.env[ENV_API_KEY])
|
|
218
|
+
return `env (${ENV_API_KEY})`;
|
|
219
|
+
const active = getActiveProfile();
|
|
220
|
+
if (active)
|
|
221
|
+
return `profile "${active.name}"`;
|
|
222
|
+
return 'not set';
|
|
223
|
+
}
|
|
224
|
+
export function describeBaseUrlSource(flagValue) {
|
|
225
|
+
if (flagValue)
|
|
226
|
+
return 'flag';
|
|
227
|
+
if (process.env[ENV_BASE_URL])
|
|
228
|
+
return `env (${ENV_BASE_URL})`;
|
|
229
|
+
const active = getActiveProfile();
|
|
230
|
+
if (active?.profile.baseUrl)
|
|
231
|
+
return `profile "${active.name}"`;
|
|
232
|
+
const env = effectiveEnvTarget();
|
|
233
|
+
if (env)
|
|
234
|
+
return `--env ${env}`;
|
|
235
|
+
return 'default (production)';
|
|
236
|
+
}
|
|
237
|
+
export function maskApiKey(key) {
|
|
238
|
+
if (key.length <= 12)
|
|
239
|
+
return key.slice(0, 4) + '...';
|
|
240
|
+
return key.slice(0, 12) + '...';
|
|
241
|
+
}
|
|
242
|
+
export const API_KEY_MISSING_MESSAGE = `Not logged in. Either:
|
|
243
|
+
1. Run '${PROGRAM_NAME} login' to authenticate
|
|
244
|
+
2. Set ${ENV_API_KEY} environment variable
|
|
245
|
+
3. Pass --api-key <key>`;
|
|
246
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrappers for the shared domain endpoints the browser also calls
|
|
3
|
+
* (/api/rooms, /api/availability, /api/bookings) — all Bearer-gated.
|
|
4
|
+
*/
|
|
5
|
+
import { type ApiResult } from './api-client.js';
|
|
6
|
+
export interface Room {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
capacity: number | null;
|
|
10
|
+
description: string | null;
|
|
11
|
+
color: string | null;
|
|
12
|
+
is_active?: boolean;
|
|
13
|
+
created_at?: string | null;
|
|
14
|
+
}
|
|
15
|
+
export declare function listRooms(input: {
|
|
16
|
+
apiKey: string;
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
}): Promise<ApiResult<{
|
|
19
|
+
rooms: Room[];
|
|
20
|
+
}>>;
|
|
21
|
+
export interface Booking {
|
|
22
|
+
id: string;
|
|
23
|
+
room_id: string;
|
|
24
|
+
member_id: string | null;
|
|
25
|
+
booker_name: string | null;
|
|
26
|
+
title: string | null;
|
|
27
|
+
starts_at: string;
|
|
28
|
+
ends_at: string;
|
|
29
|
+
status: string;
|
|
30
|
+
is_maintenance: boolean;
|
|
31
|
+
is_mine: boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare function listBookings(input: {
|
|
34
|
+
apiKey: string;
|
|
35
|
+
baseUrl?: string;
|
|
36
|
+
roomId?: string;
|
|
37
|
+
from?: string;
|
|
38
|
+
to?: string;
|
|
39
|
+
mine?: boolean;
|
|
40
|
+
}): Promise<ApiResult<{
|
|
41
|
+
bookings: Booking[];
|
|
42
|
+
}>>;
|
|
43
|
+
export declare function createBooking(input: {
|
|
44
|
+
apiKey: string;
|
|
45
|
+
baseUrl?: string;
|
|
46
|
+
roomId: string;
|
|
47
|
+
startsAt: string;
|
|
48
|
+
endsAt: string;
|
|
49
|
+
title?: string;
|
|
50
|
+
}): Promise<ApiResult<{
|
|
51
|
+
booking: {
|
|
52
|
+
id: string;
|
|
53
|
+
};
|
|
54
|
+
}>>;
|
|
55
|
+
export declare function cancelBooking(input: {
|
|
56
|
+
apiKey: string;
|
|
57
|
+
baseUrl?: string;
|
|
58
|
+
id: string;
|
|
59
|
+
}): Promise<ApiResult<unknown>>;
|
|
60
|
+
export interface AvailabilityResult {
|
|
61
|
+
[key: string]: unknown;
|
|
62
|
+
}
|
|
63
|
+
export declare function getAvailability(input: {
|
|
64
|
+
apiKey: string;
|
|
65
|
+
baseUrl?: string;
|
|
66
|
+
roomId: string;
|
|
67
|
+
from: string;
|
|
68
|
+
to: string;
|
|
69
|
+
}): Promise<ApiResult<AvailabilityResult>>;
|
|
70
|
+
//# sourceMappingURL=rooms-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rooms-client.d.ts","sourceRoot":"","sources":["../../src/utils/rooms-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG1D,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,SAAS,CAAC;IAAE,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CAAC,CAMxC;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,SAAS,CAAC;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,CAAC,CAY9C;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,SAAS,CAAC;IAAE,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC,CAAC,CAYlD;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;CACZ,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAM9B;AAED,MAAM,WAAW,kBAAkB;IAGjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,GAAG,OAAO,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAOzC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrappers for the shared domain endpoints the browser also calls
|
|
3
|
+
* (/api/rooms, /api/availability, /api/bookings) — all Bearer-gated.
|
|
4
|
+
*/
|
|
5
|
+
import { apiCall } from './api-client.js';
|
|
6
|
+
import { ENDPOINTS, resolveBaseUrl } from './config.js';
|
|
7
|
+
export async function listRooms(input) {
|
|
8
|
+
return apiCall({
|
|
9
|
+
url: resolveBaseUrl(input.baseUrl) + ENDPOINTS.rooms,
|
|
10
|
+
method: 'GET',
|
|
11
|
+
apiKey: input.apiKey
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export async function listBookings(input) {
|
|
15
|
+
const params = new URLSearchParams();
|
|
16
|
+
if (input.roomId)
|
|
17
|
+
params.set('roomId', input.roomId);
|
|
18
|
+
if (input.from)
|
|
19
|
+
params.set('from', input.from);
|
|
20
|
+
if (input.to)
|
|
21
|
+
params.set('to', input.to);
|
|
22
|
+
if (input.mine)
|
|
23
|
+
params.set('mine', 'true');
|
|
24
|
+
const qs = params.toString();
|
|
25
|
+
return apiCall({
|
|
26
|
+
url: resolveBaseUrl(input.baseUrl) + ENDPOINTS.bookings + (qs ? `?${qs}` : ''),
|
|
27
|
+
method: 'GET',
|
|
28
|
+
apiKey: input.apiKey
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export async function createBooking(input) {
|
|
32
|
+
return apiCall({
|
|
33
|
+
url: resolveBaseUrl(input.baseUrl) + ENDPOINTS.bookings,
|
|
34
|
+
method: 'POST',
|
|
35
|
+
apiKey: input.apiKey,
|
|
36
|
+
body: {
|
|
37
|
+
roomId: input.roomId,
|
|
38
|
+
startsAt: input.startsAt,
|
|
39
|
+
endsAt: input.endsAt,
|
|
40
|
+
...(input.title ? { title: input.title } : {})
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
export async function cancelBooking(input) {
|
|
45
|
+
return apiCall({
|
|
46
|
+
url: `${resolveBaseUrl(input.baseUrl) + ENDPOINTS.bookings}/${encodeURIComponent(input.id)}`,
|
|
47
|
+
method: 'DELETE',
|
|
48
|
+
apiKey: input.apiKey
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
export async function getAvailability(input) {
|
|
52
|
+
const params = new URLSearchParams({ roomId: input.roomId, from: input.from, to: input.to });
|
|
53
|
+
return apiCall({
|
|
54
|
+
url: `${resolveBaseUrl(input.baseUrl) + ENDPOINTS.availability}?${params.toString()}`,
|
|
55
|
+
method: 'GET',
|
|
56
|
+
apiKey: input.apiKey
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=rooms-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rooms-client.js","sourceRoot":"","sources":["../../src/utils/rooms-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time interpretation for the CLI (plan §8).
|
|
3
|
+
*
|
|
4
|
+
* A bare `--start "2026-06-09T10:00"` is read as **Europe/Brussels** wall-clock
|
|
5
|
+
* by default (matching the UI), converted to a UTC instant for the API. Rules:
|
|
6
|
+
*
|
|
7
|
+
* - A value that already carries a UTC `Z` or a numeric offset (`+02:00`,
|
|
8
|
+
* `-0500`) is an absolute instant — honored as-is.
|
|
9
|
+
* - A bare local value (`YYYY-MM-DDTHH:mm[:ss]`, or with a space) is interpreted
|
|
10
|
+
* in the given IANA zone (default Europe/Brussels, override with `--tz`),
|
|
11
|
+
* DST-safe, and converted to UTC.
|
|
12
|
+
*
|
|
13
|
+
* The CLI prints times back in the SAME zone it accepted, so what a member types
|
|
14
|
+
* and what they see never disagree. No external dependency: the zone offset is
|
|
15
|
+
* derived from `Intl.DateTimeFormat`, which is DST-correct.
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_TZ = "Europe/Brussels";
|
|
18
|
+
/** True when a datetime string carries an explicit offset or `Z` (absolute). */
|
|
19
|
+
export declare function hasExplicitOffset(value: string): boolean;
|
|
20
|
+
export interface ParseResult {
|
|
21
|
+
/** The resolved absolute instant. */
|
|
22
|
+
date: Date;
|
|
23
|
+
/** The IANA zone the input was interpreted in (for round-trip display). */
|
|
24
|
+
zone: string;
|
|
25
|
+
/** True when the input was a bare local value interpreted in `zone`. */
|
|
26
|
+
interpretedLocal: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve a datetime argument to an absolute instant.
|
|
30
|
+
*
|
|
31
|
+
* @param value the raw `--start` / `--end` / `--from` / `--to` argument
|
|
32
|
+
* @param tz the IANA zone for bare local values (default Europe/Brussels)
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseDateTimeArg(value: string, tz?: string): ParseResult;
|
|
35
|
+
/** Format an instant as a wall-clock string in the given zone (round-trip display). */
|
|
36
|
+
export declare function formatInZone(date: Date, tz?: string): string;
|
|
37
|
+
//# sourceMappingURL=time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../src/utils/time.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,UAAU,oBAAoB,CAAC;AAE5C,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAUxD;AA+CD,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,IAAI,EAAE,IAAI,CAAC;IACX,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAE,MAAmB,GAAG,WAAW,CAqCpF;AAED,uFAAuF;AACvF,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,GAAE,MAAmB,GAAG,MAAM,CAaxE"}
|