opensoma 0.6.0 → 0.8.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.
Files changed (55) hide show
  1. package/dist/package.json +1 -1
  2. package/dist/src/cli.d.ts.map +1 -1
  3. package/dist/src/cli.js +6 -4
  4. package/dist/src/cli.js.map +1 -1
  5. package/dist/src/client.d.ts +4 -0
  6. package/dist/src/client.d.ts.map +1 -1
  7. package/dist/src/client.js +6 -0
  8. package/dist/src/client.js.map +1 -1
  9. package/dist/src/commands/index.d.ts +1 -0
  10. package/dist/src/commands/index.d.ts.map +1 -1
  11. package/dist/src/commands/index.js +1 -0
  12. package/dist/src/commands/index.js.map +1 -1
  13. package/dist/src/commands/toz.d.ts +16 -0
  14. package/dist/src/commands/toz.d.ts.map +1 -0
  15. package/dist/src/commands/toz.js +488 -0
  16. package/dist/src/commands/toz.js.map +1 -0
  17. package/dist/src/credential-manager.d.ts +8 -2
  18. package/dist/src/credential-manager.d.ts.map +1 -1
  19. package/dist/src/credential-manager.js +27 -5
  20. package/dist/src/credential-manager.js.map +1 -1
  21. package/dist/src/index.d.ts +4 -0
  22. package/dist/src/index.d.ts.map +1 -1
  23. package/dist/src/index.js +2 -0
  24. package/dist/src/index.js.map +1 -1
  25. package/dist/src/session-recovery.js +2 -0
  26. package/dist/src/session-recovery.js.map +1 -1
  27. package/dist/src/shared/utils/config-dir.d.ts +11 -0
  28. package/dist/src/shared/utils/config-dir.d.ts.map +1 -0
  29. package/dist/src/shared/utils/config-dir.js +19 -0
  30. package/dist/src/shared/utils/config-dir.js.map +1 -0
  31. package/dist/src/toz-client.d.ts +89 -0
  32. package/dist/src/toz-client.d.ts.map +1 -0
  33. package/dist/src/toz-client.js +204 -0
  34. package/dist/src/toz-client.js.map +1 -0
  35. package/dist/src/toz-pending-store.d.ts +30 -0
  36. package/dist/src/toz-pending-store.d.ts.map +1 -0
  37. package/dist/src/toz-pending-store.js +36 -0
  38. package/dist/src/toz-pending-store.js.map +1 -0
  39. package/package.json +1 -1
  40. package/src/cli.ts +6 -3
  41. package/src/client.ts +10 -0
  42. package/src/commands/helpers.test.ts +4 -0
  43. package/src/commands/index.ts +1 -0
  44. package/src/commands/toz.test.ts +51 -0
  45. package/src/commands/toz.ts +607 -0
  46. package/src/credential-manager.test.ts +54 -0
  47. package/src/credential-manager.ts +28 -5
  48. package/src/index.ts +13 -0
  49. package/src/session-recovery.ts +2 -0
  50. package/src/shared/utils/config-dir.test.ts +41 -0
  51. package/src/shared/utils/config-dir.ts +20 -0
  52. package/src/toz-client.test.ts +243 -0
  53. package/src/toz-client.ts +311 -0
  54. package/src/toz-pending-store.test.ts +91 -0
  55. package/src/toz-pending-store.ts +63 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AACtG,YAAY,EACV,2BAA2B,EAC3B,uBAAuB,EACvB,YAAY,EACZ,OAAO,EACP,cAAc,GACf,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACzC,YAAY,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC9D,cAAc,kBAAkB,CAAA;AAChC,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AACtG,YAAY,EACV,2BAA2B,EAC3B,uBAAuB,EACvB,YAAY,EACZ,OAAO,EACP,cAAc,GACf,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACzC,YAAY,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACxC,YAAY,EACV,oBAAoB,EACpB,aAAa,EACb,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,aAAa,GACd,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAChE,cAAc,kBAAkB,CAAA;AAChC,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA"}
