@intuned/runtime 1.3.15 → 1.3.17

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 (73) hide show
  1. package/InterfaceTemplate/index.playwright.ts +1 -1
  2. package/WebTemplate.zip +0 -0
  3. package/dist/commands/api/run.js +4 -8
  4. package/dist/commands/auth-sessions/load.js +2 -2
  5. package/dist/commands/auth-sessions/run-check.js +5 -5
  6. package/dist/commands/auth-sessions/run-create.js +3 -3
  7. package/dist/commands/build.js +1 -1
  8. package/dist/commands/common/projectExclusions.js +1 -1
  9. package/dist/commands/common/tsNodeImport.js +9 -0
  10. package/dist/commands/interface/run.js +1 -1
  11. package/dist/commands/intuned-cli/commands/attempt_api.command.js +1 -1
  12. package/dist/commands/intuned-cli/commands/attempt_authsession.command.js +1 -1
  13. package/dist/commands/intuned-cli/commands/attempt_authsession_check.command.js +2 -2
  14. package/dist/commands/intuned-cli/commands/attempt_authsession_create.command.js +1 -1
  15. package/dist/commands/intuned-cli/commands/authsession.command.js +1 -1
  16. package/dist/commands/intuned-cli/commands/authsession_record.command.js +1 -1
  17. package/dist/commands/intuned-cli/commands/authsession_scaffold.command.d.ts +1 -0
  18. package/dist/commands/intuned-cli/commands/authsession_scaffold.command.js +16 -0
  19. package/dist/commands/intuned-cli/commands/deploy.command.js +13 -9
  20. package/dist/commands/intuned-cli/commands/index.d.ts +2 -2
  21. package/dist/commands/intuned-cli/commands/index.js +15 -15
  22. package/dist/commands/intuned-cli/commands/{save.command.d.ts → provision.command.d.ts} +1 -1
  23. package/dist/commands/intuned-cli/commands/provision.command.js +50 -0
  24. package/dist/commands/intuned-cli/commands/run_api.command.js +1 -1
  25. package/dist/commands/intuned-cli/commands/run_authsession.command.d.ts +3 -3
  26. package/dist/commands/intuned-cli/commands/run_authsession.command.js +2 -2
  27. package/dist/commands/intuned-cli/commands/run_authsession_create.command.js +1 -1
  28. package/dist/commands/intuned-cli/commands/run_authsession_update.command.js +2 -2
  29. package/dist/commands/intuned-cli/commands/run_authsession_validate.command.js +2 -2
  30. package/dist/commands/intuned-cli/commands/types.d.ts +1 -1
  31. package/dist/commands/intuned-cli/commands/types.js +2 -2
  32. package/dist/commands/intuned-cli/controller/__test__/api.test.js +6 -5
  33. package/dist/commands/intuned-cli/controller/__test__/authSession.test.js +12 -11
  34. package/dist/commands/intuned-cli/controller/api.js +4 -1
  35. package/dist/commands/intuned-cli/controller/authSession.js +28 -28
  36. package/dist/commands/intuned-cli/controller/deploy.js +52 -10
  37. package/dist/commands/intuned-cli/controller/index.js +1 -1
  38. package/dist/commands/intuned-cli/controller/{save.d.ts → provision.d.ts} +5 -1
  39. package/dist/commands/intuned-cli/controller/provision.js +300 -0
  40. package/dist/commands/intuned-cli/controller/scaffold.d.ts +1 -0
  41. package/dist/commands/intuned-cli/controller/scaffold.js +77 -0
  42. package/dist/commands/intuned-cli/helpers/__test__/browser.test.js +1 -0
  43. package/dist/commands/intuned-cli/helpers/__test__/tracing.test.js +1 -0
  44. package/dist/commands/intuned-cli/helpers/api.js +4 -7
  45. package/dist/commands/intuned-cli/helpers/auth.js +22 -19
  46. package/dist/commands/intuned-cli/helpers/backend.js +12 -4
  47. package/dist/commands/intuned-cli/helpers/context.js +2 -2
  48. package/dist/commands/intuned-cli/helpers/prompts.d.ts +3 -0
  49. package/dist/commands/intuned-cli/helpers/prompts.js +71 -0
  50. package/dist/commands/intuned-cli/helpers/wrapper.js +12 -2
  51. package/dist/commands/intuned-cli/main.js +21 -8
  52. package/dist/commands/intuned-cli/types.d.ts +42 -13
  53. package/dist/commands/intuned-cli/types.js +12 -2
  54. package/dist/common/backendFunctions/getAuthSessionParameters.js +1 -1
  55. package/dist/common/extension/extensionsHelpers.d.ts +6 -3
  56. package/dist/common/extension/extensionsHelpers.js +45 -19
  57. package/dist/common/extension/intunedExtensionServer.d.ts +2 -5
  58. package/dist/common/extension/intunedExtensionServer.js +6 -9
  59. package/dist/common/intunedJson.js +2 -2
  60. package/dist/common/jwtTokenManager.js +2 -2
  61. package/dist/common/launchBrowser.d.ts +2 -0
  62. package/dist/common/launchBrowser.js +41 -3
  63. package/dist/common/playwrightContext.js +7 -1
  64. package/dist/common/runApi/errors.js +1 -1
  65. package/dist/common/runApi/index.js +2 -2
  66. package/dist/common/settingsSchema.d.ts +2 -1
  67. package/dist/runtime/captcha.js +25 -11
  68. package/package.json +5 -3
  69. package/dist/commands/intuned-cli/commands/init.command.d.ts +0 -1
  70. package/dist/commands/intuned-cli/commands/init.command.js +0 -13
  71. package/dist/commands/intuned-cli/commands/save.command.js +0 -42
  72. package/dist/commands/intuned-cli/controller/save.js +0 -351
  73. /package/InterfaceTemplate/{utils.ts → __utils.ts} +0 -0
