@prostgles/app 2.3.6-dev.1788986038 → 2.3.6-dev.1789048658
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/client/build/js/298.bundle.js +1 -1
- package/client/build/js/main.bundle.js +2 -2
- package/dist/common/constants.d.ts +1 -0
- package/dist/common/constants.d.ts.map +1 -0
- package/dist/common/constants.js +4 -0
- package/dist/common/constants.js.map +1 -0
- package/dist/common/managedTableSchema.d.ts +1 -0
- package/dist/common/managedTableSchema.d.ts.map +1 -1
- package/dist/common/managedTableSchema.js +7 -1
- package/dist/common/managedTableSchema.js.map +1 -1
- package/dist/common/mcp/ui.mcp.schema.js +1 -1
- package/dist/common/prostglesApiTypes.d.ts +1 -1
- package/dist/common/prostglesApiTypes.d.ts.map +1 -1
- package/dist/common/prostglesApiTypes.js +5 -5
- package/dist/e2e/cli/index.d.ts +18 -0
- package/dist/e2e/cli/index.js +70 -0
- package/dist/e2e/cli/template.d.ts +13 -0
- package/dist/e2e/cli/template.d.ts.map +1 -0
- package/dist/e2e/cli/template.js +57 -0
- package/dist/e2e/cli/template.js.map +1 -0
- package/dist/e2e/shared/Testing.d.ts +665 -0
- package/dist/e2e/shared/Testing.js +584 -0
- package/dist/e2e/shared/constants.d.ts +19 -0
- package/dist/e2e/shared/constants.js +23 -0
- package/dist/e2e/shared/fixtures.d.ts +4 -0
- package/dist/e2e/shared/fixtures.js +40 -0
- package/dist/e2e/shared/goTo.d.ts +2 -0
- package/dist/e2e/shared/goTo.js +85 -0
- package/dist/e2e/shared/utils/constants.d.ts +19 -0
- package/dist/e2e/shared/utils/constants.js +23 -0
- package/dist/e2e/shared/utils/goTo.d.ts +2 -0
- package/dist/e2e/shared/utils/goTo.js +85 -0
- package/dist/e2e/shared/utils/utils.d.ts +144 -0
- package/dist/e2e/shared/utils/utils.js +1041 -0
- package/dist/e2e/shared/utils.d.ts +144 -0
- package/dist/e2e/shared/utils.js +1041 -0
- package/dist/e2e/tests/Testing.d.ts +665 -0
- package/dist/e2e/tests/Testing.d.ts.map +1 -0
- package/dist/e2e/tests/Testing.js +584 -0
- package/dist/e2e/tests/Testing.js.map +1 -0
- package/dist/e2e/tests/fixtures.d.ts +4 -0
- package/dist/e2e/tests/fixtures.d.ts.map +1 -0
- package/dist/e2e/tests/fixtures.js +40 -0
- package/dist/e2e/tests/fixtures.js.map +1 -0
- package/dist/e2e/tests/utils/Testing.d.ts +665 -0
- package/dist/e2e/tests/utils/Testing.js +584 -0
- package/dist/e2e/tests/utils/constants.d.ts +19 -0
- package/dist/e2e/tests/utils/constants.d.ts.map +1 -0
- package/dist/e2e/tests/utils/constants.js +23 -0
- package/dist/e2e/tests/utils/constants.js.map +1 -0
- package/dist/e2e/tests/utils/fixtures.d.ts +4 -0
- package/dist/e2e/tests/utils/fixtures.js +40 -0
- package/dist/e2e/tests/utils/goTo.d.ts +2 -0
- package/dist/e2e/tests/utils/goTo.d.ts.map +1 -0
- package/dist/e2e/tests/utils/goTo.js +85 -0
- package/dist/e2e/tests/utils/goTo.js.map +1 -0
- package/dist/e2e/tests/utils/utils.d.ts +144 -0
- package/dist/e2e/tests/utils/utils.d.ts.map +1 -0
- package/dist/e2e/tests/utils/utils.js +1041 -0
- package/dist/e2e/tests/utils/utils.js.map +1 -0
- package/dist/server/package.json +17 -4
- package/dist/server/src/ConnectionManager/getTableAuditConfig.d.ts +1 -1
- package/dist/server/src/ConnectionManager/getTableAuditConfig.d.ts.map +1 -1
- package/dist/server/src/ConnectionManager/getTableAuditConfig.js +3 -0
- package/dist/server/src/ConnectionManager/getTableAuditConfig.js.map +1 -1
- package/dist/server/src/McpHub/DockerSandbox/createContainer.spec.js +1 -1
- package/dist/server/src/McpHub/ProstglesMcpHub/ProstglesMCPServers/Prostgles/agenticWorkflow/runtimeSetup/getAgenticWorkflowDockerCoreFiles.d.ts +1 -1
- package/dist/server/src/McpHub/ProstglesMcpHub/ProstglesMCPServers/Prostgles/agenticWorkflow/runtimeSetup/getAgenticWorkflowDockerCoreFiles.d.ts.map +1 -1
- package/dist/server/src/McpHub/ProstglesMcpHub/ProstglesMCPServers/Prostgles/agenticWorkflow/runtimeSetup/getAgenticWorkflowDockerCoreFiles.js +1 -1
- package/dist/server/src/McpHub/ProstglesMcpHub/ProstglesMCPServers/WebDev/tools/utils.js +1 -1
- package/dist/server/src/McpHub/ProstglesMcpHub/ProstglesMCPServers/WebDev/tools/utils.js.map +1 -1
- package/dist/server/src/ServiceManager/ServiceManagerTypes.d.ts +3 -3
- package/dist/server/src/ServiceManager/getServiceManager.d.ts +3 -3
- package/dist/server/src/ServiceManager/services/documents/documents.service.d.ts +2 -2
- package/dist/server/src/ServiceManager/services/documents/documents.service.js +2 -2
- package/dist/server/src/ServiceManager/services/speechToText/speechToText.service.d.ts +1 -1
- package/dist/server/src/ServiceManager/services/speechToText/speechToText.service.js +1 -1
- package/dist/server/src/ServiceManager/services/speechToText/speechToText.service.js.map +1 -1
- package/dist/server/src/cli/Dockerfile +1 -1
- package/dist/server/src/cli/cli.js +91 -22
- package/dist/server/src/cli/cli.js.map +1 -1
- package/dist/server/src/cli/cliTemplateFiles.d.ts.map +1 -1
- package/dist/server/src/cli/cliTemplateFiles.js +21 -2
- package/dist/server/src/cli/cliTemplateFiles.js.map +1 -1
- package/dist/server/src/cli/startTemporaryDatabases.d.ts +18 -0
- package/dist/server/src/cli/startTemporaryDatabases.d.ts.map +1 -0
- package/dist/server/src/cli/startTemporaryDatabases.js +198 -0
- package/dist/server/src/cli/startTemporaryDatabases.js.map +1 -0
- package/dist/server/src/cli/testing/createTestDeployment.d.ts +17 -0
- package/dist/server/src/cli/testing/createTestDeployment.d.ts.map +1 -1
- package/dist/server/src/cli/testing/createTestDeployment.js +24 -157
- package/dist/server/src/cli/testing/createTestDeployment.js.map +1 -1
- package/dist/server/src/cli/testing/e2e/index.d.ts +18 -0
- package/dist/server/src/cli/testing/e2e/index.d.ts.map +1 -0
- package/dist/server/src/cli/testing/e2e/index.js +70 -0
- package/dist/server/src/cli/testing/e2e/index.js.map +1 -0
- package/dist/server/src/cli/testing/e2e/template.d.ts +13 -0
- package/dist/server/src/cli/testing/e2e/template.d.ts.map +1 -0
- package/dist/server/src/cli/testing/e2e/template.js +57 -0
- package/dist/server/src/cli/testing/e2e/template.js.map +1 -0
- package/dist/server/src/cli/testing/ui/index.d.ts +7 -0
- package/dist/server/src/cli/testing/ui/index.d.ts.map +1 -0
- package/dist/server/src/cli/testing/ui/index.js +67 -0
- package/dist/server/src/cli/testing/ui/index.js.map +1 -0
- package/dist/server/src/cli/testing/ui/template.d.ts +13 -0
- package/dist/server/src/cli/testing/ui/template.d.ts.map +1 -0
- package/dist/server/src/cli/testing/ui/template.js +49 -0
- package/dist/server/src/cli/testing/ui/template.js.map +1 -0
- package/dist/server/src/serverFunctions/adminServerFunctions/webApp/buildWebApp.js +1 -1
- package/dist/server/src/serverFunctions/adminServerFunctions/webApp/buildWebApp.js.map +1 -1
- package/dist/server/src/serverFunctions/adminServerFunctions/webApp/runDockerForWebApp.d.ts +1 -1
- package/dist/server/src/serverFunctions/adminServerFunctions/webApp/runDockerForWebApp.d.ts.map +1 -1
- package/dist/server/src/serverFunctions/adminServerFunctions/webApp/testWebApp.js +1 -1
- package/package.json +17 -4
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getCliComposeFiles = exports.srcSubfolderNames = exports.generatedFolderName = exports.srcFolderName = exports.saveCliComposeFiles = exports.saveCliTemplateFiles = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
+
const template_1 = require("../../../e2e/cli/template");
|
|
5
6
|
const utils_1 = require("../../../common/utils");
|
|
6
7
|
const crypto_1 = require("crypto");
|
|
7
8
|
const package_json_1 = tslib_1.__importDefault(require("../../package.json"));
|
|
@@ -170,6 +171,7 @@ const getCliTemplateFiles = ({ configId, environmentDefaults, }) => ({
|
|
|
170
171
|
serviceRoot: path.resolve(__dirname, "..", "..", "src", "services"),
|
|
171
172
|
} satisfies ServiceManagerConfig<typeof services>;`,
|
|
172
173
|
},
|
|
174
|
+
e2e: (0, template_1.getE2ETemplate)(configId),
|
|
173
175
|
[testsFolderName]: {
|
|
174
176
|
"deployment.test.ts": `
|
|
175
177
|
import assert from "node:assert/strict";
|
|
@@ -209,6 +211,8 @@ const getCliTemplateFiles = ({ configId, environmentDefaults, }) => ({
|
|
|
209
211
|
build/
|
|
210
212
|
${exports.generatedFolderName}/
|
|
211
213
|
.prostgles/
|
|
214
|
+
e2e/test-results/
|
|
215
|
+
e2e/playwright-report/
|
|
212
216
|
src/${servicesFolderName}/*/src/`,
|
|
213
217
|
".gitignore": `
|
|
214
218
|
node_modules/
|
|
@@ -231,7 +235,7 @@ const getCliTemplateFiles = ({ configId, environmentDefaults, }) => ({
|
|
|
231
235
|
PROSTGLES_DOCKER_DB_PASSWORD=${environmentDefaults?.PROSTGLES_DOCKER_DB_PASSWORD ?? (0, crypto_1.randomBytes)(24).toString("base64url")}
|
|
232
236
|
|
|
233
237
|
# Optional test-only override. By default npm test builds DB.Dockerfile.
|
|
234
|
-
# PROSTGLES_TEST_POSTGRES_IMAGE=postgis/postgis:17-3.
|
|
238
|
+
# PROSTGLES_TEST_POSTGRES_IMAGE=postgis/postgis:17-3.6-alpine`,
|
|
235
239
|
});
|
|
236
240
|
const readCliAsset = (filename) => {
|
|
237
241
|
const filePath = (0, path_1.join)(__dirname, filename);
|
|
@@ -335,12 +339,16 @@ const getPackageJson = (configId) => ({
|
|
|
335
339
|
"format:check": "prettier --check .",
|
|
336
340
|
start: "prostgles start --config .",
|
|
337
341
|
upgrade: "prostgles upgrade --config .",
|
|
342
|
+
"test:e2e": "npm run build && tsc -p e2e/tsconfig.json && playwright test --config e2e/playwright.config.ts",
|
|
343
|
+
"test:e2e:install": "playwright install chromium",
|
|
344
|
+
"test:e2e:report": "playwright show-report e2e/playwright-report",
|
|
338
345
|
test: 'npm run build && node --env-file-if-exists=.env --test "build/tests/**/*.test.js"',
|
|
339
346
|
},
|
|
340
347
|
dependencies: {
|
|
341
348
|
[package_json_1.default.name]: getRuntimeDependency(),
|
|
342
349
|
},
|
|
343
350
|
devDependencies: {
|
|
351
|
+
"@playwright/test": package_json_1.default.devDependencies["@playwright/test"],
|
|
344
352
|
prettier: "^3.4.2",
|
|
345
353
|
...(0, prostgles_types_1.pickKeys)(package_json_1.default.dependencies, ["typescript"]),
|
|
346
354
|
...(0, prostgles_types_1.pickKeys)(package_json_1.default.devDependencies, [
|
|
@@ -409,6 +417,8 @@ const eslintConfig = `
|
|
|
409
417
|
"build",
|
|
410
418
|
"${exports.generatedFolderName}",
|
|
411
419
|
"node_modules",
|
|
420
|
+
"e2e/test-results",
|
|
421
|
+
"e2e/playwright-report",
|
|
412
422
|
"eslint.config.mjs",
|
|
413
423
|
"src/${servicesFolderName}/*/src",
|
|
414
424
|
],
|
|
@@ -418,7 +428,7 @@ const eslintConfig = `
|
|
|
418
428
|
eslint.configs.recommended,
|
|
419
429
|
tseslint.configs.recommendedTypeChecked,
|
|
420
430
|
{
|
|
421
|
-
files: ["${exports.srcFolderName}/**/*.ts", "${testsFolderName}/**/*.ts"],
|
|
431
|
+
files: ["${exports.srcFolderName}/**/*.ts", "${testsFolderName}/**/*.ts", "e2e/**/*.ts"],
|
|
422
432
|
languageOptions: {
|
|
423
433
|
parserOptions: {
|
|
424
434
|
projectService: true,
|
|
@@ -541,11 +551,20 @@ const getCliAgentsFile = () => `
|
|
|
541
551
|
- Use semantic names ending in \`*.function.ts\`, \`*.tableConfig.ts\`, \`*.tableOptions.ts\`, and \`*.tableHooks.ts\`. Examples: \`deployProject.function.ts\`, \`orders.tableConfig.ts\`, \`customers.tableOptions.ts\`, and \`users.tableHooks.ts\`.
|
|
542
552
|
- The generated ESLint config enforces these suffixes inside their corresponding folders. Run \`npm run lint\` before committing.
|
|
543
553
|
|
|
554
|
+
## Local development
|
|
555
|
+
|
|
556
|
+
- For disposable development or UI checks, use \`npm run dev -- --temp-db\` or \`npm start -- --temp-db\`. The CLI manages PostgreSQL using the same helper as tests; no database URLs or manual Docker commands are needed. Docker must be available.
|
|
557
|
+
- Each command creates fresh state and project databases, overrides database URLs from the environment, and removes its container on exit. Dev reloads keep the databases until the command stops. Use normal dev/start with configured URLs only when persistent data is required.
|
|
558
|
+
- PostgreSQL logs are saved under \`.prostgles/test-logs/\`; the CLI prints the exact path. Logs remain after cleanup. Inspect these logs when database setup fails instead of starting another container.
|
|
559
|
+
|
|
544
560
|
## Tests
|
|
545
561
|
|
|
562
|
+
- Do not manually start PostgreSQL containers or supply database credentials for tests. Run the existing \`npm test\` workflow directly; it provisions and cleans up its own databases. Build and lint commands do not need a database.
|
|
546
563
|
- Run \`npm test\` before committing. Tests use \`@prostgles/app/testing\` to start the real app against fresh state and project databases without opening the UI.
|
|
564
|
+
- For browser workflows, use \`e2e/AGENTS.md\`, \`npm run test:e2e\`, and the shared \`@prostgles/app/testing/ui\` helpers. Play passing and failing test videos with \`npm run test:e2e:report\`.
|
|
547
565
|
- Keep deployment tests in \`tests/\`. Each call to \`createTestDeployment\` uses the current app directory and its \`DB.Dockerfile\` when present, starts a disposable PostgreSQL Docker container bound only to \`127.0.0.1\`, creates fresh state and project databases, and removes the container during cleanup. Set \`PROSTGLES_TEST_POSTGRES_IMAGE\` only to override the Dockerfile.
|
|
548
566
|
- \`npm test\` automatically saves each test deployment's stdout and stderr to \`.prostgles/test-logs/<timestamp>-<random>.log\` relative to the app root. Logs remain after cleanup; the exact file is returned as \`deployment.logPath\` and included in deployment startup errors. No custom logging command or output redirection is needed to capture deployment logs.
|
|
567
|
+
- PostgreSQL stdout and stderr are also saved to \`deployment.databaseLogPath\` (the app log path plus \`.postgres.log\`), including database startup failures. These logs remain after cleanup.
|
|
549
568
|
- After a test failure, inspect the existing logs before rerunning tests or requesting custom commands. Use \`ls -t .prostgles/test-logs/\` to find recent logs, then \`tail -n 200 .prostgles/test-logs/<filename>\` or \`rg -n -i 'error|failed' .prostgles/test-logs/<filename>\`. Logs may be large; do not read an entire log unless its size is known to be small.
|
|
550
569
|
- These files contain deployment output, not the npm/build/test-runner output. Check the test command's terminal output for lint, TypeScript, assertion, or Docker setup failures. Failures before the deployment starts may not create a log file.
|
|
551
570
|
- If the deployment fixture blocks a valid scenario, inspect \`deployment.logPath\` and report the issue against \`@prostgles/app\`; do not weaken the app or its assertions to work around the fixture.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cliTemplateFiles.js","sourceRoot":"","sources":["../../../../src/cli/cliTemplateFiles.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cliTemplateFiles.js","sourceRoot":"","sources":["../../../../src/cli/cliTemplateFiles.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const startTemporaryDatabases: ({ configPath, configId, postgresImage, startupTimeoutMs, logPath, }: {
|
|
2
|
+
logPath: string;
|
|
3
|
+
configPath: string;
|
|
4
|
+
configId: string;
|
|
5
|
+
postgresImage?: string;
|
|
6
|
+
startupTimeoutMs?: number;
|
|
7
|
+
}) => Promise<{
|
|
8
|
+
dispose: () => Promise<void>;
|
|
9
|
+
project: {
|
|
10
|
+
name: string;
|
|
11
|
+
url: string;
|
|
12
|
+
};
|
|
13
|
+
state: {
|
|
14
|
+
name: string;
|
|
15
|
+
url: string;
|
|
16
|
+
};
|
|
17
|
+
}>;
|
|
18
|
+
//# sourceMappingURL=startTemporaryDatabases.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"startTemporaryDatabases.d.ts","sourceRoot":"","sources":["../../../../src/cli/startTemporaryDatabases.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,uBAAuB,GAAU,qEAM3C;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;;;;;;;;;;EAkJA,CAAC"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.startTemporaryDatabases = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const node_child_process_1 = require("node:child_process");
|
|
6
|
+
const node_crypto_1 = require("node:crypto");
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const promises_1 = require("node:fs/promises");
|
|
9
|
+
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
10
|
+
const pg_1 = require("pg");
|
|
11
|
+
const TEST_DATABASE_NAMESPACE = "prostgles_test_";
|
|
12
|
+
const DEFAULT_POSTGRES_IMAGE = "postgis/postgis:17-3.6-alpine";
|
|
13
|
+
const START_TIMEOUT_MS = 60_000;
|
|
14
|
+
const startTemporaryDatabases = async ({ configPath, configId, postgresImage, startupTimeoutMs, logPath, }) => {
|
|
15
|
+
await (0, promises_1.mkdir)(node_path_1.default.dirname(logPath), { recursive: true });
|
|
16
|
+
const configuredImage = postgresImage ?? process.env.PROSTGLES_TEST_POSTGRES_IMAGE;
|
|
17
|
+
const dbDockerfile = node_path_1.default.join(configPath, "DB.Dockerfile");
|
|
18
|
+
let image = configuredImage;
|
|
19
|
+
if (!image && (0, node_fs_1.existsSync)(dbDockerfile)) {
|
|
20
|
+
const imageTag = `prostgles-test-${validatePrefix(configId).replaceAll("_", "-") || "app"}-db`;
|
|
21
|
+
const buildArgs = [
|
|
22
|
+
"build",
|
|
23
|
+
"--quiet",
|
|
24
|
+
"--file",
|
|
25
|
+
dbDockerfile,
|
|
26
|
+
"--tag",
|
|
27
|
+
imageTag,
|
|
28
|
+
configPath,
|
|
29
|
+
];
|
|
30
|
+
const buildResult = await runDocker(buildArgs);
|
|
31
|
+
if (buildResult.exitCode !== 0) {
|
|
32
|
+
throw getDockerError(buildArgs, buildResult);
|
|
33
|
+
}
|
|
34
|
+
image = imageTag;
|
|
35
|
+
}
|
|
36
|
+
image ??= DEFAULT_POSTGRES_IMAGE;
|
|
37
|
+
const prefix = validatePrefix(configId);
|
|
38
|
+
const runId = (0, node_crypto_1.randomBytes)(6).toString("hex");
|
|
39
|
+
const baseName = `${TEST_DATABASE_NAMESPACE}${prefix ? `${prefix}_` : ""}${runId}`;
|
|
40
|
+
const stateName = `${baseName}_state`;
|
|
41
|
+
const projectName = `${baseName}_project`;
|
|
42
|
+
const username = "prostgles_test";
|
|
43
|
+
const password = (0, node_crypto_1.randomBytes)(24).toString("base64url");
|
|
44
|
+
const containerName = `prostgles-test-${prefix ? `${prefix.replaceAll("_", "-")}-` : ""}${runId}`;
|
|
45
|
+
const runArgs = [
|
|
46
|
+
"run",
|
|
47
|
+
"--detach",
|
|
48
|
+
"--name",
|
|
49
|
+
containerName,
|
|
50
|
+
"--label",
|
|
51
|
+
"prostgles.test-deployment=true",
|
|
52
|
+
"--publish",
|
|
53
|
+
"127.0.0.1::5432",
|
|
54
|
+
"--env",
|
|
55
|
+
`POSTGRES_USER=${username}`,
|
|
56
|
+
"--env",
|
|
57
|
+
`POSTGRES_PASSWORD=${password}`,
|
|
58
|
+
"--env",
|
|
59
|
+
"POSTGRES_DB=postgres",
|
|
60
|
+
image,
|
|
61
|
+
];
|
|
62
|
+
const runResult = await runDocker(runArgs);
|
|
63
|
+
if (runResult.exitCode !== 0)
|
|
64
|
+
throw getDockerError(runArgs, runResult);
|
|
65
|
+
const logFile = await (0, promises_1.open)(logPath, "w").catch(async (error) => {
|
|
66
|
+
await runDocker(["rm", "--force", containerName]);
|
|
67
|
+
throw error;
|
|
68
|
+
});
|
|
69
|
+
const logProcess = (0, node_child_process_1.spawn)("docker", ["logs", "--follow", containerName], {
|
|
70
|
+
stdio: ["ignore", logFile.fd, logFile.fd],
|
|
71
|
+
});
|
|
72
|
+
const logsClosed = new Promise((resolve) => {
|
|
73
|
+
logProcess.once("close", () => resolve());
|
|
74
|
+
});
|
|
75
|
+
logProcess.on("error", console.error);
|
|
76
|
+
await logFile.close();
|
|
77
|
+
console.log(`PostgreSQL log file: ${logPath}`);
|
|
78
|
+
const dispose = async () => {
|
|
79
|
+
// Stop before collecting the final logs so shutdown messages are retained.
|
|
80
|
+
try {
|
|
81
|
+
await runDocker(["stop", "--time", "5", containerName]);
|
|
82
|
+
logProcess.kill();
|
|
83
|
+
await logsClosed;
|
|
84
|
+
const logs = await runDocker(["logs", containerName]);
|
|
85
|
+
if (logs.exitCode !== 0)
|
|
86
|
+
throw getDockerError(["logs"], logs);
|
|
87
|
+
await (0, promises_1.writeFile)(logPath, logs.stdout + logs.stderr);
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
logProcess.kill();
|
|
91
|
+
await removeContainer(containerName);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
try {
|
|
95
|
+
const portArgs = ["port", containerName, "5432/tcp"];
|
|
96
|
+
const portResult = await runDocker(portArgs);
|
|
97
|
+
if (portResult.exitCode !== 0)
|
|
98
|
+
throw getDockerError(portArgs, portResult);
|
|
99
|
+
const portText = portResult.stdout.trim();
|
|
100
|
+
if (!portText.startsWith("127.0.0.1:") || portText.includes("\n")) {
|
|
101
|
+
throw new Error(`Refusing a PostgreSQL test container not bound exclusively to 127.0.0.1: ${portText}`);
|
|
102
|
+
}
|
|
103
|
+
const separatorIndex = portText.lastIndexOf(":");
|
|
104
|
+
const port = Number(portText.slice(separatorIndex + 1));
|
|
105
|
+
if (!Number.isInteger(port) || port <= 0) {
|
|
106
|
+
throw new Error(`Docker returned an invalid PostgreSQL port: ${portText}`);
|
|
107
|
+
}
|
|
108
|
+
const maintenanceUrl = getDatabaseUrl(port, username, password, "postgres");
|
|
109
|
+
const startedAt = Date.now();
|
|
110
|
+
let lastConnectionError;
|
|
111
|
+
let maintenance;
|
|
112
|
+
while (Date.now() - startedAt < (startupTimeoutMs ?? START_TIMEOUT_MS)) {
|
|
113
|
+
const candidate = new pg_1.Client({ connectionString: maintenanceUrl });
|
|
114
|
+
try {
|
|
115
|
+
await candidate.connect();
|
|
116
|
+
maintenance = candidate;
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
lastConnectionError = error;
|
|
121
|
+
await candidate.end().catch(() => undefined);
|
|
122
|
+
await delay(200);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (!maintenance) {
|
|
126
|
+
const logs = await runDocker(["logs", containerName]);
|
|
127
|
+
throw new Error(`Timed out waiting for the test PostgreSQL container.\n${logs.stdout}${logs.stderr}`, { cause: lastConnectionError });
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
await maintenance.query(`CREATE DATABASE "${stateName}"`);
|
|
131
|
+
await maintenance.query(`CREATE DATABASE "${projectName}"`);
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
await maintenance.end();
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
dispose,
|
|
138
|
+
project: {
|
|
139
|
+
name: projectName,
|
|
140
|
+
url: getDatabaseUrl(port, username, password, projectName),
|
|
141
|
+
},
|
|
142
|
+
state: {
|
|
143
|
+
name: stateName,
|
|
144
|
+
url: getDatabaseUrl(port, username, password, stateName),
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
await dispose().catch(() => undefined);
|
|
150
|
+
throw new Error(`Temporary PostgreSQL setup failed. Log file: ${logPath}`, {
|
|
151
|
+
cause: error,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
exports.startTemporaryDatabases = startTemporaryDatabases;
|
|
156
|
+
const runCommand = async (command, args) => await new Promise((resolve, reject) => {
|
|
157
|
+
const child = (0, node_child_process_1.spawn)(command, args, { stdio: "pipe" });
|
|
158
|
+
let stdout = "";
|
|
159
|
+
let stderr = "";
|
|
160
|
+
child.stdout.on("data", (chunk) => {
|
|
161
|
+
stdout += chunk.toString();
|
|
162
|
+
});
|
|
163
|
+
child.stderr.on("data", (chunk) => {
|
|
164
|
+
stderr += chunk.toString();
|
|
165
|
+
});
|
|
166
|
+
child.once("error", reject);
|
|
167
|
+
child.once("close", (exitCode) => {
|
|
168
|
+
resolve({ exitCode: exitCode ?? 1, stderr, stdout });
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
const runDocker = async (args) => {
|
|
172
|
+
const result = await runCommand("docker", args).catch((error) => {
|
|
173
|
+
throw new Error("Docker is required for Prostgles temporary databases. Install Docker and ensure its daemon is running.", { cause: error });
|
|
174
|
+
});
|
|
175
|
+
return result;
|
|
176
|
+
};
|
|
177
|
+
const getDockerError = (args, result) => new Error(`docker ${args[0] ?? "command"} failed with exit code ${result.exitCode}: ${result.stderr.trim() || result.stdout.trim()}`);
|
|
178
|
+
const validatePrefix = (configId) => configId
|
|
179
|
+
.toLowerCase()
|
|
180
|
+
.replace(/[^a-z0-9_]/g, "_")
|
|
181
|
+
.slice(0, 20);
|
|
182
|
+
const getDatabaseUrl = (port, username, password, databaseName) => {
|
|
183
|
+
const url = new URL("postgresql://127.0.0.1");
|
|
184
|
+
url.username = username;
|
|
185
|
+
url.password = password;
|
|
186
|
+
url.port = String(port);
|
|
187
|
+
url.pathname = `/${databaseName}`;
|
|
188
|
+
return url.toString();
|
|
189
|
+
};
|
|
190
|
+
const delay = async (milliseconds) => await new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
191
|
+
const removeContainer = async (containerName) => {
|
|
192
|
+
const args = ["rm", "--force", containerName];
|
|
193
|
+
const result = await runDocker(args);
|
|
194
|
+
if (result.exitCode !== 0 && !result.stderr.includes("No such container")) {
|
|
195
|
+
throw getDockerError(args, result);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
//# sourceMappingURL=startTemporaryDatabases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"startTemporaryDatabases.js","sourceRoot":"","sources":["../../../../src/cli/startTemporaryDatabases.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,6 +33,23 @@ export type TestDeployment<Schema = void, Functions extends ClientFunctionHandle
|
|
|
33
33
|
projectDatabaseName: string;
|
|
34
34
|
/** File containing deployment stdout and stderr. */
|
|
35
35
|
logPath: string;
|
|
36
|
+
/** PostgreSQL output, retained after cleanup. */
|
|
37
|
+
databaseLogPath: string;
|
|
38
|
+
/** Browser session for a seeded user, compatible with Playwright storageState. */
|
|
39
|
+
storageStateAs: (userKey: string) => {
|
|
40
|
+
cookies: {
|
|
41
|
+
name: string;
|
|
42
|
+
value: string;
|
|
43
|
+
domain: string;
|
|
44
|
+
path: string;
|
|
45
|
+
expires: number;
|
|
46
|
+
httpOnly: boolean;
|
|
47
|
+
secure: boolean;
|
|
48
|
+
sameSite: "Lax";
|
|
49
|
+
}[];
|
|
50
|
+
origins: [];
|
|
51
|
+
};
|
|
52
|
+
dashboardUrl: string;
|
|
36
53
|
connectStateAs: (userKey: string) => Promise<TestDeploymentClient<void, ClientFunctionHandler, UserLike>>;
|
|
37
54
|
connectProjectAs: (userKey: string) => Promise<TestDeploymentClient<Schema, Functions, User>>;
|
|
38
55
|
dispose: () => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createTestDeployment.d.ts","sourceRoot":"","sources":["../../../../../src/cli/testing/createTestDeployment.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"createTestDeployment.d.ts","sourceRoot":"","sources":["../../../../../src/cli/testing/createTestDeployment.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,168 +4,17 @@ exports.createTestDeployment = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const node_child_process_1 = require("node:child_process");
|
|
6
6
|
const node_crypto_1 = require("node:crypto");
|
|
7
|
-
const node_fs_1 = require("node:fs");
|
|
8
7
|
const promises_1 = require("node:fs/promises");
|
|
9
8
|
const node_net_1 = require("node:net");
|
|
10
9
|
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
11
10
|
const prostgles_client_1 = tslib_1.__importDefault(require("prostgles-client"));
|
|
12
11
|
const pg_1 = require("pg");
|
|
13
|
-
const
|
|
14
|
-
const
|
|
12
|
+
const startTemporaryDatabases_1 = require("../startTemporaryDatabases");
|
|
13
|
+
const utils_1 = require("../../../../common/utils");
|
|
14
|
+
const authTypesAndConstants_1 = require("../../../../common/authTypesAndConstants");
|
|
15
15
|
const STATE_SOCKET_PATH = "/ws-api-dbs";
|
|
16
16
|
const START_TIMEOUT_MS = 60_000;
|
|
17
|
-
const runCommand = async (command, args) => await new Promise((resolve, reject) => {
|
|
18
|
-
const child = (0, node_child_process_1.spawn)(command, args, { stdio: "pipe" });
|
|
19
|
-
let stdout = "";
|
|
20
|
-
let stderr = "";
|
|
21
|
-
child.stdout.on("data", (chunk) => {
|
|
22
|
-
stdout += chunk.toString();
|
|
23
|
-
});
|
|
24
|
-
child.stderr.on("data", (chunk) => {
|
|
25
|
-
stderr += chunk.toString();
|
|
26
|
-
});
|
|
27
|
-
child.once("error", reject);
|
|
28
|
-
child.once("close", (exitCode) => {
|
|
29
|
-
resolve({ exitCode: exitCode ?? 1, stderr, stdout });
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
const runDocker = async (args) => {
|
|
33
|
-
const result = await runCommand("docker", args).catch((error) => {
|
|
34
|
-
throw new Error("Docker is required for Prostgles deployment tests. Install Docker and ensure its daemon is running.", { cause: error });
|
|
35
|
-
});
|
|
36
|
-
return result;
|
|
37
|
-
};
|
|
38
|
-
const getDockerError = (args, result) => new Error(`docker ${args[0] ?? "command"} failed with exit code ${result.exitCode}: ${result.stderr.trim() || result.stdout.trim()}`);
|
|
39
|
-
const validatePrefix = (configId) => configId
|
|
40
|
-
.toLowerCase()
|
|
41
|
-
.replace(/[^a-z0-9_]/g, "_")
|
|
42
|
-
.slice(0, 20);
|
|
43
|
-
const getDatabaseUrl = (port, username, password, databaseName) => {
|
|
44
|
-
const url = new URL("postgresql://127.0.0.1");
|
|
45
|
-
url.username = username;
|
|
46
|
-
url.password = password;
|
|
47
|
-
url.port = String(port);
|
|
48
|
-
url.pathname = `/${databaseName}`;
|
|
49
|
-
return url.toString();
|
|
50
|
-
};
|
|
51
17
|
const delay = async (milliseconds) => await new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
52
|
-
const startDockerDatabases = async ({ configPath, configId, postgresImage, startupTimeoutMs, }) => {
|
|
53
|
-
const configuredImage = postgresImage ?? process.env.PROSTGLES_TEST_POSTGRES_IMAGE;
|
|
54
|
-
const dbDockerfile = node_path_1.default.join(configPath, "DB.Dockerfile");
|
|
55
|
-
let image = configuredImage;
|
|
56
|
-
if (!image && (0, node_fs_1.existsSync)(dbDockerfile)) {
|
|
57
|
-
const imageTag = `prostgles-test-${validatePrefix(configId).replaceAll("_", "-") || "app"}-db`;
|
|
58
|
-
const buildArgs = [
|
|
59
|
-
"build",
|
|
60
|
-
"--quiet",
|
|
61
|
-
"--file",
|
|
62
|
-
dbDockerfile,
|
|
63
|
-
"--tag",
|
|
64
|
-
imageTag,
|
|
65
|
-
configPath,
|
|
66
|
-
];
|
|
67
|
-
const buildResult = await runDocker(buildArgs);
|
|
68
|
-
if (buildResult.exitCode !== 0) {
|
|
69
|
-
throw getDockerError(buildArgs, buildResult);
|
|
70
|
-
}
|
|
71
|
-
image = imageTag;
|
|
72
|
-
}
|
|
73
|
-
image ??= DEFAULT_POSTGRES_IMAGE;
|
|
74
|
-
const prefix = validatePrefix(configId);
|
|
75
|
-
const runId = (0, node_crypto_1.randomBytes)(6).toString("hex");
|
|
76
|
-
const baseName = `${TEST_DATABASE_NAMESPACE}${prefix ? `${prefix}_` : ""}${runId}`;
|
|
77
|
-
const stateName = `${baseName}_state`;
|
|
78
|
-
const projectName = `${baseName}_project`;
|
|
79
|
-
const username = "prostgles_test";
|
|
80
|
-
const password = (0, node_crypto_1.randomBytes)(24).toString("base64url");
|
|
81
|
-
const containerName = `prostgles-test-${prefix ? `${prefix.replaceAll("_", "-")}-` : ""}${runId}`;
|
|
82
|
-
const runArgs = [
|
|
83
|
-
"run",
|
|
84
|
-
"--detach",
|
|
85
|
-
"--rm",
|
|
86
|
-
"--name",
|
|
87
|
-
containerName,
|
|
88
|
-
"--label",
|
|
89
|
-
"prostgles.test-deployment=true",
|
|
90
|
-
"--publish",
|
|
91
|
-
"127.0.0.1::5432",
|
|
92
|
-
"--env",
|
|
93
|
-
`POSTGRES_USER=${username}`,
|
|
94
|
-
"--env",
|
|
95
|
-
`POSTGRES_PASSWORD=${password}`,
|
|
96
|
-
"--env",
|
|
97
|
-
"POSTGRES_DB=postgres",
|
|
98
|
-
image,
|
|
99
|
-
];
|
|
100
|
-
const runResult = await runDocker(runArgs);
|
|
101
|
-
if (runResult.exitCode !== 0)
|
|
102
|
-
throw getDockerError(runArgs, runResult);
|
|
103
|
-
const dispose = async () => {
|
|
104
|
-
const args = ["rm", "--force", containerName];
|
|
105
|
-
const result = await runDocker(args);
|
|
106
|
-
if (result.exitCode !== 0 && !result.stderr.includes("No such container")) {
|
|
107
|
-
throw getDockerError(args, result);
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
try {
|
|
111
|
-
const portArgs = ["port", containerName, "5432/tcp"];
|
|
112
|
-
const portResult = await runDocker(portArgs);
|
|
113
|
-
if (portResult.exitCode !== 0)
|
|
114
|
-
throw getDockerError(portArgs, portResult);
|
|
115
|
-
const portText = portResult.stdout.trim();
|
|
116
|
-
if (!portText.startsWith("127.0.0.1:") || portText.includes("\n")) {
|
|
117
|
-
throw new Error(`Refusing a PostgreSQL test container not bound exclusively to 127.0.0.1: ${portText}`);
|
|
118
|
-
}
|
|
119
|
-
const separatorIndex = portText.lastIndexOf(":");
|
|
120
|
-
const port = Number(portText.slice(separatorIndex + 1));
|
|
121
|
-
if (!Number.isInteger(port) || port <= 0) {
|
|
122
|
-
throw new Error(`Docker returned an invalid PostgreSQL port: ${portText}`);
|
|
123
|
-
}
|
|
124
|
-
const maintenanceUrl = getDatabaseUrl(port, username, password, "postgres");
|
|
125
|
-
const startedAt = Date.now();
|
|
126
|
-
let lastConnectionError;
|
|
127
|
-
let maintenance;
|
|
128
|
-
while (Date.now() - startedAt < (startupTimeoutMs ?? START_TIMEOUT_MS)) {
|
|
129
|
-
const candidate = new pg_1.Client({ connectionString: maintenanceUrl });
|
|
130
|
-
try {
|
|
131
|
-
await candidate.connect();
|
|
132
|
-
maintenance = candidate;
|
|
133
|
-
break;
|
|
134
|
-
}
|
|
135
|
-
catch (error) {
|
|
136
|
-
lastConnectionError = error;
|
|
137
|
-
await candidate.end().catch(() => undefined);
|
|
138
|
-
await delay(200);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
if (!maintenance) {
|
|
142
|
-
const logs = await runDocker(["logs", containerName]);
|
|
143
|
-
throw new Error(`Timed out waiting for the test PostgreSQL container.\n${logs.stdout}${logs.stderr}`, { cause: lastConnectionError });
|
|
144
|
-
}
|
|
145
|
-
try {
|
|
146
|
-
await maintenance.query(`CREATE DATABASE "${stateName}"`);
|
|
147
|
-
await maintenance.query(`CREATE DATABASE "${projectName}"`);
|
|
148
|
-
}
|
|
149
|
-
finally {
|
|
150
|
-
await maintenance.end();
|
|
151
|
-
}
|
|
152
|
-
return {
|
|
153
|
-
dispose,
|
|
154
|
-
project: {
|
|
155
|
-
name: projectName,
|
|
156
|
-
url: getDatabaseUrl(port, username, password, projectName),
|
|
157
|
-
},
|
|
158
|
-
state: {
|
|
159
|
-
name: stateName,
|
|
160
|
-
url: getDatabaseUrl(port, username, password, stateName),
|
|
161
|
-
},
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
catch (error) {
|
|
165
|
-
await dispose().catch(() => undefined);
|
|
166
|
-
throw error;
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
18
|
const getFreePort = async () => await new Promise((resolve, reject) => {
|
|
170
19
|
const server = (0, node_net_1.createServer)();
|
|
171
20
|
server.once("error", reject);
|
|
@@ -256,11 +105,14 @@ const seedUsers = async (databaseUrl, users) => {
|
|
|
256
105
|
};
|
|
257
106
|
const createTestDeployment = async ({ configPath, configId, logPath, postgresImage, seed, startupTimeoutMs = START_TIMEOUT_MS, users = [{ key: "admin", type: "admin" }], }) => {
|
|
258
107
|
const resolvedConfigPath = node_path_1.default.resolve(configPath ?? process.cwd());
|
|
259
|
-
const
|
|
108
|
+
const resolvedLogPath = node_path_1.default.resolve(logPath ??
|
|
109
|
+
node_path_1.default.join(resolvedConfigPath, ".prostgles/test-logs", `${Date.now()}-${(0, node_crypto_1.randomBytes)(4).toString("hex")}.log`));
|
|
110
|
+
const databases = await (0, startTemporaryDatabases_1.startTemporaryDatabases)({
|
|
260
111
|
configPath: resolvedConfigPath,
|
|
261
112
|
configId,
|
|
262
113
|
postgresImage,
|
|
263
114
|
startupTimeoutMs,
|
|
115
|
+
logPath: `${resolvedLogPath}.postgres.log`,
|
|
264
116
|
});
|
|
265
117
|
const port = await getFreePort().catch(async (error) => {
|
|
266
118
|
await databases.dispose();
|
|
@@ -268,8 +120,6 @@ const createTestDeployment = async ({ configPath, configId, logPath, postgresIma
|
|
|
268
120
|
});
|
|
269
121
|
const endpoint = `http://127.0.0.1:${port}`;
|
|
270
122
|
const cliPath = node_path_1.default.resolve(__dirname, "../cli.js");
|
|
271
|
-
const resolvedLogPath = node_path_1.default.resolve(logPath ??
|
|
272
|
-
node_path_1.default.join(resolvedConfigPath, ".prostgles/test-logs", `${Date.now()}-${(0, node_crypto_1.randomBytes)(4).toString("hex")}.log`));
|
|
273
123
|
const logFile = await (0, promises_1.mkdir)(node_path_1.default.dirname(resolvedLogPath), {
|
|
274
124
|
recursive: true,
|
|
275
125
|
})
|
|
@@ -408,11 +258,28 @@ const createTestDeployment = async ({ configPath, configId, logPath, postgresIma
|
|
|
408
258
|
}
|
|
409
259
|
};
|
|
410
260
|
return {
|
|
261
|
+
dashboardUrl: `${endpoint}${(0, utils_1.getConnectionPaths)({ id: connectionId }).dashboard}`,
|
|
262
|
+
storageStateAs: (userKey) => ({
|
|
263
|
+
cookies: [
|
|
264
|
+
{
|
|
265
|
+
name: authTypesAndConstants_1.sidKeyName,
|
|
266
|
+
value: getToken(userKey),
|
|
267
|
+
domain: new URL(endpoint).hostname,
|
|
268
|
+
path: "/",
|
|
269
|
+
expires: -1,
|
|
270
|
+
httpOnly: true,
|
|
271
|
+
secure: false,
|
|
272
|
+
sameSite: "Lax",
|
|
273
|
+
},
|
|
274
|
+
],
|
|
275
|
+
origins: [],
|
|
276
|
+
}),
|
|
411
277
|
connectProjectAs,
|
|
412
278
|
connectStateAs,
|
|
413
279
|
dispose,
|
|
414
280
|
endpoint,
|
|
415
281
|
logPath: resolvedLogPath,
|
|
282
|
+
databaseLogPath: `${resolvedLogPath}.postgres.log`,
|
|
416
283
|
projectDatabaseName: databases.project.name,
|
|
417
284
|
stateDatabaseName: databases.state.name,
|
|
418
285
|
};
|