package/dist/src/index.js CHANGED
@@ -4,6 +4,8 @@ export { AuthenticationError } from './errors.js';
4
4
  export { SomaHttp, UserGb } from './http.js';
5
5
  export { CredentialManager } from './credential-manager.js';
6
6
  export { TozHttp } from './toz-http.js';
7
+ export { TozClient } from './toz-client.js';
8
+ export { TozPendingStore } from './toz-pending-store.js';
7
9
  export * from './toz-formatters.js';
8
10
  export * from './types.js';
9
11
  export * from './constants.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAQtG,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAErC,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEpC,cAAc,kBAAkB,CAAA;AAChC,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAQtG,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAErC,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAWxC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErD,cAAc,kBAAkB,CAAA;AAChC,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA"}
@@ -28,6 +28,8 @@ function buildRefreshedCredentials(credentials, identity, http) {
28
28
  csrfToken,
29
29
  username: identity.userId || credentials.username,
30
30
  password: credentials.password,
31
+ tozName: credentials.tozName,
32
+ tozPhone: credentials.tozPhone,
31
33
  loggedInAt: new Date().toISOString(),
32
34
  };
33
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"session-recovery.js","sourceRoot":"","sources":["../../src/session-recovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAqB,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAMpD,MAAM,UAAU,iBAAiB,CAAC,WAAwB;IAIxD,OAAO,OAAO,CAAC,WAAW,CAAC,QAAQ,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAA;AAC9D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,WAAwB,EACxB,UAA2B,IAAI,iBAAiB,EAAE,EAClD,aAAgC,GAAG,EAAE,CAAC,IAAI,QAAQ,EAAE;IAEpD,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;QACpC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,IAAI,GAAG,UAAU,EAAE,CAAA;IACzB,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;IAE5D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAA;IACxC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,oBAAoB,GAAG,yBAAyB,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;IACnF,MAAM,OAAO,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAA;IAClD,OAAO,oBAAoB,CAAA;AAC7B,CAAC;AAED,SAAS,yBAAyB,CAChC,WAAiE,EACjE,QAAsB,EACtB,IAAyD;IAEzD,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAA;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;IAErC,IAAI,CAAC,aAAa,IAAI,CAAC,SAAS,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAA;IACjF,CAAC;IAED,OAAO;QACL,aAAa;QACb,SAAS;QACT,QAAQ,EAAE,QAAQ,CAAC,MAAM,IAAI,WAAW,CAAC,QAAQ;QACjD,QAAQ,EAAE,WAAW,CAAC,QAAQ;QAC9B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACrC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"session-recovery.js","sourceRoot":"","sources":["../../src/session-recovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAqB,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAMpD,MAAM,UAAU,iBAAiB,CAAC,WAAwB;IAIxD,OAAO,OAAO,CAAC,WAAW,CAAC,QAAQ,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAA;AAC9D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,WAAwB,EACxB,UAA2B,IAAI,iBAAiB,EAAE,EAClD,aAAgC,GAAG,EAAE,CAAC,IAAI,QAAQ,EAAE;IAEpD,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;QACpC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,IAAI,GAAG,UAAU,EAAE,CAAA;IACzB,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;IAE5D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAA;IACxC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,oBAAoB,GAAG,yBAAyB,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;IACnF,MAAM,OAAO,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAA;IAClD,OAAO,oBAAoB,CAAA;AAC7B,CAAC;AAED,SAAS,yBAAyB,CAChC,WAAiE,EACjE,QAAsB,EACtB,IAAyD;IAEzD,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAA;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;IAErC,IAAI,CAAC,aAAa,IAAI,CAAC,SAAS,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAA;IACjF,CAAC;IAED,OAAO;QACL,aAAa;QACb,SAAS;QACT,QAAQ,EAAE,QAAQ,CAAC,MAAM,IAAI,WAAW,CAAC,QAAQ;QACjD,QAAQ,EAAE,WAAW,CAAC,QAAQ;QAC9B,OAAO,EAAE,WAAW,CAAC,OAAO;QAC5B,QAAQ,EAAE,WAAW,CAAC,QAAQ;QAC9B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACrC,CAAA;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ export declare const CONFIG_DIR_ENV_VAR = "OPENSOMA_CONFIG_DIR";
2
+ /**
3
+ * Resolves the directory used to persist opensoma state (credentials, pending
4
+ * reservations, etc.).
5
+ *
6
+ * Resolution order:
7
+ * 1. `OPENSOMA_CONFIG_DIR` environment variable (if set and non-empty)
8
+ * 2. `~/.config/opensoma`
9
+ */
10
+ export declare function getConfigDir(): string;
11
+ //# sourceMappingURL=config-dir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-dir.d.ts","sourceRoot":"","sources":["../../../../src/shared/utils/config-dir.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB,wBAAwB,CAAA;AAEvD;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAMrC"}
@@ -0,0 +1,19 @@
1
+ import { homedir } from 'node:os';
2
+ import { join } from 'node:path';
3
+ export const CONFIG_DIR_ENV_VAR = 'OPENSOMA_CONFIG_DIR';
4
+ /**
5
+ * Resolves the directory used to persist opensoma state (credentials, pending
6
+ * reservations, etc.).
7
+ *
8
+ * Resolution order:
9
+ * 1. `OPENSOMA_CONFIG_DIR` environment variable (if set and non-empty)
10
+ * 2. `~/.config/opensoma`
11
+ */
12
+ export function getConfigDir() {
13
+ const fromEnv = process.env[CONFIG_DIR_ENV_VAR];
14
+ if (fromEnv && fromEnv.length > 0) {
15
+ return fromEnv;
16
+ }
17
+ return join(homedir(), '.config', 'opensoma');
18
+ }
19
+ //# sourceMappingURL=config-dir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-dir.js","sourceRoot":"","sources":["../../../../src/shared/utils/config-dir.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,MAAM,CAAC,MAAM,kBAAkB,GAAG,qBAAqB,CAAA;AAEvD;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;IAC/C,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,OAAO,OAAO,CAAA;IAChB,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;AAC/C,CAAC"}
@@ -0,0 +1,89 @@
1
+ import { TozHttp, type TozHttpOptions } from './toz-http.js';
2
+ import type { TozBooth, TozBranch, TozDuration, TozMeeting, TozReservation, TozReserved } from './types.js';
3
+ export interface TozAvailabilityQuery {
4
+ date: string;
5
+ startTime: string;
6
+ durationMinutes: number;
7
+ userCount: number;
8
+ branchIds: readonly number[];
9
+ }
10
+ export interface TozCheckQuery {
11
+ date: string;
12
+ startTimes: readonly string[];
13
+ durationMinutes: number;
14
+ userCount: number;
15
+ branchIds: readonly number[];
16
+ }
17
+ export interface TozCheckResult {
18
+ startTime: string;
19
+ booths: TozBooth[];
20
+ error?: string;
21
+ }
22
+ export interface TozReserveBoothArgs {
23
+ date: string;
24
+ startTime: string;
25
+ durationMinutes: number;
26
+ userCount: number;
27
+ boothId: number;
28
+ }
29
+ export interface TozConfirmArgs {
30
+ reservationId: string;
31
+ date: string;
32
+ startTime: string;
33
+ durationMinutes: number;
34
+ name: string;
35
+ phone: string;
36
+ email: string;
37
+ pinNum: string;
38
+ meetingId?: number;
39
+ newMeetingName?: string;
40
+ memo?: string;
41
+ }
42
+ export interface TozSearchArgs {
43
+ name?: string;
44
+ phone?: string;
45
+ startDate?: string;
46
+ endDate?: string;
47
+ meetingName?: string;
48
+ }
49
+ export interface TozCancelArgs {
50
+ reservationId: number;
51
+ name?: string;
52
+ phone?: string;
53
+ }
54
+ export interface TozClientOptions extends TozHttpOptions {
55
+ name?: string;
56
+ phone?: string;
57
+ }
58
+ export declare class TozClient {
59
+ readonly http: TozHttp;
60
+ readonly identity: {
61
+ name?: string;
62
+ phone?: string;
63
+ };
64
+ constructor(options?: TozClientOptions);
65
+ branches(): Promise<TozBranch[]>;
66
+ meetings(): Promise<TozMeeting[]>;
67
+ durations(date: string, startTime: string): Promise<TozDuration[]>;
68
+ available(query: TozAvailabilityQuery): Promise<TozBooth[]>;
69
+ check(query: TozCheckQuery): Promise<TozCheckResult[]>;
70
+ reserveBooth(args: TozReserveBoothArgs): Promise<TozReserved>;
71
+ skipEquipment(args: {
72
+ reservationId: string;
73
+ date: string;
74
+ startTime: string;
75
+ durationMinutes: number;
76
+ }): Promise<void>;
77
+ sendOtp(phone?: string): Promise<void>;
78
+ confirm(args: TozConfirmArgs): Promise<{
79
+ resultMsg: string;
80
+ isLargeBooth: boolean;
81
+ }>;
82
+ destroyHold(): Promise<void>;
83
+ myReservations(args?: TozSearchArgs): Promise<TozReservation[]>;
84
+ cancel(args: TozCancelArgs): Promise<void>;
85
+ private requireName;
86
+ private requirePhone;
87
+ private mypageLogin;
88
+ }
89
+ //# sourceMappingURL=toz-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toz-client.d.ts","sourceRoot":"","sources":["../../src/toz-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,204 @@
1
+ import { assertDurationInRange, buildBranchIdsParam, buildStartTimeParam, formatDuration, formatPhone, parseEmail, parsePhone, } from './shared/utils/toz.js';
2
+ import { isReservationConfirmSuccess, parseBookingPageBranches, parseBookingPageMeetings, parseMypageReservations, parseTozBoothes, parseTozDurations, parseTozReserved, } from './toz-formatters.js';
3
+ import { TozHttp } from './toz-http.js';
4
+ export class TozClient {
5
+ http;
6
+ identity;
7
+ constructor(options = {}) {
8
+ const { name, phone, ...httpOptions } = options;
9
+ this.http = new TozHttp(httpOptions);
10
+ this.identity = { name, phone };
11
+ }
12
+ async branches() {
13
+ await this.http.bootstrap();
14
+ return parseBookingPageBranches(await this.http.get('/booking.htm'));
15
+ }
16
+ async meetings() {
17
+ await this.http.bootstrap();
18
+ return parseBookingPageMeetings(await this.http.get('/booking.htm'));
19
+ }
20
+ async durations(date, startTime) {
21
+ await this.http.bootstrap();
22
+ const param = buildStartTimeParam(startTime);
23
+ const json = await this.http.postJson('/ajaxCheckDurationTime.htm', {
24
+ basedate: date,
25
+ hour: param.slice(0, 2),
26
+ minute: param.slice(2, 4),
27
+ });
28
+ return parseTozDurations(json);
29
+ }
30
+ async available(query) {
31
+ assertDurationInRange(query.durationMinutes);
32
+ await this.http.bootstrap();
33
+ const json = await this.http.postJson('/ajaxGetEnableBoothes.htm', {
34
+ basedate: query.date,
35
+ starttime: buildStartTimeParam(query.startTime),
36
+ durationTime: formatDuration(query.durationMinutes),
37
+ userCount: String(query.userCount),
38
+ branchIds: buildBranchIdsParam(query.branchIds),
39
+ });
40
+ return parseTozBoothes(json);
41
+ }
42
+ async check(query) {
43
+ if (query.startTimes.length === 0) {
44
+ throw new Error('toz check requires at least one --time. For a single slot, use `toz available` instead.');
45
+ }
46
+ if (query.startTimes.length > 6) {
47
+ throw new Error('Too many times (max 6 per invocation). Consider `toz available` for a single slot, or split into multiple invocations.');
48
+ }
49
+ assertDurationInRange(query.durationMinutes);
50
+ await this.http.bootstrap();
51
+ const results = [];
52
+ for (let i = 0; i < query.startTimes.length; i += 1) {
53
+ const startTime = query.startTimes[i];
54
+ try {
55
+ const booths = await this.available({
56
+ date: query.date,
57
+ startTime,
58
+ durationMinutes: query.durationMinutes,
59
+ userCount: query.userCount,
60
+ branchIds: query.branchIds,
61
+ });
62
+ results.push({ startTime, booths });
63
+ }
64
+ catch (error) {
65
+ results.push({
66
+ startTime,
67
+ booths: [],
68
+ error: error instanceof Error ? error.message : String(error),
69
+ });
70
+ }
71
+ if (i < query.startTimes.length - 1)
72
+ await sleep(500);
73
+ }
74
+ return results;
75
+ }
76
+ async reserveBooth(args) {
77
+ assertDurationInRange(args.durationMinutes);
78
+ await this.http.bootstrap();
79
+ const json = await this.http.postJson('/ajaxReservationBooth.htm', {
80
+ basedate: args.date,
81
+ starttime: buildStartTimeParam(args.startTime),
82
+ durationTime: formatDuration(args.durationMinutes),
83
+ userCount: String(args.userCount),
84
+ booth_id: String(args.boothId),
85
+ });
86
+ const reserved = parseTozReserved(json);
87
+ if (reserved.isLargeBooth) {
88
+ throw new Error('대형부스 예약은 선입금 약관 동의가 필요합니다. v1에서는 지원하지 않습니다 (small booths only).');
89
+ }
90
+ return reserved;
91
+ }
92
+ async skipEquipment(args) {
93
+ await this.http.postText('/ajaxReservationEquipment.htm', {
94
+ reservationId: args.reservationId,
95
+ basedate: args.date,
96
+ starttime: buildStartTimeParam(args.startTime),
97
+ durationTime: formatDuration(args.durationMinutes),
98
+ equipmentNotebookChecked: 'false',
99
+ equipmentProjectorChecked: 'false',
100
+ equipmentMonitorChecked: 'false',
101
+ equipmentPlayerChecked: 'false',
102
+ equipmentSpeakerChecked: 'false',
103
+ equipmentNotebookCnt: '0',
104
+ equipmentProjectorCnt: '0',
105
+ equipmentMonitorCnt: '0',
106
+ equipmentPlayerCnt: '0',
107
+ equipmentSpeakerCnt: '0',
108
+ });
109
+ }
110
+ async sendOtp(phone) {
111
+ const parts = parsePhone(this.requirePhone(phone));
112
+ const result = await this.http.postText('/ajaxHpVerify.htm', { ...parts });
113
+ if (result !== 'SUCCESS') {
114
+ throw new Error(`OTP 발송 실패: ${result}`);
115
+ }
116
+ }
117
+ async confirm(args) {
118
+ if (!args.meetingId && !args.newMeetingName) {
119
+ throw new Error('meetingId 또는 newMeetingName 중 하나는 필수입니다.');
120
+ }
121
+ const phoneParts = parsePhone(args.phone);
122
+ const emailParts = parseEmail(args.email);
123
+ const json = await this.http.postJson('/ajaxReservationConfirm.htm', {
124
+ reservationId: args.reservationId,
125
+ phone: formatPhone(phoneParts),
126
+ ...phoneParts,
127
+ name: args.name,
128
+ pinNum: args.pinNum,
129
+ ...emailParts,
130
+ meeting_id: args.meetingId ? String(args.meetingId) : '새모임',
131
+ newMeetingName: args.newMeetingName ?? '',
132
+ prepareMemo: args.memo ?? '',
133
+ projectSeq: '',
134
+ tozApplyType: '',
135
+ addedInfo: '',
136
+ attendType: '',
137
+ isMobile: 'false',
138
+ });
139
+ const resultMsg = json.resultMsg ?? '';
140
+ if (!isReservationConfirmSuccess(resultMsg)) {
141
+ throw new Error(resultMsg || '예약 확정에 실패했습니다.');
142
+ }
143
+ return { resultMsg, isLargeBooth: resultMsg.includes('대형부스') };
144
+ }
145
+ async destroyHold() {
146
+ await this.http.postText('/ajaxDestroyReservation.htm', {});
147
+ }
148
+ async myReservations(args = {}) {
149
+ await this.http.bootstrap();
150
+ await this.mypageLogin(this.requireName(args.name), this.requirePhone(args.phone));
151
+ const html = await this.http.post('/mypage.htm', {
152
+ opage: '1',
153
+ rpage: '1',
154
+ key: '',
155
+ projectSeq: '',
156
+ tozApplyType: '',
157
+ addedInfo: '',
158
+ startdate: args.startDate ?? '',
159
+ enddate: args.endDate ?? '',
160
+ meetingName: args.meetingName ?? '',
161
+ });
162
+ return parseMypageReservations(html);
163
+ }
164
+ async cancel(args) {
165
+ await this.http.bootstrap();
166
+ await this.mypageLogin(this.requireName(args.name), this.requirePhone(args.phone));
167
+ const result = await this.http.postText('/ajaxCancelReservation.htm', {
168
+ reservation_id: String(args.reservationId),
169
+ });
170
+ if (result !== 'SUCCESS') {
171
+ if (result === 'FAILED')
172
+ throw new Error('취소하지 못했습니다.');
173
+ throw new Error(result || '취소하지 못했습니다.');
174
+ }
175
+ }
176
+ requireName(name) {
177
+ const resolved = name ?? this.identity.name;
178
+ if (!resolved)
179
+ throw new Error('Toz name is required (pass via args or TozClient({ name }))');
180
+ return resolved;
181
+ }
182
+ requirePhone(phone) {
183
+ const resolved = phone ?? this.identity.phone;
184
+ if (!resolved)
185
+ throw new Error('Toz phone is required (pass via args or TozClient({ phone }))');
186
+ return resolved;
187
+ }
188
+ async mypageLogin(name, phone) {
189
+ const parts = parsePhone(phone);
190
+ await this.http.post('/mypage_login_.htm', {
191
+ key: '',
192
+ projectSeq: '',
193
+ tozApplyType: '',
194
+ addedInfo: '',
195
+ email: '',
196
+ name,
197
+ ...parts,
198
+ });
199
+ }
200
+ }
201
+ function sleep(ms) {
202
+ return new Promise((resolve) => setTimeout(resolve, ms));
203
+ }
204
+ //# sourceMappingURL=toz-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toz-client.js","sourceRoot":"","sources":["../../src/toz-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export interface TozPendingReservation {
2
+ reservationId: string;
3
+ cookies: Record<string, string>;
4
+ branchName: string;
5
+ branchTel: string;
6
+ boothGroupName: string;
7
+ isLargeBooth: boolean;
8
+ date: string;
9
+ startTime: string;
10
+ endTime: string;
11
+ durationMinutes: number;
12
+ userCount: number;
13
+ boothId: number;
14
+ meetingId?: number;
15
+ newMeetingName?: string;
16
+ email: string;
17
+ memo?: string;
18
+ name: string;
19
+ phone: string;
20
+ createdAt: string;
21
+ expiresAt: string;
22
+ }
23
+ export declare class TozPendingStore {
24
+ private readonly path;
25
+ constructor(configDir?: string);
26
+ get(): Promise<TozPendingReservation | null>;
27
+ set(reservation: TozPendingReservation): Promise<void>;
28
+ clear(): Promise<void>;
29
+ }
30
+ //# sourceMappingURL=toz-pending-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toz-pending-store.d.ts","sourceRoot":"","sources":["../../src/toz-pending-store.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,OAAO,CAAA;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;gBAEjB,SAAS,CAAC,EAAE,MAAM;IAKxB,GAAG,IAAI,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAW5C,GAAG,CAAC,WAAW,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAWtD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
@@ -0,0 +1,36 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
3
+ import { dirname, join } from 'node:path';
4
+ import { getConfigDir } from './shared/utils/config-dir.js';
5
+ export class TozPendingStore {
6
+ path;
7
+ constructor(configDir) {
8
+ const dir = configDir ?? getConfigDir();
9
+ this.path = join(dir, 'toz-pending.json');
10
+ }
11
+ async get() {
12
+ if (!existsSync(this.path))
13
+ return null;
14
+ try {
15
+ const raw = await readFile(this.path, 'utf8');
16
+ return JSON.parse(raw);
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ }
22
+ async set(reservation) {
23
+ const dir = dirname(this.path);
24
+ await mkdir(dir, { recursive: true });
25
+ // Write to a temp file with 0o600 from creation, then rename atomically.
26
+ // Avoids the default 0o644 window between writeFile() and chmod() that
27
+ // would briefly expose the cookie + phone number to other users on the system.
28
+ const tmp = `${this.path}.tmp-${process.pid}-${Date.now()}`;
29
+ await writeFile(tmp, JSON.stringify(reservation, null, 2), { mode: 0o600 });
30
+ await rename(tmp, this.path);
31
+ }
32
+ async clear() {
33
+ await rm(this.path, { force: true });
34
+ }
35
+ }
36
+ //# sourceMappingURL=toz-pending-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toz-pending-store.js","sourceRoot":"","sources":["../../src/toz-pending-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACzE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAyBxD,MAAM,OAAO,eAAe;IACT,IAAI,CAAQ;IAE7B,YAAY,SAAkB;QAC5B,MAAM,GAAG,GAAG,SAAS,IAAI,YAAY,EAAE,CAAA;QACvC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAA;IAC3C,CAAC;IAED,KAAK,CAAC,GAAG;QACP,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QAEvC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;YAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0B,CAAA;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,WAAkC;QAC1C,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC9B,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACrC,yEAAyE;QACzE,uEAAuE;QACvE,+EAA+E;QAC/E,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAA;QAC3D,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAC3E,MAAM,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACtC,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opensoma",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "SWMaestro MyPage CLI & SDK for AI agents",
5
5
  "license": "MIT",
6
6
  "repository": {
package/src/cli.ts CHANGED
@@ -14,12 +14,14 @@ import {
14
14
  roomCommand,
15
15
  scheduleCommand,
16
16
  teamCommand,
17
+ tozCommand,
17
18
  } from './commands/index'
18
19
 
19
- function isAuthCommand(command: Command): boolean {
20
+ function isUnauthenticatedCommand(command: Command): boolean {
20
21
  let current: Command | null = command
21
22
  while (current) {
22
- if (current.name() === 'auth') {
23
+ const name = current.name()
24
+ if (name === 'auth' || name === 'toz') {
23
25
  return true
24
26
  }
25
27
  current = current.parent
@@ -32,7 +34,7 @@ const program = new Command()
32
34
  program.name('opensoma').description('SWMaestro MyPage CLI for AI agents').version(pkg.version)
33
35
 
34
36
  program.hook('preAction', async (_thisCommand, actionCommand) => {
35
- if (isAuthCommand(actionCommand)) {
37
+ if (isUnauthenticatedCommand(actionCommand)) {
36
38
  return
37
39
  }
38
40
 
@@ -55,6 +57,7 @@ program.addCommand(teamCommand)
55
57
  program.addCommand(memberCommand)
56
58
  program.addCommand(scheduleCommand)
57
59
  program.addCommand(reportCommand)
60
+ program.addCommand(tozCommand)
58
61
 
59
62
  program.parse(process.argv)
60
63
 
package/src/client.ts CHANGED
@@ -22,6 +22,7 @@ import {
22
22
  } from './shared/utils/swmaestro'
23
23
  import { buildTeamActionPayload } from './shared/utils/team-action-params'
24
24
  import { buildTeamListParams, type TeamSearchQuery } from './shared/utils/team-params'
25
+ import { TozClient } from './toz-client'
25
26
  import type {
26
27
  ApplicationHistoryItem,
27
28
  ApprovalListItem,
@@ -52,6 +53,8 @@ export interface SomaClientOptions {
52
53
  username?: string
53
54
  password?: string
54
55
  verbose?: boolean
56
+ tozName?: string
57
+ tozPhone?: string
55
58
  /** @internal */
56
59
  http?: SomaHttp
57
60
  }
@@ -159,6 +162,8 @@ export class SomaClient {
159
162
  list(options?: { page?: number }): Promise<{ items: ScheduleListItem[]; pagination: Pagination }>
160
163
  }
161
164
 
165
+ readonly toz: TozClient
166
+
162
167
  constructor(options: SomaClientOptions = {}) {
163
168
  this.options = options
164
169
  this.loginCredentials =
@@ -579,6 +584,11 @@ export class SomaClient {
579
584
  return formatters.parseScheduleList(html)
580
585
  },
581
586
  }
587
+
588
+ this.toz = new TozClient({
589
+ name: options.tozName,
590
+ phone: options.tozPhone,
591
+ })
582
592
  }
583
593
 
584
594
  getSessionData(): { sessionCookie: string | undefined; csrfToken: string | null } {
@@ -115,6 +115,8 @@ describe('createAuthenticatedHttp', () => {
115
115
  csrfToken: 'stale-csrf',
116
116
  username: 'mentor@example.com',
117
117
  password: 'secret',
118
+ tozName: 'Mentor One',
119
+ tozPhone: '010-1234-5678',
118
120
  }),
119
121
  setCredentials: async (credentials: Record<string, string>) => {
120
122
  savedCredentials = credentials
@@ -154,6 +156,8 @@ describe('createAuthenticatedHttp', () => {
154
156
  csrfToken: 'fresh-csrf',
155
157
  username: 'mentor@example.com',
156
158
  password: 'secret',
159
+ tozName: 'Mentor One',
160
+ tozPhone: '010-1234-5678',
157
161
  })
158
162
  })
159
163
 
@@ -8,3 +8,4 @@ export { teamCommand } from './team'
8
8
  export { memberCommand } from './member'
9
9
  export { scheduleCommand } from './schedule'
10
10
  export { reportCommand } from './report'
11
+ export { tozCommand } from './toz'
@@ -0,0 +1,51 @@
1
+ import { describe, expect, it } from 'bun:test'
2
+
3
+ import { resolveTozIdentity, resolveTozPin } from './toz'
4
+
5
+ describe('resolveTozIdentity', () => {
6
+ it('uses flag values before stored identity', async () => {
7
+ const identity = await resolveTozIdentity('Mentor One', '010-1111-2222', {
8
+ promptPhone: async () => '010-3333-4444',
9
+ store: {
10
+ getTozIdentity: async () => ({ name: 'Mentor Two', phone: '010-5555-6666' }),
11
+ },
12
+ })
13
+
14
+ expect(identity).toEqual({ name: 'Mentor One', phone: '010-1111-2222' })
15
+ })
16
+
17
+ it('prompts for phone when name is available but phone is missing', async () => {
18
+ const identity = await resolveTozIdentity('Mentor One', undefined, {
19
+ promptPhone: async () => '010-3333-4444',
20
+ store: {
21
+ getTozIdentity: async () => null,
22
+ },
23
+ })
24
+
25
+ expect(identity).toEqual({ name: 'Mentor One', phone: '010-3333-4444' })
26
+ })
27
+
28
+ it('keeps non-interactive callers failing when phone is missing', async () => {
29
+ await expect(
30
+ resolveTozIdentity('Mentor One', undefined, {
31
+ store: {
32
+ getTozIdentity: async () => null,
33
+ },
34
+ }),
35
+ ).rejects.toThrow(/Toz identity not set/)
36
+ })
37
+ })
38
+
39
+ describe('resolveTozPin', () => {
40
+ it('uses the flag value before prompting', async () => {
41
+ const pin = await resolveTozPin('123456', async () => '654321')
42
+
43
+ expect(pin).toBe('123456')
44
+ })
45
+
46
+ it('prompts when the flag value is missing', async () => {
47
+ const pin = await resolveTozPin(undefined, async () => '654321')
48
+
49
+ expect(pin).toBe('654321')
50
+ })
51
+ })