@jskit-ai/connectors-core 0.1.35 → 0.1.37

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 CHANGED
@@ -58,8 +58,10 @@ Import `parseIntegrationConfiguration`, `validateIntegrationConfiguration` and
58
58
  `integrationsSchema` from `@jskit-ai/connectors-core/shared/configuration`.
59
59
  `integrationsSchema.getFieldDefinitions()` exposes the field definitions for
60
60
  form inspection. Validate with `validateIntegrationConfiguration`, which also
61
- checks references, credential combinations and provider scopes. Custom reference
62
- validators do not currently provide transport JSON Schema export hooks.
61
+ checks references, credential combinations and provider scopes. Use
62
+ `integrationsSchema.toJsonSchema({ mode: "replace" })` to export the structural
63
+ contract, including credential-reference constraints, for machine callers.
64
+ The export does not replace the provider-specific semantic validation.
63
65
  References use a binding namespace such as `env:NAME` or `vault:path`;
64
66
  literal HTTP/HTTPS URLs are rejected in reference fields.
65
67
  Pass registered provider definitions in `{ providers }` for provider validation.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/connectors-core",
3
- "version": "0.1.35",
3
+ "version": "0.1.37",
4
4
  "description": "Portable integration configuration and server-side account connection runtime.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -53,9 +53,9 @@
53
53
  }
54
54
  },
55
55
  "peerDependencies": {
56
- "@jskit-ai/database-runtime": "0.1.218",
57
- "@jskit-ai/http-runtime": "0.1.216",
58
- "@jskit-ai/kernel": "0.1.218"
56
+ "@jskit-ai/database-runtime": "0.1.220",
57
+ "@jskit-ai/http-runtime": "0.1.218",
58
+ "@jskit-ai/kernel": "0.1.220"
59
59
  },
60
60
  "peerDependenciesMeta": {
61
61
  "@jskit-ai/database-runtime": {
@@ -4,7 +4,7 @@ import { validateSchemaPayload } from "@jskit-ai/kernel/shared/validators";
4
4
  const name = { type: "string", required: true, minLength: 1, maxLength: 200 };
5
5
  const secretReference = {
6
6
  ...name,
7
- validator: (value) => (/^[a-z][a-z0-9-]*:[^\s]+$/u.test(value) && !/^https?:/u.test(value)) || "Use a reference such as env:VARIABLE_NAME."
7
+ pattern: "^(?!https?:)[a-z][a-z0-9-]*:[^\\s]+$"
8
8
  };
9
9
  const authenticationSchema = createSchema({
10
10
  method: { ...name, enum: ["oauth2", "api-key", "service-account", "none"] },
@@ -3,11 +3,12 @@ import { firecrawlProvider } from "../../connectors-catalog/src/server/firecrawl
3
3
  import { mailgunDefinition } from "../../connectors-catalog/src/shared/tokens.js";
4
4
  import assert from "node:assert/strict";
5
5
  import test from "node:test";
6
+ import Fastify from "fastify";
6
7
  import { createCapabilityRuntime, defineProvider } from "@jskit-ai/kernel/shared/capabilities";
7
8
  import { createActionProvider } from "@jskit-ai/kernel/server/actions";
8
9
  import { googleCalendarProvider } from "../../connector-google-calendar/src/server/provider.js";
9
10
  import { createConnectionService, createConnectorsFeature, createEnvironmentReferenceResolver } from "../src/server/index.js";
10
- import { parseIntegrationConfiguration, validateIntegrationConfiguration } from "../src/shared/configuration.js";
11
+ import { integrationsSchema, parseIntegrationConfiguration, validateIntegrationConfiguration } from "../src/shared/configuration.js";
11
12
  import { clickhouseProvider } from "../../connectors-catalog/src/server/clickhouse.js";
12
13
 
13
14
  const listScope = "https://www.googleapis.com/auth/calendar.calendarlist.readonly";
@@ -466,6 +467,27 @@ test("reference fields reject pasted web URLs while preserving environment and c
466
467
  }
467
468
  });
468
469
 
470
+ test("the exported configuration contract enforces reference constraints for every credential field", async (t) => {
471
+ const app = Fastify({ ajv: { plugins: [(ajv) => ajv.addKeyword("x-json-rest-schema")] } });
472
+ t.after(() => app.close());
473
+ app.post("/configuration", { schema: { body: integrationsSchema.toJsonSchema({ mode: "replace" }) } }, async () => ({ ok: true }));
474
+ for (const field of ["secretRef", "clientSecretRef", "callbackUrlRef"]) {
475
+ for (const [value, valid] of [
476
+ ["env:KEY", true], ["vault:applications/key", true], ["vault://applications/key", true],
477
+ ["raw-key", false], ["https://example.test/key", false], ["http://localhost/key", false],
478
+ ["env:", false], ["env:two words", false], ["ENV:KEY", false], ["env:" + "a".repeat(197), false]
479
+ ]) {
480
+ const input = field === "secretRef" ? databaseConfiguration({ method: "api-key", secretRef: value }) : configuration();
481
+ if (field !== "secretRef") input.registrations.google[field] = value;
482
+ const check = () => validateIntegrationConfiguration(input, { providers: [googleCalendarProvider, clickhouseProvider] });
483
+ if (valid) assert.doesNotThrow(check, `${field}: ${value}`);
484
+ else assert.throws(check, { code: "integration_configuration_invalid" });
485
+ const response = await app.inject({ method: "POST", url: "/configuration", payload: input });
486
+ assert.equal(response.statusCode, valid ? 200 : 400, `${field}: ${value}`);
487
+ }
488
+ }
489
+ });
490
+
469
491
  test("configuration rejects missing references and unknown scopes", () => {
470
492
  const input = configuration();
471
493
  input.integrations.calendar.authentication.registrationRef = "missing";