@brainfish-ai/devdoc 0.1.21

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 (268) hide show
  1. package/LICENSE +33 -0
  2. package/README.md +415 -0
  3. package/bin/devdoc.js +13 -0
  4. package/dist/cli/commands/build.d.ts +5 -0
  5. package/dist/cli/commands/build.js +87 -0
  6. package/dist/cli/commands/check.d.ts +1 -0
  7. package/dist/cli/commands/check.js +143 -0
  8. package/dist/cli/commands/create.d.ts +24 -0
  9. package/dist/cli/commands/create.js +387 -0
  10. package/dist/cli/commands/deploy.d.ts +9 -0
  11. package/dist/cli/commands/deploy.js +433 -0
  12. package/dist/cli/commands/dev.d.ts +6 -0
  13. package/dist/cli/commands/dev.js +139 -0
  14. package/dist/cli/commands/init.d.ts +11 -0
  15. package/dist/cli/commands/init.js +238 -0
  16. package/dist/cli/commands/keys.d.ts +12 -0
  17. package/dist/cli/commands/keys.js +165 -0
  18. package/dist/cli/commands/start.d.ts +5 -0
  19. package/dist/cli/commands/start.js +56 -0
  20. package/dist/cli/commands/upload.d.ts +13 -0
  21. package/dist/cli/commands/upload.js +238 -0
  22. package/dist/cli/commands/whoami.d.ts +8 -0
  23. package/dist/cli/commands/whoami.js +91 -0
  24. package/dist/cli/index.d.ts +1 -0
  25. package/dist/cli/index.js +106 -0
  26. package/dist/config/index.d.ts +80 -0
  27. package/dist/config/index.js +133 -0
  28. package/dist/constants.d.ts +9 -0
  29. package/dist/constants.js +13 -0
  30. package/dist/index.d.ts +7 -0
  31. package/dist/index.js +12 -0
  32. package/dist/utils/logger.d.ts +16 -0
  33. package/dist/utils/logger.js +61 -0
  34. package/dist/utils/paths.d.ts +16 -0
  35. package/dist/utils/paths.js +50 -0
  36. package/package.json +51 -0
  37. package/renderer/app/api/assets/[...path]/route.ts +123 -0
  38. package/renderer/app/api/assets/route.ts +124 -0
  39. package/renderer/app/api/assets/upload/route.ts +177 -0
  40. package/renderer/app/api/auth-schemes/route.ts +77 -0
  41. package/renderer/app/api/chat/route.ts +858 -0
  42. package/renderer/app/api/codegen/route.ts +72 -0
  43. package/renderer/app/api/collections/route.ts +1016 -0
  44. package/renderer/app/api/debug/route.ts +53 -0
  45. package/renderer/app/api/deploy/route.ts +234 -0
  46. package/renderer/app/api/device/route.ts +42 -0
  47. package/renderer/app/api/docs/route.ts +187 -0
  48. package/renderer/app/api/keys/regenerate/route.ts +80 -0
  49. package/renderer/app/api/openapi-spec/route.ts +151 -0
  50. package/renderer/app/api/projects/[slug]/route.ts +153 -0
  51. package/renderer/app/api/projects/[slug]/stats/route.ts +96 -0
  52. package/renderer/app/api/projects/register/route.ts +152 -0
  53. package/renderer/app/api/proxy/route.ts +149 -0
  54. package/renderer/app/api/proxy-stream/route.ts +168 -0
  55. package/renderer/app/api/redirects/route.ts +47 -0
  56. package/renderer/app/api/schema/route.ts +65 -0
  57. package/renderer/app/api/subdomains/check/route.ts +172 -0
  58. package/renderer/app/api/suggestions/route.ts +144 -0
  59. package/renderer/app/favicon.ico +0 -0
  60. package/renderer/app/globals.css +1103 -0
  61. package/renderer/app/layout.tsx +47 -0
  62. package/renderer/app/llms-full.txt/route.ts +346 -0
  63. package/renderer/app/llms.txt/route.ts +279 -0
  64. package/renderer/app/page.tsx +14 -0
  65. package/renderer/app/robots.txt/route.ts +84 -0
  66. package/renderer/app/sitemap.xml/route.ts +199 -0
  67. package/renderer/components/docs/index.ts +12 -0
  68. package/renderer/components/docs/mdx/accordion.tsx +169 -0
  69. package/renderer/components/docs/mdx/badge.tsx +132 -0
  70. package/renderer/components/docs/mdx/callouts.tsx +154 -0
  71. package/renderer/components/docs/mdx/cards.tsx +213 -0
  72. package/renderer/components/docs/mdx/changelog.tsx +120 -0
  73. package/renderer/components/docs/mdx/code-block.tsx +186 -0
  74. package/renderer/components/docs/mdx/code-group.tsx +421 -0
  75. package/renderer/components/docs/mdx/file-embeds.tsx +105 -0
  76. package/renderer/components/docs/mdx/frame.tsx +112 -0
  77. package/renderer/components/docs/mdx/highlight.tsx +151 -0
  78. package/renderer/components/docs/mdx/iframe.tsx +134 -0
  79. package/renderer/components/docs/mdx/image.tsx +235 -0
  80. package/renderer/components/docs/mdx/index.ts +204 -0
  81. package/renderer/components/docs/mdx/mermaid.tsx +240 -0
  82. package/renderer/components/docs/mdx/param-field.tsx +200 -0
  83. package/renderer/components/docs/mdx/steps.tsx +113 -0
  84. package/renderer/components/docs/mdx/tabs.tsx +86 -0
  85. package/renderer/components/docs/mdx-renderer.tsx +100 -0
  86. package/renderer/components/docs/navigation/breadcrumbs.tsx +76 -0
  87. package/renderer/components/docs/navigation/index.ts +8 -0
  88. package/renderer/components/docs/navigation/page-nav.tsx +64 -0
  89. package/renderer/components/docs/navigation/sidebar.tsx +515 -0
  90. package/renderer/components/docs/navigation/toc.tsx +113 -0
  91. package/renderer/components/docs/notice.tsx +105 -0
  92. package/renderer/components/docs-header.tsx +274 -0
  93. package/renderer/components/docs-viewer/agent/agent-chat.tsx +2076 -0
  94. package/renderer/components/docs-viewer/agent/cards/debug-context-card.tsx +90 -0
  95. package/renderer/components/docs-viewer/agent/cards/endpoint-context-card.tsx +49 -0
  96. package/renderer/components/docs-viewer/agent/cards/index.tsx +50 -0
  97. package/renderer/components/docs-viewer/agent/cards/response-options-card.tsx +212 -0
  98. package/renderer/components/docs-viewer/agent/cards/types.ts +84 -0
  99. package/renderer/components/docs-viewer/agent/chat-message.tsx +17 -0
  100. package/renderer/components/docs-viewer/agent/index.tsx +6 -0
  101. package/renderer/components/docs-viewer/agent/messages/assistant-message.tsx +119 -0
  102. package/renderer/components/docs-viewer/agent/messages/chat-message.tsx +46 -0
  103. package/renderer/components/docs-viewer/agent/messages/index.ts +17 -0
  104. package/renderer/components/docs-viewer/agent/messages/tool-call-display.tsx +721 -0
  105. package/renderer/components/docs-viewer/agent/messages/types.ts +61 -0
  106. package/renderer/components/docs-viewer/agent/messages/typing-indicator.tsx +24 -0
  107. package/renderer/components/docs-viewer/agent/messages/user-message.tsx +51 -0
  108. package/renderer/components/docs-viewer/code-editor/index.tsx +2 -0
  109. package/renderer/components/docs-viewer/code-editor/notes-mode.tsx +1283 -0
  110. package/renderer/components/docs-viewer/content/changelog-page.tsx +331 -0
  111. package/renderer/components/docs-viewer/content/doc-page.tsx +285 -0
  112. package/renderer/components/docs-viewer/content/documentation-viewer.tsx +17 -0
  113. package/renderer/components/docs-viewer/content/index.tsx +29 -0
  114. package/renderer/components/docs-viewer/content/introduction.tsx +21 -0
  115. package/renderer/components/docs-viewer/content/request-details.tsx +330 -0
  116. package/renderer/components/docs-viewer/content/sections/auth.tsx +69 -0
  117. package/renderer/components/docs-viewer/content/sections/body.tsx +66 -0
  118. package/renderer/components/docs-viewer/content/sections/headers.tsx +43 -0
  119. package/renderer/components/docs-viewer/content/sections/overview.tsx +40 -0
  120. package/renderer/components/docs-viewer/content/sections/parameters.tsx +43 -0
  121. package/renderer/components/docs-viewer/content/sections/responses.tsx +87 -0
  122. package/renderer/components/docs-viewer/global-auth-modal.tsx +352 -0
  123. package/renderer/components/docs-viewer/index.tsx +1466 -0
  124. package/renderer/components/docs-viewer/playground/auth-editor.tsx +280 -0
  125. package/renderer/components/docs-viewer/playground/body-editor.tsx +221 -0
  126. package/renderer/components/docs-viewer/playground/code-editor.tsx +224 -0
  127. package/renderer/components/docs-viewer/playground/code-snippet.tsx +387 -0
  128. package/renderer/components/docs-viewer/playground/graphql-playground.tsx +745 -0
  129. package/renderer/components/docs-viewer/playground/index.tsx +671 -0
  130. package/renderer/components/docs-viewer/playground/key-value-editor.tsx +261 -0
  131. package/renderer/components/docs-viewer/playground/method-selector.tsx +60 -0
  132. package/renderer/components/docs-viewer/playground/request-builder.tsx +179 -0
  133. package/renderer/components/docs-viewer/playground/request-tabs.tsx +237 -0
  134. package/renderer/components/docs-viewer/playground/response-cards/idle-card.tsx +21 -0
  135. package/renderer/components/docs-viewer/playground/response-cards/index.tsx +93 -0
  136. package/renderer/components/docs-viewer/playground/response-cards/loading-card.tsx +16 -0
  137. package/renderer/components/docs-viewer/playground/response-cards/network-error-card.tsx +23 -0
  138. package/renderer/components/docs-viewer/playground/response-cards/response-body-card.tsx +268 -0
  139. package/renderer/components/docs-viewer/playground/response-cards/types.ts +82 -0
  140. package/renderer/components/docs-viewer/playground/response-viewer.tsx +43 -0
  141. package/renderer/components/docs-viewer/search/index.ts +2 -0
  142. package/renderer/components/docs-viewer/search/search-dialog.tsx +331 -0
  143. package/renderer/components/docs-viewer/search/use-search.ts +117 -0
  144. package/renderer/components/docs-viewer/shared/markdown-renderer.tsx +431 -0
  145. package/renderer/components/docs-viewer/shared/method-badge.tsx +41 -0
  146. package/renderer/components/docs-viewer/shared/schema-viewer.tsx +349 -0
  147. package/renderer/components/docs-viewer/sidebar/collection-tree.tsx +239 -0
  148. package/renderer/components/docs-viewer/sidebar/endpoint-options.tsx +316 -0
  149. package/renderer/components/docs-viewer/sidebar/index.tsx +343 -0
  150. package/renderer/components/docs-viewer/sidebar/right-sidebar.tsx +202 -0
  151. package/renderer/components/docs-viewer/sidebar/sidebar-group.tsx +118 -0
  152. package/renderer/components/docs-viewer/sidebar/sidebar-item.tsx +226 -0
  153. package/renderer/components/docs-viewer/sidebar/sidebar-section.tsx +52 -0
  154. package/renderer/components/theme-provider.tsx +11 -0
  155. package/renderer/components/theme-toggle.tsx +76 -0
  156. package/renderer/components/ui/badge.tsx +46 -0
  157. package/renderer/components/ui/button.tsx +59 -0
  158. package/renderer/components/ui/dialog.tsx +118 -0
  159. package/renderer/components/ui/dropdown-menu.tsx +257 -0
  160. package/renderer/components/ui/input.tsx +21 -0
  161. package/renderer/components/ui/label.tsx +24 -0
  162. package/renderer/components/ui/navigation-menu.tsx +168 -0
  163. package/renderer/components/ui/select.tsx +190 -0
  164. package/renderer/components/ui/spinner.tsx +114 -0
  165. package/renderer/components/ui/tabs.tsx +66 -0
  166. package/renderer/components/ui/tooltip.tsx +61 -0
  167. package/renderer/hooks/use-code-copy.ts +88 -0
  168. package/renderer/hooks/use-openapi-title.ts +44 -0
  169. package/renderer/lib/api-docs/agent/index.ts +6 -0
  170. package/renderer/lib/api-docs/agent/indexer.ts +323 -0
  171. package/renderer/lib/api-docs/agent/spec-summary.ts +335 -0
  172. package/renderer/lib/api-docs/agent/types.ts +116 -0
  173. package/renderer/lib/api-docs/auth/auth-context.tsx +225 -0
  174. package/renderer/lib/api-docs/auth/auth-storage.ts +87 -0
  175. package/renderer/lib/api-docs/auth/crypto.ts +89 -0
  176. package/renderer/lib/api-docs/auth/index.ts +4 -0
  177. package/renderer/lib/api-docs/code-editor/db.ts +164 -0
  178. package/renderer/lib/api-docs/code-editor/hooks.ts +266 -0
  179. package/renderer/lib/api-docs/code-editor/index.ts +6 -0
  180. package/renderer/lib/api-docs/code-editor/mode-context.tsx +207 -0
  181. package/renderer/lib/api-docs/code-editor/types.ts +105 -0
  182. package/renderer/lib/api-docs/codegen/definitions.ts +297 -0
  183. package/renderer/lib/api-docs/codegen/har.ts +251 -0
  184. package/renderer/lib/api-docs/codegen/index.ts +159 -0
  185. package/renderer/lib/api-docs/factories.ts +151 -0
  186. package/renderer/lib/api-docs/index.ts +17 -0
  187. package/renderer/lib/api-docs/mobile-context.tsx +112 -0
  188. package/renderer/lib/api-docs/navigation-context.tsx +88 -0
  189. package/renderer/lib/api-docs/parsers/graphql/README.md +129 -0
  190. package/renderer/lib/api-docs/parsers/graphql/index.ts +91 -0
  191. package/renderer/lib/api-docs/parsers/graphql/parser.ts +491 -0
  192. package/renderer/lib/api-docs/parsers/graphql/transformer.ts +246 -0
  193. package/renderer/lib/api-docs/parsers/graphql/types.ts +283 -0
  194. package/renderer/lib/api-docs/parsers/openapi/README.md +32 -0
  195. package/renderer/lib/api-docs/parsers/openapi/dereferencer.ts +60 -0
  196. package/renderer/lib/api-docs/parsers/openapi/extractors/auth.ts +574 -0
  197. package/renderer/lib/api-docs/parsers/openapi/extractors/body.ts +403 -0
  198. package/renderer/lib/api-docs/parsers/openapi/extractors/index.ts +232 -0
  199. package/renderer/lib/api-docs/parsers/openapi/index.ts +171 -0
  200. package/renderer/lib/api-docs/parsers/openapi/transformer.ts +277 -0
  201. package/renderer/lib/api-docs/parsers/openapi/validator.ts +31 -0
  202. package/renderer/lib/api-docs/playground/context.tsx +107 -0
  203. package/renderer/lib/api-docs/playground/navigation-context.tsx +124 -0
  204. package/renderer/lib/api-docs/playground/request-builder.ts +223 -0
  205. package/renderer/lib/api-docs/playground/request-runner.ts +282 -0
  206. package/renderer/lib/api-docs/playground/types.ts +35 -0
  207. package/renderer/lib/api-docs/types.ts +269 -0
  208. package/renderer/lib/api-docs/utils.ts +311 -0
  209. package/renderer/lib/cache.ts +193 -0
  210. package/renderer/lib/docs/config/index.ts +29 -0
  211. package/renderer/lib/docs/config/loader.ts +142 -0
  212. package/renderer/lib/docs/config/schema.ts +298 -0
  213. package/renderer/lib/docs/index.ts +12 -0
  214. package/renderer/lib/docs/mdx/compiler.ts +176 -0
  215. package/renderer/lib/docs/mdx/frontmatter.ts +80 -0
  216. package/renderer/lib/docs/mdx/index.ts +26 -0
  217. package/renderer/lib/docs/navigation/generator.ts +348 -0
  218. package/renderer/lib/docs/navigation/index.ts +12 -0
  219. package/renderer/lib/docs/navigation/types.ts +123 -0
  220. package/renderer/lib/docs-navigation-context.tsx +80 -0
  221. package/renderer/lib/multi-tenant/context.ts +105 -0
  222. package/renderer/lib/storage/blob.ts +845 -0
  223. package/renderer/lib/utils.ts +6 -0
  224. package/renderer/next.config.ts +76 -0
  225. package/renderer/package.json +66 -0
  226. package/renderer/postcss.config.mjs +5 -0
  227. package/renderer/public/assets/images/screenshot.png +0 -0
  228. package/renderer/public/assets/logo/dark.svg +9 -0
  229. package/renderer/public/assets/logo/light.svg +9 -0
  230. package/renderer/public/assets/logo.svg +9 -0
  231. package/renderer/public/file.svg +1 -0
  232. package/renderer/public/globe.svg +1 -0
  233. package/renderer/public/icon.png +0 -0
  234. package/renderer/public/logo.svg +9 -0
  235. package/renderer/public/window.svg +1 -0
  236. package/renderer/tsconfig.json +28 -0
  237. package/templates/basic/README.md +139 -0
  238. package/templates/basic/assets/favicon.svg +4 -0
  239. package/templates/basic/assets/logo.svg +9 -0
  240. package/templates/basic/docs.json +47 -0
  241. package/templates/basic/guides/configuration.mdx +149 -0
  242. package/templates/basic/guides/overview.mdx +96 -0
  243. package/templates/basic/index.mdx +39 -0
  244. package/templates/basic/package.json +14 -0
  245. package/templates/basic/quickstart.mdx +92 -0
  246. package/templates/basic/vercel.json +6 -0
  247. package/templates/graphql/README.md +139 -0
  248. package/templates/graphql/api-reference/schema.graphql +305 -0
  249. package/templates/graphql/assets/favicon.svg +4 -0
  250. package/templates/graphql/assets/logo.svg +9 -0
  251. package/templates/graphql/docs.json +54 -0
  252. package/templates/graphql/guides/configuration.mdx +149 -0
  253. package/templates/graphql/guides/overview.mdx +96 -0
  254. package/templates/graphql/index.mdx +39 -0
  255. package/templates/graphql/package.json +14 -0
  256. package/templates/graphql/quickstart.mdx +92 -0
  257. package/templates/graphql/vercel.json +6 -0
  258. package/templates/openapi/README.md +139 -0
  259. package/templates/openapi/api-reference/openapi.json +419 -0
  260. package/templates/openapi/assets/favicon.svg +4 -0
  261. package/templates/openapi/assets/logo.svg +9 -0
  262. package/templates/openapi/docs.json +61 -0
  263. package/templates/openapi/guides/configuration.mdx +149 -0
  264. package/templates/openapi/guides/overview.mdx +96 -0
  265. package/templates/openapi/index.mdx +39 -0
  266. package/templates/openapi/package.json +14 -0
  267. package/templates/openapi/quickstart.mdx +92 -0
  268. package/templates/openapi/vercel.json +6 -0
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.dev = dev;
7
+ const child_process_1 = require("child_process");
8
+ const path_1 = __importDefault(require("path"));
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const net_1 = __importDefault(require("net"));
11
+ const config_1 = require("../../config");
12
+ const logger_1 = require("../../utils/logger");
13
+ const paths_1 = require("../../utils/paths");
14
+ /**
15
+ * Check if a port is available
16
+ */
17
+ async function isPortAvailable(port, host) {
18
+ return new Promise((resolve) => {
19
+ const server = net_1.default.createServer();
20
+ server.once('error', () => resolve(false));
21
+ server.once('listening', () => {
22
+ server.close();
23
+ resolve(true);
24
+ });
25
+ server.listen(port, host);
26
+ });
27
+ }
28
+ /**
29
+ * Find an available port starting from the given port
30
+ */
31
+ async function findAvailablePort(startPort, host) {
32
+ let port = startPort;
33
+ const maxAttempts = 10;
34
+ for (let i = 0; i < maxAttempts; i++) {
35
+ if (await isPortAvailable(port, host)) {
36
+ return port;
37
+ }
38
+ port++;
39
+ }
40
+ throw new Error(`No available port found between ${startPort} and ${startPort + maxAttempts - 1}`);
41
+ }
42
+ async function dev(options) {
43
+ const projectRoot = process.cwd();
44
+ logger_1.logger.info('Starting DevDoc development server...');
45
+ // Check for docs.json
46
+ const configPath = path_1.default.join(projectRoot, 'docs.json');
47
+ if (!fs_extra_1.default.existsSync(configPath)) {
48
+ logger_1.logger.error('docs.json not found in current directory');
49
+ logger_1.logger.info('Run "devdoc init" to create a new documentation project');
50
+ process.exit(1);
51
+ }
52
+ // Load and validate config
53
+ try {
54
+ const config = await (0, config_1.loadConfig)(projectRoot);
55
+ const validation = (0, config_1.validateConfig)(config);
56
+ if (!validation.valid) {
57
+ logger_1.logger.error('Invalid docs.json configuration:');
58
+ validation.errors.forEach(err => logger_1.logger.error(` - ${err}`));
59
+ process.exit(1);
60
+ }
61
+ logger_1.logger.success(`Loaded configuration: ${config.name || 'Untitled'}`);
62
+ }
63
+ catch (error) {
64
+ logger_1.logger.error(`Failed to load docs.json: ${error.message}`);
65
+ process.exit(1);
66
+ }
67
+ // Get the renderer directory (bundled with this package)
68
+ const rendererDir = (0, paths_1.getRendererDir)();
69
+ if (!rendererDir || !fs_extra_1.default.existsSync(rendererDir)) {
70
+ logger_1.logger.error('Renderer not found. Package may be corrupted.');
71
+ logger_1.logger.debug(`Looked for renderer at: ${rendererDir}`);
72
+ process.exit(1);
73
+ }
74
+ // Check if renderer has node_modules
75
+ const nodeModulesPath = path_1.default.join(rendererDir, 'node_modules');
76
+ if (!fs_extra_1.default.existsSync(nodeModulesPath)) {
77
+ logger_1.logger.info('Installing renderer dependencies (first run)...');
78
+ const installChild = (0, child_process_1.spawn)('npm', ['install'], {
79
+ cwd: rendererDir,
80
+ stdio: 'inherit',
81
+ shell: true,
82
+ });
83
+ await new Promise((resolve, reject) => {
84
+ installChild.on('exit', (code) => {
85
+ if (code === 0)
86
+ resolve();
87
+ else
88
+ reject(new Error(`npm install failed with code ${code}`));
89
+ });
90
+ installChild.on('error', reject);
91
+ });
92
+ logger_1.logger.success('Dependencies installed');
93
+ }
94
+ // Find available port
95
+ const requestedPort = parseInt(options.port, 10);
96
+ let actualPort;
97
+ try {
98
+ actualPort = await findAvailablePort(requestedPort, options.host);
99
+ if (actualPort !== requestedPort) {
100
+ logger_1.logger.warn(`Port ${requestedPort} is in use, using ${actualPort} instead`);
101
+ }
102
+ }
103
+ catch (error) {
104
+ logger_1.logger.error(error.message);
105
+ process.exit(1);
106
+ }
107
+ // Set environment variables - use STARTER_PATH with absolute path
108
+ const env = {
109
+ ...process.env,
110
+ STARTER_PATH: projectRoot, // Absolute path to user's project
111
+ PORT: String(actualPort),
112
+ HOSTNAME: options.host,
113
+ };
114
+ logger_1.logger.info(`Content directory: ${projectRoot}`);
115
+ logger_1.logger.info(`Starting server at http://${options.host}:${actualPort}`);
116
+ logger_1.logger.info('Press Ctrl+C to stop\n');
117
+ // Start Next.js dev server with Turbopack for better path alias support
118
+ const child = (0, child_process_1.spawn)('npx', ['next', 'dev', '--turbo', '-p', String(actualPort), '-H', options.host], {
119
+ cwd: rendererDir,
120
+ env,
121
+ stdio: 'inherit',
122
+ shell: true,
123
+ });
124
+ child.on('error', (error) => {
125
+ logger_1.logger.error(`Failed to start server: ${error.message}`);
126
+ process.exit(1);
127
+ });
128
+ child.on('exit', (code) => {
129
+ process.exit(code || 0);
130
+ });
131
+ // Handle termination
132
+ process.on('SIGINT', () => {
133
+ child.kill('SIGINT');
134
+ });
135
+ process.on('SIGTERM', () => {
136
+ child.kill('SIGTERM');
137
+ });
138
+ }
139
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV2LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9jb21tYW5kcy9kZXYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUE2Q0Esa0JBa0hDO0FBL0pELGlEQUFzQztBQUN0QyxnREFBd0I7QUFDeEIsd0RBQTBCO0FBQzFCLDhDQUFzQjtBQUN0Qix5Q0FBMEQ7QUFDMUQsK0NBQTRDO0FBQzVDLDZDQUFtRDtBQU9uRDs7R0FFRztBQUNILEtBQUssVUFBVSxlQUFlLENBQUMsSUFBWSxFQUFFLElBQVk7SUFDdkQsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1FBQzdCLE1BQU0sTUFBTSxHQUFHLGFBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNsQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMzQyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxHQUFHLEVBQUU7WUFDNUIsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hCLENBQUMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDNUIsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxLQUFLLFVBQVUsaUJBQWlCLENBQUMsU0FBaUIsRUFBRSxJQUFZO0lBQzlELElBQUksSUFBSSxHQUFHLFNBQVMsQ0FBQztJQUNyQixNQUFNLFdBQVcsR0FBRyxFQUFFLENBQUM7SUFFdkIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3JDLElBQUksTUFBTSxlQUFlLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFF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QUFFLEdBQUcsRUFBRTtRQUN6QixLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3hCLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHNwYXduIH0gZnJvbSAnY2hpbGRfcHJvY2Vzcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBmcyBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQgbmV0IGZyb20gJ25ldCc7XG5pbXBvcnQgeyBsb2FkQ29uZmlnLCB2YWxpZGF0ZUNvbmZpZyB9IGZyb20gJy4uLy4uL2NvbmZpZyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi91dGlscy9sb2dnZXInO1xuaW1wb3J0IHsgZ2V0UmVuZGVyZXJEaXIgfSBmcm9tICcuLi8uLi91dGlscy9wYXRocyc7XG5cbmludGVyZmFjZSBEZXZPcHRpb25zIHtcbiAgcG9ydDogc3RyaW5nO1xuICBob3N0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYSBwb3J0IGlzIGF2YWlsYWJsZVxuICovXG5hc3luYyBmdW5jdGlvbiBpc1BvcnRBdmFpbGFibGUocG9ydDogbnVtYmVyLCBob3N0OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgY29uc3Qgc2VydmVyID0gbmV0LmNyZWF0ZVNlcnZlcigpO1xuICAgIHNlcnZlci5vbmNlKCdlcnJvcicsICgpID0+IHJlc29sdmUoZmFsc2UpKTtcbiAgICBzZXJ2ZXIub25jZSgnbGlzdGVuaW5nJywgKCkgPT4ge1xuICAgICAgc2VydmVyLmNsb3NlKCk7XG4gICAgICByZXNvbHZlKHRydWUpO1xuICAgIH0pO1xuICAgIHNlcnZlci5saXN0ZW4ocG9ydCwgaG9zdCk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEZpbmQgYW4gYXZhaWxhYmxlIHBvcnQgc3RhcnRpbmcgZnJvbSB0aGUgZ2l2ZW4gcG9ydFxuICovXG5hc3luYyBmdW5jdGlvbiBmaW5kQXZhaWxhYmxlUG9ydChzdGFydFBvcnQ6IG51bWJlciwgaG9zdDogc3RyaW5nKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgbGV0IHBvcnQgPSBzdGFydFBvcnQ7XG4gIGNvbnN0IG1heEF0dGVtcHRzID0gMTA7XG4gIFxuICBmb3IgKGxldCBpID0gMDsgaSA8IG1heEF0dGVtcHRzOyBpKyspIHtcbiAgICBpZiAoYXdhaXQgaXNQb3J0QXZhaWxhYmxlKHBvcnQsIGhvc3QpKSB7XG4gICAgICByZXR1cm4gcG9ydDtcbiAgICB9XG4gICAgcG9ydCsrO1xuICB9XG4gIFxuICB0aHJvdyBuZXcgRXJyb3IoYE5vIGF2YWlsYWJsZSBwb3J0IGZvdW5kIGJldHdlZW4gJHtzdGFydFBvcnR9IGFuZCAke3N0YXJ0UG9ydCArIG1heEF0dGVtcHRzIC0gMX1gKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRldihvcHRpb25zOiBEZXZPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb2plY3RSb290ID0gcHJvY2Vzcy5jd2QoKTtcbiAgXG4gIGxvZ2dlci5pbmZvKCdTdGFydGluZyBEZXZEb2MgZGV2ZWxvcG1lbnQgc2VydmVyLi4uJyk7XG4gIFxuICAvLyBDaGVjayBmb3IgZG9jcy5qc29uXG4gIGNvbnN0IGNvbmZpZ1BhdGggPSBwYXRoLmpvaW4ocHJvamVjdFJvb3QsICdkb2NzLmpzb24nKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGNvbmZpZ1BhdGgpKSB7XG4gICAgbG9nZ2VyLmVycm9yKCdkb2NzLmpzb24gbm90IGZvdW5kIGluIGN1cnJlbnQgZGlyZWN0b3J5Jyk7XG4gICAgbG9nZ2VyLmluZm8oJ1J1biBcImRldmRvYyBpbml0XCIgdG8gY3JlYXRlIGEgbmV3IGRvY3VtZW50YXRpb24gcHJvamVjdCcpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxuICBcbiAgLy8gTG9hZCBhbmQgdmFsaWRhdGUgY29uZmlnXG4gIHRyeSB7XG4gICAgY29uc3QgY29uZmlnID0gYXdhaXQgbG9hZENvbmZpZyhwcm9qZWN0Um9vdCk7XG4gICAgY29uc3QgdmFsaWRhdGlvbiA9IHZhbGlkYXRlQ29uZmlnKGNvbmZpZyk7XG4gICAgXG4gICAgaWYgKCF2YWxpZGF0aW9uLnZhbGlkKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0ludmFsaWQgZG9jcy5qc29uIGNvbmZpZ3VyYXRpb246Jyk7XG4gICAgICB2YWxpZGF0aW9uLmVycm9ycy5mb3JFYWNoKGVyciA9PiBsb2dnZXIuZXJyb3IoYCAgLSAke2Vycn1gKSk7XG4gICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgfVxuICAgIFxuICAgIGxvZ2dlci5zdWNjZXNzKGBMb2FkZWQgY29uZmlndXJhdGlvbjogJHtjb25maWcubmFtZSB8fCAnVW50aXRsZWQnfWApO1xuICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gbG9hZCBkb2NzLmpzb246ICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cbiAgXG4gIC8vIEdldCB0aGUgcmVuZGVyZXIgZGlyZWN0b3J5IChidW5kbGVkIHdpdGggdGhpcyBwYWNrYWdlKVxuICBjb25zdCByZW5kZXJlckRpciA9IGdldFJlbmRlcmVyRGlyKCk7XG4gIFxuICBpZiAoIXJlbmRlcmVyRGlyIHx8ICFmcy5leGlzdHNTeW5jKHJlbmRlcmVyRGlyKSkge1xuICAgIGxvZ2dlci5lcnJvcignUmVuZGVyZXIgbm90IGZvdW5kLiBQYWNrYWdlIG1heSBiZSBjb3JydXB0ZWQuJyk7XG4gICAgbG9nZ2VyLmRlYnVnKGBMb29rZWQgZm9yIHJlbmRlcmVyIGF0OiAke3JlbmRlcmVyRGlyfWApO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxuICBcbiAgLy8gQ2hlY2sgaWYgcmVuZGVyZXIgaGFzIG5vZGVfbW9kdWxlc1xuICBjb25zdCBub2RlTW9kdWxlc1BhdGggPSBwYXRoLmpvaW4ocmVuZGVyZXJEaXIsICdub2RlX21vZHVsZXMnKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKG5vZGVNb2R1bGVzUGF0aCkpIHtcbiAgICBsb2dnZXIuaW5mbygnSW5zdGFsbGluZyByZW5kZXJlciBkZXBlbmRlbmNpZXMgKGZpcnN0IHJ1bikuLi4nKTtcbiAgICBjb25zdCBpbnN0YWxsQ2hpbGQgPSBzcGF3bignbnBtJywgWydpbnN0YWxsJ10sIHtcbiAgICAgIGN3ZDogcmVuZGVyZXJEaXIsXG4gICAgICBzdGRpbzogJ2luaGVyaXQnLFxuICAgICAgc2hlbGw6IHRydWUsXG4gICAgfSk7XG4gICAgXG4gICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgaW5zdGFsbENoaWxkLm9uKCdleGl0JywgKGNvZGUpID0+IHtcbiAgICAgICAgaWYgKGNvZGUgPT09IDApIHJlc29sdmUoKTtcbiAgICAgICAgZWxzZSByZWplY3QobmV3IEVycm9yKGBucG0gaW5zdGFsbCBmYWlsZWQgd2l0aCBjb2RlICR7Y29kZX1gKSk7XG4gICAgICB9KTtcbiAgICAgIGluc3RhbGxDaGlsZC5vbignZXJyb3InLCByZWplY3QpO1xuICAgIH0pO1xuICAgIGxvZ2dlci5zdWNjZXNzKCdEZXBlbmRlbmNpZXMgaW5zdGFsbGVkJyk7XG4gIH1cbiAgXG4gIC8vIEZpbmQgYXZhaWxhYmxlIHBvcnRcbiAgY29uc3QgcmVxdWVzdGVkUG9ydCA9IHBhcnNlSW50KG9wdGlvbnMucG9ydCwgMTApO1xuICBsZXQgYWN0dWFsUG9ydDogbnVtYmVyO1xuICBcbiAgdHJ5IHtcbiAgICBhY3R1YWxQb3J0ID0gYXdhaXQgZmluZEF2YWlsYWJsZVBvcnQocmVxdWVzdGVkUG9ydCwgb3B0aW9ucy5ob3N0KTtcbiAgICBpZiAoYWN0dWFsUG9ydCAhPT0gcmVxdWVzdGVkUG9ydCkge1xuICAgICAgbG9nZ2VyLndhcm4oYFBvcnQgJHtyZXF1ZXN0ZWRQb3J0fSBpcyBpbiB1c2UsIHVzaW5nICR7YWN0dWFsUG9ydH0gaW5zdGVhZGApO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgIGxvZ2dlci5lcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cbiAgXG4gIC8vIFNldCBlbnZpcm9ubWVudCB2YXJpYWJsZXMgLSB1c2UgU1RBUlRFUl9QQVRIIHdpdGggYWJzb2x1dGUgcGF0aFxuICBjb25zdCBlbnYgPSB7XG4gICAgLi4ucHJvY2Vzcy5lbnYsXG4gICAgU1RBUlRFUl9QQVRIOiBwcm9qZWN0Um9vdCwgLy8gQWJzb2x1dGUgcGF0aCB0byB1c2VyJ3MgcHJvamVjdFxuICAgIFBPUlQ6IFN0cmluZyhhY3R1YWxQb3J0KSxcbiAgICBIT1NUTkFNRTogb3B0aW9ucy5ob3N0LFxuICB9O1xuICBcbiAgbG9nZ2VyLmluZm8oYENvbnRlbnQgZGlyZWN0b3J5OiAke3Byb2plY3RSb290fWApO1xuICBsb2dnZXIuaW5mbyhgU3RhcnRpbmcgc2VydmVyIGF0IGh0dHA6Ly8ke29wdGlvbnMuaG9zdH06JHthY3R1YWxQb3J0fWApO1xuICBsb2dnZXIuaW5mbygnUHJlc3MgQ3RybCtDIHRvIHN0b3BcXG4nKTtcbiAgXG4gIC8vIFN0YXJ0IE5leHQuanMgZGV2IHNlcnZlciB3aXRoIFR1cmJvcGFjayBmb3IgYmV0dGVyIHBhdGggYWxpYXMgc3VwcG9ydFxuICBjb25zdCBjaGlsZCA9IHNwYXduKFxuICAgICducHgnLFxuICAgIFsnbmV4dCcsICdkZXYnLCAnLS10dXJibycsICctcCcsIFN0cmluZyhhY3R1YWxQb3J0KSwgJy1IJywgb3B0aW9ucy5ob3N0XSxcbiAgICB7XG4gICAgICBjd2Q6IHJlbmRlcmVyRGlyLFxuICAgICAgZW52LFxuICAgICAgc3RkaW86ICdpbmhlcml0JyxcbiAgICAgIHNoZWxsOiB0cnVlLFxuICAgIH1cbiAgKTtcbiAgXG4gIGNoaWxkLm9uKCdlcnJvcicsIChlcnJvcikgPT4ge1xuICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHN0YXJ0IHNlcnZlcjogJHtlcnJvci5tZXNzYWdlfWApO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfSk7XG4gIFxuICBjaGlsZC5vbignZXhpdCcsIChjb2RlKSA9PiB7XG4gICAgcHJvY2Vzcy5leGl0KGNvZGUgfHwgMCk7XG4gIH0pO1xuICBcbiAgLy8gSGFuZGxlIHRlcm1pbmF0aW9uXG4gIHByb2Nlc3Mub24oJ1NJR0lOVCcsICgpID0+IHtcbiAgICBjaGlsZC5raWxsKCdTSUdJTlQnKTtcbiAgfSk7XG4gIFxuICBwcm9jZXNzLm9uKCdTSUdURVJNJywgKCkgPT4ge1xuICAgIGNoaWxkLmtpbGwoJ1NJR1RFUk0nKTtcbiAgfSk7XG59XG4iXX0=
@@ -0,0 +1,11 @@
1
+ interface InitOptions {
2
+ slug?: string;
3
+ subdomain?: string;
4
+ force?: boolean;
5
+ url?: string;
6
+ }
7
+ /**
8
+ * Initialize a DevDoc project with .devdoc.json and register with Brainfish
9
+ */
10
+ export declare function init(options: InitOptions): Promise<void>;
11
+ export {};
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.init = init;
40
+ const path_1 = __importDefault(require("path"));
41
+ const fs_extra_1 = __importDefault(require("fs-extra"));
42
+ const config_1 = require("../../config");
43
+ const logger_1 = require("../../utils/logger");
44
+ const constants_1 = require("../../constants");
45
+ // Simple prompt helper using readline
46
+ async function prompt(question, defaultValue) {
47
+ const readline = await Promise.resolve().then(() => __importStar(require('readline')));
48
+ const rl = readline.createInterface({
49
+ input: process.stdin,
50
+ output: process.stdout,
51
+ });
52
+ return new Promise((resolve) => {
53
+ const defaultHint = defaultValue ? ` (${defaultValue})` : '';
54
+ rl.question(`${question}${defaultHint}: `, (answer) => {
55
+ rl.close();
56
+ resolve(answer.trim() || defaultValue || '');
57
+ });
58
+ });
59
+ }
60
+ /**
61
+ * Basic subdomain format validation (server does full validation)
62
+ */
63
+ function isValidSubdomainFormat(subdomain) {
64
+ if (!subdomain) {
65
+ return { valid: false, error: 'Subdomain is required' };
66
+ }
67
+ if (subdomain.length < 3) {
68
+ return { valid: false, error: 'Subdomain must be at least 3 characters' };
69
+ }
70
+ if (subdomain.length > 63) {
71
+ return { valid: false, error: 'Subdomain must be 63 characters or less' };
72
+ }
73
+ if (!/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(subdomain)) {
74
+ return { valid: false, error: 'Subdomain must start and end with alphanumeric, can contain hyphens' };
75
+ }
76
+ if (/--/.test(subdomain)) {
77
+ return { valid: false, error: 'Subdomain cannot contain consecutive hyphens' };
78
+ }
79
+ return { valid: true };
80
+ }
81
+ /**
82
+ * Check subdomain availability via API (also validates against server blacklist)
83
+ */
84
+ async function checkSubdomainAvailability(subdomain, apiUrl) {
85
+ try {
86
+ const response = await fetch(`${apiUrl}/api/subdomains/check`, {
87
+ method: 'POST',
88
+ headers: {
89
+ 'Content-Type': 'application/json',
90
+ },
91
+ body: JSON.stringify({ subdomain }),
92
+ });
93
+ const result = await response.json();
94
+ return result;
95
+ }
96
+ catch (error) {
97
+ // If API is unavailable, allow proceeding (will fail at registration if invalid)
98
+ return { available: true };
99
+ }
100
+ }
101
+ /**
102
+ * Initialize a DevDoc project with .devdoc.json and register with Brainfish
103
+ */
104
+ async function init(options) {
105
+ const projectRoot = process.cwd();
106
+ const apiUrl = options.url || process.env.DEVDOC_API_URL || constants_1.DEFAULT_API_URL;
107
+ logger_1.logger.info('Initializing DevDoc project...\n');
108
+ // Check for docs.json
109
+ const configPath = path_1.default.join(projectRoot, 'docs.json');
110
+ if (!fs_extra_1.default.existsSync(configPath)) {
111
+ logger_1.logger.error('docs.json not found in current directory');
112
+ logger_1.logger.info('Make sure you are in a DevDoc documentation project directory');
113
+ process.exit(1);
114
+ }
115
+ // Check if .devdoc.json already exists with API key
116
+ const devdocConfigPath = path_1.default.join(projectRoot, '.devdoc.json');
117
+ if (fs_extra_1.default.existsSync(devdocConfigPath) && !options.force) {
118
+ const existingConfig = fs_extra_1.default.readJsonSync(devdocConfigPath);
119
+ if (existingConfig.apiKey) {
120
+ logger_1.logger.warn('.devdoc.json already exists with API key');
121
+ logger_1.logger.info('Use --force to overwrite and create a new project');
122
+ process.exit(1);
123
+ }
124
+ }
125
+ // Load docs.json to get project name
126
+ let projectName = 'My Documentation';
127
+ try {
128
+ const config = await (0, config_1.loadConfig)(projectRoot);
129
+ projectName = config.name || projectName;
130
+ }
131
+ catch {
132
+ // Use default name
133
+ }
134
+ // Generate slug from project name or use provided slug
135
+ const slug = options.slug || generateSlug(projectName);
136
+ // Get subdomain - prompt if not provided
137
+ let subdomain = options.subdomain;
138
+ if (!subdomain) {
139
+ const suggestedSubdomain = slug;
140
+ console.log('');
141
+ subdomain = await prompt(`Enter subdomain for ${suggestedSubdomain}.devdoc.sh`, suggestedSubdomain);
142
+ subdomain = subdomain.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/^-|-$/g, '');
143
+ }
144
+ // Validate subdomain format locally
145
+ const formatCheck = isValidSubdomainFormat(subdomain);
146
+ if (!formatCheck.valid) {
147
+ logger_1.logger.error(formatCheck.error);
148
+ process.exit(1);
149
+ }
150
+ // Check subdomain availability via API (server validates blacklist)
151
+ logger_1.logger.info(`Checking if ${subdomain}.devdoc.sh is available...`);
152
+ const availability = await checkSubdomainAvailability(subdomain, apiUrl);
153
+ if (!availability.available) {
154
+ logger_1.logger.error(availability.error || `Subdomain "${subdomain}" is not available`);
155
+ if (availability.suggestion) {
156
+ logger_1.logger.info(`Suggestion: Try "${availability.suggestion}"`);
157
+ }
158
+ process.exit(1);
159
+ }
160
+ logger_1.logger.success(`✓ ${subdomain}.devdoc.sh is available!`);
161
+ console.log('');
162
+ // Register project with Brainfish API
163
+ logger_1.logger.info('Registering project with Brainfish...');
164
+ try {
165
+ const response = await fetch(`${apiUrl}/api/projects/register`, {
166
+ method: 'POST',
167
+ headers: {
168
+ 'Content-Type': 'application/json',
169
+ },
170
+ body: JSON.stringify({
171
+ name: projectName,
172
+ slug,
173
+ subdomain,
174
+ }),
175
+ });
176
+ if (!response.ok) {
177
+ const errorData = await response.json().catch(() => ({ error: 'Unknown error' }));
178
+ const errorMessage = errorData.error || `HTTP ${response.status}`;
179
+ const details = errorData.details ? `\n Details: ${errorData.details}` : '';
180
+ throw new Error(`${errorMessage}${details}`);
181
+ }
182
+ const result = await response.json();
183
+ // Create .devdoc.json with API key
184
+ const devdocConfig = {
185
+ projectId: result.projectId,
186
+ name: projectName,
187
+ slug: result.slug,
188
+ subdomain: result.subdomain,
189
+ apiKey: result.apiKey,
190
+ createdAt: new Date().toISOString(),
191
+ };
192
+ fs_extra_1.default.writeJsonSync(devdocConfigPath, devdocConfig, { spaces: 2 });
193
+ logger_1.logger.success('✓ Project registered successfully');
194
+ console.log('');
195
+ console.log(' Project ID:', result.projectId);
196
+ console.log(' URL:', `https://${result.subdomain}.devdoc.sh`);
197
+ console.log(' API Key:', result.apiKey);
198
+ console.log('');
199
+ logger_1.logger.warn('⚠️ API key saved to .devdoc.json - add to .gitignore!');
200
+ console.log('');
201
+ logger_1.logger.info('Run "devdoc deploy" to deploy your documentation');
202
+ }
203
+ catch (error) {
204
+ const message = error instanceof Error ? error.message : String(error);
205
+ logger_1.logger.error(`Failed to register project: ${message}`);
206
+ // Create local .devdoc.json without API key (offline mode)
207
+ logger_1.logger.warn('Creating local config without API key...');
208
+ const projectId = `${slug}-${generateId()}`;
209
+ const devdocConfig = {
210
+ projectId,
211
+ name: projectName,
212
+ slug,
213
+ subdomain,
214
+ createdAt: new Date().toISOString(),
215
+ };
216
+ fs_extra_1.default.writeJsonSync(devdocConfigPath, devdocConfig, { spaces: 2 });
217
+ logger_1.logger.success('✓ Created .devdoc.json (offline mode)');
218
+ console.log('');
219
+ logger_1.logger.info('Run "devdoc init" again when online to register and get API key');
220
+ }
221
+ }
222
+ /**
223
+ * Generate a URL-friendly slug from a name
224
+ */
225
+ function generateSlug(name) {
226
+ return name
227
+ .toLowerCase()
228
+ .replace(/[^a-z0-9]+/g, '-')
229
+ .replace(/^-|-$/g, '')
230
+ .substring(0, 50);
231
+ }
232
+ /**
233
+ * Generate a short random ID
234
+ */
235
+ function generateId() {
236
+ return Math.random().toString(36).substring(2, 8);
237
+ }
238
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvY29tbWFuZHMvaW5pdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTRHQSxvQkF5SUM7QUFyUEQsZ0RBQXVCO0FBQ3ZCLHdEQUF5QjtBQUN6Qix5Q0FBeUM7QUFDekMsK0NBQTJDO0FBQzNDLCtDQUFpRDtBQWlDakQsc0NBQXNDO0FBQ3RDLEtBQUssVUFBVSxNQUFNLENBQUMsUUFBZ0IsRUFBRSxZQUFxQjtJQUMzRCxNQUFNLFFBQVEsR0FBRyx3REFBYSxVQUFVLEdBQUMsQ0FBQTtJQUN6QyxNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsZUFBZSxDQUFDO1FBQ2xDLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSztRQUNwQixNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07S0FDdkIsQ0FBQyxDQUFBO0lBRUYsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1FBQzdCLE1BQU0sV0FBVyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMsS0FBSyxZQUFZLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFBO1FBQzVELEVBQUUsQ0FBQyxRQUFRLENBQUMsR0FBRyxRQUFRLEdBQUcsV0FBVyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUNwRCxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUE7WUFDVixPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLFlBQVksSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUM5QyxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxzQkFBc0IsQ0FBQyxTQUFpQjtJQUMvQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDZixPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUss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LElBQUksQ0FBQyxpRUFBaUUsQ0FBQyxDQUFBO0lBQ2hGLENBQUM7QUFDSCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLFlBQVksQ0FBQyxJQUFZO0lBQ2hDLE9BQU8sSUFBSTtTQUNSLFdBQVcsRUFBRTtTQUNiLE9BQU8sQ0FBQyxhQUFhLEVBQUUsR0FBRyxDQUFDO1NBQzNCLE9BQU8sQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDO1NBQ3JCLFNBQVMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUE7QUFDckIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxVQUFVO0lBQ2pCLE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFBO0FBQ25ELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tICdwYXRoJ1xuaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJ1xuaW1wb3J0IHsgbG9hZENvbmZpZyB9IGZyb20gJy4uLy4uL2NvbmZpZydcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3V0aWxzL2xvZ2dlcidcbmltcG9ydCB7IERFRkFVTFRfQVBJX1VSTCB9IGZyb20gJy4uLy4uL2NvbnN0YW50cydcblxuaW50ZXJmYWNlIEluaXRPcHRpb25zIHtcbiAgc2x1Zz86IHN0cmluZ1xuICBzdWJkb21haW4/OiBzdHJpbmdcbiAgZm9yY2U/OiBib29sZWFuXG4gIHVybD86IHN0cmluZ1xufVxuXG5pbnRlcmZhY2UgRGV2RG9jQ29uZmlnIHtcbiAgcHJvamVjdElkOiBzdHJpbmdcbiAgbmFtZTogc3RyaW5nXG4gIHNsdWc6IHN0cmluZ1xuICBzdWJkb21haW46IHN0cmluZ1xuICBhcGlLZXk/OiBzdHJpbmdcbiAgY3JlYXRlZEF0OiBzdHJpbmdcbn1cblxuaW50ZXJmYWNlIFJlZ2lzdGVyUmVzcG9uc2Uge1xuICBzdWNjZXNzOiBib29sZWFuXG4gIHByb2plY3RJZDogc3RyaW5nXG4gIHNsdWc6IHN0cmluZ1xuICBzdWJkb21haW46IHN0cmluZ1xuICBhcGlLZXk6IHN0cmluZ1xuICBlcnJvcj86IHN0cmluZ1xufVxuXG5pbnRlcmZhY2UgQ2hlY2tTdWJkb21haW5SZXNwb25zZSB7XG4gIGF2YWlsYWJsZTogYm9vbGVhblxuICBlcnJvcj86IHN0cmluZ1xuICBzdWdnZXN0aW9uPzogc3RyaW5nXG59XG5cbi8vIFNpbXBsZSBwcm9tcHQgaGVscGVyIHVzaW5nIHJlYWRsaW5lXG5hc3luYyBmdW5jdGlvbiBwcm9tcHQocXVlc3Rpb246IHN0cmluZywgZGVmYXVsdFZhbHVlPzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgcmVhZGxpbmUgPSBhd2FpdCBpbXBvcnQoJ3JlYWRsaW5lJylcbiAgY29uc3QgcmwgPSByZWFkbGluZS5jcmVhdGVJbnRlcmZhY2Uoe1xuICAgIGlucHV0OiBwcm9jZXNzLnN0ZGluLFxuICAgIG91dHB1dDogcHJvY2Vzcy5zdGRvdXQsXG4gIH0pXG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgY29uc3QgZGVmYXVsdEhpbnQgPSBkZWZhdWx0VmFsdWUgPyBgICgke2RlZmF1bHRWYWx1ZX0pYCA6ICcnXG4gICAgcmwucXVlc3Rpb24oYCR7cXVlc3Rpb259JHtkZWZhdWx0SGludH06IGAsIChhbnN3ZXIpID0+IHtcbiAgICAgIHJsLmNsb3NlKClcbiAgICAgIHJlc29sdmUoYW5zd2VyLnRyaW0oKSB8fCBkZWZhdWx0VmFsdWUgfHwgJycpXG4gICAgfSlcbiAgfSlcbn1cblxuLyoqXG4gKiBCYXNpYyBzdWJkb21haW4gZm9ybWF0IHZhbGlkYXRpb24gKHNlcnZlciBkb2VzIGZ1bGwgdmFsaWRhdGlvbilcbiAqL1xuZnVuY3Rpb24gaXNWYWxpZFN1YmRvbWFpbkZvcm1hdChzdWJkb21haW46IHN0cmluZyk6IHsgdmFsaWQ6IGJvb2xlYW47IGVycm9yPzogc3RyaW5nIH0ge1xuICBpZiAoIXN1YmRvbWFpbikge1xuICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSwgZXJyb3I6ICdTdWJkb21haW4gaXMgcmVxdWlyZWQnIH1cbiAgfVxuICBcbiAgaWYgKHN1YmRvbWFpbi5sZW5ndGggPCAzKSB7XG4gICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlLCBlcnJvcjogJ1N1YmRvbWFpbiBtdXN0IGJlIGF0IGxlYXN0IDMgY2hhcmFjdGVycycgfVxuICB9XG4gIFxuICBpZiAoc3ViZG9tYWluLmxlbmd0aCA+IDYzKSB7XG4gICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlLCBlcnJvcjogJ1N1YmRvbWFpbiBtdXN0IGJlIDYzIGNoYXJhY3RlcnMgb3IgbGVzcycgfVxuICB9XG4gIFxuICBpZiAoIS9eW2EtejAtOV0oW2EtejAtOS1dKlthLXowLTldKT8kLy50ZXN0KHN1YmRvbWFpbikpIHtcbiAgICByZXR1cm4geyB2YWxpZDogZmFsc2UsIGVycm9yOiAnU3ViZG9tYWluIG11c3Qgc3RhcnQgYW5kIGVuZCB3aXRoIGFscGhhbnVtZXJpYywgY2FuIGNvbnRhaW4gaHlwaGVucycgfVxuICB9XG4gIFxuICBpZiAoLy0tLy50ZXN0KHN1YmRvbWFpbikpIHtcbiAgICByZXR1cm4geyB2YWxpZDogZmFsc2UsIGVycm9yOiAnU3ViZG9tYWluIGNhbm5vdCBjb250YWluIGNvbnNlY3V0aXZlIGh5cGhlbnMnIH1cbiAgfVxuICBcbiAgcmV0dXJuIHsgdmFsaWQ6IHRydWUgfVxufVxuXG4vKipcbiAqIENoZWNrIHN1YmRvbWFpbiBhdmFpbGFiaWxpdHkgdmlhIEFQSSAoYWxzbyB2YWxpZGF0ZXMgYWdhaW5zdCBzZXJ2ZXIgYmxhY2tsaXN0KVxuICovXG5hc3luYyBmdW5jdGlvbiBjaGVja1N1YmRvbWFpbkF2YWlsYWJpbGl0eShcbiAgc3ViZG9tYWluOiBzdHJpbmcsXG4gIGFwaVVybDogc3RyaW5nXG4pOiBQcm9taXNlPENoZWNrU3ViZG9tYWluUmVzcG9uc2U+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke2FwaVVybH0vYXBpL3N1YmRvbWFpbnMvY2hlY2tgLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgIH0sXG4gICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHN1YmRvbWFpbiB9KSxcbiAgICB9KVxuICAgIFxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKSBhcyBDaGVja1N1YmRvbWFpblJlc3BvbnNlXG4gICAgcmV0dXJuIHJlc3VsdFxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIC8vIElmIEFQSSBpcyB1bmF2YWlsYWJsZSwgYWxsb3cgcHJvY2VlZGluZyAod2lsbCBmYWlsIGF0IHJlZ2lzdHJhdGlvbiBpZiBpbnZhbGlkKVxuICAgIHJldHVybiB7IGF2YWlsYWJsZTogdHJ1ZSB9XG4gIH1cbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIGEgRGV2RG9jIHByb2plY3Qgd2l0aCAuZGV2ZG9jLmpzb24gYW5kIHJlZ2lzdGVyIHdpdGggQnJhaW5maXNoXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpbml0KG9wdGlvbnM6IEluaXRPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb2plY3RSb290ID0gcHJvY2Vzcy5jd2QoKVxuICBjb25zdCBhcGlVcmwgPSBvcHRpb25zLnVybCB8fCBwcm9jZXNzLmVudi5ERVZET0NfQVBJX1VSTCB8fCBERUZBVUxUX0FQSV9VUkxcbiAgXG4gIGxvZ2dlci5pbmZvKCdJbml0aWFsaXppbmcgRGV2RG9jIHByb2plY3QuLi5cXG4nKVxuICBcbiAgLy8gQ2hlY2sgZm9yIGRvY3MuanNvblxuICBjb25zdCBjb25maWdQYXRoID0gcGF0aC5qb2luKHByb2plY3RSb290LCAnZG9jcy5qc29uJylcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGNvbmZpZ1BhdGgpKSB7XG4gICAgbG9nZ2VyLmVycm9yKCdkb2NzLmpzb24gbm90IGZvdW5kIGluIGN1cnJlbnQgZGlyZWN0b3J5JylcbiAgICBsb2dnZXIuaW5mbygnTWFrZSBzdXJlIHlvdSBhcmUgaW4gYSBEZXZEb2MgZG9jdW1lbnRhdGlvbiBwcm9qZWN0IGRpcmVjdG9yeScpXG4gICAgcHJvY2Vzcy5leGl0KDEpXG4gIH1cbiAgXG4gIC8vIENoZWNrIGlmIC5kZXZkb2MuanNvbiBhbHJlYWR5IGV4aXN0cyB3aXRoIEFQSSBrZXlcbiAgY29uc3QgZGV2ZG9jQ29uZmlnUGF0aCA9IHBhdGguam9pbihwcm9qZWN0Um9vdCwgJy5kZXZkb2MuanNvbicpXG4gIGlmIChmcy5leGlzdHNTeW5jKGRldmRvY0NvbmZpZ1BhdGgpICYmICFvcHRpb25zLmZvcmNlKSB7XG4gICAgY29uc3QgZXhpc3RpbmdDb25maWcgPSBmcy5yZWFkSnNvblN5bmMoZGV2ZG9jQ29uZmlnUGF0aCkgYXMgRGV2RG9jQ29uZmlnXG4gICAgaWYgKGV4aXN0aW5nQ29uZmlnLmFwaUtleSkge1xuICAgICAgbG9nZ2VyLndhcm4oJy5kZXZkb2MuanNvbiBhbHJlYWR5IGV4aXN0cyB3aXRoIEFQSSBrZXknKVxuICAgICAgbG9nZ2VyLmluZm8oJ1VzZSAtLWZvcmNlIHRvIG92ZXJ3cml0ZSBhbmQgY3JlYXRlIGEgbmV3IHByb2plY3QnKVxuICAgICAgcHJvY2Vzcy5leGl0KDEpXG4gICAgfVxuICB9XG4gIFxuICAvLyBMb2FkIGRvY3MuanNvbiB0byBnZXQgcHJvamVjdCBuYW1lXG4gIGxldCBwcm9qZWN0TmFtZSA9ICdNeSBEb2N1bWVudGF0aW9uJ1xuICB0cnkge1xuICAgIGNvbnN0IGNvbmZpZyA9IGF3YWl0IGxvYWRDb25maWcocHJvamVjdFJvb3QpXG4gICAgcHJvamVjdE5hbWUgPSBjb25maWcubmFtZSB8fCBwcm9qZWN0TmFtZVxuICB9IGNhdGNoIHtcbiAgICAvLyBVc2UgZGVmYXVsdCBuYW1lXG4gIH1cbiAgXG4gIC8vIEdlbmVyYXRlIHNsdWcgZnJvbSBwcm9qZWN0IG5hbWUgb3IgdXNlIHByb3ZpZGVkIHNsdWdcbiAgY29uc3Qgc2x1ZyA9IG9wdGlvbnMuc2x1ZyB8fCBnZW5lcmF0ZVNsdWcocHJvamVjdE5hbWUpXG4gIFxuICAvLyBHZXQgc3ViZG9tYWluIC0gcHJvbXB0IGlmIG5vdCBwcm92aWRlZFxuICBsZXQgc3ViZG9tYWluID0gb3B0aW9ucy5zdWJkb21haW5cbiAgXG4gIGlmICghc3ViZG9tYWluKSB7XG4gICAgY29uc3Qgc3VnZ2VzdGVkU3ViZG9tYWluID0gc2x1Z1xuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIHN1YmRvbWFpbiA9IGF3YWl0IHByb21wdChgRW50ZXIgc3ViZG9tYWluIGZvciAke3N1Z2dlc3RlZFN1YmRvbWFpbn0uZGV2ZG9jLnNoYCwgc3VnZ2VzdGVkU3ViZG9tYWluKVxuICAgIHN1YmRvbWFpbiA9IHN1YmRvbWFpbi50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1teYS16MC05LV0vZywgJy0nKS5yZXBsYWNlKC9eLXwtJC9nLCAnJylcbiAgfVxuICBcbiAgLy8gVmFsaWRhdGUgc3ViZG9tYWluIGZvcm1hdCBsb2NhbGx5XG4gIGNvbnN0IGZvcm1hdENoZWNrID0gaXNWYWxpZFN1YmRvbWFpbkZvcm1hdChzdWJkb21haW4pXG4gIGlmICghZm9ybWF0Q2hlY2sudmFsaWQpIHtcbiAgICBsb2dnZXIuZXJyb3IoZm9ybWF0Q2hlY2suZXJyb3IhKVxuICAgIHByb2Nlc3MuZXhpdCgxKVxuICB9XG4gIFxuICAvLyBDaGVjayBzdWJkb21haW4gYXZhaWxhYmlsaXR5IHZpYSBBUEkgKHNlcnZlciB2YWxpZGF0ZXMgYmxhY2tsaXN0KVxuICBsb2dnZXIuaW5mbyhgQ2hlY2tpbmcgaWYgJHtzdWJkb21haW59LmRldmRvYy5zaCBpcyBhdmFpbGFibGUuLi5gKVxuICBjb25zdCBhdmFpbGFiaWxpdHkgPSBhd2FpdCBjaGVja1N1YmRvbWFpbkF2YWlsYWJpbGl0eShzdWJkb21haW4sIGFwaVVybClcbiAgXG4gIGlmICghYXZhaWxhYmlsaXR5LmF2YWlsYWJsZSkge1xuICAgIGxvZ2dlci5lcnJvcihhdmFpbGFiaWxpdHkuZXJyb3IgfHwgYFN1YmRvbWFpbiBcIiR7c3ViZG9tYWlufVwiIGlzIG5vdCBhdmFpbGFibGVgKVxuICAgIGlmIChhdmFpbGFiaWxpdHkuc3VnZ2VzdGlvbikge1xuICAgICAgbG9nZ2VyLmluZm8oYFN1Z2dlc3Rpb246IFRyeSBcIiR7YXZhaWxhYmlsaXR5LnN1Z2dlc3Rpb259XCJgKVxuICAgIH1cbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxuICBcbiAgbG9nZ2VyLnN1Y2Nlc3MoYOKckyAke3N1YmRvbWFpbn0uZGV2ZG9jLnNoIGlzIGF2YWlsYWJsZSFgKVxuICBjb25zb2xlLmxvZygnJylcbiAgXG4gIC8vIFJlZ2lzdGVyIHByb2plY3Qgd2l0aCBCcmFpbmZpc2ggQVBJXG4gIGxvZ2dlci5pbmZvKCdSZWdpc3RlcmluZyBwcm9qZWN0IHdpdGggQnJhaW5maXNoLi4uJylcbiAgXG4gIHRyeSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChgJHthcGlVcmx9L2FwaS9wcm9qZWN0cy9yZWdpc3RlcmAsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgfSxcbiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgbmFtZTogcHJvamVjdE5hbWUsXG4gICAgICAgIHNsdWcsXG4gICAgICAgIHN1YmRvbWFpbixcbiAgICAgIH0pLFxuICAgIH0pXG4gICAgXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgY29uc3QgZXJyb3JEYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpLmNhdGNoKCgpID0+ICh7IGVycm9yOiAnVW5rbm93biBlcnJvcicgfSkpIGFzIHsgZXJyb3I/OiBzdHJpbmc7IGRldGFpbHM/OiBzdHJpbmcgfVxuICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3JEYXRhLmVycm9yIHx8IGBIVFRQICR7cmVzcG9uc2Uuc3RhdHVzfWBcbiAgICAgIGNvbnN0IGRldGFpbHMgPSBlcnJvckRhdGEuZGV0YWlscyA/IGBcXG4gICBEZXRhaWxzOiAke2Vycm9yRGF0YS5kZXRhaWxzfWAgOiAnJ1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2Vycm9yTWVzc2FnZX0ke2RldGFpbHN9YClcbiAgICB9XG4gICAgXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpIGFzIFJlZ2lzdGVyUmVzcG9uc2VcbiAgICBcbiAgICAvLyBDcmVhdGUgLmRldmRvYy5qc29uIHdpdGggQVBJIGtleVxuICAgIGNvbnN0IGRldmRvY0NvbmZpZzogRGV2RG9jQ29uZmlnID0ge1xuICAgICAgcHJvamVjdElkOiByZXN1bHQucHJvamVjdElkLFxuICAgICAgbmFtZTogcHJvamVjdE5hbWUsXG4gICAgICBzbHVnOiByZXN1bHQuc2x1ZyxcbiAgICAgIHN1YmRvbWFpbjogcmVzdWx0LnN1YmRvbWFpbixcbiAgICAgIGFwaUtleTogcmVzdWx0LmFwaUtleSxcbiAgICAgIGNyZWF0ZWRBdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgIH1cbiAgICBcbiAgICBmcy53cml0ZUpzb25TeW5jKGRldmRvY0NvbmZpZ1BhdGgsIGRldmRvY0NvbmZpZywgeyBzcGFjZXM6IDIgfSlcbiAgICBcbiAgICBsb2dnZXIuc3VjY2Vzcygn4pyTIFByb2plY3QgcmVnaXN0ZXJlZCBzdWNjZXNzZnVsbHknKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIGNvbnNvbGUubG9nKCcgIFByb2plY3QgSUQ6JywgcmVzdWx0LnByb2plY3RJZClcbiAgICBjb25zb2xlLmxvZygnICBVUkw6JywgYGh0dHBzOi8vJHtyZXN1bHQuc3ViZG9tYWlufS5kZXZkb2Muc2hgKVxuICAgIGNvbnNvbGUubG9nKCcgIEFQSSBLZXk6JywgcmVzdWx0LmFwaUtleSlcbiAgICBjb25zb2xlLmxvZygnJylcbiAgICBsb2dnZXIud2Fybign4pqg77iPICBBUEkga2V5IHNhdmVkIHRvIC5kZXZkb2MuanNvbiAtIGFkZCB0byAuZ2l0aWdub3JlIScpXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgbG9nZ2VyLmluZm8oJ1J1biBcImRldmRvYyBkZXBsb3lcIiB0byBkZXBsb3kgeW91ciBkb2N1bWVudGF0aW9uJylcbiAgICBcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXG4gICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gcmVnaXN0ZXIgcHJvamVjdDogJHttZXNzYWdlfWApXG4gICAgXG4gICAgLy8gQ3JlYXRlIGxvY2FsIC5kZXZkb2MuanNvbiB3aXRob3V0IEFQSSBrZXkgKG9mZmxpbmUgbW9kZSlcbiAgICBsb2dnZXIud2FybignQ3JlYXRpbmcgbG9jYWwgY29uZmlnIHdpdGhvdXQgQVBJIGtleS4uLicpXG4gICAgY29uc3QgcHJvamVjdElkID0gYCR7c2x1Z30tJHtnZW5lcmF0ZUlkKCl9YFxuICAgIGNvbnN0IGRldmRvY0NvbmZpZzogRGV2RG9jQ29uZmlnID0ge1xuICAgICAgcHJvamVjdElkLFxuICAgICAgbmFtZTogcHJvamVjdE5hbWUsXG4gICAgICBzbHVnLFxuICAgICAgc3ViZG9tYWluLFxuICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgfVxuICAgIFxuICAgIGZzLndyaXRlSnNvblN5bmMoZGV2ZG9jQ29uZmlnUGF0aCwgZGV2ZG9jQ29uZmlnLCB7IHNwYWNlczogMiB9KVxuICAgIFxuICAgIGxvZ2dlci5zdWNjZXNzKCfinJMgQ3JlYXRlZCAuZGV2ZG9jLmpzb24gKG9mZmxpbmUgbW9kZSknKVxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIGxvZ2dlci5pbmZvKCdSdW4gXCJkZXZkb2MgaW5pdFwiIGFnYWluIHdoZW4gb25saW5lIHRvIHJlZ2lzdGVyIGFuZCBnZXQgQVBJIGtleScpXG4gIH1cbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBhIFVSTC1mcmllbmRseSBzbHVnIGZyb20gYSBuYW1lXG4gKi9cbmZ1bmN0aW9uIGdlbmVyYXRlU2x1ZyhuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbmFtZVxuICAgIC50b0xvd2VyQ2FzZSgpXG4gICAgLnJlcGxhY2UoL1teYS16MC05XSsvZywgJy0nKVxuICAgIC5yZXBsYWNlKC9eLXwtJC9nLCAnJylcbiAgICAuc3Vic3RyaW5nKDAsIDUwKVxufVxuXG4vKipcbiAqIEdlbmVyYXRlIGEgc2hvcnQgcmFuZG9tIElEXG4gKi9cbmZ1bmN0aW9uIGdlbmVyYXRlSWQoKTogc3RyaW5nIHtcbiAgcmV0dXJuIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cmluZygyLCA4KVxufVxuIl19
@@ -0,0 +1,12 @@
1
+ interface KeysOptions {
2
+ url?: string;
3
+ }
4
+ /**
5
+ * List API keys for the current project
6
+ */
7
+ export declare function listKeys(_options: KeysOptions): Promise<void>;
8
+ /**
9
+ * Regenerate API key for the current project
10
+ */
11
+ export declare function regenerateKey(options: KeysOptions): Promise<void>;
12
+ export {};
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.listKeys = listKeys;
40
+ exports.regenerateKey = regenerateKey;
41
+ const path_1 = __importDefault(require("path"));
42
+ const fs_extra_1 = __importDefault(require("fs-extra"));
43
+ const logger_1 = require("../../utils/logger");
44
+ const constants_1 = require("../../constants");
45
+ /**
46
+ * List API keys for the current project
47
+ */
48
+ async function listKeys(_options) {
49
+ const projectRoot = process.cwd();
50
+ const devdocConfigPath = path_1.default.join(projectRoot, '.devdoc.json');
51
+ if (!fs_extra_1.default.existsSync(devdocConfigPath)) {
52
+ logger_1.logger.error('No project found in current directory.');
53
+ logger_1.logger.info('Run "devdoc deploy" first to create a project.');
54
+ process.exit(1);
55
+ }
56
+ try {
57
+ const config = fs_extra_1.default.readJsonSync(devdocConfigPath);
58
+ if (!config.slug) {
59
+ logger_1.logger.error('Invalid .devdoc.json - missing project slug.');
60
+ process.exit(1);
61
+ }
62
+ console.log('');
63
+ console.log(` Project: ${logger_1.logger.cyan(config.slug)}`);
64
+ if (config.apiKey) {
65
+ // Show masked key
66
+ const maskedKey = config.apiKey.substring(0, 12) + '...' + config.apiKey.substring(config.apiKey.length - 4);
67
+ console.log(` API Key: ${maskedKey}`);
68
+ }
69
+ else {
70
+ console.log(` API Key: ${logger_1.logger.yellow('Not found')}`);
71
+ }
72
+ if (config.url) {
73
+ console.log(` URL: ${config.url}`);
74
+ }
75
+ if (config.lastDeployed) {
76
+ console.log(` Last deployed: ${new Date(config.lastDeployed).toLocaleString()}`);
77
+ }
78
+ console.log('');
79
+ }
80
+ catch (error) {
81
+ const message = error instanceof Error ? error.message : String(error);
82
+ logger_1.logger.error(`Failed to read project config: ${message}`);
83
+ process.exit(1);
84
+ }
85
+ }
86
+ /**
87
+ * Regenerate API key for the current project
88
+ */
89
+ async function regenerateKey(options) {
90
+ const projectRoot = process.cwd();
91
+ const apiUrl = options.url || process.env.DEVDOC_API_URL || constants_1.DEFAULT_API_URL;
92
+ const devdocConfigPath = path_1.default.join(projectRoot, '.devdoc.json');
93
+ if (!fs_extra_1.default.existsSync(devdocConfigPath)) {
94
+ logger_1.logger.error('No project found in current directory.');
95
+ logger_1.logger.info('Run "devdoc deploy" first to create a project.');
96
+ process.exit(1);
97
+ }
98
+ let config;
99
+ try {
100
+ config = fs_extra_1.default.readJsonSync(devdocConfigPath);
101
+ }
102
+ catch {
103
+ logger_1.logger.error('Failed to read .devdoc.json');
104
+ process.exit(1);
105
+ }
106
+ if (!config.slug || !config.apiKey) {
107
+ logger_1.logger.error('Invalid .devdoc.json - missing project slug or API key.');
108
+ process.exit(1);
109
+ }
110
+ logger_1.logger.warn('⚠️ This will invalidate your current API key.');
111
+ logger_1.logger.warn(' Any CI/CD pipelines using the old key will fail.');
112
+ console.log('');
113
+ // Simple confirmation
114
+ const readline = await Promise.resolve().then(() => __importStar(require('readline')));
115
+ const rl = readline.createInterface({
116
+ input: process.stdin,
117
+ output: process.stdout,
118
+ });
119
+ const answer = await new Promise((resolve) => {
120
+ rl.question('Continue? (y/N) ', resolve);
121
+ });
122
+ rl.close();
123
+ if (answer.toLowerCase() !== 'y') {
124
+ logger_1.logger.info('Cancelled.');
125
+ process.exit(0);
126
+ }
127
+ console.log('');
128
+ logger_1.logger.info('Regenerating API key...');
129
+ try {
130
+ const response = await fetch(`${apiUrl}/api/keys/regenerate`, {
131
+ method: 'POST',
132
+ headers: {
133
+ 'Content-Type': 'application/json',
134
+ 'Authorization': `Bearer ${config.apiKey}`,
135
+ },
136
+ body: JSON.stringify({
137
+ slug: config.slug,
138
+ }),
139
+ });
140
+ if (!response.ok) {
141
+ const errorData = await response.json().catch(() => ({ error: 'Unknown error' }));
142
+ throw new Error(errorData.error || `HTTP ${response.status}`);
143
+ }
144
+ const result = await response.json();
145
+ if (!result.apiKey) {
146
+ throw new Error('No API key returned');
147
+ }
148
+ // Update local config
149
+ config.apiKey = result.apiKey;
150
+ fs_extra_1.default.writeJsonSync(devdocConfigPath, config, { spaces: 2 });
151
+ console.log('');
152
+ logger_1.logger.success('✓ New API key generated!');
153
+ console.log('');
154
+ console.log(` New key: ${result.apiKey}`);
155
+ console.log('');
156
+ logger_1.logger.info('Updated .devdoc.json with new key.');
157
+ logger_1.logger.warn('⚠️ Update your CI/CD secrets with this new key.');
158
+ }
159
+ catch (error) {
160
+ const message = error instanceof Error ? error.message : String(error);
161
+ logger_1.logger.error(`Failed to regenerate key: ${message}`);
162
+ process.exit(1);
163
+ }
164
+ }
165
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvY29tbWFuZHMva2V5cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW1CQSw0QkE0Q0M7QUFLRCxzQ0E4RkM7QUFsS0QsZ0RBQXVCO0FBQ3ZCLHdEQUF5QjtBQUN6QiwrQ0FBMkM7QUFDM0MsK0NBQWlEO0FBYWpEOztHQUVHO0FBQ0ksS0FBSyxVQUFVLFFBQVEsQ0FBQyxRQUFxQjtJQUNsRCxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUE7SUFDakMsTUFBTSxnQkFBZ0IsR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxjQUFjLENBQUMsQ0FBQTtJQUUvRCxJQUFJLENBQUMsa0JBQUUsQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxDQUFDO1FBQ3JDLGVBQU0sQ0FBQyxLQUFLLENBQUMsd0NBQXdDLENBQUMsQ0FBQTtRQUN0RCxlQUFNLENBQUMsSUFBSSxDQUFDLGdEQUFnRCxDQUFDLENBQUE7UUFDN0QsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNqQixDQUFDO0lBRUQsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsa0JBQUUsQ0FBQyxZQUFZLENBQUMsZ0JBQWdCLENBQWlCLENBQUE7UUFFaEUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNqQixlQUFNLENBQUMsS0FBSyxDQUFDLDhDQUE4QyxDQUFDLENBQUE7WUFDNUQsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNqQixDQUFDO1FBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQTtRQUNmLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxlQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJ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TSxPQUFPLEdBQUcsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3RFLGVBQU0sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLE9BQU8sRUFBRSxDQUFDLENBQUE7UUFDcEQsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNqQixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXG5pbXBvcnQgZnMgZnJvbSAnZnMtZXh0cmEnXG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi91dGlscy9sb2dnZXInXG5pbXBvcnQgeyBERUZBVUxUX0FQSV9VUkwgfSBmcm9tICcuLi8uLi9jb25zdGFudHMnXG5cbmludGVyZmFjZSBLZXlzT3B0aW9ucyB7XG4gIHVybD86IHN0cmluZ1xufVxuXG5pbnRlcmZhY2UgRGV2RG9jQ29uZmlnIHtcbiAgc2x1Zz86IHN0cmluZ1xuICBhcGlLZXk/OiBzdHJpbmdcbiAgdXJsPzogc3RyaW5nXG4gIGxhc3REZXBsb3llZD86IHN0cmluZ1xufVxuXG4vKipcbiAqIExpc3QgQVBJIGtleXMgZm9yIHRoZSBjdXJyZW50IHByb2plY3RcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxpc3RLZXlzKF9vcHRpb25zOiBLZXlzT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9qZWN0Um9vdCA9IHByb2Nlc3MuY3dkKClcbiAgY29uc3QgZGV2ZG9jQ29uZmlnUGF0aCA9IHBhdGguam9pbihwcm9qZWN0Um9vdCwgJy5kZXZkb2MuanNvbicpXG4gIFxuICBpZiAoIWZzLmV4aXN0c1N5bmMoZGV2ZG9jQ29uZmlnUGF0aCkpIHtcbiAgICBsb2dnZXIuZXJyb3IoJ05vIHByb2plY3QgZm91bmQgaW4gY3VycmVudCBkaXJlY3RvcnkuJylcbiAgICBsb2dnZXIuaW5mbygnUnVuIFwiZGV2ZG9jIGRlcGxveVwiIGZpcnN0IHRvIGNyZWF0ZSBhIHByb2plY3QuJylcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxuICBcbiAgdHJ5IHtcbiAgICBjb25zdCBjb25maWcgPSBmcy5yZWFkSnNvblN5bmMoZGV2ZG9jQ29uZmlnUGF0aCkgYXMgRGV2RG9jQ29uZmlnXG4gICAgXG4gICAgaWYgKCFjb25maWcuc2x1Zykge1xuICAgICAgbG9nZ2VyLmVycm9yKCdJbnZhbGlkIC5kZXZkb2MuanNvbiAtIG1pc3NpbmcgcHJvamVjdCBzbHVnLicpXG4gICAgICBwcm9jZXNzLmV4aXQoMSlcbiAgICB9XG4gICAgXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgY29uc29sZS5sb2coYCAgUHJvamVjdDogJHtsb2dnZXIuY3lhbihjb25maWcuc2x1Zyl9YClcbiAgICBcbiAgICBpZiAoY29uZmlnLmFwaUtleSkge1xuICAgICAgLy8gU2hvdyBtYXNrZWQga2V5XG4gICAgICBjb25zdCBtYXNrZWRLZXkgPSBjb25maWcuYXBpS2V5LnN1YnN0cmluZygwLCAxMikgKyAnLi4uJyArIGNvbmZpZy5hcGlLZXkuc3Vic3RyaW5nKGNvbmZpZy5hcGlLZXkubGVuZ3RoIC0gNClcbiAgICAgIGNvbnNvbGUubG9nKGAgIEFQSSBLZXk6ICR7bWFza2VkS2V5fWApXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKGAgIEFQSSBLZXk6ICR7bG9nZ2VyLnllbGxvdygnTm90IGZvdW5kJyl9YClcbiAgICB9XG4gICAgXG4gICAgaWYgKGNvbmZpZy51cmwpIHtcbiAgICAgIGNvbnNvbGUubG9nKGAgIFVSTDogICAgICR7Y29uZmlnLnVybH1gKVxuICAgIH1cbiAgICBcbiAgICBpZiAoY29uZmlnLmxhc3REZXBsb3llZCkge1xuICAgICAgY29uc29sZS5sb2coYCAgTGFzdCBkZXBsb3llZDogJHtuZXcgRGF0ZShjb25maWcubGFzdERlcGxveWVkKS50b0xvY2FsZVN0cmluZygpfWApXG4gICAgfVxuICAgIFxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIFxuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcilcbiAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byByZWFkIHByb2plY3QgY29uZmlnOiAke21lc3NhZ2V9YClcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxufVxuXG4vKipcbiAqIFJlZ2VuZXJhdGUgQVBJIGtleSBmb3IgdGhlIGN1cnJlbnQgcHJvamVjdFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVnZW5lcmF0ZUtleShvcHRpb25zOiBLZXlzT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9qZWN0Um9vdCA9IHByb2Nlc3MuY3dkKClcbiAgY29uc3QgYXBpVXJsID0gb3B0aW9ucy51cmwgfHwgcHJvY2Vzcy5lbnYuREVWRE9DX0FQSV9VUkwgfHwgREVGQVVMVF9BUElfVVJMXG4gIGNvbnN0IGRldmRvY0NvbmZpZ1BhdGggPSBwYXRoLmpvaW4ocHJvamVjdFJvb3QsICcuZGV2ZG9jLmpzb24nKVxuICBcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGRldmRvY0NvbmZpZ1BhdGgpKSB7XG4gICAgbG9nZ2VyLmVycm9yKCdObyBwcm9qZWN0IGZvdW5kIGluIGN1cnJlbnQgZGlyZWN0b3J5LicpXG4gICAgbG9nZ2VyLmluZm8oJ1J1biBcImRldmRvYyBkZXBsb3lcIiBmaXJzdCB0byBjcmVhdGUgYSBwcm9qZWN0LicpXG4gICAgcHJvY2Vzcy5leGl0KDEpXG4gIH1cbiAgXG4gIGxldCBjb25maWc6IERldkRvY0NvbmZpZ1xuICB0cnkge1xuICAgIGNvbmZpZyA9IGZzLnJlYWRKc29uU3luYyhkZXZkb2NDb25maWdQYXRoKSBhcyBEZXZEb2NDb25maWdcbiAgfSBjYXRjaCB7XG4gICAgbG9nZ2VyLmVycm9yKCdGYWlsZWQgdG8gcmVhZCAuZGV2ZG9jLmpzb24nKVxuICAgIHByb2Nlc3MuZXhpdCgxKVxuICB9XG4gIFxuICBpZiAoIWNvbmZpZy5zbHVnIHx8ICFjb25maWcuYXBpS2V5KSB7XG4gICAgbG9nZ2VyLmVycm9yKCdJbnZhbGlkIC5kZXZkb2MuanNvbiAtIG1pc3NpbmcgcHJvamVjdCBzbHVnIG9yIEFQSSBrZXkuJylcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxuICBcbiAgbG9nZ2VyLndhcm4oJ+KaoO+4jyAgVGhpcyB3aWxsIGludmFsaWRhdGUgeW91ciBjdXJyZW50IEFQSSBrZXkuJylcbiAgbG9nZ2VyLndhcm4oJyAgIEFueSBDSS9DRCBwaXBlbGluZXMgdXNpbmcgdGhlIG9sZCBrZXkgd2lsbCBmYWlsLicpXG4gIGNvbnNvbGUubG9nKCcnKVxuICBcbiAgLy8gU2ltcGxlIGNvbmZpcm1hdGlvblxuICBjb25zdCByZWFkbGluZSA9IGF3YWl0IGltcG9ydCgncmVhZGxpbmUnKVxuICBjb25zdCBybCA9IHJlYWRsaW5lLmNyZWF0ZUludGVyZmFjZSh7XG4gICAgaW5wdXQ6IHByb2Nlc3Muc3RkaW4sXG4gICAgb3V0cHV0OiBwcm9jZXNzLnN0ZG91dCxcbiAgfSlcbiAgXG4gIGNvbnN0IGFuc3dlciA9IGF3YWl0IG5ldyBQcm9taXNlPHN0cmluZz4oKHJlc29sdmUpID0+IHtcbiAgICBybC5xdWVzdGlvbignQ29udGludWU/ICh5L04pICcsIHJlc29sdmUpXG4gIH0pXG4gIHJsLmNsb3NlKClcbiAgXG4gIGlmIChhbnN3ZXIudG9Mb3dlckNhc2UoKSAhPT0gJ3knKSB7XG4gICAgbG9nZ2VyLmluZm8oJ0NhbmNlbGxlZC4nKVxuICAgIHByb2Nlc3MuZXhpdCgwKVxuICB9XG4gIFxuICBjb25zb2xlLmxvZygnJylcbiAgbG9nZ2VyLmluZm8oJ1JlZ2VuZXJhdGluZyBBUEkga2V5Li4uJylcbiAgXG4gIHRyeSB7XG4gICAgaW50ZXJmYWNlIFJlZ2VuZXJhdGVSZXNwb25zZSB7XG4gICAgICBzdWNjZXNzOiBib29sZWFuXG4gICAgICBhcGlLZXk/OiBzdHJpbmdcbiAgICAgIGVycm9yPzogc3RyaW5nXG4gICAgfVxuICAgIFxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYCR7YXBpVXJsfS9hcGkva2V5cy9yZWdlbmVyYXRlYCwge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICdBdXRob3JpemF0aW9uJzogYEJlYXJlciAke2NvbmZpZy5hcGlLZXl9YCxcbiAgICAgIH0sXG4gICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIHNsdWc6IGNvbmZpZy5zbHVnLFxuICAgICAgfSksXG4gICAgfSlcbiAgICBcbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICBjb25zdCBlcnJvckRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCkuY2F0Y2goKCkgPT4gKHsgZXJyb3I6ICdVbmtub3duIGVycm9yJyB9KSkgYXMgeyBlcnJvcj86IHN0cmluZyB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JEYXRhLmVycm9yIHx8IGBIVFRQICR7cmVzcG9uc2Uuc3RhdHVzfWApXG4gICAgfVxuICAgIFxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKSBhcyBSZWdlbmVyYXRlUmVzcG9uc2VcbiAgICBcbiAgICBpZiAoIXJlc3VsdC5hcGlLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gQVBJIGtleSByZXR1cm5lZCcpXG4gICAgfVxuICAgIFxuICAgIC8vIFVwZGF0ZSBsb2NhbCBjb25maWdcbiAgICBjb25maWcuYXBpS2V5ID0gcmVzdWx0LmFwaUtleVxuICAgIGZzLndyaXRlSnNvblN5bmMoZGV2ZG9jQ29uZmlnUGF0aCwgY29uZmlnLCB7IHNwYWNlczogMiB9KVxuICAgIFxuICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIGxvZ2dlci5zdWNjZXNzKCfinJMgTmV3IEFQSSBrZXkgZ2VuZXJhdGVkIScpXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgY29uc29sZS5sb2coYCAgTmV3IGtleTogJHtyZXN1bHQuYXBpS2V5fWApXG4gICAgY29uc29sZS5sb2coJycpXG4gICAgbG9nZ2VyLmluZm8oJ1VwZGF0ZWQgLmRldmRvYy5qc29uIHdpdGggbmV3IGtleS4nKVxuICAgIGxvZ2dlci53YXJuKCfimqDvuI8gIFVwZGF0ZSB5b3VyIENJL0NEIHNlY3JldHMgd2l0aCB0aGlzIG5ldyBrZXkuJylcbiAgICBcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXG4gICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gcmVnZW5lcmF0ZSBrZXk6ICR7bWVzc2FnZX1gKVxuICAgIHByb2Nlc3MuZXhpdCgxKVxuICB9XG59XG4iXX0=