@iwonz/ywtc 0.0.0 → 2.0.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 (94) hide show
  1. package/.env.example +4 -0
  2. package/CHANGELOG.md +39 -0
  3. package/LICENSE +21 -0
  4. package/README.md +258 -1
  5. package/dist/adapters/confluence.d.ts +46 -0
  6. package/dist/adapters/confluence.js +187 -0
  7. package/dist/adapters/confluence.js.map +1 -0
  8. package/dist/adapters/factory.d.ts +3 -0
  9. package/dist/adapters/factory.js +11 -0
  10. package/dist/adapters/factory.js.map +1 -0
  11. package/dist/adapters/yandex.d.ts +45 -0
  12. package/dist/adapters/yandex.js +233 -0
  13. package/dist/adapters/yandex.js.map +1 -0
  14. package/dist/cli-arguments.d.ts +41 -0
  15. package/dist/cli-arguments.js +149 -0
  16. package/dist/cli-arguments.js.map +1 -0
  17. package/dist/cli.d.ts +2 -0
  18. package/dist/cli.js +180 -0
  19. package/dist/cli.js.map +1 -0
  20. package/dist/clients/confluence-cloud.d.ts +45 -0
  21. package/dist/clients/confluence-cloud.js +261 -0
  22. package/dist/clients/confluence-cloud.js.map +1 -0
  23. package/dist/clients/confluence-factory.d.ts +3 -0
  24. package/dist/clients/confluence-factory.js +8 -0
  25. package/dist/clients/confluence-factory.js.map +1 -0
  26. package/dist/clients/confluence.d.ts +42 -0
  27. package/dist/clients/confluence.js +286 -0
  28. package/dist/clients/confluence.js.map +1 -0
  29. package/dist/clients/yandex-wiki.d.ts +35 -0
  30. package/dist/clients/yandex-wiki.js +255 -0
  31. package/dist/clients/yandex-wiki.js.map +1 -0
  32. package/dist/config.d.ts +52 -0
  33. package/dist/config.js +177 -0
  34. package/dist/config.js.map +1 -0
  35. package/dist/content-model.d.ts +12 -0
  36. package/dist/content-model.js +416 -0
  37. package/dist/content-model.js.map +1 -0
  38. package/dist/conversion.d.ts +43 -0
  39. package/dist/conversion.js +450 -0
  40. package/dist/conversion.js.map +1 -0
  41. package/dist/doctor.d.ts +24 -0
  42. package/dist/doctor.js +45 -0
  43. package/dist/doctor.js.map +1 -0
  44. package/dist/domain.d.ts +202 -0
  45. package/dist/domain.js +18 -0
  46. package/dist/domain.js.map +1 -0
  47. package/dist/filesystem-export.d.ts +53 -0
  48. package/dist/filesystem-export.js +243 -0
  49. package/dist/filesystem-export.js.map +1 -0
  50. package/dist/graph.d.ts +13 -0
  51. package/dist/graph.js +121 -0
  52. package/dist/graph.js.map +1 -0
  53. package/dist/http.d.ts +26 -0
  54. package/dist/http.js +100 -0
  55. package/dist/http.js.map +1 -0
  56. package/dist/index.d.ts +24 -0
  57. package/dist/index.js +25 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/input.d.ts +4 -0
  60. package/dist/input.js +56 -0
  61. package/dist/input.js.map +1 -0
  62. package/dist/locators.d.ts +24 -0
  63. package/dist/locators.js +84 -0
  64. package/dist/locators.js.map +1 -0
  65. package/dist/logger.d.ts +7 -0
  66. package/dist/logger.js +28 -0
  67. package/dist/logger.js.map +1 -0
  68. package/dist/migrator.d.ts +53 -0
  69. package/dist/migrator.js +669 -0
  70. package/dist/migrator.js.map +1 -0
  71. package/dist/rate-limiter.d.ts +12 -0
  72. package/dist/rate-limiter.js +31 -0
  73. package/dist/rate-limiter.js.map +1 -0
  74. package/dist/report.d.ts +101 -0
  75. package/dist/report.js +106 -0
  76. package/dist/report.js.map +1 -0
  77. package/dist/state.d.ts +119 -0
  78. package/dist/state.js +201 -0
  79. package/dist/state.js.map +1 -0
  80. package/dist/types.d.ts +197 -0
  81. package/dist/types.js +2 -0
  82. package/dist/types.js.map +1 -0
  83. package/dist/updater.d.ts +24 -0
  84. package/dist/updater.js +92 -0
  85. package/dist/updater.js.map +1 -0
  86. package/dist/version.d.ts +1 -0
  87. package/dist/version.js +8 -0
  88. package/dist/version.js.map +1 -0
  89. package/dist/workspace.d.ts +29 -0
  90. package/dist/workspace.js +157 -0
  91. package/dist/workspace.js.map +1 -0
  92. package/docs/assets/readme-header.png +0 -0
  93. package/package.json +108 -3
  94. package/ywtc.config.example.yaml +52 -0
