@intuned/runtime-dev 1.3.0-responseLimits.1 → 1.3.1-api-token.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # UNRELEASED
2
2
 
3
- -
3
+ # 1.3.0
4
+ - Limit Automation response size to 2MB at MAX.
4
5
 
5
6
  # 1.2.0
6
7
 
Binary file
@@ -6,19 +6,16 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.deployCommand = void 0;
7
7
  var _command = require("./command");
8
8
  var _dotenv = _interopRequireDefault(require("dotenv"));
9
+ var _save = require("../controller/save");
9
10
  var _deploy = require("../controller/deploy");
10
11
  var _helpers = require("../helpers");
11
- var _zod = require("zod");
12
+ var _save2 = require("./save.command");
12
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
14
  _dotenv.default.config({
14
15
  path: `.env`
15
16
  });
16
- const deployCommandSchema = _zod.z.tuple([_zod.z.union([_zod.z.string(), _zod.z.undefined()]), _zod.z.object({
17
- workspaceId: _zod.z.string().optional(),
18
- apiKey: _zod.z.string().optional()
19
- })]);
20
- const deployCommand = exports.deployCommand = _command.program.command("deploy").description("Deploy an Intuned project to the platform").argument("[project-name]", "Name of the project to deploy").option("-w, --workspace-id <id>", "Your Intuned workspace ID").option("-k, --api-key <key>", "Your Intuned API key").action((0, _helpers.withErrorLogging)(async (inputProjectName, inputOptions) => {
21
- const parseResult = deployCommandSchema.safeParse([inputProjectName, inputOptions]);
17
+ const deployCommand = exports.deployCommand = _command.program.command("deploy").description("Save and deploy an Intuned project to the platform").argument("[project-name]", "Name of the project to deploy").option("-w, --workspace-id <id>", "Your Intuned workspace ID").option("-k, --api-key <key>", "Your Intuned API key").action((0, _helpers.withErrorLogging)(async (inputProjectName, inputOptions) => {
18
+ const parseResult = _save2.saveOrDeployCommandSchema.safeParse([inputProjectName, inputOptions]);
22
19
  if (!parseResult.success) {
23
20
  return (0, _helpers.logInvalidInput)(parseResult);
24
21
  }
@@ -26,7 +23,7 @@ const deployCommand = exports.deployCommand = _command.program.command("deploy")
26
23
  const {
27
24
  isValid,
28
25
  errorMessage
29
- } = await (0, _deploy.validateIntunedProject)();
26
+ } = await (0, _save.validateIntunedProject)();
30
27
  if (!isValid) {
31
28
  const message = `^r^+Project to be deployed is not a valid Intuned project:^:^R ${errorMessage}:\n`;
32
29
  throw new _helpers.CLIError(message, {
@@ -37,7 +34,7 @@ const deployCommand = exports.deployCommand = _command.program.command("deploy")
37
34
  if (!_projectName) {
38
35
  throw new _helpers.CLIError("Project name is required");
39
36
  }
40
- const projectNameValidation = (0, _deploy.validateProjectName)(_projectName);
37
+ const projectNameValidation = (0, _save.validateProjectName)(_projectName);
41
38
  if (!projectNameValidation.isValid) {
42
39
  throw new _helpers.CLIError(projectNameValidation.errorMessage);
43
40
  }
@@ -1,6 +1,7 @@
1
1
  export * from "./command";
2
2
  export * from "./build.command";
3
3
  export * from "./deploy.command";
4
+ export * from "./save.command";
4
5
  export * from "./init.command";
5
6
  export * from "./run.command";
6
7
  export * from "./run_api.command";
@@ -36,6 +36,17 @@ Object.keys(_deploy).forEach(function (key) {
36
36
  }
37
37
  });
38
38
  });
39
+ var _save = require("./save.command");
40
+ Object.keys(_save).forEach(function (key) {
41
+ if (key === "default" || key === "__esModule") return;
42
+ if (key in exports && exports[key] === _save[key]) return;
43
+ Object.defineProperty(exports, key, {
44
+ enumerable: true,
45
+ get: function () {
46
+ return _save[key];
47
+ }
48
+ });
49
+ });
39
50
  var _init = require("./init.command");
40
51
  Object.keys(_init).forEach(function (key) {
41
52
  if (key === "default" || key === "__esModule") return;
@@ -0,0 +1,12 @@
1
+ import { z } from "zod";
2
+ export declare const saveOrDeployCommandSchema: z.ZodTuple<[z.ZodUnion<[z.ZodString, z.ZodUndefined]>, z.ZodObject<{
3
+ workspaceId: z.ZodOptional<z.ZodString>;
4
+ apiKey: z.ZodOptional<z.ZodString>;
5
+ }, "strip", z.ZodTypeAny, {
6
+ workspaceId?: string | undefined;
7
+ apiKey?: string | undefined;
8
+ }, {
9
+ workspaceId?: string | undefined;
10
+ apiKey?: string | undefined;
11
+ }>], null>;
12
+ export declare const saveCommand: import("commander").Command;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.saveOrDeployCommandSchema = exports.saveCommand = void 0;
7
+ var _command = require("./command");
8
+ var _dotenv = _interopRequireDefault(require("dotenv"));
9
+ var _save = require("../controller/save");
10
+ var _helpers = require("../helpers");
11
+ var _zod = require("zod");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ _dotenv.default.config({
14
+ path: `.env`
15
+ });
16
+ const saveOrDeployCommandSchema = exports.saveOrDeployCommandSchema = _zod.z.tuple([_zod.z.union([_zod.z.string(), _zod.z.undefined()]), _zod.z.object({
17
+ workspaceId: _zod.z.string().optional(),
18
+ apiKey: _zod.z.string().optional()
19
+ })]);
20
+ const saveCommand = exports.saveCommand = _command.program.command("save").description("Save an Intuned project to the platform without deploying it").argument("[project-name]", "Name of the project to save").option("-w, --workspace-id <id>", "Your Intuned workspace ID").option("-k, --api-key <key>", "Your Intuned API key").action((0, _helpers.withErrorLogging)(async (inputProjectName, inputOptions) => {
21
+ const parseResult = saveOrDeployCommandSchema.safeParse([inputProjectName, inputOptions]);
22
+ if (!parseResult.success) {
23
+ return (0, _helpers.logInvalidInput)(parseResult);
24
+ }
25
+ const [projectName, options] = parseResult.data;
26
+ const {
27
+ isValid,
28
+ errorMessage
29
+ } = await (0, _save.validateIntunedProject)();
30
+ if (!isValid) {
31
+ const message = `^r^+Project to be saved is not a valid Intuned project:^:^R ${errorMessage}:\n`;
32
+ throw new _helpers.CLIError(message, {
33
+ autoColor: false
34
+ });
35
+ }
36
+ const _projectName = projectName || (await (0, _helpers.getSettingIntunedJSON)("projectName"));
37
+ if (!_projectName) {
38
+ throw new _helpers.CLIError("Project name is required");
39
+ }
40
+ const projectNameValidation = (0, _save.validateProjectName)(_projectName);
41
+ if (!projectNameValidation.isValid) {
42
+ throw new _helpers.CLIError(projectNameValidation.errorMessage);
43
+ }
44
+ const auth = await (0, _helpers.getAuthCredentials)(options);
45
+ await (0, _save.runSaveProject)(_projectName, auth);
46
+ }));
@@ -1,15 +1,4 @@
1
1
  import { z } from "zod";
2
- import type { AuthCredentials, FileSystemTree } from "../types";
3
- export declare function convertProjectToCodeTree(projectPath: string): Promise<FileSystemTree>;
2
+ import type { AuthCredentials } from "../types";
4
3
  export declare function runDeployProject(projectName: string, auth: AuthCredentials): Promise<void>;
5
4
  export declare const projectNameSchema: z.ZodEffects<z.ZodString, string, string>;
6
- export declare const validateProjectName: (projectName: string) => {
7
- isValid: true;
8
- } | {
9
- isValid: false;
10
- errorMessage: string;
11
- };
12
- export declare const validateIntunedProject: () => Promise<{
13
- isValid: boolean;
14
- errorMessage?: string;
15
- }>;
@@ -3,147 +3,31 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.convertProjectToCodeTree = convertProjectToCodeTree;
7
6
  exports.projectNameSchema = void 0;
8
7
  exports.runDeployProject = runDeployProject;
9
- exports.validateProjectName = exports.validateIntunedProject = void 0;
10
- var fs = _interopRequireWildcard(require("fs-extra"));
11
- var path = _interopRequireWildcard(require("path"));
12
- var _minimatch = require("minimatch");
13
8
  var _zod = require("zod");
14
- var _projectExclusions = _interopRequireDefault(require("../../common/projectExclusions"));
15
9
  var _constants = require("../constants");
16
10
  var _helpers = require("../helpers");
17
- var _lodash = require("lodash");
18
- var _uuid = require("uuid");
19
11
  var _terminal = require("../helpers/terminal");
20
12
  var _promises = require("timers/promises");
21
13
  var _ms = _interopRequireDefault(require("ms"));
22
- var _build = require("./build");
14
+ var _save = require("./save");
23
15
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
24
- 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); }
25
- 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; }
26
- function ignoreFilesByPattern(filePath, patterns, projectPath) {
27
- const relativePath = path.relative(projectPath, filePath);
28
- if (relativePath.startsWith("node_modules")) {
29
- return true;
30
- }
31
- for (const pattern of patterns) {
32
- if (!pattern || pattern.startsWith("#")) continue;
33
- if (pattern.startsWith("!")) {
34
- if ((0, _minimatch.minimatch)(relativePath, pattern.substring(1))) {
35
- return false;
36
- }
37
- } else if ((0, _minimatch.minimatch)(relativePath, pattern)) {
38
- return true;
39
- }
40
- }
41
- return false;
42
- }
43
- function listFilesNotIgnored(projectPath, ignorePatterns) {
44
- const results = [];
45
- function traverseDirectory(dirPath) {
46
- try {
47
- const entries = fs.readdirSync(dirPath);
48
- for (const entry of entries) {
49
- const fullPath = path.join(dirPath, entry);
50
- if (ignoreFilesByPattern(fullPath, ignorePatterns, projectPath)) {
51
- continue;
52
- }
53
- try {
54
- const stats = fs.statSync(fullPath);
55
- if (stats.isDirectory()) {
56
- traverseDirectory(fullPath);
57
- } else if (stats.isFile()) {
58
- results.push(path.relative(projectPath, fullPath));
59
- }
60
- } catch (error) {
61
- (0, _terminal.terminal)(`^yWarning: Could not access ${fullPath}^:\n`);
62
- }
63
- }
64
- } catch (error) {
65
- (0, _terminal.terminal)(`^YWarning: Could not read directory ${dirPath}^:\n`);
66
- }
67
- }
68
- traverseDirectory(projectPath);
69
- return results;
70
- }
71
- async function convertProjectToCodeTree(projectPath) {
72
- const filesToDeploy = listFilesNotIgnored(projectPath, _projectExclusions.default);
73
- const filesToDeployText = " " + filesToDeploy.join("\n ");
74
- (0, _terminal.terminal)("^CFiles to be deployed:^:\n");
75
- (0, _terminal.terminal)(filesToDeployText + "\n");
76
- function readDirectory(dirPath) {
77
- const tree = {};
78
- try {
79
- const entries = fs.readdirSync(dirPath);
80
- for (const entry of entries) {
81
- const entryPath = path.join(dirPath, entry);
82
- if (ignoreFilesByPattern(entryPath, _projectExclusions.default, projectPath)) {
83
- continue;
84
- }
85
- try {
86
- const stats = fs.statSync(entryPath);
87
- if (stats.isFile()) {
88
- try {
89
- const content = fs.readFileSync(entryPath, "utf-8");
90
- tree[entry] = {
91
- file: {
92
- contents: content
93
- }
94
- };
95
- } catch (error) {
96
- (0, _terminal.terminal)(`^yWarning: Could not read file ${entryPath}^:\n`);
97
- }
98
- } else if (stats.isDirectory()) {
99
- const subTree = readDirectory(entryPath);
100
- if (Object.keys(subTree).length > 0) {
101
- tree[entry] = {
102
- directory: subTree
103
- };
104
- }
105
- }
106
- } catch (error) {
107
- (0, _terminal.terminal)(`^yWarning: Could not access ${entryPath}^:\n`);
108
- }
109
- }
110
- } catch (error) {
111
- (0, _terminal.terminal)(`^YWarning: Could not read directory ${dirPath}^:\n`);
112
- }
113
- return tree;
114
- }
115
- const tree = readDirectory(projectPath);
116
- await mapToIDEParams(tree);
117
- return tree;
118
- }
119
16
  async function runDeployProject(projectName, auth) {
17
+ await (0, _save.runSaveProject)(projectName, auth);
120
18
  const {
121
19
  workspaceId,
122
20
  apiKey
123
21
  } = auth;
124
22
  const baseUrl = (0, _helpers.getBaseUrl)();
125
- const url = `${baseUrl}/api/v1/workspace/${workspaceId}/projects/create`;
23
+ const url = `${baseUrl}/api/v1/workspace/${workspaceId}/projects/${projectName}/deploy`;
126
24
  const headers = {
127
25
  "x-api-key": apiKey,
128
26
  "Content-Type": "application/json"
129
27
  };
130
- const projectPath = process.cwd();
131
- const codeTree = await convertProjectToCodeTree(projectPath);
132
- codeTree["tsconfig.json"] = {
133
- file: {
134
- contents: JSON.stringify(_constants.tsConfigCli, null, 2)
135
- }
136
- };
137
- const deployProjectPayload = {
138
- name: projectName,
139
- codeTree,
140
- isCli: true,
141
- language: "typescript"
142
- };
143
28
  const response = await fetch(url, {
144
29
  headers,
145
- method: "POST",
146
- body: JSON.stringify(deployProjectPayload)
30
+ method: "POST"
147
31
  });
148
32
  if (!response.ok) {
149
33
  if (response.status === 401) {
@@ -223,115 +107,9 @@ async function runDeployProject(projectName, auth) {
223
107
  const projectNameSchema = exports.projectNameSchema = _zod.z.string().min(1, "Project Name is required").max(50, "Name must be 50 characters or less").regex(/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/, "Name can only contain lowercase letters, numbers, hyphens, and underscores in between").refine(value => !_zod.z.string().uuid().safeParse(value).success, {
224
108
  message: "Name cannot be a UUID"
225
109
  });
226
- const validateProjectName = projectName => {
227
- const validation = projectNameSchema.safeParse(projectName);
228
- if (!validation.success) {
229
- return {
230
- isValid: false,
231
- errorMessage: validation.error.errors[0].message
232
- };
233
- }
234
- return {
235
- isValid: true
236
- };
237
- };
238
- exports.validateProjectName = validateProjectName;
239
- const validateIntunedProject = async () => {
240
- const currentDirectoryToDeploy = process.cwd();
241
- const validationSteps = [{
242
- name: "build",
243
- check: async () => {
244
- try {
245
- const buildResult = await (0, _build.runBuild)();
246
- if (!buildResult) {
247
- return {
248
- isValid: false,
249
- errorMessage: "Build failed"
250
- };
251
- }
252
- return {
253
- isValid: true
254
- };
255
- } catch (error) {
256
- return {
257
- isValid: false,
258
- errorMessage: "Build failed"
259
- };
260
- }
261
- }
262
- }, {
263
- name: "package.json",
264
- check: async () => {
265
- try {
266
- const packageJsonPath = path.join(currentDirectoryToDeploy, "package.json");
267
- await fs.exists(packageJsonPath);
268
- const packageJson = JSON.parse(await fs.readFile(packageJsonPath, {
269
- encoding: "utf-8"
270
- }));
271
- const userCodePlaywrightVersion = packageJson.dependencies?.playwright;
272
- if (userCodePlaywrightVersion !== _constants.CURRENT_PLAYWRIGHT_VERSION) {
273
- return {
274
- isValid: false,
275
- errorMessage: `Playwright version mismatch: expected ${_constants.CURRENT_PLAYWRIGHT_VERSION}, found ${userCodePlaywrightVersion || "none"}`
276
- };
277
- }
278
- return {
279
- isValid: true
280
- };
281
- } catch (error) {
282
- return {
283
- isValid: false,
284
- errorMessage: "Package.json file not found or cannot be read"
285
- };
286
- }
287
- }
288
- }, {
289
- name: "Intuned.json",
290
- check: async () => {
291
- try {
292
- const intunedJsonPath = path.join(currentDirectoryToDeploy, "Intuned.json");
293
- await fs.exists(intunedJsonPath);
294
- return {
295
- isValid: true
296
- };
297
- } catch (error) {
298
- return {
299
- isValid: false,
300
- errorMessage: "Intuned.json file not found"
301
- };
302
- }
303
- }
304
- }, {
305
- name: "api folder",
306
- check: async () => {
307
- try {
308
- const apiFolderPath = path.join(currentDirectoryToDeploy, "api");
309
- await fs.access(apiFolderPath);
310
- return {
311
- isValid: true
312
- };
313
- } catch (error) {
314
- return {
315
- isValid: false,
316
- errorMessage: "API folder not found"
317
- };
318
- }
319
- }
320
- }];
321
- for (const step of validationSteps) {
322
- const result = await step.check();
323
- if (!result.isValid) {
324
- return result;
325
- }
326
- }
327
- return {
328
- isValid: true
329
- };
330
- };
331
- exports.validateIntunedProject = validateIntunedProject;
332
110
  const checkIntunedProjectDeployStatus = async (workspaceId, projectName, apiKey) => {
333
111
  const baseUrl = (0, _helpers.getBaseUrl)();
334
- const url = `${baseUrl}/api/v1/workspace/${workspaceId}/projects/create/${projectName}/result`;
112
+ const url = `${baseUrl}/api/v1/workspace/${workspaceId}/projects/${projectName}/deploy/result`;
335
113
  const headers = {
336
114
  "x-api-key": apiKey,
337
115
  "Content-Type": "application/json"
@@ -357,58 +135,4 @@ const checkIntunedProjectDeployStatus = async (workspaceId, projectName, apiKey)
357
135
  status: "failed",
358
136
  message: `Deployment failed, please try again: ${data.message}`
359
137
  };
360
- };
361
- async function mapToIDEParams(tree) {
362
- if (!tree) {
363
- return;
364
- }
365
- if (!tree["parameters"] || "file" in tree["parameters"]) {
366
- return;
367
- }
368
- const apiParametersMap = {};
369
- const cliParameters = Object.keys(tree["parameters"].directory);
370
- const ____testParameters = {
371
- directory: {}
372
- };
373
- for (const parameterKey of cliParameters) {
374
- const parameter = tree["parameters"].directory[parameterKey];
375
- if ("directory" in parameter) {
376
- continue;
377
- }
378
- if ((0, _lodash.isEmpty)(parameter.file.contents)) {
379
- continue;
380
- }
381
- const parameterPayload = JSON.parse(parameter.file.contents);
382
- if (!parameterPayload["__api-name"]) {
383
- continue;
384
- }
385
- const api = parameterPayload["__api-name"];
386
- const {
387
- "__api-name": _,
388
- ...parameterValue
389
- } = parameterPayload;
390
- const testParameter = {
391
- name: parameterKey.replace(".json", ""),
392
- lastUsed: false,
393
- id: (0, _uuid.v4)(),
394
- value: JSON.stringify(parameterValue)
395
- };
396
- if (!apiParametersMap[api]) {
397
- apiParametersMap[api] = [];
398
- }
399
- apiParametersMap[api].push(testParameter);
400
- }
401
- for (const api in apiParametersMap) {
402
- if (apiParametersMap[api].length > 0) {
403
- apiParametersMap[api][apiParametersMap[api].length - 1].lastUsed = true;
404
- }
405
- ____testParameters.directory[`${api}.json`] = {
406
- file: {
407
- contents: JSON.stringify(apiParametersMap[api], null, 2)
408
- }
409
- };
410
- }
411
- delete tree["parameters"];
412
- tree["____testParameters"] = ____testParameters;
413
- return;
414
- }
138
+ };
@@ -0,0 +1,14 @@
1
+ import { z } from "zod";
2
+ import type { AuthCredentials } from "../types";
3
+ export declare function runSaveProject(projectName: string, auth: AuthCredentials): Promise<void>;
4
+ export declare const projectNameSchema: z.ZodEffects<z.ZodString, string, string>;
5
+ export declare const validateProjectName: (projectName: string) => {
6
+ isValid: true;
7
+ } | {
8
+ isValid: false;
9
+ errorMessage: string;
10
+ };
11
+ export declare const validateIntunedProject: () => Promise<{
12
+ isValid: boolean;
13
+ errorMessage?: string;
14
+ }>;
@@ -0,0 +1,365 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.projectNameSchema = void 0;
7
+ exports.runSaveProject = runSaveProject;
8
+ exports.validateProjectName = exports.validateIntunedProject = void 0;
9
+ var fs = _interopRequireWildcard(require("fs-extra"));
10
+ var path = _interopRequireWildcard(require("path"));
11
+ var _minimatch = require("minimatch");
12
+ var _zod = require("zod");
13
+ var _projectExclusions = _interopRequireDefault(require("../../common/projectExclusions"));
14
+ var _constants = require("../constants");
15
+ var _helpers = require("../helpers");
16
+ var _lodash = require("lodash");
17
+ var _uuid = require("uuid");
18
+ var _terminal = require("../helpers/terminal");
19
+ var _build = require("./build");
20
+ var dotenv = _interopRequireWildcard(require("dotenv"));
21
+ var _constants2 = require("../../../common/constants");
22
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
23
+ 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); }
24
+ 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; }
25
+ const saveProjectApiResponseSchema = _zod.z.string().transform((val, ctx) => {
26
+ try {
27
+ return JSON.parse(val);
28
+ } catch (e) {
29
+ ctx.addIssue({
30
+ code: _zod.z.ZodIssueCode.custom,
31
+ message: "Response is not valid JSON"
32
+ });
33
+ return _zod.z.NEVER;
34
+ }
35
+ }).pipe(_zod.z.object({
36
+ id: _zod.z.string().uuid()
37
+ }));
38
+ async function runSaveProject(projectName, auth) {
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
+ "x-api-key": apiKey,
47
+ "Content-Type": "application/json"
48
+ };
49
+ const projectPath = process.cwd();
50
+ const codeTree = await convertProjectToCodeTree(projectPath);
51
+ codeTree["tsconfig.json"] = {
52
+ file: {
53
+ contents: JSON.stringify(_constants.tsConfigCli, null, 2)
54
+ }
55
+ };
56
+ const deployProjectPayload = {
57
+ codeTree,
58
+ platformType: "CLI",
59
+ language: "typescript"
60
+ };
61
+ const response = await fetch(url, {
62
+ headers,
63
+ method: "PUT",
64
+ body: JSON.stringify(deployProjectPayload)
65
+ });
66
+ if (!response.ok) {
67
+ if (response.status === 401) {
68
+ throw new _helpers.CLIError(`Invalid API key. Please check your API key and try again.`);
69
+ }
70
+ throw new _helpers.CLIError(`^r^+Invalid response from server\n^:^R${response.status} ${await response.text()}^:\n^r^+Project deployment failed^:\n`, {
71
+ autoColor: false
72
+ });
73
+ }
74
+ (0, _terminal.terminal)("^g^+Project saved successfully!^:\n");
75
+ const body = await response.text();
76
+ const parseResult = saveProjectApiResponseSchema.safeParse(body);
77
+ if (!parseResult.success) {
78
+ (0, _terminal.terminal)(`^yWarning: Could not parse save project response:^:\n`);
79
+ (0, _terminal.terminal)(body + "\n");
80
+ return;
81
+ }
82
+ const {
83
+ id: projectId
84
+ } = parseResult.data;
85
+ const dotEnvPath = path.join(projectPath, ".env");
86
+ if (await fs.exists(dotEnvPath)) {
87
+ const envContent = await fs.readFile(dotEnvPath, "utf-8");
88
+ const dotenvContent = dotenv.parse(envContent);
89
+ let contentToAppend = "";
90
+ if (!dotenvContent[_constants2.PROJECT_ID_ENV_VAR_KEY] || dotenvContent[_constants2.PROJECT_ID_ENV_VAR_KEY] !== projectId) {
91
+ contentToAppend += `\n${_constants2.PROJECT_ID_ENV_VAR_KEY}=${projectId}`;
92
+ }
93
+ if (!dotenvContent[_constants2.WORKSPACE_ID_ENV_VAR_KEY]) {
94
+ contentToAppend += `\n${_constants2.WORKSPACE_ID_ENV_VAR_KEY}=${workspaceId}`;
95
+ }
96
+ if (!dotenvContent[_constants2.API_KEY_ENV_VAR_KEY]) {
97
+ contentToAppend += `\n${_constants2.API_KEY_ENV_VAR_KEY}=${apiKey}`;
98
+ }
99
+ if (contentToAppend) {
100
+ await fs.appendFile(dotEnvPath, contentToAppend + "\n");
101
+ (0, _terminal.terminal)(`^g^+Updated .env file with project credentials.^:\n`);
102
+ }
103
+ } else {
104
+ await fs.writeFile(dotEnvPath, `${_constants2.PROJECT_ID_ENV_VAR_KEY}=${projectId}
105
+ ${_constants2.WORKSPACE_ID_ENV_VAR_KEY}=${workspaceId}
106
+ ${_constants2.API_KEY_ENV_VAR_KEY}=${apiKey}`);
107
+ (0, _terminal.terminal)(`^g^+Created .env file with project credentials.^:\n`);
108
+ }
109
+ }
110
+ const projectNameSchema = exports.projectNameSchema = _zod.z.string().min(1, "Project Name is required").max(50, "Name must be 50 characters or less").regex(/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/, "Name can only contain lowercase letters, numbers, hyphens, and underscores in between").refine(value => !_zod.z.string().uuid().safeParse(value).success, {
111
+ message: "Name cannot be a UUID"
112
+ });
113
+ const validateProjectName = projectName => {
114
+ const validation = projectNameSchema.safeParse(projectName);
115
+ if (!validation.success) {
116
+ return {
117
+ isValid: false,
118
+ errorMessage: validation.error.errors[0].message
119
+ };
120
+ }
121
+ return {
122
+ isValid: true
123
+ };
124
+ };
125
+ exports.validateProjectName = validateProjectName;
126
+ const validateIntunedProject = async () => {
127
+ const currentDirectoryToDeploy = process.cwd();
128
+ const validationSteps = [{
129
+ name: "build",
130
+ check: async () => {
131
+ try {
132
+ const buildResult = await (0, _build.runBuild)();
133
+ if (!buildResult) {
134
+ return {
135
+ isValid: false,
136
+ errorMessage: "Build failed"
137
+ };
138
+ }
139
+ return {
140
+ isValid: true
141
+ };
142
+ } catch (error) {
143
+ return {
144
+ isValid: false,
145
+ errorMessage: "Build failed"
146
+ };
147
+ }
148
+ }
149
+ }, {
150
+ name: "package.json",
151
+ check: async () => {
152
+ try {
153
+ const packageJsonPath = path.join(currentDirectoryToDeploy, "package.json");
154
+ await fs.exists(packageJsonPath);
155
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, {
156
+ encoding: "utf-8"
157
+ }));
158
+ const userCodePlaywrightVersion = packageJson.dependencies?.playwright;
159
+ if (userCodePlaywrightVersion !== _constants.CURRENT_PLAYWRIGHT_VERSION) {
160
+ return {
161
+ isValid: false,
162
+ errorMessage: `Playwright version mismatch: expected ${_constants.CURRENT_PLAYWRIGHT_VERSION}, found ${userCodePlaywrightVersion || "none"}`
163
+ };
164
+ }
165
+ return {
166
+ isValid: true
167
+ };
168
+ } catch (error) {
169
+ return {
170
+ isValid: false,
171
+ errorMessage: "Package.json file not found or cannot be read"
172
+ };
173
+ }
174
+ }
175
+ }, {
176
+ name: "Intuned.json",
177
+ check: async () => {
178
+ try {
179
+ const intunedJsonPath = path.join(currentDirectoryToDeploy, "Intuned.json");
180
+ await fs.exists(intunedJsonPath);
181
+ return {
182
+ isValid: true
183
+ };
184
+ } catch (error) {
185
+ return {
186
+ isValid: false,
187
+ errorMessage: "Intuned.json file not found"
188
+ };
189
+ }
190
+ }
191
+ }, {
192
+ name: "api folder",
193
+ check: async () => {
194
+ try {
195
+ const apiFolderPath = path.join(currentDirectoryToDeploy, "api");
196
+ await fs.access(apiFolderPath);
197
+ return {
198
+ isValid: true
199
+ };
200
+ } catch (error) {
201
+ return {
202
+ isValid: false,
203
+ errorMessage: "API folder not found"
204
+ };
205
+ }
206
+ }
207
+ }];
208
+ for (const step of validationSteps) {
209
+ const result = await step.check();
210
+ if (!result.isValid) {
211
+ return result;
212
+ }
213
+ }
214
+ return {
215
+ isValid: true
216
+ };
217
+ };
218
+ exports.validateIntunedProject = validateIntunedProject;
219
+ function ignoreFilesByPattern(filePath, patterns, projectPath) {
220
+ const relativePath = path.relative(projectPath, filePath);
221
+ if (relativePath.startsWith("node_modules")) {
222
+ return true;
223
+ }
224
+ for (const pattern of patterns) {
225
+ if (!pattern || pattern.startsWith("#")) continue;
226
+ if (pattern.startsWith("!")) {
227
+ if ((0, _minimatch.minimatch)(relativePath, pattern.substring(1))) {
228
+ return false;
229
+ }
230
+ } else if ((0, _minimatch.minimatch)(relativePath, pattern)) {
231
+ return true;
232
+ }
233
+ }
234
+ return false;
235
+ }
236
+ function listFilesNotIgnored(projectPath, ignorePatterns) {
237
+ const results = [];
238
+ function traverseDirectory(dirPath) {
239
+ try {
240
+ const entries = fs.readdirSync(dirPath);
241
+ for (const entry of entries) {
242
+ const fullPath = path.join(dirPath, entry);
243
+ if (ignoreFilesByPattern(fullPath, ignorePatterns, projectPath)) {
244
+ continue;
245
+ }
246
+ try {
247
+ const stats = fs.statSync(fullPath);
248
+ if (stats.isDirectory()) {
249
+ traverseDirectory(fullPath);
250
+ } else if (stats.isFile()) {
251
+ results.push(path.relative(projectPath, fullPath));
252
+ }
253
+ } catch (error) {
254
+ (0, _terminal.terminal)(`^yWarning: Could not access ${fullPath}^:\n`);
255
+ }
256
+ }
257
+ } catch (error) {
258
+ (0, _terminal.terminal)(`^YWarning: Could not read directory ${dirPath}^:\n`);
259
+ }
260
+ }
261
+ traverseDirectory(projectPath);
262
+ return results;
263
+ }
264
+ async function convertProjectToCodeTree(projectPath) {
265
+ const filesToDeploy = listFilesNotIgnored(projectPath, _projectExclusions.default);
266
+ const filesToDeployText = " " + filesToDeploy.join("\n ");
267
+ (0, _terminal.terminal)("^CFiles to be saved:^:\n");
268
+ (0, _terminal.terminal)(filesToDeployText + "\n");
269
+ function readDirectory(dirPath) {
270
+ const tree = {};
271
+ try {
272
+ const entries = fs.readdirSync(dirPath);
273
+ for (const entry of entries) {
274
+ const entryPath = path.join(dirPath, entry);
275
+ if (ignoreFilesByPattern(entryPath, _projectExclusions.default, projectPath)) {
276
+ continue;
277
+ }
278
+ try {
279
+ const stats = fs.statSync(entryPath);
280
+ if (stats.isFile()) {
281
+ try {
282
+ const content = fs.readFileSync(entryPath, "utf-8");
283
+ tree[entry] = {
284
+ file: {
285
+ contents: content
286
+ }
287
+ };
288
+ } catch (error) {
289
+ (0, _terminal.terminal)(`^yWarning: Could not read file ${entryPath}^:\n`);
290
+ }
291
+ } else if (stats.isDirectory()) {
292
+ const subTree = readDirectory(entryPath);
293
+ if (Object.keys(subTree).length > 0) {
294
+ tree[entry] = {
295
+ directory: subTree
296
+ };
297
+ }
298
+ }
299
+ } catch (error) {
300
+ (0, _terminal.terminal)(`^yWarning: Could not access ${entryPath}^:\n`);
301
+ }
302
+ }
303
+ } catch (error) {
304
+ (0, _terminal.terminal)(`^YWarning: Could not read directory ${dirPath}^:\n`);
305
+ }
306
+ return tree;
307
+ }
308
+ const tree = readDirectory(projectPath);
309
+ mapToIDEParams(tree);
310
+ return tree;
311
+ }
312
+ function mapToIDEParams(tree) {
313
+ if (!tree) {
314
+ return;
315
+ }
316
+ if (!tree["parameters"] || "file" in tree["parameters"]) {
317
+ return;
318
+ }
319
+ const apiParametersMap = {};
320
+ const cliParameters = Object.keys(tree["parameters"].directory);
321
+ const ____testParameters = {
322
+ directory: {}
323
+ };
324
+ for (const parameterKey of cliParameters) {
325
+ const parameter = tree["parameters"].directory[parameterKey];
326
+ if ("directory" in parameter) {
327
+ continue;
328
+ }
329
+ if ((0, _lodash.isEmpty)(parameter.file.contents)) {
330
+ continue;
331
+ }
332
+ const parameterPayload = JSON.parse(parameter.file.contents);
333
+ if (!parameterPayload["__api-name"]) {
334
+ continue;
335
+ }
336
+ const api = parameterPayload["__api-name"];
337
+ const {
338
+ "__api-name": _,
339
+ ...parameterValue
340
+ } = parameterPayload;
341
+ const testParameter = {
342
+ name: parameterKey.replace(".json", ""),
343
+ lastUsed: false,
344
+ id: (0, _uuid.v4)(),
345
+ value: JSON.stringify(parameterValue)
346
+ };
347
+ if (!apiParametersMap[api]) {
348
+ apiParametersMap[api] = [];
349
+ }
350
+ apiParametersMap[api].push(testParameter);
351
+ }
352
+ for (const api in apiParametersMap) {
353
+ if (apiParametersMap[api].length > 0) {
354
+ apiParametersMap[api][apiParametersMap[api].length - 1].lastUsed = true;
355
+ }
356
+ ____testParameters.directory[`${api}.json`] = {
357
+ file: {
358
+ contents: JSON.stringify(apiParametersMap[api], null, 2)
359
+ }
360
+ };
361
+ }
362
+ delete tree["parameters"];
363
+ tree["____testParameters"] = ____testParameters;
364
+ return;
365
+ }
@@ -5,16 +5,17 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.getAuthCredentials = getAuthCredentials;
7
7
  exports.getBaseUrl = getBaseUrl;
8
+ var _constants = require("../../../common/constants");
8
9
  var _errors = require("./errors");
9
10
  var _intunedJson = require("./intunedJson");
10
11
  async function getAuthCredentials(options) {
11
12
  const workspaceId = options.workspaceId || (await (0, _intunedJson.getSettingIntunedJSON)("workspaceId"));
12
- const apiKey = options.apiKey || process.env.INTUNED_API_KEY;
13
+ const apiKey = options.apiKey || process.env[_constants.API_KEY_ENV_VAR_KEY];
13
14
  if (!workspaceId) {
14
15
  throw new _errors.CLIError("Workspace ID is required. Please provide it via command line options or Intuned.json");
15
16
  }
16
17
  if (!apiKey) {
17
- throw new _errors.CLIError("API key is required. Please provide it via command line options or INTUNED_API_KEY environment variable.");
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.`);
18
19
  }
19
20
  return {
20
21
  workspaceId,
@@ -1,3 +1,6 @@
1
1
  export declare const API_FOLDER_NAME = "api";
2
2
  export declare const AUTH_SESSIONS_FOLDER_NAME = "auth-sessions";
3
3
  export declare const AUTH_SESSIONS_INSTANCES_FOLDER_NAME = "auth-sessions-instances";
4
+ export declare const WORKSPACE_ID_ENV_VAR_KEY = "INTUNED_WORKSPACE_ID";
5
+ export declare const PROJECT_ID_ENV_VAR_KEY = "INTUNED_PROJECT_ID";
6
+ export declare const API_KEY_ENV_VAR_KEY = "INTUNED_API_KEY";
@@ -3,7 +3,10 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.AUTH_SESSIONS_INSTANCES_FOLDER_NAME = exports.AUTH_SESSIONS_FOLDER_NAME = exports.API_FOLDER_NAME = void 0;
6
+ exports.WORKSPACE_ID_ENV_VAR_KEY = exports.PROJECT_ID_ENV_VAR_KEY = exports.AUTH_SESSIONS_INSTANCES_FOLDER_NAME = exports.AUTH_SESSIONS_FOLDER_NAME = exports.API_KEY_ENV_VAR_KEY = exports.API_FOLDER_NAME = void 0;
7
7
  const API_FOLDER_NAME = exports.API_FOLDER_NAME = "api";
8
8
  const AUTH_SESSIONS_FOLDER_NAME = exports.AUTH_SESSIONS_FOLDER_NAME = "auth-sessions";
9
- const AUTH_SESSIONS_INSTANCES_FOLDER_NAME = exports.AUTH_SESSIONS_INSTANCES_FOLDER_NAME = "auth-sessions-instances";
9
+ const AUTH_SESSIONS_INSTANCES_FOLDER_NAME = exports.AUTH_SESSIONS_INSTANCES_FOLDER_NAME = "auth-sessions-instances";
10
+ const WORKSPACE_ID_ENV_VAR_KEY = exports.WORKSPACE_ID_ENV_VAR_KEY = "INTUNED_WORKSPACE_ID";
11
+ const PROJECT_ID_ENV_VAR_KEY = exports.PROJECT_ID_ENV_VAR_KEY = "INTUNED_PROJECT_ID";
12
+ const API_KEY_ENV_VAR_KEY = exports.API_KEY_ENV_VAR_KEY = "INTUNED_API_KEY";
@@ -10,6 +10,7 @@ declare class JwtTokenManager {
10
10
  private scheduleTokenRefresh;
11
11
  private refreshToken;
12
12
  fetchWithToken(...[input, init]: Parameters<typeof fetch>): Promise<Response>;
13
+ get backendFunctionsBaseUrl(): string;
13
14
  }
14
15
  export declare const backendFunctionsTokenManager: JwtTokenManager;
15
16
  export declare function callBackendFunctionWithToken(path: string, init?: Parameters<typeof fetch>[1]): Promise<Response>;
@@ -8,6 +8,7 @@ exports.callBackendFunctionWithToken = callBackendFunctionWithToken;
8
8
  var _crossFetch = _interopRequireDefault(require("cross-fetch"));
9
9
  var jwt = _interopRequireWildcard(require("jsonwebtoken"));
10
10
  var _neverthrow = require("neverthrow");
11
+ var _constants = require("./constants");
11
12
  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); }
12
13
  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; }
13
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -51,7 +52,7 @@ class JwtTokenManager {
51
52
  }
52
53
  async refreshToken() {
53
54
  if (process.env.RUN_ENVIRONMENT?.toLowerCase() !== "authoring") return;
54
- const res = await this.fetchWithToken(this.refreshTokenPath, {
55
+ const res = await this.fetchWithToken(`${this.backendFunctionsBaseUrl}/refreshBackendFunctionsToken`, {
55
56
  method: "GET"
56
57
  });
57
58
  if (res.status === 401) {
@@ -70,10 +71,18 @@ class JwtTokenManager {
70
71
  headers
71
72
  });
72
73
  }
74
+ get backendFunctionsBaseUrl() {
75
+ if (!process.env.FUNCTIONS_DOMAIN || !process.env[_constants.WORKSPACE_ID_ENV_VAR_KEY]) {
76
+ throw new Error(`Cannot call backend function - FUNCTIONS_DOMAIN or ${_constants.WORKSPACE_ID_ENV_VAR_KEY} not set`);
77
+ }
78
+ if (!process.env[_constants.PROJECT_ID_ENV_VAR_KEY] && !process.env.INTUNED_INTEGRATION_ID) {
79
+ throw new Error(`Cannot call backend function - ${_constants.PROJECT_ID_ENV_VAR_KEY} or INTUNED_INTEGRATION_ID not set`);
80
+ }
81
+ return `${process.env.FUNCTIONS_DOMAIN}/api/${process.env[_constants.WORKSPACE_ID_ENV_VAR_KEY]}/functions/${process.env[_constants.PROJECT_ID_ENV_VAR_KEY] ?? process.env.INTUNED_INTEGRATION_ID}`;
82
+ }
73
83
  }
74
- const backendFunctionsPath = `${process.env.FUNCTIONS_DOMAIN}/api/${process.env.INTUNED_WORKSPACE_ID}/functions/${process.env.INTUNED_INTEGRATION_ID}`;
75
- const backendFunctionsTokenManager = exports.backendFunctionsTokenManager = new JwtTokenManager(`${backendFunctionsPath}/refreshBackendFunctionsToken`);
84
+ const backendFunctionsTokenManager = exports.backendFunctionsTokenManager = new JwtTokenManager(`refreshBackendFunctionsToken`);
76
85
  backendFunctionsTokenManager.token = process.env.INTUNED_AUTHORING_SESSION_BACKEND_FUNCTIONS_TOKEN;
77
86
  function callBackendFunctionWithToken(path, init) {
78
- return backendFunctionsTokenManager.fetchWithToken(`${backendFunctionsPath}/${path}`, init);
87
+ return backendFunctionsTokenManager.fetchWithToken(`${backendFunctionsTokenManager.backendFunctionsBaseUrl}/${path}`, init);
79
88
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intuned/runtime-dev",
3
- "version": "1.3.0-responseLimits.1",
3
+ "version": "1.3.1-api-token.0",
4
4
  "description": "Intuned runtime",
5
5
  "exports": {
6
6
  ".": "./dist/index.js",
@@ -90,9 +90,7 @@
90
90
  "typescript": "5.1.6",
91
91
  "uuid": "11.1.0",
92
92
  "wait-on": "7.2.0",
93
- "zod": "^3.21.4",
94
- "playwright": "^1.44.0",
95
- "playwright-core": "^1.44.0"
93
+ "zod": "^3.21.4"
96
94
  },
97
95
  "devDependencies": {
98
96
  "@babel/cli": "^7.23.4",