@backstage/backend-test-utils 1.11.4-next.0 → 1.11.4-next.1
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 +10 -0
- package/dist/alpha/services/MockActionsRegistry.cjs.js +20 -1
- package/dist/alpha/services/MockActionsRegistry.cjs.js.map +1 -1
- package/dist/alpha.d.ts +3 -2
- package/dist/database/mysql.cjs.js +6 -2
- package/dist/database/mysql.cjs.js.map +1 -1
- package/dist/database/types.cjs.js +3 -1
- package/dist/database/types.cjs.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @backstage/backend-test-utils
|
|
2
2
|
|
|
3
|
+
## 1.11.4-next.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 2d181c0: Increased MySQL connection and pool timeouts to reduce flaky `connect ETIMEDOUT` failures in CI. The test MySQL container now also uses `mysql_native_password` for cheaper connection handshakes and disables binary logging.
|
|
8
|
+
- 06a2035: Updated `MockActionsRegistry` to support the new secrets schema. The mock now validates secrets against the declared schema, rejects missing secrets for actions that require them, and forwards secrets to the action handler.
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
- @backstage/backend-defaults@0.17.3-next.1
|
|
11
|
+
- @backstage/backend-plugin-api@1.9.2-next.1
|
|
12
|
+
|
|
3
13
|
## 1.11.4-next.0
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
|
@@ -36,7 +36,10 @@ class MockActionsRegistry {
|
|
|
36
36
|
examples: action.examples,
|
|
37
37
|
schema: {
|
|
38
38
|
input: action.schema?.input ? zodToJsonSchema__default.default(action.schema.input(v3.z)) : zodToJsonSchema__default.default(v3.z.object({})),
|
|
39
|
-
output: action.schema?.output ? zodToJsonSchema__default.default(action.schema.output(v3.z)) : zodToJsonSchema__default.default(v3.z.object({}))
|
|
39
|
+
output: action.schema?.output ? zodToJsonSchema__default.default(action.schema.output(v3.z)) : zodToJsonSchema__default.default(v3.z.object({})),
|
|
40
|
+
...action.schema?.secrets && {
|
|
41
|
+
secrets: zodToJsonSchema__default.default(action.schema.secrets(v3.z))
|
|
42
|
+
}
|
|
40
43
|
}
|
|
41
44
|
}))
|
|
42
45
|
};
|
|
@@ -53,8 +56,24 @@ class MockActionsRegistry {
|
|
|
53
56
|
if (!input.success) {
|
|
54
57
|
throw new errors.InputError(`Invalid input to action "${opts.id}"`, input.error);
|
|
55
58
|
}
|
|
59
|
+
if (action.schema?.secrets && !opts.secrets) {
|
|
60
|
+
throw new errors.InputError(
|
|
61
|
+
`Action "${opts.id}" requires secrets but none were provided`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
if (!action.schema?.secrets && opts.secrets) {
|
|
65
|
+
throw new errors.InputError(`Action "${opts.id}" does not accept secrets`);
|
|
66
|
+
}
|
|
67
|
+
const secrets = action.schema?.secrets ? action.schema.secrets(v3.z).safeParse(opts.secrets) : { success: true, data: void 0 };
|
|
68
|
+
if (!secrets.success) {
|
|
69
|
+
throw new errors.InputError(
|
|
70
|
+
`Invalid secrets for action "${opts.id}"`,
|
|
71
|
+
secrets.error
|
|
72
|
+
);
|
|
73
|
+
}
|
|
56
74
|
const result = await action.action({
|
|
57
75
|
input: input.data,
|
|
76
|
+
secrets: secrets.data,
|
|
58
77
|
credentials: opts.credentials ?? mockCredentials.mockCredentials.none(),
|
|
59
78
|
logger: this.logger
|
|
60
79
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MockActionsRegistry.cjs.js","sources":["../../../src/alpha/services/MockActionsRegistry.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n BackstageCredentials,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport { InputError, NotFoundError } from '@backstage/errors';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport { z, AnyZodObject } from 'zod/v3';\nimport zodToJsonSchema from 'zod-to-json-schema';\nimport { mockCredentials } from '../../services';\nimport {\n ActionsRegistryActionOptions,\n ActionsRegistryService,\n ActionsService,\n ActionsServiceAction,\n} from '@backstage/backend-plugin-api/alpha';\n\n/**\n * A mock implementation of the ActionsRegistryService and ActionsService that can be used in tests.\n *\n * This is useful for testing actions that are registered with the ActionsRegistryService and ActionsService.\n *\n * The plugin ID is hardcoded to `testing` in the mock implementation.\n *\n * @example\n * ```ts\n * const actionsRegistry = mockServices.actionsRegistry();\n *\n * actionsRegistry.register({\n * name: 'test',\n * title: 'Test',\n * description: 'Test',\n * schema: {\n * input: z.object({ name: z.string() }),\n * output: z.object({ name: z.string() }),\n * },\n * action: async ({ input }) => ({ output: { name: input.name } }),\n * });\n *\n *\n * const result = await actionsRegistry.invoke({\n * id: 'testing:test',\n * input: { name: 'test' },\n * });\n *\n * expect(result).toEqual({ output: { name: 'test' } });\n * ```\n *\n * @alpha\n */\nexport class MockActionsRegistry\n implements ActionsRegistryService, ActionsService\n{\n private readonly logger: LoggerService;\n\n private constructor(logger: LoggerService) {\n this.logger = logger;\n }\n\n static create(opts: { logger: LoggerService }) {\n return new MockActionsRegistry(opts.logger);\n }\n\n readonly actions: Map<string, ActionsRegistryActionOptions<any, any>> =\n new Map();\n\n async list(): Promise<{ actions: ActionsServiceAction[] }> {\n return {\n actions: Array.from(this.actions.entries()).map(([id, action]) => ({\n id,\n pluginId: 'test',\n name: action.name,\n title: action.title,\n description: action.description,\n attributes: {\n destructive: action.attributes?.destructive ?? true,\n idempotent: action.attributes?.idempotent ?? false,\n readOnly: action.attributes?.readOnly ?? false,\n },\n examples: action.examples,\n schema: {\n input: action.schema?.input\n ? zodToJsonSchema(action.schema.input(z))\n : zodToJsonSchema(z.object({})),\n output: action.schema?.output\n ? zodToJsonSchema(action.schema.output(z))\n : zodToJsonSchema(z.object({})),\n } as ActionsServiceAction['schema'],\n })),\n };\n }\n\n async invoke(opts: {\n id: string;\n input?: JsonObject;\n credentials?: BackstageCredentials;\n }): Promise<{ output: JsonValue }> {\n const action = this.actions.get(opts.id);\n\n if (!action) {\n const availableActionIds = Array.from(this.actions.keys()).join(', ');\n throw new NotFoundError(\n `Action \"${opts.id}\" not found, available actions: ${\n availableActionIds ? `\"${availableActionIds}\"` : 'none'\n }`,\n );\n }\n\n const input = action.schema?.input\n ? action.schema.input(z).safeParse(opts.input)\n : ({ success: true, data: undefined } as const);\n\n if (!input.success) {\n throw new InputError(`Invalid input to action \"${opts.id}\"`, input.error);\n }\n\n const result = await action.action({\n input: input.data,\n credentials: opts.credentials ?? mockCredentials.none(),\n logger: this.logger,\n });\n\n const output = action.schema?.output\n ? action.schema.output(z).safeParse(result?.output)\n : ({ success: true, data: result?.output } as const);\n\n if (!output.success) {\n throw new InputError(\n `Invalid output from action \"${opts.id}\"`,\n output.error,\n );\n }\n\n return { output: output.data };\n }\n\n register<\n TInputSchema extends AnyZodObject,\n TOutputSchema extends AnyZodObject,\n >(options: ActionsRegistryActionOptions<TInputSchema, TOutputSchema>): void {\n // hardcode test: prefix similar to how the default actions registry does it\n // and other places around the testing ecosystem:\n // https://github.com/backstage/backstage/blob/a9219496d5c073aaa0b8caf32ece10455cf65e61/packages/backend-test-utils/src/next/services/mockServices.ts#L321\n // https://github.com/backstage/backstage/blob/861f162b4a39117b824669d67a951ed1db142e3d/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts#L99\n const id = `test:${options.name}`;\n\n if (this.actions.has(id)) {\n throw new Error(`Action with id \"${id}\" is already registered`);\n }\n\n this.actions.set(id, options);\n }\n}\n"],"names":["zodToJsonSchema","z","NotFoundError","InputError","mockCredentials"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MockActionsRegistry.cjs.js","sources":["../../../src/alpha/services/MockActionsRegistry.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n BackstageCredentials,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport { InputError, NotFoundError } from '@backstage/errors';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport { z, AnyZodObject } from 'zod/v3';\nimport zodToJsonSchema from 'zod-to-json-schema';\nimport { mockCredentials } from '../../services';\nimport {\n ActionsRegistryActionOptions,\n ActionsRegistryService,\n ActionsService,\n ActionsServiceAction,\n} from '@backstage/backend-plugin-api/alpha';\n\n/**\n * A mock implementation of the ActionsRegistryService and ActionsService that can be used in tests.\n *\n * This is useful for testing actions that are registered with the ActionsRegistryService and ActionsService.\n *\n * The plugin ID is hardcoded to `testing` in the mock implementation.\n *\n * @example\n * ```ts\n * const actionsRegistry = mockServices.actionsRegistry();\n *\n * actionsRegistry.register({\n * name: 'test',\n * title: 'Test',\n * description: 'Test',\n * schema: {\n * input: z.object({ name: z.string() }),\n * output: z.object({ name: z.string() }),\n * },\n * action: async ({ input }) => ({ output: { name: input.name } }),\n * });\n *\n *\n * const result = await actionsRegistry.invoke({\n * id: 'testing:test',\n * input: { name: 'test' },\n * });\n *\n * expect(result).toEqual({ output: { name: 'test' } });\n * ```\n *\n * @alpha\n */\nexport class MockActionsRegistry\n implements ActionsRegistryService, ActionsService\n{\n private readonly logger: LoggerService;\n\n private constructor(logger: LoggerService) {\n this.logger = logger;\n }\n\n static create(opts: { logger: LoggerService }) {\n return new MockActionsRegistry(opts.logger);\n }\n\n readonly actions: Map<string, ActionsRegistryActionOptions<any, any, any>> =\n new Map();\n\n async list(): Promise<{ actions: ActionsServiceAction[] }> {\n return {\n actions: Array.from(this.actions.entries()).map(([id, action]) => ({\n id,\n pluginId: 'test',\n name: action.name,\n title: action.title,\n description: action.description,\n attributes: {\n destructive: action.attributes?.destructive ?? true,\n idempotent: action.attributes?.idempotent ?? false,\n readOnly: action.attributes?.readOnly ?? false,\n },\n examples: action.examples,\n schema: {\n input: action.schema?.input\n ? zodToJsonSchema(action.schema.input(z))\n : zodToJsonSchema(z.object({})),\n output: action.schema?.output\n ? zodToJsonSchema(action.schema.output(z))\n : zodToJsonSchema(z.object({})),\n ...(action.schema?.secrets && {\n secrets: zodToJsonSchema(action.schema.secrets(z)),\n }),\n } as ActionsServiceAction['schema'],\n })),\n };\n }\n\n async invoke(opts: {\n id: string;\n input?: JsonObject;\n secrets?: JsonObject;\n credentials?: BackstageCredentials;\n }): Promise<{ output: JsonValue }> {\n const action = this.actions.get(opts.id);\n\n if (!action) {\n const availableActionIds = Array.from(this.actions.keys()).join(', ');\n throw new NotFoundError(\n `Action \"${opts.id}\" not found, available actions: ${\n availableActionIds ? `\"${availableActionIds}\"` : 'none'\n }`,\n );\n }\n\n const input = action.schema?.input\n ? action.schema.input(z).safeParse(opts.input)\n : ({ success: true, data: undefined } as const);\n\n if (!input.success) {\n throw new InputError(`Invalid input to action \"${opts.id}\"`, input.error);\n }\n\n if (action.schema?.secrets && !opts.secrets) {\n throw new InputError(\n `Action \"${opts.id}\" requires secrets but none were provided`,\n );\n }\n\n if (!action.schema?.secrets && opts.secrets) {\n throw new InputError(`Action \"${opts.id}\" does not accept secrets`);\n }\n\n const secrets = action.schema?.secrets\n ? action.schema.secrets(z).safeParse(opts.secrets)\n : ({ success: true, data: undefined } as const);\n\n if (!secrets.success) {\n throw new InputError(\n `Invalid secrets for action \"${opts.id}\"`,\n secrets.error,\n );\n }\n\n const result = await action.action({\n input: input.data,\n secrets: secrets.data,\n credentials: opts.credentials ?? mockCredentials.none(),\n logger: this.logger,\n });\n\n const output = action.schema?.output\n ? action.schema.output(z).safeParse(result?.output)\n : ({ success: true, data: result?.output } as const);\n\n if (!output.success) {\n throw new InputError(\n `Invalid output from action \"${opts.id}\"`,\n output.error,\n );\n }\n\n return { output: output.data };\n }\n\n register<\n TInputSchema extends AnyZodObject,\n TOutputSchema extends AnyZodObject,\n TSecretsSchema extends AnyZodObject | undefined = undefined,\n >(\n options: ActionsRegistryActionOptions<\n TInputSchema,\n TOutputSchema,\n TSecretsSchema\n >,\n ): void {\n // hardcode test: prefix similar to how the default actions registry does it\n // and other places around the testing ecosystem:\n // https://github.com/backstage/backstage/blob/a9219496d5c073aaa0b8caf32ece10455cf65e61/packages/backend-test-utils/src/next/services/mockServices.ts#L321\n // https://github.com/backstage/backstage/blob/861f162b4a39117b824669d67a951ed1db142e3d/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts#L99\n const id = `test:${options.name}`;\n\n if (this.actions.has(id)) {\n throw new Error(`Action with id \"${id}\" is already registered`);\n }\n\n this.actions.set(id, options);\n }\n}\n"],"names":["zodToJsonSchema","z","NotFoundError","InputError","mockCredentials"],"mappings":";;;;;;;;;;;;;AAgEO,MAAM,mBAAA,CAEb;AAAA,EACmB,MAAA;AAAA,EAET,YAAY,MAAA,EAAuB;AACzC,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA,EAEA,OAAO,OAAO,IAAA,EAAiC;AAC7C,IAAA,OAAO,IAAI,mBAAA,CAAoB,IAAA,CAAK,MAAM,CAAA;AAAA,EAC5C;AAAA,EAES,OAAA,uBACH,GAAA,EAAI;AAAA,EAEV,MAAM,IAAA,GAAqD;AACzD,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,EAAA,EAAI,MAAM,CAAA,MAAO;AAAA,QACjE,EAAA;AAAA,QACA,QAAA,EAAU,MAAA;AAAA,QACV,MAAM,MAAA,CAAO,IAAA;AAAA,QACb,OAAO,MAAA,CAAO,KAAA;AAAA,QACd,aAAa,MAAA,CAAO,WAAA;AAAA,QACpB,UAAA,EAAY;AAAA,UACV,WAAA,EAAa,MAAA,CAAO,UAAA,EAAY,WAAA,IAAe,IAAA;AAAA,UAC/C,UAAA,EAAY,MAAA,CAAO,UAAA,EAAY,UAAA,IAAc,KAAA;AAAA,UAC7C,QAAA,EAAU,MAAA,CAAO,UAAA,EAAY,QAAA,IAAY;AAAA,SAC3C;AAAA,QACA,UAAU,MAAA,CAAO,QAAA;AAAA,QACjB,MAAA,EAAQ;AAAA,UACN,OAAO,MAAA,CAAO,MAAA,EAAQ,KAAA,GAClBA,gCAAA,CAAgB,OAAO,MAAA,CAAO,KAAA,CAAMC,IAAC,CAAC,IACtCD,gCAAA,CAAgBC,IAAA,CAAE,MAAA,CAAO,EAAE,CAAC,CAAA;AAAA,UAChC,QAAQ,MAAA,CAAO,MAAA,EAAQ,MAAA,GACnBD,gCAAA,CAAgB,OAAO,MAAA,CAAO,MAAA,CAAOC,IAAC,CAAC,IACvCD,gCAAA,CAAgBC,IAAA,CAAE,MAAA,CAAO,EAAE,CAAC,CAAA;AAAA,UAChC,GAAI,MAAA,CAAO,MAAA,EAAQ,OAAA,IAAW;AAAA,YAC5B,SAASD,gCAAA,CAAgB,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQC,IAAC,CAAC;AAAA;AACnD;AACF,OACF,CAAE;AAAA,KACJ;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,IAAA,EAKsB;AACjC,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,KAAK,EAAE,CAAA;AAEvC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,kBAAA,GAAqB,MAAM,IAAA,CAAK,IAAA,CAAK,QAAQ,IAAA,EAAM,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AACpE,MAAA,MAAM,IAAIC,oBAAA;AAAA,QACR,CAAA,QAAA,EAAW,KAAK,EAAE,CAAA,gCAAA,EAChB,qBAAqB,CAAA,CAAA,EAAI,kBAAkB,MAAM,MACnD,CAAA;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,QAAQ,MAAA,CAAO,MAAA,EAAQ,KAAA,GACzB,MAAA,CAAO,OAAO,KAAA,CAAMD,IAAC,CAAA,CAAE,SAAA,CAAU,KAAK,KAAK,CAAA,GAC1C,EAAE,OAAA,EAAS,IAAA,EAAM,MAAM,MAAA,EAAU;AAEtC,IAAA,IAAI,CAAC,MAAM,OAAA,EAAS;AAClB,MAAA,MAAM,IAAIE,iBAAA,CAAW,CAAA,yBAAA,EAA4B,KAAK,EAAE,CAAA,CAAA,CAAA,EAAK,MAAM,KAAK,CAAA;AAAA,IAC1E;AAEA,IAAA,IAAI,MAAA,CAAO,MAAA,EAAQ,OAAA,IAAW,CAAC,KAAK,OAAA,EAAS;AAC3C,MAAA,MAAM,IAAIA,iBAAA;AAAA,QACR,CAAA,QAAA,EAAW,KAAK,EAAE,CAAA,yCAAA;AAAA,OACpB;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,OAAA,IAAW,KAAK,OAAA,EAAS;AAC3C,MAAA,MAAM,IAAIA,iBAAA,CAAW,CAAA,QAAA,EAAW,IAAA,CAAK,EAAE,CAAA,yBAAA,CAA2B,CAAA;AAAA,IACpE;AAEA,IAAA,MAAM,UAAU,MAAA,CAAO,MAAA,EAAQ,OAAA,GAC3B,MAAA,CAAO,OAAO,OAAA,CAAQF,IAAC,CAAA,CAAE,SAAA,CAAU,KAAK,OAAO,CAAA,GAC9C,EAAE,OAAA,EAAS,IAAA,EAAM,MAAM,MAAA,EAAU;AAEtC,IAAA,IAAI,CAAC,QAAQ,OAAA,EAAS;AACpB,MAAA,MAAM,IAAIE,iBAAA;AAAA,QACR,CAAA,4BAAA,EAA+B,KAAK,EAAE,CAAA,CAAA,CAAA;AAAA,QACtC,OAAA,CAAQ;AAAA,OACV;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,MAAA,CAAO;AAAA,MACjC,OAAO,KAAA,CAAM,IAAA;AAAA,MACb,SAAS,OAAA,CAAQ,IAAA;AAAA,MACjB,WAAA,EAAa,IAAA,CAAK,WAAA,IAAeC,+BAAA,CAAgB,IAAA,EAAK;AAAA,MACtD,QAAQ,IAAA,CAAK;AAAA,KACd,CAAA;AAED,IAAA,MAAM,SAAS,MAAA,CAAO,MAAA,EAAQ,SAC1B,MAAA,CAAO,MAAA,CAAO,OAAOH,IAAC,CAAA,CAAE,SAAA,CAAU,MAAA,EAAQ,MAAM,CAAA,GAC/C,EAAE,SAAS,IAAA,EAAM,IAAA,EAAM,QAAQ,MAAA,EAAO;AAE3C,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,MAAA,MAAM,IAAIE,iBAAA;AAAA,QACR,CAAA,4BAAA,EAA+B,KAAK,EAAE,CAAA,CAAA,CAAA;AAAA,QACtC,MAAA,CAAO;AAAA,OACT;AAAA,IACF;AAEA,IAAA,OAAO,EAAE,MAAA,EAAQ,MAAA,CAAO,IAAA,EAAK;AAAA,EAC/B;AAAA,EAEA,SAKE,OAAA,EAKM;AAKN,IAAA,MAAM,EAAA,GAAK,CAAA,KAAA,EAAQ,OAAA,CAAQ,IAAI,CAAA,CAAA;AAE/B,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,EAAG;AACxB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,EAAE,CAAA,uBAAA,CAAyB,CAAA;AAAA,IAChE;AAEA,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAA,EAAI,OAAO,CAAA;AAAA,EAC9B;AACF;;;;"}
|
package/dist/alpha.d.ts
CHANGED
|
@@ -45,18 +45,19 @@ declare class MockActionsRegistry implements ActionsRegistryService, ActionsServ
|
|
|
45
45
|
static create(opts: {
|
|
46
46
|
logger: LoggerService;
|
|
47
47
|
}): MockActionsRegistry;
|
|
48
|
-
readonly actions: Map<string, ActionsRegistryActionOptions<any, any>>;
|
|
48
|
+
readonly actions: Map<string, ActionsRegistryActionOptions<any, any, any>>;
|
|
49
49
|
list(): Promise<{
|
|
50
50
|
actions: ActionsServiceAction[];
|
|
51
51
|
}>;
|
|
52
52
|
invoke(opts: {
|
|
53
53
|
id: string;
|
|
54
54
|
input?: JsonObject;
|
|
55
|
+
secrets?: JsonObject;
|
|
55
56
|
credentials?: BackstageCredentials;
|
|
56
57
|
}): Promise<{
|
|
57
58
|
output: JsonValue;
|
|
58
59
|
}>;
|
|
59
|
-
register<TInputSchema extends AnyZodObject, TOutputSchema extends AnyZodObject>(options: ActionsRegistryActionOptions<TInputSchema, TOutputSchema>): void;
|
|
60
|
+
register<TInputSchema extends AnyZodObject, TOutputSchema extends AnyZodObject, TSecretsSchema extends AnyZodObject | undefined = undefined>(options: ActionsRegistryActionOptions<TInputSchema, TOutputSchema, TSecretsSchema>): void;
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
/**
|
|
@@ -32,7 +32,10 @@ async function startMysqlContainer(image) {
|
|
|
32
32
|
const user = "root";
|
|
33
33
|
const password = node_crypto.randomUUID();
|
|
34
34
|
const { GenericContainer } = require("testcontainers");
|
|
35
|
-
const container = await new GenericContainer(image).withExposedPorts(3306).withEnvironment({ MYSQL_ROOT_PASSWORD: password }).withTmpFs({ "/var/lib/mysql": "rw" }).
|
|
35
|
+
const container = await new GenericContainer(image).withExposedPorts(3306).withEnvironment({ MYSQL_ROOT_PASSWORD: password }).withTmpFs({ "/var/lib/mysql": "rw" }).withCommand([
|
|
36
|
+
"--default-authentication-plugin=mysql_native_password",
|
|
37
|
+
"--skip-log-bin"
|
|
38
|
+
]).start();
|
|
36
39
|
const host = container.getHost();
|
|
37
40
|
const port = container.getMappedPort(3306);
|
|
38
41
|
const connection = { host, port, user, password };
|
|
@@ -123,7 +126,8 @@ class MysqlEngine {
|
|
|
123
126
|
client: this.#properties.driver,
|
|
124
127
|
connection: {
|
|
125
128
|
...this.#connection,
|
|
126
|
-
database: databaseName
|
|
129
|
+
database: databaseName,
|
|
130
|
+
connectTimeout: 3e4
|
|
127
131
|
},
|
|
128
132
|
...types.LARGER_POOL_CONFIG
|
|
129
133
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mysql.cjs.js","sources":["../../src/database/mysql.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { randomBytes } from 'node:crypto';\nimport knexFactory, { Knex } from 'knex';\nimport { randomUUID as uuid } from 'node:crypto';\nimport yn from 'yn';\nimport { waitForReady } from '../util/waitForReady';\nimport { Engine, LARGER_POOL_CONFIG, TestDatabaseProperties } from './types';\n\nasync function waitForMysqlReady(\n connection: Knex.MySqlConnectionConfig,\n): Promise<void> {\n await waitForReady(async () => {\n const knex = knexFactory({\n client: 'mysql2',\n connection: {\n // make a copy because the driver mutates this\n ...connection,\n },\n });\n try {\n const result = await knex.select(knex.raw('version() AS version'));\n return Array.isArray(result) && Boolean(result[0]?.version);\n } finally {\n await knex.destroy();\n }\n }, 'the database');\n}\n\nexport async function startMysqlContainer(image: string): Promise<{\n connection: Knex.MySqlConnectionConfig;\n stopContainer: () => Promise<void>;\n}> {\n const user = 'root';\n const password = uuid();\n\n // Lazy-load to avoid side-effect of importing testcontainers\n const { GenericContainer } =\n require('testcontainers') as typeof import('testcontainers');\n\n const container = await new GenericContainer(image)\n .withExposedPorts(3306)\n .withEnvironment({ MYSQL_ROOT_PASSWORD: password })\n .withTmpFs({ '/var/lib/mysql': 'rw' })\n .start();\n\n const host = container.getHost();\n const port = container.getMappedPort(3306);\n const connection = { host, port, user, password };\n const stopContainer = async () => {\n await container.stop({ timeout: 10_000 });\n };\n\n await waitForMysqlReady(connection);\n\n return { connection, stopContainer };\n}\n\nexport function parseMysqlConnectionString(\n connectionString: string,\n): Knex.MySqlConnectionConfig {\n try {\n const {\n protocol,\n username,\n password,\n port,\n hostname,\n pathname,\n searchParams,\n } = new URL(connectionString);\n\n if (protocol !== 'mysql:') {\n throw new Error(`Unknown protocol ${protocol}`);\n } else if (!username || !password) {\n throw new Error(`Missing username/password`);\n } else if (!pathname.match(/^\\/[^/]+$/)) {\n throw new Error(`Expected single path segment`);\n }\n\n const result: Knex.MySqlConnectionConfig = {\n user: username,\n password,\n host: hostname,\n port: Number(port || 3306),\n database: decodeURIComponent(pathname.substring(1)),\n };\n\n const ssl = searchParams.get('ssl');\n if (ssl) {\n result.ssl = ssl;\n }\n\n const debug = searchParams.get('debug');\n if (debug) {\n result.debug = yn(debug);\n }\n\n return result;\n } catch (e) {\n throw new Error(`Error while parsing MySQL connection string, ${e}`, e);\n }\n}\n\nexport class MysqlEngine implements Engine {\n static async create(\n properties: TestDatabaseProperties,\n ): Promise<MysqlEngine> {\n const { connectionStringEnvironmentVariableName, dockerImageName } =\n properties;\n\n if (connectionStringEnvironmentVariableName) {\n const connectionString =\n process.env[connectionStringEnvironmentVariableName];\n if (connectionString) {\n const connection = parseMysqlConnectionString(connectionString);\n return new MysqlEngine(\n properties,\n connection as Knex.MySqlConnectionConfig,\n );\n }\n }\n\n if (dockerImageName) {\n const { connection, stopContainer } = await startMysqlContainer(\n dockerImageName,\n );\n return new MysqlEngine(properties, connection, stopContainer);\n }\n\n throw new Error(`Test databasee for ${properties.name} not configured`);\n }\n\n readonly #properties: TestDatabaseProperties;\n readonly #connection: Knex.MySqlConnectionConfig;\n readonly #knexInstances: Knex[];\n readonly #databaseNames: string[];\n readonly #stopContainer?: () => Promise<void>;\n\n constructor(\n properties: TestDatabaseProperties,\n connection: Knex.MySqlConnectionConfig,\n stopContainer?: () => Promise<void>,\n ) {\n this.#properties = properties;\n this.#connection = connection;\n this.#knexInstances = [];\n this.#databaseNames = [];\n this.#stopContainer = stopContainer;\n }\n\n async createDatabaseInstance(): Promise<Knex> {\n const adminConnection = this.#connectAdmin();\n try {\n const databaseName = `db${randomBytes(16).toString('hex')}`;\n\n await adminConnection.raw('CREATE DATABASE ??', [databaseName]);\n this.#databaseNames.push(databaseName);\n\n const knexInstance = knexFactory({\n client: this.#properties.driver,\n connection: {\n ...this.#connection,\n database: databaseName,\n },\n ...LARGER_POOL_CONFIG,\n });\n this.#knexInstances.push(knexInstance);\n\n return knexInstance;\n } finally {\n await adminConnection.destroy();\n }\n }\n\n async shutdown(): Promise<void> {\n for (const instance of this.#knexInstances) {\n await instance.destroy();\n }\n\n const adminConnection = this.#connectAdmin();\n try {\n for (const databaseName of this.#databaseNames) {\n await adminConnection.raw('DROP DATABASE ??', [databaseName]);\n }\n } finally {\n await adminConnection.destroy();\n }\n\n await this.#stopContainer?.();\n }\n\n #connectAdmin(): Knex {\n const connection = {\n ...this.#connection,\n database: null as unknown as string,\n };\n return knexFactory({\n client: this.#properties.driver,\n connection,\n pool: {\n min: 0,\n max: 1,\n acquireTimeoutMillis: 20_000,\n createTimeoutMillis: 20_000,\n createRetryIntervalMillis: 1_000,\n },\n });\n }\n}\n"],"names":["waitForReady","knexFactory","uuid","yn","randomBytes","LARGER_POOL_CONFIG"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mysql.cjs.js","sources":["../../src/database/mysql.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { randomBytes } from 'node:crypto';\nimport knexFactory, { Knex } from 'knex';\nimport { randomUUID as uuid } from 'node:crypto';\nimport yn from 'yn';\nimport { waitForReady } from '../util/waitForReady';\nimport { Engine, LARGER_POOL_CONFIG, TestDatabaseProperties } from './types';\n\nasync function waitForMysqlReady(\n connection: Knex.MySqlConnectionConfig,\n): Promise<void> {\n await waitForReady(async () => {\n const knex = knexFactory({\n client: 'mysql2',\n connection: {\n // make a copy because the driver mutates this\n ...connection,\n },\n });\n try {\n const result = await knex.select(knex.raw('version() AS version'));\n return Array.isArray(result) && Boolean(result[0]?.version);\n } finally {\n await knex.destroy();\n }\n }, 'the database');\n}\n\nexport async function startMysqlContainer(image: string): Promise<{\n connection: Knex.MySqlConnectionConfig;\n stopContainer: () => Promise<void>;\n}> {\n const user = 'root';\n const password = uuid();\n\n // Lazy-load to avoid side-effect of importing testcontainers\n const { GenericContainer } =\n require('testcontainers') as typeof import('testcontainers');\n\n const container = await new GenericContainer(image)\n .withExposedPorts(3306)\n .withEnvironment({ MYSQL_ROOT_PASSWORD: password })\n .withTmpFs({ '/var/lib/mysql': 'rw' })\n .withCommand([\n '--default-authentication-plugin=mysql_native_password',\n '--skip-log-bin',\n ])\n .start();\n\n const host = container.getHost();\n const port = container.getMappedPort(3306);\n const connection = { host, port, user, password };\n const stopContainer = async () => {\n await container.stop({ timeout: 10_000 });\n };\n\n await waitForMysqlReady(connection);\n\n return { connection, stopContainer };\n}\n\nexport function parseMysqlConnectionString(\n connectionString: string,\n): Knex.MySqlConnectionConfig {\n try {\n const {\n protocol,\n username,\n password,\n port,\n hostname,\n pathname,\n searchParams,\n } = new URL(connectionString);\n\n if (protocol !== 'mysql:') {\n throw new Error(`Unknown protocol ${protocol}`);\n } else if (!username || !password) {\n throw new Error(`Missing username/password`);\n } else if (!pathname.match(/^\\/[^/]+$/)) {\n throw new Error(`Expected single path segment`);\n }\n\n const result: Knex.MySqlConnectionConfig = {\n user: username,\n password,\n host: hostname,\n port: Number(port || 3306),\n database: decodeURIComponent(pathname.substring(1)),\n };\n\n const ssl = searchParams.get('ssl');\n if (ssl) {\n result.ssl = ssl;\n }\n\n const debug = searchParams.get('debug');\n if (debug) {\n result.debug = yn(debug);\n }\n\n return result;\n } catch (e) {\n throw new Error(`Error while parsing MySQL connection string, ${e}`, e);\n }\n}\n\nexport class MysqlEngine implements Engine {\n static async create(\n properties: TestDatabaseProperties,\n ): Promise<MysqlEngine> {\n const { connectionStringEnvironmentVariableName, dockerImageName } =\n properties;\n\n if (connectionStringEnvironmentVariableName) {\n const connectionString =\n process.env[connectionStringEnvironmentVariableName];\n if (connectionString) {\n const connection = parseMysqlConnectionString(connectionString);\n return new MysqlEngine(\n properties,\n connection as Knex.MySqlConnectionConfig,\n );\n }\n }\n\n if (dockerImageName) {\n const { connection, stopContainer } = await startMysqlContainer(\n dockerImageName,\n );\n return new MysqlEngine(properties, connection, stopContainer);\n }\n\n throw new Error(`Test databasee for ${properties.name} not configured`);\n }\n\n readonly #properties: TestDatabaseProperties;\n readonly #connection: Knex.MySqlConnectionConfig;\n readonly #knexInstances: Knex[];\n readonly #databaseNames: string[];\n readonly #stopContainer?: () => Promise<void>;\n\n constructor(\n properties: TestDatabaseProperties,\n connection: Knex.MySqlConnectionConfig,\n stopContainer?: () => Promise<void>,\n ) {\n this.#properties = properties;\n this.#connection = connection;\n this.#knexInstances = [];\n this.#databaseNames = [];\n this.#stopContainer = stopContainer;\n }\n\n async createDatabaseInstance(): Promise<Knex> {\n const adminConnection = this.#connectAdmin();\n try {\n const databaseName = `db${randomBytes(16).toString('hex')}`;\n\n await adminConnection.raw('CREATE DATABASE ??', [databaseName]);\n this.#databaseNames.push(databaseName);\n\n const knexInstance = knexFactory({\n client: this.#properties.driver,\n connection: {\n ...this.#connection,\n database: databaseName,\n connectTimeout: 30_000,\n },\n ...LARGER_POOL_CONFIG,\n });\n this.#knexInstances.push(knexInstance);\n\n return knexInstance;\n } finally {\n await adminConnection.destroy();\n }\n }\n\n async shutdown(): Promise<void> {\n for (const instance of this.#knexInstances) {\n await instance.destroy();\n }\n\n const adminConnection = this.#connectAdmin();\n try {\n for (const databaseName of this.#databaseNames) {\n await adminConnection.raw('DROP DATABASE ??', [databaseName]);\n }\n } finally {\n await adminConnection.destroy();\n }\n\n await this.#stopContainer?.();\n }\n\n #connectAdmin(): Knex {\n const connection = {\n ...this.#connection,\n database: null as unknown as string,\n };\n return knexFactory({\n client: this.#properties.driver,\n connection,\n pool: {\n min: 0,\n max: 1,\n acquireTimeoutMillis: 20_000,\n createTimeoutMillis: 20_000,\n createRetryIntervalMillis: 1_000,\n },\n });\n }\n}\n"],"names":["waitForReady","knexFactory","uuid","yn","randomBytes","LARGER_POOL_CONFIG"],"mappings":";;;;;;;;;;;;;AAuBA,eAAe,kBACb,UAAA,EACe;AACf,EAAA,MAAMA,0BAAa,YAAY;AAC7B,IAAA,MAAM,OAAOC,4BAAA,CAAY;AAAA,MACvB,MAAA,EAAQ,QAAA;AAAA,MACR,UAAA,EAAY;AAAA;AAAA,QAEV,GAAG;AAAA;AACL,KACD,CAAA;AACD,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,MAAM,IAAA,CAAK,OAAO,IAAA,CAAK,GAAA,CAAI,sBAAsB,CAAC,CAAA;AACjE,MAAA,OAAO,KAAA,CAAM,QAAQ,MAAM,CAAA,IAAK,QAAQ,MAAA,CAAO,CAAC,GAAG,OAAO,CAAA;AAAA,IAC5D,CAAA,SAAE;AACA,MAAA,MAAM,KAAK,OAAA,EAAQ;AAAA,IACrB;AAAA,EACF,GAAG,cAAc,CAAA;AACnB;AAEA,eAAsB,oBAAoB,KAAA,EAGvC;AACD,EAAA,MAAM,IAAA,GAAO,MAAA;AACb,EAAA,MAAM,WAAWC,sBAAA,EAAK;AAGtB,EAAA,MAAM,EAAE,gBAAA,EAAiB,GACvB,OAAA,CAAQ,gBAAgB,CAAA;AAE1B,EAAA,MAAM,SAAA,GAAY,MAAM,IAAI,gBAAA,CAAiB,KAAK,CAAA,CAC/C,gBAAA,CAAiB,IAAI,CAAA,CACrB,eAAA,CAAgB,EAAE,mBAAA,EAAqB,QAAA,EAAU,CAAA,CACjD,SAAA,CAAU,EAAE,gBAAA,EAAkB,IAAA,EAAM,CAAA,CACpC,WAAA,CAAY;AAAA,IACX,uDAAA;AAAA,IACA;AAAA,GACD,EACA,KAAA,EAAM;AAET,EAAA,MAAM,IAAA,GAAO,UAAU,OAAA,EAAQ;AAC/B,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,aAAA,CAAc,IAAI,CAAA;AACzC,EAAA,MAAM,UAAA,GAAa,EAAE,IAAA,EAAM,IAAA,EAAM,MAAM,QAAA,EAAS;AAChD,EAAA,MAAM,gBAAgB,YAAY;AAChC,IAAA,MAAM,SAAA,CAAU,IAAA,CAAK,EAAE,OAAA,EAAS,KAAQ,CAAA;AAAA,EAC1C,CAAA;AAEA,EAAA,MAAM,kBAAkB,UAAU,CAAA;AAElC,EAAA,OAAO,EAAE,YAAY,aAAA,EAAc;AACrC;AAEO,SAAS,2BACd,gBAAA,EAC4B;AAC5B,EAAA,IAAI;AACF,IAAA,MAAM;AAAA,MACJ,QAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA,IAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF,GAAI,IAAI,GAAA,CAAI,gBAAgB,CAAA;AAE5B,IAAA,IAAI,aAAa,QAAA,EAAU;AACzB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,QAAQ,CAAA,CAAE,CAAA;AAAA,IAChD,CAAA,MAAA,IAAW,CAAC,QAAA,IAAY,CAAC,QAAA,EAAU;AACjC,MAAA,MAAM,IAAI,MAAM,CAAA,yBAAA,CAA2B,CAAA;AAAA,IAC7C,CAAA,MAAA,IAAW,CAAC,QAAA,CAAS,KAAA,CAAM,WAAW,CAAA,EAAG;AACvC,MAAA,MAAM,IAAI,MAAM,CAAA,4BAAA,CAA8B,CAAA;AAAA,IAChD;AAEA,IAAA,MAAM,MAAA,GAAqC;AAAA,MACzC,IAAA,EAAM,QAAA;AAAA,MACN,QAAA;AAAA,MACA,IAAA,EAAM,QAAA;AAAA,MACN,IAAA,EAAM,MAAA,CAAO,IAAA,IAAQ,IAAI,CAAA;AAAA,MACzB,QAAA,EAAU,kBAAA,CAAmB,QAAA,CAAS,SAAA,CAAU,CAAC,CAAC;AAAA,KACpD;AAEA,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,GAAA,CAAI,KAAK,CAAA;AAClC,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,MAAA,CAAO,GAAA,GAAM,GAAA;AAAA,IACf;AAEA,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,GAAA,CAAI,OAAO,CAAA;AACtC,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,MAAA,CAAO,KAAA,GAAQC,oBAAG,KAAK,CAAA;AAAA,IACzB;AAEA,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,CAAA,EAAG;AACV,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6CAAA,EAAgD,CAAC,IAAI,CAAC,CAAA;AAAA,EACxE;AACF;AAEO,MAAM,WAAA,CAA8B;AAAA,EACzC,aAAa,OACX,UAAA,EACsB;AACtB,IAAA,MAAM,EAAE,uCAAA,EAAyC,eAAA,EAAgB,GAC/D,UAAA;AAEF,IAAA,IAAI,uCAAA,EAAyC;AAC3C,MAAA,MAAM,gBAAA,GACJ,OAAA,CAAQ,GAAA,CAAI,uCAAuC,CAAA;AACrD,MAAA,IAAI,gBAAA,EAAkB;AACpB,QAAA,MAAM,UAAA,GAAa,2BAA2B,gBAAgB,CAAA;AAC9D,QAAA,OAAO,IAAI,WAAA;AAAA,UACT,UAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,eAAA,EAAiB;AACnB,MAAA,MAAM,EAAE,UAAA,EAAY,aAAA,EAAc,GAAI,MAAM,mBAAA;AAAA,QAC1C;AAAA,OACF;AACA,MAAA,OAAO,IAAI,WAAA,CAAY,UAAA,EAAY,UAAA,EAAY,aAAa,CAAA;AAAA,IAC9D;AAEA,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,UAAA,CAAW,IAAI,CAAA,eAAA,CAAiB,CAAA;AAAA,EACxE;AAAA,EAES,WAAA;AAAA,EACA,WAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EAET,WAAA,CACE,UAAA,EACA,UAAA,EACA,aAAA,EACA;AACA,IAAA,IAAA,CAAK,WAAA,GAAc,UAAA;AACnB,IAAA,IAAA,CAAK,WAAA,GAAc,UAAA;AACnB,IAAA,IAAA,CAAK,iBAAiB,EAAC;AACvB,IAAA,IAAA,CAAK,iBAAiB,EAAC;AACvB,IAAA,IAAA,CAAK,cAAA,GAAiB,aAAA;AAAA,EACxB;AAAA,EAEA,MAAM,sBAAA,GAAwC;AAC5C,IAAA,MAAM,eAAA,GAAkB,KAAK,aAAA,EAAc;AAC3C,IAAA,IAAI;AACF,MAAA,MAAM,eAAe,CAAA,EAAA,EAAKC,uBAAA,CAAY,EAAE,CAAA,CAAE,QAAA,CAAS,KAAK,CAAC,CAAA,CAAA;AAEzD,MAAA,MAAM,eAAA,CAAgB,GAAA,CAAI,oBAAA,EAAsB,CAAC,YAAY,CAAC,CAAA;AAC9D,MAAA,IAAA,CAAK,cAAA,CAAe,KAAK,YAAY,CAAA;AAErC,MAAA,MAAM,eAAeH,4BAAA,CAAY;AAAA,QAC/B,MAAA,EAAQ,KAAK,WAAA,CAAY,MAAA;AAAA,QACzB,UAAA,EAAY;AAAA,UACV,GAAG,IAAA,CAAK,WAAA;AAAA,UACR,QAAA,EAAU,YAAA;AAAA,UACV,cAAA,EAAgB;AAAA,SAClB;AAAA,QACA,GAAGI;AAAA,OACJ,CAAA;AACD,MAAA,IAAA,CAAK,cAAA,CAAe,KAAK,YAAY,CAAA;AAErC,MAAA,OAAO,YAAA;AAAA,IACT,CAAA,SAAE;AACA,MAAA,MAAM,gBAAgB,OAAA,EAAQ;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,MAAM,QAAA,GAA0B;AAC9B,IAAA,KAAA,MAAW,QAAA,IAAY,KAAK,cAAA,EAAgB;AAC1C,MAAA,MAAM,SAAS,OAAA,EAAQ;AAAA,IACzB;AAEA,IAAA,MAAM,eAAA,GAAkB,KAAK,aAAA,EAAc;AAC3C,IAAA,IAAI;AACF,MAAA,KAAA,MAAW,YAAA,IAAgB,KAAK,cAAA,EAAgB;AAC9C,QAAA,MAAM,eAAA,CAAgB,GAAA,CAAI,kBAAA,EAAoB,CAAC,YAAY,CAAC,CAAA;AAAA,MAC9D;AAAA,IACF,CAAA,SAAE;AACA,MAAA,MAAM,gBAAgB,OAAA,EAAQ;AAAA,IAChC;AAEA,IAAA,MAAM,KAAK,cAAA,IAAiB;AAAA,EAC9B;AAAA,EAEA,aAAA,GAAsB;AACpB,IAAA,MAAM,UAAA,GAAa;AAAA,MACjB,GAAG,IAAA,CAAK,WAAA;AAAA,MACR,QAAA,EAAU;AAAA,KACZ;AACA,IAAA,OAAOJ,4BAAA,CAAY;AAAA,MACjB,MAAA,EAAQ,KAAK,WAAA,CAAY,MAAA;AAAA,MACzB,UAAA;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,GAAA,EAAK,CAAA;AAAA,QACL,GAAA,EAAK,CAAA;AAAA,QACL,oBAAA,EAAsB,GAAA;AAAA,QACtB,mBAAA,EAAqB,GAAA;AAAA,QACrB,yBAAA,EAA2B;AAAA;AAC7B,KACD,CAAA;AAAA,EACH;AACF;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs.js","sources":["../../src/database/types.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Knex } from 'knex';\nimport { getDockerImageForName } from '../util/getDockerImageForName';\n\nexport interface Engine {\n createDatabaseInstance(): Promise<Knex>;\n shutdown(): Promise<void>;\n}\n\n/**\n * The possible databases to test against.\n *\n * @public\n */\nexport type TestDatabaseId =\n | 'POSTGRES_18'\n | 'POSTGRES_17'\n | 'POSTGRES_16'\n | 'POSTGRES_15'\n | 'POSTGRES_14'\n | 'POSTGRES_13'\n | 'POSTGRES_12'\n | 'POSTGRES_11'\n | 'POSTGRES_9'\n | 'MYSQL_8'\n | 'SQLITE_3';\n\nexport type TestDatabaseProperties = {\n name: string;\n driver: string;\n dockerImageName?: string;\n connectionStringEnvironmentVariableName?: string;\n};\n\nexport const allDatabases: Record<TestDatabaseId, TestDatabaseProperties> =\n Object.freeze({\n POSTGRES_18: {\n name: 'Postgres 18.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:18'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES18_CONNECTION_STRING',\n },\n POSTGRES_17: {\n name: 'Postgres 17.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:17'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES17_CONNECTION_STRING',\n },\n POSTGRES_16: {\n name: 'Postgres 16.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:16'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES16_CONNECTION_STRING',\n },\n POSTGRES_15: {\n name: 'Postgres 15.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:15'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES15_CONNECTION_STRING',\n },\n POSTGRES_14: {\n name: 'Postgres 14.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:14'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES14_CONNECTION_STRING',\n },\n POSTGRES_13: {\n name: 'Postgres 13.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:13'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING',\n },\n POSTGRES_12: {\n name: 'Postgres 12.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:12'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES12_CONNECTION_STRING',\n },\n POSTGRES_11: {\n name: 'Postgres 11.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:11'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES11_CONNECTION_STRING',\n },\n POSTGRES_9: {\n name: 'Postgres 9.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:9'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES9_CONNECTION_STRING',\n },\n MYSQL_8: {\n name: 'MySQL 8.x',\n driver: 'mysql2',\n dockerImageName: getDockerImageForName('mysql:8'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_MYSQL8_CONNECTION_STRING',\n },\n SQLITE_3: {\n name: 'SQLite 3.x',\n driver: 'better-sqlite3',\n },\n });\n\nexport const LARGER_POOL_CONFIG = {\n pool: {\n min: 0,\n max: 50,\n },\n};\n"],"names":["getDockerImageForName"],"mappings":";;;;AAiDO,MAAM,YAAA,GACX,OAAO,MAAA,CAAO;AAAA,EACZ,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,cAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,YAAY,CAAA;AAAA,IACnD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,WAAA;AAAA,IACN,MAAA,EAAQ,QAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,SAAS,CAAA;AAAA,IAChD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,YAAA;AAAA,IACN,MAAA,EAAQ;AAAA;AAEZ,CAAC;AAEI,MAAM,kBAAA,GAAqB;AAAA,EAChC,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK,CAAA;AAAA,IACL,GAAA,EAAK;AAAA;
|
|
1
|
+
{"version":3,"file":"types.cjs.js","sources":["../../src/database/types.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Knex } from 'knex';\nimport { getDockerImageForName } from '../util/getDockerImageForName';\n\nexport interface Engine {\n createDatabaseInstance(): Promise<Knex>;\n shutdown(): Promise<void>;\n}\n\n/**\n * The possible databases to test against.\n *\n * @public\n */\nexport type TestDatabaseId =\n | 'POSTGRES_18'\n | 'POSTGRES_17'\n | 'POSTGRES_16'\n | 'POSTGRES_15'\n | 'POSTGRES_14'\n | 'POSTGRES_13'\n | 'POSTGRES_12'\n | 'POSTGRES_11'\n | 'POSTGRES_9'\n | 'MYSQL_8'\n | 'SQLITE_3';\n\nexport type TestDatabaseProperties = {\n name: string;\n driver: string;\n dockerImageName?: string;\n connectionStringEnvironmentVariableName?: string;\n};\n\nexport const allDatabases: Record<TestDatabaseId, TestDatabaseProperties> =\n Object.freeze({\n POSTGRES_18: {\n name: 'Postgres 18.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:18'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES18_CONNECTION_STRING',\n },\n POSTGRES_17: {\n name: 'Postgres 17.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:17'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES17_CONNECTION_STRING',\n },\n POSTGRES_16: {\n name: 'Postgres 16.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:16'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES16_CONNECTION_STRING',\n },\n POSTGRES_15: {\n name: 'Postgres 15.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:15'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES15_CONNECTION_STRING',\n },\n POSTGRES_14: {\n name: 'Postgres 14.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:14'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES14_CONNECTION_STRING',\n },\n POSTGRES_13: {\n name: 'Postgres 13.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:13'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING',\n },\n POSTGRES_12: {\n name: 'Postgres 12.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:12'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES12_CONNECTION_STRING',\n },\n POSTGRES_11: {\n name: 'Postgres 11.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:11'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES11_CONNECTION_STRING',\n },\n POSTGRES_9: {\n name: 'Postgres 9.x',\n driver: 'pg',\n dockerImageName: getDockerImageForName('postgres:9'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_POSTGRES9_CONNECTION_STRING',\n },\n MYSQL_8: {\n name: 'MySQL 8.x',\n driver: 'mysql2',\n dockerImageName: getDockerImageForName('mysql:8'),\n connectionStringEnvironmentVariableName:\n 'BACKSTAGE_TEST_DATABASE_MYSQL8_CONNECTION_STRING',\n },\n SQLITE_3: {\n name: 'SQLite 3.x',\n driver: 'better-sqlite3',\n },\n });\n\nexport const LARGER_POOL_CONFIG = {\n pool: {\n min: 0,\n max: 50,\n acquireTimeoutMillis: 30_000,\n createTimeoutMillis: 30_000,\n },\n};\n"],"names":["getDockerImageForName"],"mappings":";;;;AAiDO,MAAM,YAAA,GACX,OAAO,MAAA,CAAO;AAAA,EACZ,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,eAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,aAAa,CAAA;AAAA,IACpD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,cAAA;AAAA,IACN,MAAA,EAAQ,IAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,YAAY,CAAA;AAAA,IACnD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,WAAA;AAAA,IACN,MAAA,EAAQ,QAAA;AAAA,IACR,eAAA,EAAiBA,4CAAsB,SAAS,CAAA;AAAA,IAChD,uCAAA,EACE;AAAA,GACJ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,YAAA;AAAA,IACN,MAAA,EAAQ;AAAA;AAEZ,CAAC;AAEI,MAAM,kBAAA,GAAqB;AAAA,EAChC,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK,CAAA;AAAA,IACL,GAAA,EAAK,EAAA;AAAA,IACL,oBAAA,EAAsB,GAAA;AAAA,IACtB,mBAAA,EAAqB;AAAA;AAEzB;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/backend-test-utils",
|
|
3
|
-
"version": "1.11.4-next.
|
|
3
|
+
"version": "1.11.4-next.1",
|
|
4
4
|
"description": "Test helpers library for Backstage backends",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "node-library"
|
|
@@ -58,8 +58,8 @@
|
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@backstage/backend-app-api": "1.7.1-next.0",
|
|
61
|
-
"@backstage/backend-defaults": "0.17.
|
|
62
|
-
"@backstage/backend-plugin-api": "1.9.2-next.
|
|
61
|
+
"@backstage/backend-defaults": "0.17.3-next.1",
|
|
62
|
+
"@backstage/backend-plugin-api": "1.9.2-next.1",
|
|
63
63
|
"@backstage/config": "1.3.8",
|
|
64
64
|
"@backstage/errors": "1.3.1",
|
|
65
65
|
"@backstage/plugin-auth-node": "0.7.2-next.0",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"zod-to-json-schema": "^3.25.1"
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
|
93
|
-
"@backstage/cli": "0.36.3-next.
|
|
93
|
+
"@backstage/cli": "0.36.3-next.1",
|
|
94
94
|
"@types/jest": "*",
|
|
95
95
|
"@types/lodash": "^4.14.151",
|
|
96
96
|
"@types/supertest": "^2.0.8",
|