@intuned/runtime-dev 1.3.17-ws.0 → 1.3.18-dev.2
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/.babelrc +6 -0
- package/CHANGELOG.md +1 -1
- package/InterfaceTemplate/{utils.ts → __utils.ts} +3 -1
- package/InterfaceTemplate/index.playwright.ts +1 -1
- package/bin/intuned +0 -0
- package/bin/intuned-interface +7 -0
- package/dist/commands/api/run.js +7 -11
- package/dist/commands/auth-sessions/load.js +2 -2
- package/dist/commands/auth-sessions/run-check.js +8 -8
- package/dist/commands/auth-sessions/run-create.js +6 -6
- package/dist/commands/build.js +2 -3
- package/dist/commands/common/browserUtils.d.ts +3 -3
- package/dist/commands/common/browserUtils.js +3 -4
- package/dist/commands/common/getFirstLineNumber.test.js +1 -2
- package/dist/commands/common/projectExclusions.js +1 -1
- package/dist/commands/common/tsNodeImport.d.ts +1 -1
- package/dist/commands/common/tsNodeImport.js +10 -2
- package/dist/commands/common/utils/fileUtils.js +1 -2
- package/dist/commands/common/utils/{unixSocket.d.ts → interfaceClient.d.ts} +10 -2
- package/dist/commands/common/utils/{unixSocket.js → interfaceClient.js} +16 -5
- package/dist/commands/common/utils/template.js +1 -2
- package/dist/commands/interface/run.js +23 -49
- package/dist/commands/intuned-cli/commands/attempt_api.command.js +1 -1
- package/dist/commands/intuned-cli/commands/attempt_authsession.command.js +1 -1
- package/dist/commands/intuned-cli/commands/attempt_authsession_check.command.js +2 -2
- package/dist/commands/intuned-cli/commands/attempt_authsession_create.command.js +1 -1
- package/dist/commands/intuned-cli/commands/authsession.command.js +1 -1
- package/dist/commands/intuned-cli/commands/authsession_record.command.js +1 -1
- package/dist/commands/intuned-cli/commands/authsession_scaffold.command.d.ts +1 -0
- package/dist/commands/intuned-cli/commands/authsession_scaffold.command.js +16 -0
- package/dist/commands/intuned-cli/commands/deploy.command.js +13 -9
- package/dist/commands/intuned-cli/commands/index.d.ts +2 -2
- package/dist/commands/intuned-cli/commands/index.js +15 -15
- package/dist/commands/intuned-cli/commands/{save.command.d.ts → provision.command.d.ts} +3 -3
- package/dist/commands/intuned-cli/commands/provision.command.js +50 -0
- package/dist/commands/intuned-cli/commands/run_api.command.js +1 -1
- package/dist/commands/intuned-cli/commands/run_authsession.command.d.ts +8 -1
- package/dist/commands/intuned-cli/commands/run_authsession.command.js +2 -2
- package/dist/commands/intuned-cli/commands/run_authsession_create.command.js +1 -1
- package/dist/commands/intuned-cli/commands/run_authsession_update.command.js +2 -2
- package/dist/commands/intuned-cli/commands/run_authsession_validate.command.js +2 -2
- package/dist/commands/intuned-cli/commands/types.d.ts +9 -1
- package/dist/commands/intuned-cli/commands/types.js +9 -5
- package/dist/commands/intuned-cli/controller/__test__/api.test.js +30 -19
- package/dist/commands/intuned-cli/controller/__test__/authSession.test.js +140 -77
- package/dist/commands/intuned-cli/controller/api.d.ts +2 -2
- package/dist/commands/intuned-cli/controller/api.js +6 -3
- package/dist/commands/intuned-cli/controller/authSession.d.ts +16 -16
- package/dist/commands/intuned-cli/controller/authSession.js +50 -39
- package/dist/commands/intuned-cli/controller/build.js +1 -2
- package/dist/commands/intuned-cli/controller/deploy.js +53 -12
- package/dist/commands/intuned-cli/controller/index.js +2 -3
- package/dist/commands/intuned-cli/controller/{save.d.ts → provision.d.ts} +5 -1
- package/dist/commands/intuned-cli/controller/provision.js +299 -0
- package/dist/commands/intuned-cli/controller/scaffold.d.ts +1 -0
- package/dist/commands/intuned-cli/controller/scaffold.js +77 -0
- package/dist/commands/intuned-cli/helpers/__test__/browser.test.js +45 -5
- package/dist/commands/intuned-cli/helpers/__test__/tracing.test.js +4 -3
- package/dist/commands/intuned-cli/helpers/api.js +4 -7
- package/dist/commands/intuned-cli/helpers/auth.d.ts +4 -4
- package/dist/commands/intuned-cli/helpers/auth.js +24 -21
- package/dist/commands/intuned-cli/helpers/backend.js +12 -4
- package/dist/commands/intuned-cli/helpers/browser.d.ts +4 -4
- package/dist/commands/intuned-cli/helpers/browser.js +40 -5
- package/dist/commands/intuned-cli/helpers/context.js +2 -2
- package/dist/commands/intuned-cli/helpers/errors.d.ts +1 -1
- package/dist/commands/intuned-cli/helpers/errors.js +2 -2
- package/dist/commands/intuned-cli/helpers/intunedJson.d.ts +6 -5
- package/dist/commands/intuned-cli/helpers/prompts.d.ts +3 -0
- package/dist/commands/intuned-cli/helpers/prompts.js +71 -0
- package/dist/commands/intuned-cli/helpers/timeout.js +2 -2
- package/dist/commands/intuned-cli/helpers/traces.d.ts +1 -1
- package/dist/commands/intuned-cli/helpers/wrapper.js +14 -4
- package/dist/commands/intuned-cli/main.js +1 -2
- package/dist/commands/intuned-cli/types.d.ts +41 -12
- package/dist/commands/intuned-cli/types.js +12 -2
- package/dist/commands/ts-check.js +1 -2
- package/dist/common/backendFunctions/getAuthSessionParameters.js +1 -1
- package/dist/common/binStartupScript.js +1 -2
- package/dist/common/browserTabs.d.ts +72 -0
- package/dist/common/browserTabs.js +74 -0
- package/dist/common/constants.d.ts +1 -0
- package/dist/common/constants.js +2 -1
- package/dist/common/contextStorageStateHelpers.d.ts +4 -3
- package/dist/common/contextStorageStateHelpers.js +4 -1
- package/dist/common/extension/extensionsHelpers.d.ts +1 -1
- package/dist/common/extension/types.d.ts +14 -7
- package/dist/common/formatZodError.d.ts +1 -1
- package/dist/common/intunedJson.d.ts +19 -14
- package/dist/common/intunedJson.js +4 -4
- package/dist/common/jwtTokenManager.js +10 -6
- package/dist/common/launchBrowser.d.ts +10 -0
- package/dist/common/launchBrowser.js +67 -7
- package/dist/common/playwrightContext.d.ts +5 -5
- package/dist/common/playwrightContext.js +24 -14
- package/dist/common/runApi/importUsingImportFunction.d.ts +1 -3
- package/dist/common/runApi/importUsingImportFunction.js +7 -7
- package/dist/common/runApi/index.d.ts +3 -6
- package/dist/common/runApi/index.js +28 -52
- package/dist/common/settingsSchema.d.ts +52 -45
- package/dist/common/settingsSchema.js +3 -3
- package/dist/common/setupContextHook.d.ts +1 -2
- package/dist/common/setupContextHook.js +2 -2
- package/dist/common/telemetry.js +1 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -7
- package/dist/runtime/downloadDirectory.js +2 -2
- package/dist/vendor/runtime-interface.d.ts +1 -0
- package/dist/vendor/runtime-interface.js +493 -0
- package/package.json +19 -11
- package/tsup.config.ts +12 -0
- package/WebTemplate.zip +0 -0
- package/dist/commands/intuned-cli/commands/init.command.d.ts +0 -1
- package/dist/commands/intuned-cli/commands/init.command.js +0 -13
- package/dist/commands/intuned-cli/commands/save.command.js +0 -42
- package/dist/commands/intuned-cli/controller/save.js +0 -357
- package/dist/common/runApi/errors.d.ts +0 -72
- package/dist/common/runApi/errors.js +0 -169
- package/dist/common/runApi/types.d.ts +0 -830
- package/dist/common/runApi/types.js +0 -73
|
@@ -0,0 +1,299 @@
|
|
|
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 _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
22
|
+
const provisionProjectApiResponseSchema = _zod.z.string().transform((val, ctx) => {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(val);
|
|
25
|
+
} catch (e) {
|
|
26
|
+
ctx.addIssue({
|
|
27
|
+
code: _zod.z.ZodIssueCode.custom,
|
|
28
|
+
message: "Response is not valid JSON"
|
|
29
|
+
});
|
|
30
|
+
return _zod.z.NEVER;
|
|
31
|
+
}
|
|
32
|
+
}).pipe(_zod.z.object({
|
|
33
|
+
id: _zod.z.string().uuid(),
|
|
34
|
+
enableFirstRunExperience: _zod.z.boolean().optional(),
|
|
35
|
+
environmentVariablesKeys: _zod.z.array(_zod.z.string()).default([]).catch(() => [])
|
|
36
|
+
}));
|
|
37
|
+
async function runProvisionProject(projectName, auth, silent = false) {
|
|
38
|
+
const {
|
|
39
|
+
workspaceId,
|
|
40
|
+
apiKey
|
|
41
|
+
} = auth;
|
|
42
|
+
const baseUrl = (0, _helpers.getBaseUrl)();
|
|
43
|
+
const url = `${baseUrl}/api/v1/workspace/${workspaceId}/projects/${projectName}`;
|
|
44
|
+
const headers = {
|
|
45
|
+
[_constants2.API_KEY_HEADER_NAME]: apiKey,
|
|
46
|
+
"Content-Type": "application/json"
|
|
47
|
+
};
|
|
48
|
+
const projectPath = process.cwd();
|
|
49
|
+
const codeTree = await convertProjectToCodeTree(projectPath);
|
|
50
|
+
const intunedSettingsFile = await (0, _helpers.getIntunedSettingsFile)();
|
|
51
|
+
codeTree["Intuned.json"] = {
|
|
52
|
+
file: {
|
|
53
|
+
contents: JSON.stringify(intunedSettingsFile.parse(await fs.readFile(intunedSettingsFile.path, "utf-8")))
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
codeTree["tsconfig.json"] = {
|
|
57
|
+
file: {
|
|
58
|
+
contents: JSON.stringify(_constants.tsConfigCli, null, 2)
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const upsertProjectPayload = {
|
|
62
|
+
codeTree,
|
|
63
|
+
platformType: "CLI",
|
|
64
|
+
language: "typescript"
|
|
65
|
+
};
|
|
66
|
+
const response = await fetch(url, {
|
|
67
|
+
headers,
|
|
68
|
+
method: "PUT",
|
|
69
|
+
body: JSON.stringify(upsertProjectPayload)
|
|
70
|
+
});
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
if (response.status === 401) {
|
|
73
|
+
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`);
|
|
74
|
+
}
|
|
75
|
+
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`, {
|
|
76
|
+
autoColor: false
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (!silent) {
|
|
80
|
+
(0, _terminal.terminal)("^g^+Project provisioned successfully!^:\n");
|
|
81
|
+
}
|
|
82
|
+
const body = await response.text();
|
|
83
|
+
const parseResult = provisionProjectApiResponseSchema.safeParse(body);
|
|
84
|
+
if (!parseResult.success) {
|
|
85
|
+
(0, _terminal.terminal)(`^yWarning: Could not parse provision project response:^:\n`);
|
|
86
|
+
(0, _terminal.terminal)(body + "\n");
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const {
|
|
90
|
+
id: projectId,
|
|
91
|
+
enableFirstRunExperience,
|
|
92
|
+
environmentVariablesKeys
|
|
93
|
+
} = parseResult.data;
|
|
94
|
+
const dotEnvPath = path.join(projectPath, ".env");
|
|
95
|
+
if (!(await fs.exists(dotEnvPath))) {
|
|
96
|
+
await fs.writeFile(dotEnvPath, `${_constants2.PROJECT_ID_ENV_VAR_KEY}=${projectId}
|
|
97
|
+
${_constants2.WORKSPACE_ID_ENV_VAR_KEY}=${workspaceId}
|
|
98
|
+
${_constants2.API_KEY_ENV_VAR_KEY}=${apiKey}`);
|
|
99
|
+
(0, _terminal.terminal)(`^g^+Created .env file with project credentials.^:\n`);
|
|
100
|
+
return {
|
|
101
|
+
projectId,
|
|
102
|
+
enableFirstRunExperience,
|
|
103
|
+
environmentVariablesKeys,
|
|
104
|
+
dotenvContent: {}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const envContent = await fs.readFile(dotEnvPath, "utf-8");
|
|
108
|
+
const dotenvContent = dotenv.parse(envContent);
|
|
109
|
+
let contentToAppend = "";
|
|
110
|
+
const projectCredentialsEnvVars = {
|
|
111
|
+
[_constants2.PROJECT_ID_ENV_VAR_KEY]: projectId,
|
|
112
|
+
[_constants2.WORKSPACE_ID_ENV_VAR_KEY]: workspaceId,
|
|
113
|
+
[_constants2.API_KEY_ENV_VAR_KEY]: apiKey
|
|
114
|
+
};
|
|
115
|
+
for (const key in projectCredentialsEnvVars) {
|
|
116
|
+
if (dotenvContent[key] === projectCredentialsEnvVars[key]) {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (dotenvContent[key]) {
|
|
120
|
+
(0, _terminal.terminal)(`^yWarning: Existing ${key} in .env has invalid value. Appending correct value.^:\n`);
|
|
121
|
+
}
|
|
122
|
+
contentToAppend += `${key}=${projectCredentialsEnvVars[key]}\n`;
|
|
123
|
+
}
|
|
124
|
+
if (contentToAppend) {
|
|
125
|
+
await fs.appendFile(dotEnvPath, contentToAppend + "\n");
|
|
126
|
+
(0, _terminal.terminal)(`^g^+Updated .env file with project credentials.^:\n`);
|
|
127
|
+
}
|
|
128
|
+
const dotenvContentToReturn = {
|
|
129
|
+
...dotenvContent
|
|
130
|
+
};
|
|
131
|
+
for (const key of [_constants2.PROJECT_ID_ENV_VAR_KEY, _constants2.WORKSPACE_ID_ENV_VAR_KEY, _constants2.API_KEY_ENV_VAR_KEY]) {
|
|
132
|
+
if (key in dotenvContentToReturn) {
|
|
133
|
+
delete dotenvContentToReturn[key];
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
projectId,
|
|
138
|
+
enableFirstRunExperience,
|
|
139
|
+
environmentVariablesKeys,
|
|
140
|
+
dotenvContent: dotenvContentToReturn
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
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, {
|
|
144
|
+
message: "Cannot be a UUID"
|
|
145
|
+
});
|
|
146
|
+
const validateProjectName = projectName => {
|
|
147
|
+
const validation = projectNameSchema.safeParse(projectName);
|
|
148
|
+
if (!validation.success) {
|
|
149
|
+
return {
|
|
150
|
+
isValid: false,
|
|
151
|
+
errorMessage: validation.error.errors[0].message
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
isValid: true
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
exports.validateProjectName = validateProjectName;
|
|
159
|
+
const validateIntunedProject = async () => {
|
|
160
|
+
const currentDirectoryToProvision = process.cwd();
|
|
161
|
+
const intunedSettingsFile = await (0, _helpers.getIntunedSettingsFile)();
|
|
162
|
+
const validationSteps = [{
|
|
163
|
+
name: "build",
|
|
164
|
+
check: async () => {
|
|
165
|
+
try {
|
|
166
|
+
const buildResult = await (0, _build.runBuild)();
|
|
167
|
+
if (!buildResult) {
|
|
168
|
+
return {
|
|
169
|
+
isValid: false,
|
|
170
|
+
errorMessage: "Build failed"
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
isValid: true
|
|
175
|
+
};
|
|
176
|
+
} catch (error) {
|
|
177
|
+
return {
|
|
178
|
+
isValid: false,
|
|
179
|
+
errorMessage: "Build failed"
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}, {
|
|
184
|
+
name: intunedSettingsFile.name,
|
|
185
|
+
check: async () => {
|
|
186
|
+
try {
|
|
187
|
+
const intunedJsonPath = path.join(currentDirectoryToProvision, intunedSettingsFile.name);
|
|
188
|
+
await fs.exists(intunedJsonPath);
|
|
189
|
+
return {
|
|
190
|
+
isValid: true
|
|
191
|
+
};
|
|
192
|
+
} catch (error) {
|
|
193
|
+
return {
|
|
194
|
+
isValid: false,
|
|
195
|
+
errorMessage: `${intunedSettingsFile.name} file not found`
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}, {
|
|
200
|
+
name: "api folder",
|
|
201
|
+
check: async () => {
|
|
202
|
+
try {
|
|
203
|
+
const apiFolderPath = path.join(currentDirectoryToProvision, "api");
|
|
204
|
+
await fs.access(apiFolderPath);
|
|
205
|
+
return {
|
|
206
|
+
isValid: true
|
|
207
|
+
};
|
|
208
|
+
} catch (error) {
|
|
209
|
+
return {
|
|
210
|
+
isValid: false,
|
|
211
|
+
errorMessage: "API folder not found"
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}];
|
|
216
|
+
for (const step of validationSteps) {
|
|
217
|
+
const result = await step.check();
|
|
218
|
+
if (!result.isValid) {
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
isValid: true
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
exports.validateIntunedProject = validateIntunedProject;
|
|
227
|
+
async function convertProjectToCodeTree(projectPath) {
|
|
228
|
+
const ig = (0, _ignore.default)();
|
|
229
|
+
const gitIgnorePath = await findGitIgnoreFile(projectPath);
|
|
230
|
+
if (gitIgnorePath) {
|
|
231
|
+
const gitIgnoreContent = await fs.readFile(gitIgnorePath, "utf-8");
|
|
232
|
+
ig.add(gitIgnoreContent);
|
|
233
|
+
}
|
|
234
|
+
ig.add(_projectExclusions.default);
|
|
235
|
+
async function traverse(dirPath) {
|
|
236
|
+
const tree = {};
|
|
237
|
+
const fileNames = [];
|
|
238
|
+
const entries = await fs.readdir(dirPath, {
|
|
239
|
+
withFileTypes: true
|
|
240
|
+
});
|
|
241
|
+
for (const entry of entries) {
|
|
242
|
+
const entryPath = path.join(dirPath, entry.name);
|
|
243
|
+
if (ig.ignores(path.relative(projectPath, entryPath))) {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
if (entry.isFile()) {
|
|
247
|
+
try {
|
|
248
|
+
const content = await fs.readFile(entryPath, "utf-8");
|
|
249
|
+
tree[entry.name] = {
|
|
250
|
+
file: {
|
|
251
|
+
contents: content
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
fileNames.push(path.relative(projectPath, entryPath));
|
|
255
|
+
} catch (error) {
|
|
256
|
+
(0, _terminal.terminal)(`^yWarning: Could not read file ${entryPath}^:\n`);
|
|
257
|
+
}
|
|
258
|
+
} else if (entry.isDirectory()) {
|
|
259
|
+
const {
|
|
260
|
+
tree: subTree,
|
|
261
|
+
fileNames: subFileNames
|
|
262
|
+
} = await traverse(entryPath);
|
|
263
|
+
fileNames.push(...subFileNames);
|
|
264
|
+
if (Object.keys(subTree).length > 0) {
|
|
265
|
+
tree[entry.name] = {
|
|
266
|
+
directory: subTree
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return {
|
|
272
|
+
tree,
|
|
273
|
+
fileNames
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
const {
|
|
277
|
+
tree,
|
|
278
|
+
fileNames
|
|
279
|
+
} = await traverse(projectPath);
|
|
280
|
+
const filesToProvisionText = " " + fileNames.join("\n ");
|
|
281
|
+
(0, _terminal.terminal)("^CFiles to be provisioned:^:\n");
|
|
282
|
+
(0, _terminal.terminal)(filesToProvisionText + "\n");
|
|
283
|
+
return tree;
|
|
284
|
+
}
|
|
285
|
+
async function findGitIgnoreFile(projectPath) {
|
|
286
|
+
let currentDirectory = projectPath;
|
|
287
|
+
while (true) {
|
|
288
|
+
const gitIgnorePath = path.join(currentDirectory, ".gitignore");
|
|
289
|
+
if (await fs.exists(gitIgnorePath)) {
|
|
290
|
+
return gitIgnorePath;
|
|
291
|
+
}
|
|
292
|
+
const parentDirectory = path.dirname(currentDirectory);
|
|
293
|
+
if (parentDirectory === currentDirectory) {
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
currentDirectory = parentDirectory;
|
|
297
|
+
}
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var _vitest = require("vitest");
|
|
4
4
|
var _browser = require("../browser");
|
|
5
5
|
var _launchBrowser = require("../../../../common/launchBrowser");
|
|
6
|
+
var _errors = require("../errors");
|
|
6
7
|
function getTerminal() {
|
|
7
8
|
return new Proxy(() => ({}), {
|
|
8
9
|
get: () => getTerminal(),
|
|
@@ -10,6 +11,7 @@ function getTerminal() {
|
|
|
10
11
|
});
|
|
11
12
|
}
|
|
12
13
|
_vitest.vi.mock("fs-extra", () => ({
|
|
14
|
+
ensureDir: _vitest.vi.fn(),
|
|
13
15
|
exists: _vitest.vi.fn().mockResolvedValue(true)
|
|
14
16
|
}));
|
|
15
17
|
_vitest.vi.mock("portfinder", () => ({
|
|
@@ -21,7 +23,8 @@ _vitest.vi.mock("../../../../common/launchBrowser", () => ({
|
|
|
21
23
|
close: _vitest.vi.fn().mockResolvedValue(undefined)
|
|
22
24
|
},
|
|
23
25
|
page: {}
|
|
24
|
-
}))
|
|
26
|
+
})),
|
|
27
|
+
getIgnoreHttpErrorsFromConfig: _vitest.vi.fn().mockResolvedValue(false)
|
|
25
28
|
}));
|
|
26
29
|
_vitest.vi.mock("../../helpers/terminal", () => ({
|
|
27
30
|
terminal: getTerminal()
|
|
@@ -38,8 +41,21 @@ _vitest.vi.mock("../../helpers", async importOriginal => {
|
|
|
38
41
|
terminal: getTerminal()
|
|
39
42
|
};
|
|
40
43
|
});
|
|
44
|
+
_vitest.vi.mock("../../../../common/browserTabs", () => {
|
|
45
|
+
return {
|
|
46
|
+
getCDPTabs: _vitest.vi.fn().mockResolvedValue([{
|
|
47
|
+
id: "tab1",
|
|
48
|
+
title: "Tab 1",
|
|
49
|
+
url: "http://example.com/1"
|
|
50
|
+
}, {
|
|
51
|
+
id: "tab2",
|
|
52
|
+
title: "Tab 2",
|
|
53
|
+
url: "http://example.com/2"
|
|
54
|
+
}])
|
|
55
|
+
};
|
|
56
|
+
});
|
|
41
57
|
(0, _vitest.describe)("Browser CLI options", () => {
|
|
42
|
-
(0, _vitest.it)("returns cdp options if cdpUrl is set", async () => {
|
|
58
|
+
(0, _vitest.it)("returns cdp options with first tab if cdpUrl is set and no cdpTabId is not provided", async () => {
|
|
43
59
|
const options = await (0, _browser.getCLIRunOptions)({
|
|
44
60
|
keepBrowserOpen: true,
|
|
45
61
|
headless: true,
|
|
@@ -47,9 +63,32 @@ _vitest.vi.mock("../../helpers", async importOriginal => {
|
|
|
47
63
|
});
|
|
48
64
|
(0, _vitest.expect)(options).toEqual(_vitest.expect.objectContaining({
|
|
49
65
|
environment: "cdp",
|
|
50
|
-
cdpAddress: "cdp_url"
|
|
66
|
+
cdpAddress: "cdp_url",
|
|
67
|
+
cdpTargetId: "tab1"
|
|
68
|
+
}));
|
|
69
|
+
});
|
|
70
|
+
(0, _vitest.it)("returns cdp options with selected tab if cdpUrl and cdpTabId are provided", async () => {
|
|
71
|
+
const options = await (0, _browser.getCLIRunOptions)({
|
|
72
|
+
keepBrowserOpen: true,
|
|
73
|
+
headless: true,
|
|
74
|
+
cdpUrl: "cdp_url",
|
|
75
|
+
cdpTabId: "tab2"
|
|
76
|
+
});
|
|
77
|
+
(0, _vitest.expect)(options).toEqual(_vitest.expect.objectContaining({
|
|
78
|
+
environment: "cdp",
|
|
79
|
+
cdpAddress: "cdp_url",
|
|
80
|
+
cdpTargetId: "tab2"
|
|
51
81
|
}));
|
|
52
82
|
});
|
|
83
|
+
(0, _vitest.it)("fails in cdp options if cdp url is provided and invalid tab id is provided", async () => {
|
|
84
|
+
const optionsPromise = (0, _browser.getCLIRunOptions)({
|
|
85
|
+
keepBrowserOpen: true,
|
|
86
|
+
headless: true,
|
|
87
|
+
cdpUrl: "cdp_url",
|
|
88
|
+
cdpTabId: "tab3"
|
|
89
|
+
});
|
|
90
|
+
await (0, _vitest.expect)(optionsPromise).rejects.toThrowError(_errors.CLIError);
|
|
91
|
+
});
|
|
53
92
|
(0, _vitest.it)("returns standalone options if keepBrowserOpen is not set", async () => {
|
|
54
93
|
const options = await (0, _browser.getCLIRunOptions)({
|
|
55
94
|
keepBrowserOpen: false,
|
|
@@ -61,7 +100,7 @@ _vitest.vi.mock("../../helpers", async importOriginal => {
|
|
|
61
100
|
}));
|
|
62
101
|
});
|
|
63
102
|
(0, _vitest.describe)("when keepBrowserOpen is set", () => {
|
|
64
|
-
beforeEach(async () => {
|
|
103
|
+
(0, _vitest.beforeEach)(async () => {
|
|
65
104
|
_vitest.vi.clearAllMocks();
|
|
66
105
|
await (0, _browser.closeCliBrowser)();
|
|
67
106
|
});
|
|
@@ -74,7 +113,8 @@ _vitest.vi.mock("../../helpers", async importOriginal => {
|
|
|
74
113
|
(0, _vitest.expect)(_launchBrowser.launchChromium).toHaveBeenCalledWith({
|
|
75
114
|
headless: false,
|
|
76
115
|
cdpPort: 1234,
|
|
77
|
-
proxy: "proxy"
|
|
116
|
+
proxy: "proxy",
|
|
117
|
+
ignoreHttpErrors: false
|
|
78
118
|
});
|
|
79
119
|
(0, _vitest.expect)(options).toEqual(_vitest.expect.objectContaining({
|
|
80
120
|
environment: "cdp",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _vitest = require("vitest");
|
|
4
|
-
var
|
|
4
|
+
var _dist = require("../../../../../dist");
|
|
5
5
|
function getTerminal() {
|
|
6
6
|
return new Proxy(() => ({}), {
|
|
7
7
|
get: () => getTerminal(),
|
|
@@ -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", () => ({
|
|
@@ -24,14 +25,14 @@ _vitest.vi.mock("../../helpers", async importOriginal => {
|
|
|
24
25
|
(0, _vitest.describe)("Tracing wrapper", () => {
|
|
25
26
|
(0, _vitest.it)("calls wrapped function with disabled tracing when id is undefined", async () => {
|
|
26
27
|
const fn = _vitest.vi.fn();
|
|
27
|
-
await (0,
|
|
28
|
+
await (0, _dist.withCLITrace)(fn, undefined);
|
|
28
29
|
(0, _vitest.expect)(fn).toHaveBeenCalledWith({
|
|
29
30
|
enabled: false
|
|
30
31
|
});
|
|
31
32
|
});
|
|
32
33
|
(0, _vitest.it)("calls wrapped function with enabled tracing when id is defined", async () => {
|
|
33
34
|
const fn = _vitest.vi.fn();
|
|
34
|
-
await (0,
|
|
35
|
+
await (0, _dist.withCLITrace)(fn, "trace-id");
|
|
35
36
|
(0, _vitest.expect)(fn).toHaveBeenCalledWith({
|
|
36
37
|
enabled: true,
|
|
37
38
|
filePath: _vitest.expect.stringContaining("trace-id")
|
|
@@ -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
|
-
|
|
8
|
+
var _tsNodeImport = require("../../common/tsNodeImport");
|
|
11
9
|
async function assertApiFileExists(dirname, api) {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
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
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { AuthSessionMetadata } from "../types";
|
|
2
|
-
import { RunApiStorageState
|
|
2
|
+
import { RunApiStorageState } from "@intuned/runtime-interface";
|
|
3
3
|
export declare function isAuthEnabled(): Promise<boolean>;
|
|
4
4
|
export declare function assertAuthEnabled(): Promise<void>;
|
|
5
5
|
export declare function assertAuthConsistent(authSession: string | undefined): Promise<void>;
|
|
6
6
|
export declare function loadAuthSessionInstance(authSessionId: string): Promise<{
|
|
7
7
|
storageState: {
|
|
8
8
|
cookies: {
|
|
9
|
-
path: string;
|
|
10
9
|
value: string;
|
|
11
|
-
|
|
10
|
+
path: string;
|
|
12
11
|
name: string;
|
|
12
|
+
domain: string;
|
|
13
13
|
expires: number;
|
|
14
14
|
httpOnly: boolean;
|
|
15
15
|
secure: boolean;
|
|
@@ -33,7 +33,7 @@ export declare function loadAuthSessionInstance(authSessionId: string): Promise<
|
|
|
33
33
|
metadata: AuthSessionMetadata;
|
|
34
34
|
}>;
|
|
35
35
|
export declare function storeAuthSessionInstance({ state, id, input, proxy, metadata, }: {
|
|
36
|
-
state:
|
|
36
|
+
state: RunApiStorageState;
|
|
37
37
|
id: string;
|
|
38
38
|
input?: Record<string, any>;
|
|
39
39
|
proxy?: string;
|