mirror of
https://github.com/graphql-hive/console
synced 2026-04-21 14:37:17 +00:00
feat: federation 2 service container (#743)
This commit is contained in:
parent
ca9d60d4df
commit
f0735fad28
12 changed files with 462 additions and 3 deletions
1
.github/workflows/ci.yaml
vendored
1
.github/workflows/ci.yaml
vendored
|
|
@ -239,6 +239,7 @@ jobs:
|
|||
packages/services/usage-ingestor/dist
|
||||
packages/services/usage/dist
|
||||
packages/services/webhooks/dist
|
||||
packages/services/external-composition/federation-2/dist
|
||||
packages/web/app/dist.zip
|
||||
|
||||
rust:
|
||||
|
|
|
|||
18
docker.hcl
18
docker.hcl
|
|
@ -260,6 +260,23 @@ target "webhooks" {
|
|||
]
|
||||
}
|
||||
|
||||
target "composition-federation-2" {
|
||||
inherits = ["service-base", get_target()]
|
||||
context = "${PWD}/packages/services/external-composition/federation-2/dist"
|
||||
args = {
|
||||
IMAGE_TITLE = "graphql-hive/composition-federation-2"
|
||||
IMAGE_DESCRIPTION = "Federation 2 Composition Service for GraphQL Hive."
|
||||
PORT = "3069"
|
||||
HEALTHCHECK_CMD = "wget --spider -q http://127.0.0.1:$${PORT}/_readiness"
|
||||
}
|
||||
tags = [
|
||||
local_image_tag("composition-federation-2"),
|
||||
stable_image_tag("composition-federation-2"),
|
||||
image_tag("composition-federation-2", COMMIT_SHA),
|
||||
image_tag("composition-federation-2", BRANCH_NAME)
|
||||
]
|
||||
}
|
||||
|
||||
target "app" {
|
||||
inherits = ["app-base", get_target()]
|
||||
context = "${PWD}/packages/web/app/dist"
|
||||
|
|
@ -291,6 +308,7 @@ group "build" {
|
|||
"webhooks",
|
||||
"server",
|
||||
"stripe-billing",
|
||||
"composition-federation-2",
|
||||
"app"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,6 +224,23 @@ services:
|
|||
PORT: 3013
|
||||
CF_BROKER_SIGNATURE: secretSignature
|
||||
|
||||
composition_federation_2:
|
||||
image: '${DOCKER_REGISTRY}composition-federation-2${DOCKER_TAG}'
|
||||
networks:
|
||||
- 'stack'
|
||||
healthcheck:
|
||||
test: ['CMD', 'wget', '--spider', '-q', 'localhost:3069/_readiness']
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 6
|
||||
start_period: 5s
|
||||
ports:
|
||||
- 3069:3069
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
PORT: 3069
|
||||
SECRET: secretsecret
|
||||
|
||||
external_composition:
|
||||
image: node:16.15.1-alpine3.14
|
||||
entrypoint:
|
||||
|
|
@ -307,7 +324,7 @@ services:
|
|||
ports:
|
||||
- 3001:3001
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
NODE_ENV: development
|
||||
POSTGRES_HOST: db
|
||||
POSTGRES_PORT: 5432
|
||||
POSTGRES_DB: registry
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
import {
|
||||
createOrganization,
|
||||
publishSchema,
|
||||
createProject,
|
||||
createToken,
|
||||
enableExternalSchemaComposition,
|
||||
} from '../../../testkit/flow';
|
||||
import { authenticate } from '../../../testkit/auth';
|
||||
import { TargetAccessScope, ProjectType, ProjectAccessScope } from '@app/gql/graphql';
|
||||
|
||||
const dockerAddress = 'composition_federation_2:3069';
|
||||
|
||||
test('call an external service to compose and validate services', async () => {
|
||||
const { access_token: owner_access_token } = await authenticate('main');
|
||||
const orgResult = await createOrganization(
|
||||
{
|
||||
name: 'foo',
|
||||
},
|
||||
owner_access_token,
|
||||
);
|
||||
const org = orgResult.body.data!.createOrganization.ok!.createdOrganizationPayload.organization;
|
||||
|
||||
const projectResult = await createProject(
|
||||
{
|
||||
organization: org.cleanId,
|
||||
type: ProjectType.Federation,
|
||||
name: 'bar',
|
||||
},
|
||||
owner_access_token,
|
||||
);
|
||||
|
||||
const project = projectResult.body.data!.createProject.ok!.createdProject;
|
||||
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
|
||||
|
||||
// Create a token with write rights
|
||||
const writeTokenResult = await createToken(
|
||||
{
|
||||
name: 'test',
|
||||
organization: org.cleanId,
|
||||
project: project.cleanId,
|
||||
target: target.cleanId,
|
||||
organizationScopes: [],
|
||||
projectScopes: [ProjectAccessScope.Settings, ProjectAccessScope.Read],
|
||||
targetScopes: [TargetAccessScope.RegistryRead, TargetAccessScope.RegistryWrite],
|
||||
},
|
||||
owner_access_token,
|
||||
);
|
||||
expect(writeTokenResult.body.errors).not.toBeDefined();
|
||||
const writeToken = writeTokenResult.body.data!.createToken.ok!.secret;
|
||||
|
||||
const usersServiceName = Math.random().toString(16).substring(2);
|
||||
const publishUsersResult = await publishSchema(
|
||||
{
|
||||
author: 'Kamil',
|
||||
commit: 'init',
|
||||
url: 'https://api.com/users',
|
||||
sdl: `type Query { me: User } type User @key(fields: "id") { id: ID! name: String }`,
|
||||
service: usersServiceName,
|
||||
},
|
||||
writeToken,
|
||||
);
|
||||
|
||||
// Schema publish should be successful
|
||||
expect(publishUsersResult.body.errors).not.toBeDefined();
|
||||
expect(publishUsersResult.body.data!.schemaPublish.__typename).toBe('SchemaPublishSuccess');
|
||||
|
||||
// enable external composition
|
||||
const externalCompositionResult = await enableExternalSchemaComposition(
|
||||
{
|
||||
endpoint: `http://${dockerAddress}/compose`,
|
||||
// eslint-disable-next-line no-process-env
|
||||
secret: process.env.EXTERNAL_COMPOSITION_SECRET!,
|
||||
project: project.cleanId,
|
||||
organization: org.cleanId,
|
||||
},
|
||||
writeToken,
|
||||
);
|
||||
expect(externalCompositionResult.body.errors).not.toBeDefined();
|
||||
expect(externalCompositionResult.body.data!.enableExternalSchemaComposition.ok?.endpoint).toBe(
|
||||
`http://${dockerAddress}/compose`,
|
||||
);
|
||||
|
||||
const productsServiceName = Math.random().toString(16).substring(2);
|
||||
const publishProductsResult = await publishSchema(
|
||||
{
|
||||
author: 'Kamil',
|
||||
commit: 'init',
|
||||
url: 'https://api.com/products',
|
||||
sdl: `type Query { products: [Product] } type Product @key(fields: "id") { id: ID! name: String }`,
|
||||
service: productsServiceName,
|
||||
},
|
||||
writeToken,
|
||||
);
|
||||
|
||||
// Schema publish should be successful
|
||||
expect(publishProductsResult.body.errors).not.toBeDefined();
|
||||
expect(publishProductsResult.body.data!.schemaPublish.__typename).toBe('SchemaPublishSuccess');
|
||||
});
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
"build": "pnpm graphql:generate && pnpm turbo build --color",
|
||||
"build:libraries": "pnpm graphql:generate && pnpm turbo build --filter=./packages/libraries/* --color",
|
||||
"build:local": "pnpm graphql:generate && pnpm turbo build-local --color",
|
||||
"build:services": "pnpm graphql:generate && pnpm turbo build --filter=./packages/services/* --color",
|
||||
"build:services": "pnpm graphql:generate && pnpm turbo build --filter=./packages/services/**/* --color",
|
||||
"build:web": "pnpm graphql:generate && pnpm turbo build --filter=./packages/web/* --color",
|
||||
"docker:build": "docker buildx bake -f docker.hcl --load build",
|
||||
"env:sync": "node ./scripts/sync-env-files.js",
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
# Composition Service for Apollo Federation 2
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "@hive/external-composition-federation-2",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "bob runify --single",
|
||||
"dev": "tsup-node src/dev.ts --format esm --shims --target node16 --watch --sourcemap --onSuccess 'node --enable-source-maps dist/dev.js' | pino-pretty --translateTime HH:MM:ss TT --ignore pid,hostname"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/composition": "^2.2.1",
|
||||
"@whatwg-node/fetch": "^0.5.3",
|
||||
"@whatwg-node/server": "^0.4.17",
|
||||
"graphql": "^16.6.0",
|
||||
"zod": "^3.15.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@graphql-hive/external-composition": "workspace:*"
|
||||
},
|
||||
"buildOptions": {
|
||||
"runify": true,
|
||||
"tsup": true,
|
||||
"tags": [],
|
||||
"banner": "../../../../scripts/banner.js"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import zod from 'zod';
|
||||
|
||||
// treat an empty string (`''`) as undefined
|
||||
const emptyString = <T extends zod.ZodType>(input: T) => {
|
||||
return zod.preprocess((value: unknown) => {
|
||||
if (value === '') return undefined;
|
||||
return value;
|
||||
}, input);
|
||||
};
|
||||
|
||||
function extractConfig<Input, Output>(config: zod.SafeParseReturnType<Input, Output>): Output {
|
||||
if (!config.success) {
|
||||
throw new Error('Something went wrong.');
|
||||
}
|
||||
return config.data;
|
||||
}
|
||||
|
||||
const BaseSchema = zod.object({
|
||||
NODE_ENV: zod.string(),
|
||||
ENVIRONMENT: zod.string(),
|
||||
RELEASE: emptyString(zod.string().optional()),
|
||||
PORT: zod.string(),
|
||||
SECRET: zod.string(),
|
||||
});
|
||||
|
||||
const configs = {
|
||||
// eslint-disable-next-line no-process-env
|
||||
base: BaseSchema.safeParse(process.env),
|
||||
};
|
||||
|
||||
const environmentErrors: Array<string> = [];
|
||||
|
||||
for (const config of Object.values(configs)) {
|
||||
if (config.success === false) {
|
||||
environmentErrors.push(JSON.stringify(config.error.format(), null, 4));
|
||||
}
|
||||
}
|
||||
|
||||
if (environmentErrors.length) {
|
||||
const fullError = environmentErrors.join(`\n`);
|
||||
console.error('❌ Invalid environment variables:', fullError);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const base = extractConfig(configs.base);
|
||||
|
||||
export const env = {
|
||||
environment: base.ENVIRONMENT,
|
||||
release: base.RELEASE ?? 'local',
|
||||
http: {
|
||||
port: base.PORT ?? 5000,
|
||||
},
|
||||
secret: base.SECRET,
|
||||
};
|
||||
100
packages/services/external-composition/federation-2/src/index.ts
Normal file
100
packages/services/external-composition/federation-2/src/index.ts
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
import { verifyRequest, compose, signatureHeaderName } from '@graphql-hive/external-composition';
|
||||
import { composeServices } from '@apollo/composition';
|
||||
import { parse, printSchema } from 'graphql';
|
||||
import { createServer } from 'node:http';
|
||||
import process from 'node:process';
|
||||
import { createServerAdapter } from '@whatwg-node/server';
|
||||
import { Response } from '@whatwg-node/fetch';
|
||||
import { env } from './environment';
|
||||
|
||||
const composeFederation = compose(services => {
|
||||
const result = composeServices(
|
||||
services.map(service => {
|
||||
return {
|
||||
typeDefs: parse(service.sdl),
|
||||
name: service.name,
|
||||
url: service.url,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
if (result.errors?.length) {
|
||||
return {
|
||||
type: 'failure',
|
||||
result: {
|
||||
errors: result.errors.map(error => ({
|
||||
message: error.message,
|
||||
})),
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
type: 'success',
|
||||
result: {
|
||||
// TODO: verify why supergraphSdl can be undefine :)
|
||||
supergraph: result.supergraphSdl!,
|
||||
// TODO: verify why schema can be undefine :)
|
||||
sdl: printSchema(result.schema!.toGraphQLJSSchema()),
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const requestListener = createServerAdapter(async request => {
|
||||
const url = new URL(request.url);
|
||||
|
||||
if (url.pathname === '/_readiness') {
|
||||
return new Response('Ok.', {
|
||||
status: 200,
|
||||
});
|
||||
}
|
||||
|
||||
if (request.method === 'POST' && url.pathname === '/compose') {
|
||||
const signatureHeaderValue = request.headers.get(signatureHeaderName);
|
||||
if (signatureHeaderValue === null) {
|
||||
return new Response(`Missing signature header '${signatureHeaderName}'.`, { status: 400 });
|
||||
}
|
||||
|
||||
const body = await request.text();
|
||||
|
||||
const error = verifyRequest({
|
||||
// Stringified body, or raw body if you have access to it
|
||||
body,
|
||||
// Pass here the signature from `X-Hive-Signature-256` header
|
||||
signature: signatureHeaderValue,
|
||||
// Pass here the secret you configured in GraphQL Hive
|
||||
secret: env.secret,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
return new Response(error, { status: 500 });
|
||||
} else {
|
||||
const result = composeFederation(JSON.parse(body));
|
||||
return new Response(JSON.stringify(result), {
|
||||
status: 200,
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return new Response('', {
|
||||
status: 404,
|
||||
});
|
||||
});
|
||||
|
||||
const server = createServer(requestListener);
|
||||
|
||||
server.listen(env.http.port, () => {
|
||||
console.log(`Listening on http://localhost:${env.http.port}`);
|
||||
});
|
||||
|
||||
process.on('SIGINT', () => {
|
||||
server.close(err => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "esnext",
|
||||
"rootDir": "../../.."
|
||||
},
|
||||
"files": ["src/index.ts"]
|
||||
}
|
||||
136
pnpm-lock.yaml
136
pnpm-lock.yaml
|
|
@ -528,6 +528,23 @@ importers:
|
|||
pino-pretty: 6.0.0
|
||||
tslib: 2.4.1
|
||||
|
||||
packages/services/external-composition/federation-2:
|
||||
specifiers:
|
||||
'@apollo/composition': ^2.2.1
|
||||
'@graphql-hive/external-composition': workspace:*
|
||||
'@whatwg-node/fetch': ^0.5.3
|
||||
'@whatwg-node/server': ^0.4.17
|
||||
graphql: 16.6.0
|
||||
zod: ^3.15.1
|
||||
dependencies:
|
||||
'@apollo/composition': 2.2.1_graphql@16.6.0
|
||||
'@whatwg-node/fetch': 0.5.3
|
||||
'@whatwg-node/server': 0.4.17
|
||||
graphql: 16.6.0
|
||||
zod: 3.19.1
|
||||
devDependencies:
|
||||
'@graphql-hive/external-composition': link:../../../libraries/external-composition
|
||||
|
||||
packages/services/police-worker:
|
||||
specifiers:
|
||||
'@cloudflare/workers-types': 3.4.0
|
||||
|
|
@ -1385,6 +1402,28 @@ packages:
|
|||
dependencies:
|
||||
graphql: 16.6.0
|
||||
|
||||
/@apollo/composition/2.2.1_graphql@16.6.0:
|
||||
resolution: {integrity: sha512-xmd4NiCU+rW6elTZuIflR+GzZf626fJX7NVraTHXgDL8pZ7eluPal/T6vsQEg+Cb9tlAUjDhCB4RqVYPgV69RQ==}
|
||||
engines: {node: '>=14.15.0'}
|
||||
peerDependencies:
|
||||
graphql: ^16.5.0
|
||||
dependencies:
|
||||
'@apollo/federation-internals': 2.2.1_graphql@16.6.0
|
||||
'@apollo/query-graphs': 2.2.1_graphql@16.6.0
|
||||
graphql: 16.6.0
|
||||
dev: false
|
||||
|
||||
/@apollo/federation-internals/2.2.1_graphql@16.6.0:
|
||||
resolution: {integrity: sha512-T+nxIhppu/5jNFIhfzYERIhgDvp2QqbSqnQpViDNEmK/iPKsXLFtOedZZgsAUpMIQoUedNNNuceTE9+lDUn+bA==}
|
||||
engines: {node: '>=14.15.0'}
|
||||
peerDependencies:
|
||||
graphql: ^16.5.0
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
graphql: 16.6.0
|
||||
js-levenshtein: 1.1.6
|
||||
dev: false
|
||||
|
||||
/@apollo/federation/0.38.1:
|
||||
resolution: {integrity: sha512-miifyAEsFgiYKeM3lUHFH6+vKa2vm9dXKSyWVpX6oeJiPblFLe2/iByN3psZQO2sRdVqO1OKYrGXdgKc74XDKw==}
|
||||
engines: {node: '>=12.13.0'}
|
||||
|
|
@ -1430,6 +1469,20 @@ packages:
|
|||
'@types/node': 10.17.60
|
||||
long: 4.0.0
|
||||
|
||||
/@apollo/query-graphs/2.2.1_graphql@16.6.0:
|
||||
resolution: {integrity: sha512-lDK1HfsJlM4P2AcdhNYxXnq5zWohyLiWVyhC0SEnhR/BRfoP2UOC31MHK0waRLAQP5SBMBVolRn6AhtSFNmEyA==}
|
||||
engines: {node: '>=14.15.0'}
|
||||
peerDependencies:
|
||||
graphql: ^16.5.0
|
||||
dependencies:
|
||||
'@apollo/federation-internals': 2.2.1_graphql@16.6.0
|
||||
'@types/uuid': 8.3.4
|
||||
deep-equal: 2.1.0
|
||||
graphql: 16.6.0
|
||||
ts-graphviz: 0.16.0
|
||||
uuid: 9.0.0
|
||||
dev: false
|
||||
|
||||
/@apollo/subgraph/0.6.1:
|
||||
resolution: {integrity: sha512-w/6FoubSxuzXSx8uvLE1wEuHZVHRXFyfHPKdM76wX5U/xw82zlUKseVO7wTuVODTcnUzEA30udYeCApUoC3/Xw==}
|
||||
engines: {node: '>=12.13.0'}
|
||||
|
|
@ -11050,7 +11103,6 @@ packages:
|
|||
|
||||
/@types/uuid/8.3.4:
|
||||
resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==}
|
||||
dev: true
|
||||
|
||||
/@types/verror/1.10.6:
|
||||
resolution: {integrity: sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ==}
|
||||
|
|
@ -14458,6 +14510,26 @@ packages:
|
|||
resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==}
|
||||
dev: true
|
||||
|
||||
/deep-equal/2.1.0:
|
||||
resolution: {integrity: sha512-2pxgvWu3Alv1PoWEyVg7HS8YhGlUFUV7N5oOvfL6d+7xAmLSemMwv/c8Zv/i9KFzxV5Kt5CAvQc70fLwVuf4UA==}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
es-get-iterator: 1.1.2
|
||||
get-intrinsic: 1.1.3
|
||||
is-arguments: 1.1.1
|
||||
is-date-object: 1.0.5
|
||||
is-regex: 1.1.4
|
||||
isarray: 2.0.5
|
||||
object-is: 1.1.5
|
||||
object-keys: 1.1.1
|
||||
object.assign: 4.1.4
|
||||
regexp.prototype.flags: 1.4.3
|
||||
side-channel: 1.0.4
|
||||
which-boxed-primitive: 1.0.2
|
||||
which-collection: 1.0.1
|
||||
which-typed-array: 1.1.8
|
||||
dev: false
|
||||
|
||||
/deep-extend/0.6.0:
|
||||
resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
|
@ -14943,6 +15015,19 @@ packages:
|
|||
/es-array-method-boxes-properly/1.0.0:
|
||||
resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==}
|
||||
|
||||
/es-get-iterator/1.1.2:
|
||||
resolution: {integrity: sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
get-intrinsic: 1.1.3
|
||||
has-symbols: 1.0.3
|
||||
is-arguments: 1.1.1
|
||||
is-map: 2.0.2
|
||||
is-set: 2.0.2
|
||||
is-string: 1.0.7
|
||||
isarray: 2.0.5
|
||||
dev: false
|
||||
|
||||
/es-shim-unscopables/1.0.0:
|
||||
resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==}
|
||||
dependencies:
|
||||
|
|
@ -18058,6 +18143,10 @@ packages:
|
|||
tslib: 2.4.1
|
||||
dev: true
|
||||
|
||||
/is-map/2.0.2:
|
||||
resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==}
|
||||
dev: false
|
||||
|
||||
/is-module/1.0.0:
|
||||
resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==}
|
||||
dev: true
|
||||
|
|
@ -18158,6 +18247,10 @@ packages:
|
|||
scoped-regex: 2.1.0
|
||||
dev: true
|
||||
|
||||
/is-set/2.0.2:
|
||||
resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==}
|
||||
dev: false
|
||||
|
||||
/is-shared-array-buffer/1.0.2:
|
||||
resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==}
|
||||
dependencies:
|
||||
|
|
@ -18237,11 +18330,22 @@ packages:
|
|||
resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==}
|
||||
dev: true
|
||||
|
||||
/is-weakmap/2.0.1:
|
||||
resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==}
|
||||
dev: false
|
||||
|
||||
/is-weakref/1.0.2:
|
||||
resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
|
||||
/is-weakset/2.0.2:
|
||||
resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
get-intrinsic: 1.1.3
|
||||
dev: false
|
||||
|
||||
/is-windows/1.0.2:
|
||||
resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
|
@ -18263,6 +18367,10 @@ packages:
|
|||
resolution: {integrity: sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==}
|
||||
dev: false
|
||||
|
||||
/isarray/2.0.5:
|
||||
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
|
||||
dev: false
|
||||
|
||||
/isbinaryfile/4.0.10:
|
||||
resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==}
|
||||
engines: {node: '>= 8.0.0'}
|
||||
|
|
@ -18869,6 +18977,11 @@ packages:
|
|||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/js-levenshtein/1.1.6:
|
||||
resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/js-sdsl/4.1.5:
|
||||
resolution: {integrity: sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==}
|
||||
dev: true
|
||||
|
|
@ -21684,6 +21797,14 @@ packages:
|
|||
/object-inspect/1.12.2:
|
||||
resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==}
|
||||
|
||||
/object-is/1.1.5:
|
||||
resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
define-properties: 1.1.4
|
||||
dev: false
|
||||
|
||||
/object-keys/0.4.0:
|
||||
resolution: {integrity: sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==}
|
||||
dev: false
|
||||
|
|
@ -25737,6 +25858,10 @@ packages:
|
|||
resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==}
|
||||
dev: false
|
||||
|
||||
/ts-graphviz/0.16.0:
|
||||
resolution: {integrity: sha512-3fTPO+G6bSQNvMh/XQQzyiahVLMMj9kqYO99ivUraNJ3Wp05HZOOVtRhi6w9hq7+laP1MKHjLBtGWqTeb1fcpg==}
|
||||
dev: false
|
||||
|
||||
/ts-interface-checker/0.1.13:
|
||||
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
|
||||
|
||||
|
|
@ -26937,6 +27062,15 @@ packages:
|
|||
is-string: 1.0.7
|
||||
is-symbol: 1.0.4
|
||||
|
||||
/which-collection/1.0.1:
|
||||
resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==}
|
||||
dependencies:
|
||||
is-map: 2.0.2
|
||||
is-set: 2.0.2
|
||||
is-weakmap: 2.0.1
|
||||
is-weakset: 2.0.2
|
||||
dev: false
|
||||
|
||||
/which-module/2.0.0:
|
||||
resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==}
|
||||
dev: true
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
packages:
|
||||
- packages/services/*
|
||||
- packages/services/external-composition/*
|
||||
- packages/web/*
|
||||
- packages/libraries/*
|
||||
- integration-tests
|
||||
|
|
|
|||
Loading…
Reference in a new issue