@@ -0,0 +1,300 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.projectNameSchema = void 0;
7
+ exports.runProvisionProject = runProvisionProject;
8
+ exports.validateProjectName = exports.validateIntunedProject = void 0;
9
+ var fs = _interopRequireWildcard(require("fs-extra"));
10
+ var path = _interopRequireWildcard(require("path"));
11
+ var _zod = require("zod");
12
+ var _projectExclusions = _interopRequireDefault(require("../../common/projectExclusions"));
13
+ var _constants = require("../constants");
14
+ var _helpers = require("../helpers");
15
+ var _terminal = require("../helpers/terminal");
16
+ var _build = require("./build");
17
+ var dotenv = _interopRequireWildcard(require("dotenv"));
18
+ var _constants2 = require("../../../common/constants");
19
+ var _ignore = _interopRequireDefault(require("ignore"));
20
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
21
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
22
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
23
+ const provisionProjectApiResponseSchema = _zod.z.string().transform((val, ctx) => {
24
+ try {
25
+ return JSON.parse(val);
26
+ } catch (e) {
27
+ ctx.addIssue({
28
+ code: _zod.z.ZodIssueCode.custom,
29
+ message: "Response is not valid JSON"
30
+ });
31
+ return _zod.z.NEVER;
32
+ }
33
+ }).pipe(_zod.z.object({
34
+ id: _zod.z.string().uuid(),
35
+ enableFirstRunExperience: _zod.z.boolean().optional(),
36
+ environmentVariablesKeys: _zod.z.array(_zod.z.string()).default([]).catch(() => [])
37
+ }));
38
+ async function runProvisionProject(projectName, auth, silent = false) {
39
+ const {
40
+ workspaceId,
41
+ apiKey
42
+ } = auth;
43
+ const baseUrl = (0, _helpers.getBaseUrl)();
44
+ const url = `${baseUrl}/api/v1/workspace/${workspaceId}/projects/${projectName}`;
45
+ const headers = {
46
+ [_constants2.API_KEY_HEADER_NAME]: apiKey,
47
+ "Content-Type": "application/json"
48
+ };
49
+ const projectPath = process.cwd();
50
+ const codeTree = await convertProjectToCodeTree(projectPath);
51
+ const intunedSettingsFile = await (0, _helpers.getIntunedSettingsFile)();
52
+ codeTree["Intuned.json"] = {
53
+ file: {
54
+ contents: JSON.stringify(intunedSettingsFile.parse(await fs.readFile(intunedSettingsFile.path, "utf-8")))
55
+ }
56
+ };
57
+ codeTree["tsconfig.json"] = {
58
+ file: {
59
+ contents: JSON.stringify(_constants.tsConfigCli, null, 2)
60
+ }
61
+ };
62
+ const upsertProjectPayload = {
63
+ codeTree,
64
+ platformType: "CLI",
65
+ language: "typescript"
66
+ };
67
+ const response = await fetch(url, {
68
+ headers,
69
+ method: "PUT",
70
+ body: JSON.stringify(upsertProjectPayload)
71
+ });
72
+ if (!response.ok) {
73
+ if (response.status === 401) {
74
+ throw new _helpers.CLIError(`Invalid API key. The provided API key is not authorized to access this workspace.\n` + `Please verify your API key at: https://app.intuned.io/settings/api-keys`);
75
+ }
76
+ throw new _helpers.CLIError(`^r^+Project provisioning failed:^:\n` + `^RServer returned status ${response.status}^:\n` + `^RResponse: ${await response.text()}^:\n\n` + `^yCommon causes:^:\n` + ` • Invalid workspace ID or project name\n` + ` • Insufficient permissions\n` + ` • Network connectivity issues\n` + ` • Project structure validation errors\n`, {
77
+ autoColor: false
78
+ });
79
+ }
80
+ if (!silent) {
81
+ (0, _terminal.terminal)("^g^+Project provisioned successfully!^:\n");
82
+ }
83
+ const body = await response.text();
84
+ const parseResult = provisionProjectApiResponseSchema.safeParse(body);
85
+ if (!parseResult.success) {
86
+ (0, _terminal.terminal)(`^yWarning: Could not parse provision project response:^:\n`);
87
+ (0, _terminal.terminal)(body + "\n");
88
+ return;
89
+ }
90
+ const {
91
+ id: projectId,
92
+ enableFirstRunExperience,
93
+ environmentVariablesKeys
94
+ } = parseResult.data;
95
+ const dotEnvPath = path.join(projectPath, ".env");
96
+ if (!(await fs.exists(dotEnvPath))) {
97
+ await fs.writeFile(dotEnvPath, `${_constants2.PROJECT_ID_ENV_VAR_KEY}=${projectId}
98
+ ${_constants2.WORKSPACE_ID_ENV_VAR_KEY}=${workspaceId}
99
+ ${_constants2.API_KEY_ENV_VAR_KEY}=${apiKey}`);
100
+ (0, _terminal.terminal)(`^g^+Created .env file with project credentials.^:\n`);
101
+ return {
102
+ projectId,
103
+ enableFirstRunExperience,
104
+ environmentVariablesKeys,
105
+ dotenvContent: {}
106
+ };
107
+ }
108
+ const envContent = await fs.readFile(dotEnvPath, "utf-8");
109
+ const dotenvContent = dotenv.parse(envContent);
110
+ let contentToAppend = "";
111
+ const projectCredentialsEnvVars = {
112
+ [_constants2.PROJECT_ID_ENV_VAR_KEY]: projectId,
113
+ [_constants2.WORKSPACE_ID_ENV_VAR_KEY]: workspaceId,
114
+ [_constants2.API_KEY_ENV_VAR_KEY]: apiKey
115
+ };
116
+ for (const key in projectCredentialsEnvVars) {
117
+ if (dotenvContent[key] === projectCredentialsEnvVars[key]) {
118
+ continue;
119
+ }
120
+ if (dotenvContent[key]) {
121
+ (0, _terminal.terminal)(`^yWarning: Existing ${key} in .env has invalid value. Appending correct value.^:\n`);
122
+ }
123
+ contentToAppend += `${key}=${projectCredentialsEnvVars[key]}\n`;
124
+ }
125
+ if (contentToAppend) {
126
+ await fs.appendFile(dotEnvPath, contentToAppend + "\n");
127
+ (0, _terminal.terminal)(`^g^+Updated .env file with project credentials.^:\n`);
128
+ }
129
+ const dotenvContentToReturn = {
130
+ ...dotenvContent
131
+ };
132
+ for (const key of [_constants2.PROJECT_ID_ENV_VAR_KEY, _constants2.WORKSPACE_ID_ENV_VAR_KEY, _constants2.API_KEY_ENV_VAR_KEY]) {
133
+ if (key in dotenvContentToReturn) {
134
+ delete dotenvContentToReturn[key];
135
+ }
136
+ }
137
+ return {
138
+ projectId,
139
+ enableFirstRunExperience,
140
+ environmentVariablesKeys,
141
+ dotenvContent: dotenvContentToReturn
142
+ };
143
+ }
144
+ const projectNameSchema = exports.projectNameSchema = _zod.z.string().min(1, "Name is required").max(200, "Must be 200 characters or less").regex(/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/, "Can only contain lowercase letters, numbers, hyphens, and underscores in between").refine(value => !_zod.z.string().uuid().safeParse(value).success, {
145
+ message: "Cannot be a UUID"
146
+ });
147
+ const validateProjectName = projectName => {
148
+ const validation = projectNameSchema.safeParse(projectName);
149
+ if (!validation.success) {
150
+ return {
151
+ isValid: false,
152
+ errorMessage: validation.error.errors[0].message
153
+ };
154
+ }
155
+ return {
156
+ isValid: true
157
+ };
158
+ };
159
+ exports.validateProjectName = validateProjectName;
160
+ const validateIntunedProject = async () => {
161
+ const currentDirectoryToProvision = process.cwd();
162
+ const intunedSettingsFile = await (0, _helpers.getIntunedSettingsFile)();
163
+ const validationSteps = [{
164
+ name: "build",
165
+ check: async () => {
166
+ try {
167
+ const buildResult = await (0, _build.runBuild)();
168
+ if (!buildResult) {
169
+ return {
170
+ isValid: false,
171
+ errorMessage: "Build failed"
172
+ };
173
+ }
174
+ return {
175
+ isValid: true
176
+ };
177
+ } catch (error) {
178
+ return {
179
+ isValid: false,
180
+ errorMessage: "Build failed"
181
+ };
182
+ }
183
+ }
184
+ }, {
185
+ name: intunedSettingsFile.name,
186
+ check: async () => {
187
+ try {
188
+ const intunedJsonPath = path.join(currentDirectoryToProvision, intunedSettingsFile.name);
189
+ await fs.exists(intunedJsonPath);
190
+ return {
191
+ isValid: true
192
+ };
193
+ } catch (error) {
194
+ return {
195
+ isValid: false,
196
+ errorMessage: `${intunedSettingsFile.name} file not found`
197
+ };
198
+ }
199
+ }
200
+ }, {
201
+ name: "api folder",
202
+ check: async () => {
203
+ try {
204
+ const apiFolderPath = path.join(currentDirectoryToProvision, "api");
205
+ await fs.access(apiFolderPath);
206
+ return {
207
+ isValid: true
208
+ };
209
+ } catch (error) {
210
+ return {
211
+ isValid: false,
212
+ errorMessage: "API folder not found"
213
+ };
214
+ }
215
+ }
216
+ }];
217
+ for (const step of validationSteps) {
218
+ const result = await step.check();
219
+ if (!result.isValid) {
220
+ return result;
221
+ }
222
+ }
223
+ return {
224
+ isValid: true
225
+ };
226
+ };
227
+ exports.validateIntunedProject = validateIntunedProject;
228
+ async function convertProjectToCodeTree(projectPath) {
229
+ const ig = (0, _ignore.default)();
230
+ const gitIgnorePath = await findGitIgnoreFile(projectPath);
231
+ if (gitIgnorePath) {
232
+ const gitIgnoreContent = await fs.readFile(gitIgnorePath, "utf-8");
233
+ ig.add(gitIgnoreContent);
234
+ }
235
+ ig.add(_projectExclusions.default);
236
+ async function traverse(dirPath) {
237
+ const tree = {};
238
+ const fileNames = [];
239
+ const entries = await fs.readdir(dirPath, {
240
+ withFileTypes: true
241
+ });
242
+ for (const entry of entries) {
243
+ const entryPath = path.join(dirPath, entry.name);
244
+ if (ig.ignores(path.relative(projectPath, entryPath))) {
245
+ continue;
246
+ }
247
+ if (entry.isFile()) {
248
+ try {
249
+ const content = await fs.readFile(entryPath, "utf-8");
250
+ tree[entry.name] = {
251
+ file: {
252
+ contents: content
253
+ }
254
+ };
255
+ fileNames.push(path.relative(projectPath, entryPath));
256
+ } catch (error) {
257
+ (0, _terminal.terminal)(`^yWarning: Could not read file ${entryPath}^:\n`);
258
+ }
259
+ } else if (entry.isDirectory()) {
260
+ const {
261
+ tree: subTree,
262
+ fileNames: subFileNames
263
+ } = await traverse(entryPath);
264
+ fileNames.push(...subFileNames);
265
+ if (Object.keys(subTree).length > 0) {
266
+ tree[entry.name] = {
267
+ directory: subTree
268
+ };
269
+ }
270
+ }
271
+ }
272
+ return {
273
+ tree,
274
+ fileNames
275
+ };
276
+ }
277
+ const {
278
+ tree,
279
+ fileNames
280
+ } = await traverse(projectPath);
281
+ const filesToProvisionText = " " + fileNames.join("\n ");
282
+ (0, _terminal.terminal)("^CFiles to be provisioned:^:\n");
283
+ (0, _terminal.terminal)(filesToProvisionText + "\n");
284
+ return tree;
285
+ }
286
+ async function findGitIgnoreFile(projectPath) {
287
+ let currentDirectory = projectPath;
288
+ while (true) {
289
+ const gitIgnorePath = path.join(currentDirectory, ".gitignore");
290
+ if (await fs.exists(gitIgnorePath)) {
291
+ return gitIgnorePath;
292
+ }
293
+ const parentDirectory = path.dirname(currentDirectory);
294
+ if (parentDirectory === currentDirectory) {
295
+ break;
296
+ }
297
+ currentDirectory = parentDirectory;
298
+ }
299
+ return null;
300
+ }
@@ -0,0 +1 @@
1
+ export declare function scaffoldAuthSessionFiles(): Promise<void>;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.scaffoldAuthSessionFiles = scaffoldAuthSessionFiles;
7
+ var _zod = require("zod");
8
+ var _helpers = require("../helpers");
9
+ var _types = require("../types");
10
+ var _tsNodeImport = require("../../common/tsNodeImport");
11
+ var _constants = require("../../../common/constants");
12
+ var _fsExtra = require("fs-extra");
13
+ var _path = _interopRequireDefault(require("path"));
14
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
+ const authSessionTemplateResponseSchema = _zod.z.object({
16
+ "auth-sessions": _types.fileSystemTreeSchema
17
+ });
18
+ async function scaffoldAuthSessionFiles() {
19
+ const [createResult, checkResult] = await Promise.all([(0, _tsNodeImport.tsNodeImport)(`${_constants.AUTH_SESSIONS_FOLDER_NAME}/create`), (0, _tsNodeImport.tsNodeImport)(`${_constants.AUTH_SESSIONS_FOLDER_NAME}/check`)]);
20
+ const createExists = createResult.isOk() || createResult.error.type !== "not_found";
21
+ const checkExists = checkResult.isOk() || checkResult.error.type !== "not_found";
22
+ if (createExists && checkExists) {
23
+ (0, _helpers.terminal)("^g^+AuthSession files already exist^:\n");
24
+ return;
25
+ }
26
+ (0, _helpers.terminal)("^g^+Scaffolding...^:\n");
27
+ const authSessionTemplateUrl = new URL("/api/v1/templates/authsession", (0, _helpers.getBaseUrl)());
28
+ authSessionTemplateUrl.searchParams.append("language", "typescript");
29
+ const response = await fetch(authSessionTemplateUrl.toString(), {
30
+ method: "GET"
31
+ });
32
+ const text = await response.text();
33
+ if (!response.ok) {
34
+ throw new Error(`Failed to fetch AuthSession template
35
+ Got ${response.status} ${response.statusText}
36
+ ${text}`);
37
+ }
38
+ let json;
39
+ try {
40
+ json = JSON.parse(text);
41
+ } catch (e) {
42
+ throw new Error(`Failed to parse AuthSession template response as JSON
43
+ ${text}`);
44
+ }
45
+ const parseResult = authSessionTemplateResponseSchema.safeParse(json);
46
+ if (!parseResult.success) {
47
+ throw new Error(`AuthSession template response has invalid shape: ${JSON.stringify(parseResult.error.errors, null, 2)}`);
48
+ }
49
+ const authSessionsContent = parseResult.data["auth-sessions"];
50
+ const cwd = process.cwd();
51
+ const exists = {
52
+ create: createExists,
53
+ check: checkExists
54
+ };
55
+ await (0, _fsExtra.ensureDir)(_path.default.join(cwd, _constants.AUTH_SESSIONS_FOLDER_NAME));
56
+ for (const api in exists) {
57
+ if (exists[api]) {
58
+ continue;
59
+ }
60
+ const [name, node] = Object.entries(authSessionsContent).find(entry => "file" in entry[1] && entry[0].replace(/\.[^/.]+$/, "") === api) ?? [undefined, undefined];
61
+ if (!name || !node) {
62
+ continue;
63
+ }
64
+ const {
65
+ file: {
66
+ contents
67
+ }
68
+ } = node;
69
+ if (typeof contents !== "string") {
70
+ continue;
71
+ }
72
+ await (0, _fsExtra.writeFile)(_path.default.join(cwd, _constants.AUTH_SESSIONS_FOLDER_NAME, name), contents, {
73
+ encoding: "utf-8"
74
+ });
75
+ (0, _helpers.terminal)(`^g^+Written ^_${_path.default.join(_constants.AUTH_SESSIONS_FOLDER_NAME, name)}^:\n`);
76
+ }
77
+ }
@@ -10,6 +10,7 @@ function getTerminal() {
10
10
  });
