@databricks-solutions/lakebase-scm-utils 0.2.45 → 0.2.46
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/README.md +13 -4
- package/dist/scripts/index.cjs +12 -3
- package/dist/scripts/index.js +12 -3
- package/dist/scripts/lakebase/ci-resolve-branch.cli.cjs +12 -3
- package/dist/scripts/lakebase/ci-resolve-branch.cli.js +12 -3
- package/dist/scripts/lakebase/collapse-heads.cli.cjs +12 -3
- package/dist/scripts/lakebase/collapse-heads.cli.js +12 -3
- package/dist/scripts/lakebase/detect-language.cli.cjs +12 -3
- package/dist/scripts/lakebase/detect-language.cli.js +12 -3
- package/dist/scripts/lakebase/doctor.cli.cjs +12 -3
- package/dist/scripts/lakebase/doctor.cli.js +12 -3
- package/dist/scripts/lakebase/get-connection.cli.cjs +12 -3
- package/dist/scripts/lakebase/get-connection.cli.js +12 -3
- package/dist/scripts/lakebase/index.cjs +12 -3
- package/dist/scripts/lakebase/index.d.cts +0 -11
- package/dist/scripts/lakebase/index.d.ts +0 -11
- package/dist/scripts/lakebase/index.js +12 -3
- package/dist/scripts/lakebase/infra-runner.cli.cjs +12 -3
- package/dist/scripts/lakebase/infra-runner.cli.js +12 -3
- package/dist/scripts/lakebase/new-migration.cli.cjs +12 -3
- package/dist/scripts/lakebase/new-migration.cli.js +12 -3
- package/dist/scripts/lakebase/schema-diff.cli.cjs +12 -3
- package/dist/scripts/lakebase/schema-diff.cli.js +12 -3
- package/dist/scripts/lakebase/schema-migrate.cli.cjs +12 -3
- package/dist/scripts/lakebase/schema-migrate.cli.js +12 -3
- package/dist/scripts/lakebase/scm-claim-feature.cli.cjs +12 -3
- package/dist/scripts/lakebase/scm-claim-feature.cli.js +12 -3
- package/dist/scripts/lakebase/scm-doctor.cli.cjs +12 -3
- package/dist/scripts/lakebase/scm-doctor.cli.js +12 -3
- package/dist/scripts/lakebase/scm-merge.cli.cjs +12 -3
- package/dist/scripts/lakebase/scm-merge.cli.js +12 -3
- package/dist/scripts/lakebase/scm-reconcile-tier.cli.cjs +12 -3
- package/dist/scripts/lakebase/scm-reconcile-tier.cli.js +12 -3
- package/dist/scripts/util/index.cjs +2 -2
- package/dist/scripts/util/index.js +2 -2
- package/package.json +1 -1
- package/scripts/lakebase/constants.ts +23 -5
- package/scripts/lakebase/get-connection.ts +17 -3
- package/skills/lakebase-scm-workflows/README.md +2 -1
- package/templates/project/nodejs/package.json +3 -1
- package/templates/project/nodejs/src/index.js +8 -0
- package/templates/project/nodejs/src/openapi.js +20 -0
- package/templates/project/nodejs/src/routes/health.js +18 -0
- package/templates/project/nodejs/tests/app.test.js +16 -0
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
DEFAULT_DATABASE,
|
|
24
24
|
DEFAULT_ENDPOINT,
|
|
25
25
|
POSTGRES_PORT,
|
|
26
|
+
SCM_CLIENT_ENV,
|
|
26
27
|
SCM_UTILS_APPLICATION_NAME,
|
|
27
28
|
} from "./constants.js";
|
|
28
29
|
import { substrateSelfVersion } from "./self-version.js";
|
|
@@ -39,11 +40,24 @@ import { KIT_TIMEOUTS } from "./kit-config.js";
|
|
|
39
40
|
* `pg_stat_activity`. Never throws (an unreadable scm-utils version -> `scm-utils/unknown`; a
|
|
40
41
|
* blank env is ignored), so labelling can never break a connection.
|
|
41
42
|
*/
|
|
43
|
+
/** Sanitize a consumer-provided application_name label: printable ASCII only (runs of control
|
|
44
|
+
* chars / whitespace collapse to a single '-'), trimmed of leading/trailing '-', and capped to
|
|
45
|
+
* Postgres's 63-byte application_name limit. Empty after cleaning -> the scm-utils default. */
|
|
46
|
+
function sanitizeApplicationName(raw: string): string {
|
|
47
|
+
const cleaned = raw.replace(/[^\x21-\x7e]+/g, "-").replace(/^-+|-+$/g, "");
|
|
48
|
+
if (!cleaned) return `${SCM_UTILS_APPLICATION_NAME}/${substrateSelfVersion()}`;
|
|
49
|
+
// Printable-ASCII only, so byte length == char length; trim to the 63-byte cap.
|
|
50
|
+
return cleaned.length > 63 ? cleaned.slice(0, 63) : cleaned;
|
|
51
|
+
}
|
|
52
|
+
|
|
42
53
|
export function connectionApplicationName(): string {
|
|
54
|
+
// Precedence: a consumer's generic self-brand > Consort back-compat > scm-utils default.
|
|
55
|
+
// A NEW consumer just sets LAKEBASE_SCM_CLIENT="<brand>/<version>" — no scm-utils change needed.
|
|
56
|
+
const client = process.env[SCM_CLIENT_ENV]?.trim();
|
|
57
|
+
if (client) return sanitizeApplicationName(client);
|
|
43
58
|
const consortVersion = process.env[CONSORT_VERSION_ENV]?.trim();
|
|
44
|
-
return consortVersion
|
|
45
|
-
|
|
46
|
-
: `${SCM_UTILS_APPLICATION_NAME}/${substrateSelfVersion()}`;
|
|
59
|
+
if (consortVersion) return `${CONSORT_APPLICATION_NAME}/${consortVersion}`;
|
|
60
|
+
return `${SCM_UTILS_APPLICATION_NAME}/${substrateSelfVersion()}`;
|
|
47
61
|
}
|
|
48
62
|
// AppKit / @databricks/lakebase re-exports a WorkspaceClient type that
|
|
49
63
|
// matches what createLakebasePool expects. We accept `unknown` at the API
|
|
@@ -228,7 +228,8 @@ The same flow applies to the `--enable-e2e`-scaffolded `playwright.config.ts` +
|
|
|
228
228
|
| `lakebase-infra-runner` | Run the `[Infra]`-tag suite (schema-diff + migration status + endpoint readiness) for a branch. Used by scaffolded `test:infra` scripts. |
|
|
229
229
|
| `lakebase-update-commands` | Refresh a scaffolded project's `.claude/commands/{design,build}.md` from the kit's current templates. Interactive per-file confirm by default; `--force` skips prompts, `--dry-run` previews, `--json` emits a structured report. Hook files (`<name>.{pre,post}-hook.md`) are NEVER touched. |
|
|
230
230
|
| `lakebase-feature-status` | One-screen snapshot of a TDD feature's workflow state. Pairs with `consort`. |
|
|
231
|
-
|
|
231
|
+
|
|
232
|
+
> An MCP presentation of this same substrate surface ships in the `consort` package as `lakebase-mcp-server` (stdio; for Claude Desktop / OpenAI Codex / Cursor-via-MCP / Genie Code consumers). It is not an scm-utils bin.
|
|
232
233
|
|
|
233
234
|
## JS/TS exports
|
|
234
235
|
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
require('dotenv').config();
|
|
2
2
|
const express = require('express');
|
|
3
|
+
const swaggerUi = require('swagger-ui-express');
|
|
4
|
+
const openapiSpec = require('./openapi');
|
|
3
5
|
const healthRoutes = require('./routes/health');
|
|
4
6
|
|
|
5
7
|
const app = express();
|
|
6
8
|
app.use(express.json());
|
|
7
9
|
app.use('/', healthRoutes);
|
|
8
10
|
|
|
11
|
+
// Swagger / OpenAPI UI for acceptance review (parity with FastAPI's /docs): the interactive UI at
|
|
12
|
+
// /docs and the raw spec at /openapi.json, both derived from the route @openapi annotations. For an
|
|
13
|
+
// API-only story, the acceptance gate points the reviewer here to exercise the endpoints.
|
|
14
|
+
app.use('/docs', swaggerUi.serve, swaggerUi.setup(openapiSpec));
|
|
15
|
+
app.get('/openapi.json', (req, res) => res.json(openapiSpec));
|
|
16
|
+
|
|
9
17
|
const PORT = process.env.PORT || 3000;
|
|
10
18
|
|
|
11
19
|
if (require.main === module) {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const swaggerJsdoc = require('swagger-jsdoc');
|
|
3
|
+
|
|
4
|
+
// The OpenAPI spec is built from the `@openapi` JSDoc blocks on the route files, so the Swagger UI
|
|
5
|
+
// at /docs reflects the real endpoints as they are added — the Express analogue of FastAPI's
|
|
6
|
+
// automatic /docs. Annotate every route you add with an `@openapi` block (see src/routes/health.js
|
|
7
|
+
// for the pattern); it then appears in /docs and /openapi.json with no extra wiring.
|
|
8
|
+
const spec = swaggerJsdoc({
|
|
9
|
+
definition: {
|
|
10
|
+
openapi: '3.0.3',
|
|
11
|
+
info: {
|
|
12
|
+
title: '{{PROJECT_NAME}}',
|
|
13
|
+
version: '1.0.0',
|
|
14
|
+
description: 'API surface for acceptance review (Swagger UI at /docs).',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
apis: [path.join(__dirname, 'routes', '*.js')],
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
module.exports = spec;
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
const express = require('express');
|
|
2
2
|
const router = express.Router();
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @openapi
|
|
6
|
+
* /health:
|
|
7
|
+
* get:
|
|
8
|
+
* summary: Liveness probe
|
|
9
|
+
* description: Returns ok when the service is up. Pattern for annotating routes so they appear in /docs.
|
|
10
|
+
* responses:
|
|
11
|
+
* 200:
|
|
12
|
+
* description: Service is up
|
|
13
|
+
* content:
|
|
14
|
+
* application/json:
|
|
15
|
+
* schema:
|
|
16
|
+
* type: object
|
|
17
|
+
* properties:
|
|
18
|
+
* status:
|
|
19
|
+
* type: string
|
|
20
|
+
* example: ok
|
|
21
|
+
*/
|
|
4
22
|
router.get('/health', (req, res) => {
|
|
5
23
|
res.json({ status: 'ok' });
|
|
6
24
|
});
|
|
@@ -8,3 +8,19 @@ describe('Health check', () => {
|
|
|
8
8
|
expect(res.body.status).toBe('ok');
|
|
9
9
|
});
|
|
10
10
|
});
|
|
11
|
+
|
|
12
|
+
describe('API docs (Swagger UI for acceptance review)', () => {
|
|
13
|
+
test('GET /openapi.json exposes the OpenAPI spec, including annotated routes', async () => {
|
|
14
|
+
const res = await request(app).get('/openapi.json');
|
|
15
|
+
expect(res.statusCode).toBe(200);
|
|
16
|
+
expect(res.body.openapi).toBeDefined();
|
|
17
|
+
// The @openapi annotation on the health route is picked up by swagger-jsdoc.
|
|
18
|
+
expect(res.body.paths['/health']).toBeDefined();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('GET /docs/ serves the Swagger UI', async () => {
|
|
22
|
+
const res = await request(app).get('/docs/');
|
|
23
|
+
expect(res.statusCode).toBe(200);
|
|
24
|
+
expect(res.text).toMatch(/swagger-ui/i);
|
|
25
|
+
});
|
|
26
|
+
});
|