package/dist/state.js ADDED
@@ -0,0 +1,201 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { mkdir, readFile, rename, stat, writeFile } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ function canonicalUrl(value) {
5
+ const url = new URL(value);
6
+ url.hash = '';
7
+ url.search = '';
8
+ url.pathname = url.pathname.replace(/\/+$/, '') || '/';
9
+ return url.toString().replace(/\/$/, '');
10
+ }
11
+ function canonicalIdentity(identity) {
12
+ const endpoint = (value) => value.provider === 'filesystem'
13
+ ? { provider: value.provider, path: path.resolve(value.path), format: value.format }
14
+ : {
15
+ profile: value.profile,
16
+ provider: value.provider,
17
+ instance: canonicalUrl(value.instance),
18
+ objectId: value.objectId,
19
+ ...(value.containerId ? { containerId: value.containerId } : {}),
20
+ };
21
+ return { schema: 'ywtc-state-v2', source: endpoint(identity.source), destination: endpoint(identity.destination) };
22
+ }
23
+ export function transferStateId(identity) {
24
+ return createHash('sha256').update(JSON.stringify(canonicalIdentity(identity))).digest('hex').slice(0, 24);
25
+ }
26
+ export function resolveStateLocation(identity, options = {}) {
27
+ const id = transferStateId(identity);
28
+ if (options.stateFilename !== undefined) {
29
+ const filename = options.stateFilename.trim();
30
+ if (!filename)
31
+ throw new Error('--state must be a non-empty JSON path. Omit it to use automatic state selection.');
32
+ const runtimeDirectory = path.dirname(filename);
33
+ return {
34
+ id,
35
+ mode: 'explicit',
36
+ filename,
37
+ runtimeDirectory,
38
+ cacheDirectory: path.join(runtimeDirectory, 'cache'),
39
+ reportsDirectory: path.join(runtimeDirectory, 'reports'),
40
+ };
41
+ }
42
+ const runtimeDirectory = options.runtimeDirectory ?? '.states';
43
+ return {
44
+ id,
45
+ mode: 'automatic',
46
+ filename: path.join(runtimeDirectory, `${id}.json`),
47
+ runtimeDirectory,
48
+ cacheDirectory: path.join(runtimeDirectory, 'cache'),
49
+ reportsDirectory: path.join(runtimeDirectory, 'reports'),
50
+ };
51
+ }
52
+ function emptyState(identity) {
53
+ const now = new Date().toISOString();
54
+ return { version: 2, identity, createdAt: now, updatedAt: now, pages: {}, graph: { edges: [] }, runs: [] };
55
+ }
56
+ function isRecord(value) {
57
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
58
+ }
59
+ function identityEquals(left, right) {
60
+ return JSON.stringify(canonicalIdentity(left)) === JSON.stringify(canonicalIdentity(right));
61
+ }
62
+ function help(filename) {
63
+ return `Restore a v2 backup, choose a matching --state file, omit --state for automatic selection, or use --fresh to preserve "${filename}" and start clean.`;
64
+ }
65
+ async function readState(filename) {
66
+ let content;
67
+ try {
68
+ content = await readFile(filename, 'utf8');
69
+ }
70
+ catch (error) {
71
+ if (error.code === 'ENOENT')
72
+ return undefined;
73
+ throw new Error(`Cannot read transfer state "${filename}". ${help(filename)}`, { cause: error });
74
+ }
75
+ let value;
76
+ try {
77
+ value = JSON.parse(content);
78
+ }
79
+ catch (error) {
80
+ throw new Error(`Transfer state "${filename}" is not valid JSON. ${help(filename)}`, { cause: error });
81
+ }
82
+ if (isRecord(value) && value.version === 1) {
83
+ throw new Error(`Transfer state "${filename}" uses unsupported schema v1. It was preserved unchanged. Use a new workdir/state or --fresh; automatic conversion could duplicate remote content.`);
84
+ }
85
+ if (!isRecord(value) || value.version !== 2 || !isRecord(value.identity) || !isRecord(value.pages) || !isRecord(value.graph) || !Array.isArray(value.runs)) {
86
+ throw new Error(`Transfer state "${filename}" has an unsupported or incomplete schema. ${help(filename)}`);
87
+ }
88
+ return value;
89
+ }
90
+ function backupFilename(filename) {
91
+ return `${filename}.backup-${new Date().toISOString().replace(/[:.]/g, '-')}-${randomUUID().slice(0, 8)}`;
92
+ }
93
+ export class StateStore {
94
+ filename;
95
+ state;
96
+ saveChain = Promise.resolve();
97
+ readOnly = false;
98
+ info;
99
+ constructor(filename) {
100
+ this.filename = filename;
101
+ }
102
+ async load(identity, options = {}) {
103
+ this.readOnly = options.dryRun ?? false;
104
+ if (options.fresh) {
105
+ let preserved;
106
+ if (!this.readOnly) {
107
+ const backup = backupFilename(this.filename);
108
+ try {
109
+ const selected = await stat(this.filename);
110
+ if (!selected.isFile())
111
+ throw new Error(`State path is not a regular file: ${this.filename}`);
112
+ await rename(this.filename, backup);
113
+ preserved = backup;
114
+ }
115
+ catch (error) {
116
+ if (error.code !== 'ENOENT')
117
+ throw error;
118
+ }
119
+ }
120
+ this.state = emptyState(identity);
121
+ this.info = { source: 'fresh', ...(preserved ? { backupFilename: preserved } : {}) };
122
+ return this.state;
123
+ }
124
+ const selected = await readState(this.filename);
125
+ if (selected) {
126
+ if (!identityEquals(selected.identity, identity)) {
127
+ throw new Error(`Transfer state "${this.filename}" belongs to another canonical source/destination pair. ${help(this.filename)}`);
128
+ }
129
+ for (const run of selected.runs) {
130
+ if (run.status === 'running') {
131
+ run.status = 'interrupted';
132
+ run.finishedAt = new Date().toISOString();
133
+ }
134
+ }
135
+ this.state = selected;
136
+ this.info = { source: 'existing' };
137
+ return selected;
138
+ }
139
+ this.state = emptyState(identity);
140
+ this.info = { source: 'new' };
141
+ return this.state;
142
+ }
143
+ get value() {
144
+ if (!this.state)
145
+ throw new Error('StateStore.load() must be called before accessing state');
146
+ return this.state;
147
+ }
148
+ get loadInfo() {
149
+ if (!this.info)
150
+ throw new Error('StateStore.load() must be called before accessing load information');
151
+ return this.info;
152
+ }
153
+ async beginRun(scope, dryRun) {
154
+ const run = {
155
+ id: randomUUID(),
156
+ startedAt: new Date().toISOString(),
157
+ status: 'running',
158
+ scope,
159
+ dryRun,
160
+ pages: 0,
161
+ warnings: 0,
162
+ errors: 0,
163
+ };
164
+ this.value.runs.push(run);
165
+ if (!dryRun)
166
+ await this.save();
167
+ return run;
168
+ }
169
+ async finishRun(runId, status, counts) {
170
+ const run = this.value.runs.find((candidate) => candidate.id === runId);
171
+ if (!run)
172
+ throw new Error(`State run ${runId} was not initialized`);
173
+ Object.assign(run, counts, { status, finishedAt: new Date().toISOString() });
174
+ if (!this.readOnly)
175
+ await this.save();
176
+ }
177
+ async setGraph(rootId, edges) {
178
+ this.value.graph = { rootId, edges };
179
+ if (!this.readOnly)
180
+ await this.save();
181
+ }
182
+ async setPage(page) {
183
+ this.value.pages[page.sourceCanonicalId] = page;
184
+ if (!this.readOnly)
185
+ await this.save();
186
+ }
187
+ async save() {
188
+ if (this.readOnly)
189
+ throw new Error(`Refusing to write transfer state "${this.filename}" during --dry-run.`);
190
+ const write = this.saveChain.catch(() => undefined).then(async () => {
191
+ this.value.updatedAt = new Date().toISOString();
192
+ const temporary = `${this.filename}.${process.pid}.${Date.now()}.${randomUUID().slice(0, 8)}.tmp`;
193
+ await mkdir(path.dirname(this.filename), { recursive: true, mode: 0o700 });
194
+ await writeFile(temporary, `${JSON.stringify(this.value, null, 2)}\n`, { mode: 0o600 });
195
+ await rename(temporary, this.filename);
196
+ });
197
+ this.saveChain = write;
198
+ await write;
199
+ }
200
+ }
201
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,197 @@
1
+ import type { Readable } from 'node:stream';
2
+ export type YandexPageType = 'page' | 'grid' | 'wysiwyg' | 'template';
3
+ export interface YandexBreadcrumb {
4
+ id?: number;
5
+ slug: string;
6
+ title: string;
7
+ page_exists?: boolean;
8
+ }
9
+ export interface YandexPageDetails {
10
+ id: number;
11
+ slug: string;
12
+ title: string;
13
+ page_type: YandexPageType;
14
+ content?: string;
15
+ breadcrumbs?: YandexBreadcrumb[];
16
+ redirect?: {
17
+ page_id: number;
18
+ redirect_target: {
19
+ id: number;
20
+ slug: string;
21
+ title: string;
22
+ page_type?: YandexPageType | null;
23
+ };
24
+ } | null;
25
+ attributes?: {
26
+ created_at?: string;
27
+ modified_at?: string;
28
+ lang?: string;
29
+ is_readonly?: boolean;
30
+ is_draft?: boolean;
31
+ };
32
+ }
33
+ export interface YandexPageIdentity {
34
+ id: number;
35
+ slug: string;
36
+ }
37
+ export interface YandexAttachment {
38
+ id: number;
39
+ name: string;
40
+ is_downloadable: boolean;
41
+ download_url: string;
42
+ size: string | number;
43
+ description?: string;
44
+ created_at?: string;
45
+ mimetype?: string;
46
+ has_preview?: boolean;
47
+ check_status?: string;
48
+ }
49
+ export interface YandexGridColumn {
50
+ id?: string;
51
+ slug: string;
52
+ title: string;
53
+ type?: string;
54
+ format?: 'yfm' | 'wom' | 'plain' | null;
55
+ width?: number;
56
+ width_units?: '%' | 'px' | null;
57
+ }
58
+ export interface YandexGridRow {
59
+ id: string;
60
+ row: unknown[];
61
+ pinned?: boolean;
62
+ color?: string;
63
+ }
64
+ export interface YandexGrid {
65
+ id: string | number;
66
+ title: string;
67
+ page?: YandexPageIdentity;
68
+ structure: {
69
+ columns: YandexGridColumn[];
70
+ default_sort?: unknown[];
71
+ };
72
+ rows: YandexGridRow[];
73
+ rich_text_format?: 'yfm' | 'wom' | 'plain';
74
+ revision?: string;
75
+ }
76
+ export interface YandexGridSummary {
77
+ id: string;
78
+ title: string;
79
+ created_at?: string;
80
+ }
81
+ export interface DownloadedFile {
82
+ path: string;
83
+ size: number;
84
+ sha256: string;
85
+ mimeType?: string;
86
+ }
87
+ export interface ConfluencePage {
88
+ id: string;
89
+ type: 'page';
90
+ status?: string;
91
+ title: string;
92
+ space: {
93
+ key: string;
94
+ id?: number | string;
95
+ name?: string;
96
+ };
97
+ ancestors?: Array<{
98
+ id: string;
99
+ }>;
100
+ version?: {
101
+ number: number;
102
+ };
103
+ body?: {
104
+ storage?: {
105
+ value: string;
106
+ representation: string;
107
+ };
108
+ view?: {
109
+ value: string;
110
+ representation: string;
111
+ };
112
+ };
113
+ operations?: Array<{
114
+ operation: string;
115
+ targetType: string;
116
+ }>;
117
+ _links?: {
118
+ webui?: string;
119
+ base?: string;
120
+ self?: string;
121
+ };
122
+ }
123
+ export interface ConfluenceAttachment {
124
+ id: string;
125
+ title: string;
126
+ metadata?: {
127
+ mediaType?: string;
128
+ };
129
+ extensions?: {
130
+ fileSize?: number;
131
+ };
132
+ _links?: {
133
+ download?: string;
134
+ webui?: string;
135
+ };
136
+ }
137
+ export interface ConfluencePlatformInfo {
138
+ deployment: 'data-center' | 'cloud';
139
+ product: string;
140
+ version?: string;
141
+ api: string;
142
+ }
143
+ export interface YandexWikiApi {
144
+ getPageBySlug(slug: string): Promise<YandexPageDetails>;
145
+ getPageById(id: number): Promise<YandexPageDetails>;
146
+ getDescendants(id: number): Promise<YandexPageIdentity[]>;
147
+ getAttachments(pageId: number): Promise<YandexAttachment[]>;
148
+ getPageGrids(pageId: number): Promise<YandexGridSummary[]>;
149
+ getGrid(id: string): Promise<YandexGrid>;
150
+ download(pageId: number, attachmentId: number, destination: string): Promise<DownloadedFile>;
151
+ createPage(input: {
152
+ slug: string;
153
+ title: string;
154
+ content: string;
155
+ }): Promise<YandexPageDetails>;
156
+ updatePage(input: {
157
+ id: number;
158
+ title: string;
159
+ content: string;
160
+ }): Promise<YandexPageDetails>;
161
+ uploadAttachment(input: {
162
+ pageId: number;
163
+ filename: string;
164
+ path: string;
165
+ size: number;
166
+ }): Promise<YandexAttachment>;
167
+ }
168
+ export interface ConfluenceApi {
169
+ preflight?(): Promise<ConfluencePlatformInfo>;
170
+ resolveTarget(input: string): Promise<ConfluencePage>;
171
+ getPage(id: string): Promise<ConfluencePage>;
172
+ findPageByTitle(spaceKey: string, title: string): Promise<ConfluencePage | undefined>;
173
+ createPage(input: {
174
+ spaceKey: string;
175
+ parentId: string;
176
+ title: string;
177
+ storage: string;
178
+ }): Promise<ConfluencePage>;
179
+ updatePage(input: {
180
+ pageId: string;
181
+ title: string;
182
+ storage: string;
183
+ }): Promise<ConfluencePage>;
184
+ findAttachment(pageId: string, filename: string): Promise<ConfluenceAttachment | undefined>;
185
+ uploadAttachment(input: {
186
+ pageId: string;
187
+ filename: string;
188
+ file: Readable;
189
+ contentLength?: number;
190
+ mimeType?: string;
191
+ existingAttachmentId?: string;
192
+ }): Promise<ConfluenceAttachment>;
193
+ listAttachments(pageId: string): Promise<ConfluenceAttachment[]>;
194
+ getDescendants(pageId: string): Promise<ConfluencePage[]>;
195
+ downloadAttachment(pageId: string, attachment: ConfluenceAttachment, destination: string): Promise<DownloadedFile>;
196
+ pageWebUrl(page: ConfluencePage): string;
197
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ export type InstallationChannel = 'brew' | 'global-npm' | 'npx' | 'local' | 'source' | 'unknown';
2
+ export interface UpdateResult {
3
+ current: string;
4
+ latest: string;
5
+ channel: InstallationChannel;
6
+ updateAvailable: boolean;
7
+ installed: boolean;
8
+ command: string;
9
+ }
10
+ export declare function detectInstallationChannel(options?: {
11
+ entrypoint?: string;
12
+ environment?: NodeJS.ProcessEnv;
13
+ packageRoot?: string;
14
+ }): Promise<InstallationChannel>;
15
+ export declare function latestPublishedVersion(fetchImplementation?: typeof fetch): Promise<string>;
16
+ export declare function isNewerVersion(candidate: string, current: string): boolean;
17
+ export declare function runUpdate(options: {
18
+ currentVersion: string;
19
+ install: boolean;
20
+ via?: 'npm' | 'brew';
21
+ channel?: InstallationChannel;
22
+ fetchLatest?: () => Promise<string>;
23
+ execute?: (command: string, args: string[]) => Promise<void>;
24
+ }): Promise<UpdateResult>;
@@ -0,0 +1,92 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { access } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ async function pathExists(filename) {
6
+ try {
7
+ await access(filename);
8
+ return true;
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
14
+ export async function detectInstallationChannel(options = {}) {
15
+ const environment = options.environment ?? process.env;
16
+ const entrypoint = path.resolve(options.entrypoint ?? process.argv[1] ?? '');
17
+ const packageRoot = options.packageRoot ?? path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
18
+ if (entrypoint.includes('/Cellar/ywtc/') || entrypoint.includes('/homebrew/'))
19
+ return 'brew';
20
+ if (environment.npm_command === 'exec' || entrypoint.includes('/_npx/'))
21
+ return 'npx';
22
+ if (await pathExists(path.join(packageRoot, '.git')))
23
+ return 'source';
24
+ if (entrypoint.includes(`${path.sep}node_modules${path.sep}.bin${path.sep}`))
25
+ return 'local';
26
+ const npmPrefix = environment.npm_config_prefix;
27
+ if (npmPrefix && entrypoint.startsWith(path.resolve(npmPrefix)))
28
+ return 'global-npm';
29
+ if (entrypoint.includes(`${path.sep}lib${path.sep}node_modules${path.sep}@iwonz${path.sep}ywtc${path.sep}`))
30
+ return 'global-npm';
31
+ return 'unknown';
32
+ }
33
+ export async function latestPublishedVersion(fetchImplementation = fetch) {
34
+ const response = await fetchImplementation('https://registry.npmjs.org/@iwonz%2Fywtc/latest', {
35
+ headers: { Accept: 'application/json' },
36
+ signal: AbortSignal.timeout(15_000),
37
+ });
38
+ if (!response.ok)
39
+ throw new Error(`Cannot check npm for updates: HTTP ${response.status}`);
40
+ const payload = await response.json();
41
+ if (typeof payload.version !== 'string')
42
+ throw new Error('npm update response does not contain a version');
43
+ return payload.version;
44
+ }
45
+ function semverParts(version) {
46
+ const match = version.match(/^(\d+)\.(\d+)\.(\d+)/);
47
+ if (!match)
48
+ return [0, 0, 0];
49
+ return [Number(match[1]), Number(match[2]), Number(match[3])];
50
+ }
51
+ export function isNewerVersion(candidate, current) {
52
+ const left = semverParts(candidate);
53
+ const right = semverParts(current);
54
+ for (let index = 0; index < left.length; index += 1) {
55
+ if (left[index] !== right[index])
56
+ return (left[index] ?? 0) > (right[index] ?? 0);
57
+ }
58
+ return false;
59
+ }
60
+ function runProcess(command, args) {
61
+ return new Promise((resolve, reject) => {
62
+ const child = spawn(command, args, { shell: false, stdio: 'inherit' });
63
+ child.once('error', reject);
64
+ child.once('exit', (code, signal) => {
65
+ if (code === 0)
66
+ resolve();
67
+ else
68
+ reject(new Error(`${command} ${args.join(' ')} failed with ${signal ? `signal ${signal}` : `exit code ${code}`}`));
69
+ });
70
+ });
71
+ }
72
+ export async function runUpdate(options) {
73
+ const channel = options.channel ?? await detectInstallationChannel();
74
+ const latest = await (options.fetchLatest ?? latestPublishedVersion)();
75
+ const requested = options.via ?? (channel === 'brew' ? 'brew' : 'npm');
76
+ const command = requested === 'brew' ? 'brew update && brew upgrade ywtc' : 'npm install -g @iwonz/ywtc@latest';
77
+ const updateAvailable = isNewerVersion(latest, options.currentVersion);
78
+ const safe = (requested === 'brew' && channel === 'brew') || (requested === 'npm' && channel === 'global-npm');
79
+ if (!options.install || !updateAvailable || !safe) {
80
+ return { current: options.currentVersion, latest, channel, updateAvailable, installed: false, command };
81
+ }
82
+ const execute = options.execute ?? runProcess;
83
+ if (requested === 'brew') {
84
+ await execute('brew', ['update']);
85
+ await execute('brew', ['upgrade', 'ywtc']);
86
+ }
87
+ else {
88
+ await execute('npm', ['install', '-g', '@iwonz/ywtc@latest']);
89
+ }
90
+ return { current: options.currentVersion, latest, channel, updateAvailable, installed: true, command };
91
+ }
92
+ //# sourceMappingURL=updater.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updater.js","sourceRoot":"","sources":["../src/updater.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function packageVersion(): string;
@@ -0,0 +1,8 @@
1
+ import { readFileSync } from 'node:fs';
2
+ export function packageVersion() {
3
+ const packageJson = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
4
+ if (typeof packageJson.version !== 'string')
5
+ throw new Error('Package version is missing');
6
+ return packageJson.version;
7
+ }
8
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,SAAS,CAAC;AAErC,MAAM,UAAU,cAAc;IAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAwB,CAAC;IACzH,IAAI,OAAO,WAAW,CAAC,OAAO,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC3F,OAAO,WAAW,CAAC,OAAO,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,29 @@
1
+ export declare const WORKSPACE_MARKER = ".ywtc-workspace.json";
2
+ export declare const WORKSPACE_ENV = ".env";
3
+ export declare const WORKSPACE_CONFIG = "ywtc.config.yaml";
4
+ export declare const WORKSPACE_STATES = ".states";
5
+ export declare const ENV_TEMPLATE = "# Secrets referenced by ywtc.config.yaml\nYANDEX_WIKI_TOKEN=\nCONFLUENCE_TOKEN=\nCONFLUENCE_EMAIL=\n\n# Optional global overrides\nHTTP_TIMEOUT_MS=30000\nMIGRATION_CONCURRENCY=4\n";
6
+ export declare const CONFIG_TEMPLATE = "schemaVersion: 2\n\ndefaults:\n timeoutMs: 30000\n concurrency: 4\n\nconnections:\n yandex:\n type: yandex-wiki\n apiUrl: https://api.wiki.yandex.net/v1\n webUrl: https://wiki.example.com\n authType: oauth\n tokenEnv: YANDEX_WIKI_TOKEN\n organization:\n type: yandex360\n id: \"\"\n limits:\n readConcurrency: 4\n writeConcurrency: 2\n downloadConcurrency: 2\n uploadConcurrency: 2\n requestsPerSecond: 8\n burst: 8\n\n confluence:\n type: confluence\n deployment: data-center\n baseUrl: https://confluence.example.com/confluence\n authType: pat\n tokenEnv: CONFLUENCE_TOKEN\n limits:\n readConcurrency: 4\n writeConcurrency: 2\n downloadConcurrency: 2\n uploadConcurrency: 2\n requestsPerSecond: 8\n burst: 10\n";
7
+ export interface Workspace {
8
+ root: string;
9
+ marker: string;
10
+ envFile: string;
11
+ configFile: string;
12
+ statesDirectory: string;
13
+ cacheDirectory: string;
14
+ reportsDirectory: string;
15
+ source: 'explicit' | 'current' | 'default';
16
+ }
17
+ export interface WorkspaceInitialization {
18
+ workspace: Workspace;
19
+ created: string[];
20
+ existing: string[];
21
+ }
22
+ export declare function resolveWorkspace(options?: {
23
+ explicit?: string;
24
+ cwd?: string;
25
+ homeDirectory?: string;
26
+ }): Promise<Workspace>;
27
+ export declare function initializeWorkspace(workspace: Workspace): Promise<WorkspaceInitialization>;
28
+ export declare function validateWorkspaceMarker(workspace: Workspace): Promise<void>;
29
+ export declare function resolveWorkspacePath(workspace: Workspace, value: string): string;