11
11
  }
12
12
  _vitest.vi.mock("fs-extra", () => ({
13
+ ensureDir: _vitest.vi.fn(),
13
14
  exists: _vitest.vi.fn().mockResolvedValue(true)
14
15
  }));
15
16
  _vitest.vi.mock("portfinder", () => ({
@@ -9,6 +9,7 @@ function getTerminal() {
9
9
  });
10
10
  }
11
11
  _vitest.vi.mock("fs-extra", () => ({
12
+ ensureDir: _vitest.vi.fn(),
12
13
  exists: _vitest.vi.fn().mockResolvedValue(true)
13
14
  }));
14
15
  _vitest.vi.mock("../../helpers/terminal", () => ({
@@ -4,15 +4,12 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.assertApiFileExists = assertApiFileExists;
7
- var _path = _interopRequireDefault(require("path"));
8
- var _fsExtra = require("fs-extra");
9
7
  var _errors = require("./errors");
10
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
8
+ var _tsNodeImport = require("../../common/tsNodeImport");
11
9
  async function assertApiFileExists(dirname, api) {
12
- const file = `${dirname}/${api}.ts`;
13
- const filePath = _path.default.join(process.cwd(), file);
14
- if (!(await (0, _fsExtra.exists)(filePath))) {
15
- throw new _errors.CLIAssertionError(`^+^r API^ ^+${dirname}/${api}^ ^r^+is not implemented.^:`, {
10
+ const result = await (0, _tsNodeImport.tsNodeImport)(`${dirname}/${api}`);
11
+ if (result.isErr() && result.error.type === "not_found") {
12
+ throw new _errors.CLIAssertionError(`^+^r API^ ^+${dirname}/${api}^ ^r^+does not exist. Make sure to use an existing API name.^:`, {
16
13
  autoColor: false
17
14
  });
18
15
  }
@@ -20,25 +20,21 @@ var _formatZodError = require("../../../common/formatZodError");
20
20
  var _asyncLocalStorage = require("../../../common/asyncLocalStorage");
21
21
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
22
22
  async function isAuthEnabled() {
23
- try {
24
- const intunedJson = await (0, _intunedJson.loadIntunedJson)();
25
- return Boolean(intunedJson?.authSessions?.enabled);
26
- } catch (error) {
27
- return false;
28
- }
23
+ const intunedJson = await (0, _intunedJson.loadIntunedJson)();
24
+ return Boolean(intunedJson?.authSessions?.enabled);
29
25
  }
30
26
  async function assertAuthEnabled() {
31
27
  if (!(await isAuthEnabled())) {
32
- throw new _errors.CLIAssertionError(`Auth session is not enabled, enable it in ${await (0, _intunedJson.getIntunedSettingsFileName)()} to use it`);
28
+ throw new _errors.CLIAssertionError(await getAuthNotEnabledErrorMessage());
33
29
  }
34
30
  }
35
31
  async function assertAuthConsistent(authSession) {
36
32
  const _isAuthEnabled = await isAuthEnabled();
37
33
  if (_isAuthEnabled && !authSession) {
38
- throw new _errors.CLIAssertionError("Auth session is enabled, but no auth session is provided. Please provide an auth session ID.");
34
+ throw new _errors.CLIAssertionError("AuthSession is enabled, but no AuthSession is provided. Please provide an AuthSession using '--auth-session <id>' option.");
39
35
  }
40
36
  if (!_isAuthEnabled && authSession) {
41
- throw new _errors.CLIAssertionError(`Auth session is not enabled, enable it in ${await (0, _intunedJson.getIntunedSettingsFileName)()} to use it`);
37
+ throw new _errors.CLIAssertionError(await getAuthNotEnabledErrorMessage());
42
38
  }
43
39
  }
44
40
  async function loadAuthSessionInstance(authSessionId) {
@@ -47,12 +43,12 @@ async function loadAuthSessionInstance(authSessionId) {
47
43
  const authSessionInstanceStoragePath = _path.default.join(authSessionInstancePath, `auth-session.json`);
48
44
  const authSessionInstanceMetadataPath = _path.default.join(authSessionInstancePath, `metadata.json`);
49
45
  if (!(await (0, _fsExtra.exists)(authSessionInstanceStoragePath))) {
50
- throw new _errors.CLIError(`Auth session instance with ID ${authSessionId} not found`);
46
+ throw new _errors.CLIError(`AuthSession instance with ID ${authSessionId} not found. Make sure the ID is correct.`);
51
47
  }
52
48
  const authSessionInstanceJson = await (0, _fsExtra.readJSON)(authSessionInstanceStoragePath);
53
49
  const authSessionInstanceParseResult = _runApi.runApiStorageStateSchema.safeParse(authSessionInstanceJson);
54
50
  if (!authSessionInstanceParseResult.success) {
55
- throw new _errors.CLIError(`Auth session instance with ID ${authSessionId} is not valid: ${(0, _formatZodError.formatZodError)(authSessionInstanceParseResult.error)}`);
51
+ throw new _errors.CLIError(`AuthSession instance with ID ${authSessionId} is not valid: ${(0, _formatZodError.formatZodError)(authSessionInstanceParseResult.error)}`);
56
52
  }
57
53
  const metadata = await (0, _fsExtra.readJSON)(authSessionInstanceMetadataPath);
58
54
  return {
@@ -60,7 +56,7 @@ async function loadAuthSessionInstance(authSessionId) {
60
56
  metadata
61
57
  };
62
58
  } catch (error) {
63
- throw new _errors.CLIError(`Error retrieving auth session instance: ${error.message}`);
59
+ throw new _errors.CLIError(`Error loading AuthSession instance: ${error.message}`);
64
60
  }
65
61
  }
66
62
  async function storeAuthSessionInstance({
@@ -81,7 +77,7 @@ async function storeAuthSessionInstance({
81
77
  });
82
78
  const projectAuthConfig = (await (0, _intunedJson.loadIntunedJson)()).authSessions;
83
79
  if (!projectAuthConfig.enabled) {
84
- throw new _errors.CLIError(`Auth sessions are not enabled in ${await (0, _intunedJson.getIntunedSettingsFileName)()}`);
80
+ throw new _errors.CLIError(`AuthSessions are not enabled in ${await (0, _intunedJson.getIntunedSettingsFileName)()}. Make sure they are enabled.`);
85
81
  }
86
82
  const authSessionInstanceMetadataPath = _path.default.join(authSessionInstancePath, `metadata.json`);
87
83
  const authSessionMetadata = {
@@ -104,19 +100,19 @@ async function storeAuthSessionInstance({
104
100
  });
105
101
  return authSessionInstancePath;
106
102
  } catch (error) {
107
- throw new _errors.CLIError(`Error storing auth session instance: ${error.message}`);
103
+ throw new _errors.CLIError(`Error storing AuthSession instance: ${error.message}`);
108
104
  }
109
105
  }
110
106
  function registerGetAuthSessionParameters(authSessionId) {
111
107
  async function getAuthSessionParameters() {
112
108
  if (!authSessionId) {
113
- throw new Error("getAuthSessionParameters cannot be called without using an auth session");
109
+ throw new Error("getAuthSessionParameters cannot be called without using an AuthSession");
114
110
  }
115
111
  const {
116
112
  metadata
117
113
  } = await loadAuthSessionInstance(authSessionId);
118
114
  if (metadata?.authSessionType === "MANUAL") {
119
- throw new Error("Auth session is recorder-based, it does not have parameters.");
115
+ throw new Error("AuthSession is recorder-based, it does not have parameters.");
120
116
  }
121
117
  return metadata?.authSessionInput ?? {};
122
118
  }
@@ -125,20 +121,27 @@ function registerGetAuthSessionParameters(authSessionId) {
125
121
  async function getAuthSessionRecorderParameters() {
126
122
  const intunedJson = await (0, _intunedJson.loadIntunedJson)();
127
123
  if (!intunedJson.authSessions.enabled) {
128
- throw new _errors.CLIError(`Auth sessions are not enabled in ${await (0, _intunedJson.getIntunedSettingsFileName)()}`);
124
+ throw new _errors.CLIError(`AuthSessions are not enabled in ${await (0, _intunedJson.getIntunedSettingsFileName)()}. Make sure they are enabled.`);
129
125
  }
130
126
  if (intunedJson.authSessions.type !== "MANUAL") {
131
- throw new _errors.CLIError(`Auth session type is not recorder-based in ${await (0, _intunedJson.getIntunedSettingsFileName)()}`);
127
+ throw new _errors.CLIError(`AuthSession type is not recorder-based in ${await (0, _intunedJson.getIntunedSettingsFileName)()}.
128
+ Make sure the AuthSession type is set to 'MANUAL'
129
+ For more details, check out https://docs.intunedhq.com/docs/05-references/intuned-json#configuration-properties.`);
132
130
  }
133
131
  const {
134
132
  startUrl,
135
133
  finishUrl
136
134
  } = intunedJson.authSessions;
137
135
  if (startUrl === undefined || finishUrl === undefined) {
138
- throw new _errors.CLIError(`Auth session type is recorder-based but start_url or finish_url is not set in ${await (0, _intunedJson.getIntunedSettingsFileName)()}`);
136
+ throw new _errors.CLIError(`AuthSession type is recorder-based but start_url or finish_url is not set in ${await (0, _intunedJson.getIntunedSettingsFileName)()}.
137
+ Please set both values to use recorder-based AuthSessions.
138
+ For more details, check out https://docs.intunedhq.com/docs/05-references/intuned-json#configuration-properties`);
139
139
  }
140
140
  return {
141
141
  startUrl,
142
142
  finishUrl
143
143
  };
144
+ }
145
+ async function getAuthNotEnabledErrorMessage() {
146
+ return "AuthSessions are not enabled.\n" + `Enable AuthSessions in ${await (0, _intunedJson.getIntunedSettingsFileName)()} to use this feature.\n` + "See https://docs.intunedhq.com/docs/02-features/auth-sessions#1-enable-authsessions-for-your-project for more information.";
144
147
  }
@@ -8,14 +8,22 @@ exports.getBaseUrl = getBaseUrl;
8
8
  var _constants = require("../../../common/constants");
9
9
  var _errors = require("./errors");
10
10
  var _intunedJson = require("./intunedJson");
11
+ var _prompts = require("./prompts");
11
12
  async function getAuthCredentials(options) {
12
- const workspaceId = options.workspaceId || (await (0, _intunedJson.loadIntunedJson)()).workspaceId;
13
- const apiKey = options.apiKey || process.env[_constants.API_KEY_ENV_VAR_KEY];
13
+ const settings = await (0, _intunedJson.loadIntunedJson)();
14
+ let workspaceId = options.workspaceId || settings.workspaceId || process.env[_constants.WORKSPACE_ID_ENV_VAR_KEY];
15
+ let apiKey = options.apiKey || process.env[_constants.API_KEY_ENV_VAR_KEY];
14
16
  if (!workspaceId) {
15
- throw new _errors.CLIError(`Workspace ID is required. Please provide it via command line options or ${await (0, _intunedJson.getIntunedSettingsFileName)()}`);
17
+ workspaceId = await (0, _prompts.promptForWorkspaceId)();
18
+ }
19
+ if (!workspaceId) {
20
+ throw new _errors.CLIError(`Workspace ID is required. Please provide it via command line options or ${await (0, _intunedJson.getIntunedSettingsFileName)()}.\n` + `Expected format: UUID (e.g., 123e4567-e89b-12d3-a456-426614174000)\n` + `Find your workspace ID at: https://app.intuned.io/settings/api-keys`);
21
+ }
22
+ if (!apiKey) {
23
+ apiKey = await (0, _prompts.promptForApiKey)();
16
24
  }
17
25
  if (!apiKey) {
18
- throw new _errors.CLIError(`API key is required. Please provide it via command line options or ${_constants.API_KEY_ENV_VAR_KEY} environment variable.`);
26
+ throw new _errors.CLIError(`API key is required. Please provide it via command line options or ${_constants.API_KEY_ENV_VAR_KEY} environment variable.\n` + `Get your API key at: https://app.intuned.io/settings/api-keys`);
19
27
  }
20
28
  return {
21
29
  workspaceId,
@@ -13,13 +13,13 @@ async function withCLIContext(fn, options) {
13
13
  async function getAuthSessionParameters() {
14
14
  const id = options?.authSessionId;
15
15
  if (!id) {
16
- throw new Error("getAuthSessionParameters cannot be called without using an auth session");
16
+ throw new Error("getAuthSessionParameters cannot be called without using an AuthSession");
17
17
  }
18
18
  const {
19
19
  metadata
20
20
  } = await (0, _auth.loadAuthSessionInstance)(id);
21
21
  if (metadata?.authSessionType === "MANUAL") {
22
- throw new Error("Auth session is recorder-based, it does not have parameters.");
22
+ throw new Error("AuthSession is recorder-based, it does not have parameters.");
23
23
  }
24
24
  return metadata?.authSessionInput ?? {};
25
25
  }
@@ -0,0 +1,3 @@
1
+ export declare function promptForProjectName(validate: (name: string) => boolean | string): Promise<string | undefined>;
2
+ export declare function promptForWorkspaceId(): Promise<string>;
3
+ export declare function promptForApiKey(): Promise<string>;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.promptForApiKey = promptForApiKey;
7
+ exports.promptForProjectName = promptForProjectName;
8
+ exports.promptForWorkspaceId = promptForWorkspaceId;
9
+ var _prompts = _interopRequireDefault(require("prompts"));
10
+ var _zod = require("zod");
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ async function promptForProjectName(validate) {
13
+ const {
14
+ projectName
15
+ } = await (0, _prompts.default)({
16
+ type: "text",
17
+ name: "projectName",
18
+ message: "Project name (required):",
19
+ validate
20
+ });
21
+ return projectName?.trim();
22
+ }
23
+ const workspaceIdSchema = _zod.z.string().uuid("Workspace ID must be a valid UUID");
24
+ async function promptForWorkspaceId() {
25
+ const {
26
+ workspaceId
27
+ } = await (0, _prompts.default)({
28
+ type: "text",
29
+ name: "workspaceId",
30
+ message: "Workspace ID (required):",
31
+ validate: value => {
32
+ const parsed = workspaceIdSchema.safeParse(String(value).trim());
33
+ return parsed.success ? true : parsed.error.errors[0].message;
34
+ }
35
+ });
36
+ return workspaceId.trim();
37
+ }
38
+ const apiKeySchema = _zod.z.string().min(1, "API Key cannot be empty").superRefine((val, ctx) => {
39
+ if (val.includes(" ")) {
40
+ ctx.addIssue({
41
+ code: "custom",
42
+ message: "API Key cannot contain spaces"
43
+ });
44
+ }
45
+ if (!val.startsWith("in1_")) {
46
+ ctx.addIssue({
47
+ code: "custom",
48
+ message: "API Key must start with 'in1_'"
49
+ });
50
+ }
51
+ if (val.length !== 36) {
52
+ ctx.addIssue({
53
+ code: "custom",
54
+ message: "API Key must be 36 characters long"
55
+ });
56
+ }
57
+ });
58
+ async function promptForApiKey() {
59
+ const {
60
+ apiKey
61
+ } = await (0, _prompts.default)({
62
+ type: "text",
63
+ name: "apiKey",
64
+ message: "API Key (required, get it at: https://app.intuned.io/settings/api-keys):",
65
+ validate: value => {
66
+ const parsed = apiKeySchema.safeParse(String(value).trim());
67
+ return parsed.success ? true : parsed.error.errors.map(e => e.message).join(", ");
68
+ }
69
+ });
70
+ return apiKey.trim();
71
+ }