From c0086646fd7a8c6e57a11cc7234eed55342b5b78 Mon Sep 17 00:00:00 2001 From: Paul Rastoin <45004772+prastoin@users.noreply.github.com> Date: Mon, 30 Mar 2026 16:18:45 +0200 Subject: [PATCH] [APP] Stricter API assertions (#19114) # Introduction Improved the ci assertions to be sure the default logic function worked fully ## what's next About to introduce a s3 + lambda e2e test to cover the lambda driver too in addition of the local driver --- .github/workflows/ci-create-app-e2e.yaml | 2 +- .../src/utils/app-template.ts | 6 +- packages/twenty-apps/hello-world/package.json | 4 +- .../create-hello-world-company.ts | 6 +- packages/twenty-apps/hello-world/yarn.lock | 230 ++++++++++-------- 5 files changed, 136 insertions(+), 112 deletions(-) diff --git a/.github/workflows/ci-create-app-e2e.yaml b/.github/workflows/ci-create-app-e2e.yaml index 4a974ac953..fa2581a8ad 100644 --- a/.github/workflows/ci-create-app-e2e.yaml +++ b/.github/workflows/ci-create-app-e2e.yaml @@ -188,7 +188,7 @@ jobs: cd /tmp/e2e-test-workspace/test-app EXEC_OUTPUT=$(npx --no-install twenty exec --functionName create-hello-world-company) echo "$EXEC_OUTPUT" - echo "$EXEC_OUTPUT" | grep -q "Created company" + echo "$EXEC_OUTPUT" | grep -q 'Created company.*Hello World.*with id' - name: Run scaffolded app integration test env: diff --git a/packages/create-twenty-app/src/utils/app-template.ts b/packages/create-twenty-app/src/utils/app-template.ts index 519298d429..1adbad4151 100644 --- a/packages/create-twenty-app/src/utils/app-template.ts +++ b/packages/create-twenty-app/src/utils/app-template.ts @@ -425,8 +425,12 @@ const handler = async (): Promise<{ message: string }> => { }, }); + if (!createCompany?.id || !createCompany?.name) { + throw new Error('Failed to create company: missing id or name in response'); + } + return { - message: \`Created company "\${createCompany?.name}" with id \${createCompany?.id}\`, + message: \`Created company "\${createCompany.name}" with id \${createCompany.id}\`, }; }; diff --git a/packages/twenty-apps/hello-world/package.json b/packages/twenty-apps/hello-world/package.json index f896e9ba26..b5261feb83 100644 --- a/packages/twenty-apps/hello-world/package.json +++ b/packages/twenty-apps/hello-world/package.json @@ -20,8 +20,8 @@ "@types/react": "^18.2.0", "oxlint": "^0.16.0", "react": "^18.2.0", - "twenty-client-sdk": "portal:../../twenty-client-sdk", - "twenty-sdk": "portal:../../twenty-sdk", + "twenty-client-sdk": "0.8.0-canary.5", + "twenty-sdk": "0.8.0-canary.5", "typescript": "^5.9.3", "vite-tsconfig-paths": "^4.2.1", "vitest": "^3.1.1" diff --git a/packages/twenty-apps/hello-world/src/logic-functions/create-hello-world-company.ts b/packages/twenty-apps/hello-world/src/logic-functions/create-hello-world-company.ts index 4388f3c03c..16cbc2c6bf 100644 --- a/packages/twenty-apps/hello-world/src/logic-functions/create-hello-world-company.ts +++ b/packages/twenty-apps/hello-world/src/logic-functions/create-hello-world-company.ts @@ -16,8 +16,12 @@ const handler = async (): Promise<{ message: string }> => { }, }); + if (!createCompany?.id || !createCompany?.name) { + throw new Error('Failed to create company: missing id or name in response'); + } + return { - message: `Created company "${createCompany?.name}" with id ${createCompany?.id}`, + message: `Created company "${createCompany.name}" with id ${createCompany.id}`, }; }; diff --git a/packages/twenty-apps/hello-world/yarn.lock b/packages/twenty-apps/hello-world/yarn.lock index 571eb2ec24..2405b3614f 100644 --- a/packages/twenty-apps/hello-world/yarn.lock +++ b/packages/twenty-apps/hello-world/yarn.lock @@ -5,13 +5,13 @@ __metadata: version: 8 cacheKey: 10c0 -"@alcalzone/ansi-tokenize@npm:^0.1.3": - version: 0.1.3 - resolution: "@alcalzone/ansi-tokenize@npm:0.1.3" +"@alcalzone/ansi-tokenize@npm:^0.2.4": + version: 0.2.5 + resolution: "@alcalzone/ansi-tokenize@npm:0.2.5" dependencies: ansi-styles: "npm:^6.2.1" - is-fullwidth-code-point: "npm:^4.0.0" - checksum: 10c0/b88c5708271bb64ce132fc80dac8d5b87fc1699bf3abfdf10ecae40dbb56ab82460818f5746ecdd9870a00be9854e039d5cb3a121b808d0ff6f5bc7d0146cb38 + is-fullwidth-code-point: "npm:^5.0.0" + checksum: 10c0/dd8622288426b5b7dbf8b68d51d4b930cea591d0e3b9dbc3f523131464d78ac922c165fcb7ba5307f133d35dbcaa0e6648a1c3fb6a0dc2725546d6f867b70af4 languageName: node linkType: hard @@ -2655,7 +2655,7 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^7.0.0": +"ansi-escapes@npm:^7.3.0": version: 7.3.0 resolution: "ansi-escapes@npm:7.3.0" dependencies: @@ -2717,7 +2717,7 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.2.1": +"ansi-styles@npm:^6.2.1, ansi-styles@npm:^6.2.3": version: 6.2.3 resolution: "ansi-styles@npm:6.2.3" checksum: 10c0/23b8a4ce14e18fb854693b95351e286b771d23d8844057ed2e7d083cd3e708376c3323707ec6a24365f7d7eda3ca00327fe04092e29e551499ec4c8b7bfac868 @@ -2948,7 +2948,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^5.3.0": +"chalk@npm:^5.3.0, chalk@npm:^5.6.0": version: 5.6.2 resolution: "chalk@npm:5.6.2" checksum: 10c0/99a4b0f0e7991796b1e7e3f52dceb9137cae2a9dfc8fc0784a550dc4c558e15ab32ed70b14b21b52beb2679b4892b41a0aa44249bcb996f01e125d58477c6976 @@ -3020,13 +3020,13 @@ __metadata: languageName: node linkType: hard -"cli-truncate@npm:^4.0.0": - version: 4.0.0 - resolution: "cli-truncate@npm:4.0.0" +"cli-truncate@npm:^5.1.1": + version: 5.2.0 + resolution: "cli-truncate@npm:5.2.0" dependencies: - slice-ansi: "npm:^5.0.0" - string-width: "npm:^7.0.0" - checksum: 10c0/d7f0b73e3d9b88cb496e6c086df7410b541b56a43d18ade6a573c9c18bd001b1c3fba1ad578f741a4218fdc794d042385f8ac02c25e1c295a2d8b9f3cb86eb4c + slice-ansi: "npm:^8.0.0" + string-width: "npm:^8.2.0" + checksum: 10c0/0d4ec94702ca85b64522ac93633837fb5ea7db17b79b1322a60f6045e6ae2b8cd7bd4c1d19ac7d1f9e10e3bbda1112e172e439b68c02b785ee00da8d6a5c5471 languageName: node linkType: hard @@ -3306,7 +3306,7 @@ __metadata: languageName: node linkType: hard -"es-toolkit@npm:^1.22.0": +"es-toolkit@npm:^1.39.10": version: 1.45.1 resolution: "es-toolkit@npm:1.45.1" dependenciesMeta: @@ -3727,7 +3727,7 @@ __metadata: languageName: node linkType: hard -"get-east-asian-width@npm:^1.0.0, get-east-asian-width@npm:^1.3.1": +"get-east-asian-width@npm:^1.0.0, get-east-asian-width@npm:^1.3.1, get-east-asian-width@npm:^1.5.0": version: 1.5.0 resolution: "get-east-asian-width@npm:1.5.0" checksum: 10c0/bff8bbc8d81790b9477f7aa55b1806b9f082a8dc1359fff7bd8b96939622c86b729685afc2bfeb22def1fc6ef1e5228e4d87dd4e6da60bc43a5edfb03c4ee167 @@ -3906,8 +3906,8 @@ __metadata: "@types/react": "npm:^18.2.0" oxlint: "npm:^0.16.0" react: "npm:^18.2.0" - twenty-client-sdk: "portal:../../twenty-client-sdk" - twenty-sdk: "portal:../../twenty-sdk" + twenty-client-sdk: "npm:0.8.0-canary.5" + twenty-sdk: "npm:0.8.0-canary.5" typescript: "npm:^5.9.3" vite-tsconfig-paths: "npm:^4.2.1" vitest: "npm:^3.1.1" @@ -4030,44 +4030,45 @@ __metadata: languageName: node linkType: hard -"ink@npm:^5.1.1": - version: 5.2.1 - resolution: "ink@npm:5.2.1" +"ink@npm:^6.8.0": + version: 6.8.0 + resolution: "ink@npm:6.8.0" dependencies: - "@alcalzone/ansi-tokenize": "npm:^0.1.3" - ansi-escapes: "npm:^7.0.0" + "@alcalzone/ansi-tokenize": "npm:^0.2.4" + ansi-escapes: "npm:^7.3.0" ansi-styles: "npm:^6.2.1" auto-bind: "npm:^5.0.1" - chalk: "npm:^5.3.0" + chalk: "npm:^5.6.0" cli-boxes: "npm:^3.0.0" cli-cursor: "npm:^4.0.0" - cli-truncate: "npm:^4.0.0" + cli-truncate: "npm:^5.1.1" code-excerpt: "npm:^4.0.0" - es-toolkit: "npm:^1.22.0" + es-toolkit: "npm:^1.39.10" indent-string: "npm:^5.0.0" - is-in-ci: "npm:^1.0.0" + is-in-ci: "npm:^2.0.0" patch-console: "npm:^2.0.0" - react-reconciler: "npm:^0.29.0" - scheduler: "npm:^0.23.0" + react-reconciler: "npm:^0.33.0" + scheduler: "npm:^0.27.0" signal-exit: "npm:^3.0.7" - slice-ansi: "npm:^7.1.0" + slice-ansi: "npm:^8.0.0" stack-utils: "npm:^2.0.6" - string-width: "npm:^7.2.0" - type-fest: "npm:^4.27.0" - widest-line: "npm:^5.0.0" + string-width: "npm:^8.1.1" + terminal-size: "npm:^4.0.1" + type-fest: "npm:^5.4.1" + widest-line: "npm:^6.0.0" wrap-ansi: "npm:^9.0.0" ws: "npm:^8.18.0" yoga-layout: "npm:~3.2.1" peerDependencies: - "@types/react": ">=18.0.0" - react: ">=18.0.0" - react-devtools-core: ^4.19.1 + "@types/react": ">=19.0.0" + react: ">=19.0.0" + react-devtools-core: ">=6.1.2" peerDependenciesMeta: "@types/react": optional: true react-devtools-core: optional: true - checksum: 10c0/0e2607712783353fbe99438ca4220db3d5874c7ae1a07e2b232f7539489b13a9db929b3046eedeccf318a3ffa222a572287dbe2307c848b8e7f6ec4bba39e550 + checksum: 10c0/50500e547fdf6a1f1d836d6befbd4770e3ab649ef0be1884500a6da411fb68a90e22dd7dcc9c404911d30e9f87506b3b9d8e997c6c6ceac85ee054b4dadefaff languageName: node linkType: hard @@ -4140,14 +4141,7 @@ __metadata: languageName: node linkType: hard -"is-fullwidth-code-point@npm:^4.0.0": - version: 4.0.0 - resolution: "is-fullwidth-code-point@npm:4.0.0" - checksum: 10c0/df2a717e813567db0f659c306d61f2f804d480752526886954a2a3e2246c7745fd07a52b5fecf2b68caf0a6c79dcdace6166fdf29cc76ed9975cc334f0a018b8 - languageName: node - linkType: hard - -"is-fullwidth-code-point@npm:^5.0.0": +"is-fullwidth-code-point@npm:^5.0.0, is-fullwidth-code-point@npm:^5.1.0": version: 5.1.0 resolution: "is-fullwidth-code-point@npm:5.1.0" dependencies: @@ -4165,12 +4159,12 @@ __metadata: languageName: node linkType: hard -"is-in-ci@npm:^1.0.0": - version: 1.0.0 - resolution: "is-in-ci@npm:1.0.0" +"is-in-ci@npm:^2.0.0": + version: 2.0.0 + resolution: "is-in-ci@npm:2.0.0" bin: is-in-ci: cli.js - checksum: 10c0/98f9cec4c35aece4cf731abf35ebf28359a9b0324fac810da05b842515d9ccb33b8999c1d9a679f0362e1a4df3292065c38d7f86327b1387fa667bc0150f4898 + checksum: 10c0/1e1d1056939a681e8206035de5ad84e0404556eaa7622bb55f0f1868b9788bff3df427bc0b1ed5a172623154a90fcb1e759a230817cd73d09435543ae3c71feb languageName: node linkType: hard @@ -5014,15 +5008,14 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^18.2.0": - version: 18.3.1 - resolution: "react-dom@npm:18.3.1" +"react-dom@npm:^19.0.0": + version: 19.2.4 + resolution: "react-dom@npm:19.2.4" dependencies: - loose-envify: "npm:^1.1.0" - scheduler: "npm:^0.23.2" + scheduler: "npm:^0.27.0" peerDependencies: - react: ^18.3.1 - checksum: 10c0/a752496c1941f958f2e8ac56239172296fcddce1365ce45222d04a1947e0cc5547df3e8447f855a81d6d39f008d7c32eab43db3712077f09e3f67c4874973e85 + react: ^19.2.4 + checksum: 10c0/f0c63f1794dedb154136d4d0f59af00b41907f4859571c155940296808f4b94bf9c0c20633db75b5b2112ec13d8d7dd4f9bf57362ed48782f317b11d05a44f35 languageName: node linkType: hard @@ -5033,15 +5026,14 @@ __metadata: languageName: node linkType: hard -"react-reconciler@npm:^0.29.0": - version: 0.29.2 - resolution: "react-reconciler@npm:0.29.2" +"react-reconciler@npm:^0.33.0": + version: 0.33.0 + resolution: "react-reconciler@npm:0.33.0" dependencies: - loose-envify: "npm:^1.1.0" - scheduler: "npm:^0.23.2" + scheduler: "npm:^0.27.0" peerDependencies: - react: ^18.3.1 - checksum: 10c0/94f48ddc348a974256cf13c859f5a94efdb0cd72e04c51b1a4d5c72a8b960ccd35df2196057ee6a4cbcb26145e12b01e3f9ba3b183fddb901414db36a07cbf43 + react: ^19.2.0 + checksum: 10c0/3f7b27ea8d0ff4c8bf0e402a285e1af9b7d0e6f4c1a70a28f4384938bc1130bc82a90a31df0b79ef5e380e2e55e2598bd90b4dbf802b1203d735ba0355817d3a languageName: node linkType: hard @@ -5054,6 +5046,13 @@ __metadata: languageName: node linkType: hard +"react@npm:^19.0.0": + version: 19.2.4 + resolution: "react@npm:19.2.4" + checksum: 10c0/cd2c9ff67a720799cc3b38a516009986f7fc4cb8d3e15716c6211cf098d1357ee3e348ab05ad0600042bbb0fd888530ba92e329198c92eafa0994f5213396596 + languageName: node + linkType: hard + "readdirp@npm:^4.0.1": version: 4.1.2 resolution: "readdirp@npm:4.1.2" @@ -5298,12 +5297,10 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.23.0, scheduler@npm:^0.23.2": - version: 0.23.2 - resolution: "scheduler@npm:0.23.2" - dependencies: - loose-envify: "npm:^1.1.0" - checksum: 10c0/26383305e249651d4c58e6705d5f8425f153211aef95f15161c151f7b8de885f24751b377e4a0b3dd42cce09aad3f87a61dab7636859c0d89b7daf1a1e2a5c78 +"scheduler@npm:^0.27.0": + version: 0.27.0 + resolution: "scheduler@npm:0.27.0" + checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452 languageName: node linkType: hard @@ -5406,23 +5403,13 @@ __metadata: languageName: node linkType: hard -"slice-ansi@npm:^5.0.0": - version: 5.0.0 - resolution: "slice-ansi@npm:5.0.0" +"slice-ansi@npm:^8.0.0": + version: 8.0.0 + resolution: "slice-ansi@npm:8.0.0" dependencies: - ansi-styles: "npm:^6.0.0" - is-fullwidth-code-point: "npm:^4.0.0" - checksum: 10c0/2d4d40b2a9d5cf4e8caae3f698fe24ae31a4d778701724f578e984dcb485ec8c49f0c04dab59c401821e80fcdfe89cace9c66693b0244e40ec485d72e543914f - languageName: node - linkType: hard - -"slice-ansi@npm:^7.1.0": - version: 7.1.2 - resolution: "slice-ansi@npm:7.1.2" - dependencies: - ansi-styles: "npm:^6.2.1" - is-fullwidth-code-point: "npm:^5.0.0" - checksum: 10c0/36742f2eb0c03e2e81a38ed14d13a64f7b732fe38c3faf96cce0599788a345011e840db35f1430ca606ea3f8db2abeb92a8d25c2753a819e3babaa10c2e289a2 + ansi-styles: "npm:^6.2.3" + is-fullwidth-code-point: "npm:^5.1.0" + checksum: 10c0/0ce4aa91febb7cea4a00c2c27bb820fa53b6d2862ce0f80f7120134719f7914fc416b0ed966cf35250a3169e152916392f35917a2d7cad0fcc5d8b841010fa9a languageName: node linkType: hard @@ -5532,7 +5519,7 @@ __metadata: languageName: node linkType: hard -"string-width@npm:^7.0.0, string-width@npm:^7.2.0": +"string-width@npm:^7.0.0": version: 7.2.0 resolution: "string-width@npm:7.2.0" dependencies: @@ -5543,6 +5530,16 @@ __metadata: languageName: node linkType: hard +"string-width@npm:^8.1.0, string-width@npm:^8.1.1, string-width@npm:^8.2.0": + version: 8.2.0 + resolution: "string-width@npm:8.2.0" + dependencies: + get-east-asian-width: "npm:^1.5.0" + strip-ansi: "npm:^7.1.2" + checksum: 10c0/d8915428b43519b0f494da6590dbe4491857d8a12e40250e50fc01fbb616ffd8400a436bbe25712255ee129511fe0414c49d3b6b9627e2bc3a33dcec1d2eda02 + languageName: node + linkType: hard + "strip-ansi@npm:^3.0.0, strip-ansi@npm:^3.0.1": version: 3.0.1 resolution: "strip-ansi@npm:3.0.1" @@ -5570,7 +5567,7 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^7.1.0": +"strip-ansi@npm:^7.1.0, strip-ansi@npm:^7.1.2": version: 7.2.0 resolution: "strip-ansi@npm:7.2.0" dependencies: @@ -5640,6 +5637,13 @@ __metadata: languageName: node linkType: hard +"tagged-tag@npm:^1.0.0": + version: 1.0.0 + resolution: "tagged-tag@npm:1.0.0" + checksum: 10c0/91d25c9ffb86a91f20522cefb2cbec9b64caa1febe27ad0df52f08993ff60888022d771e868e6416cf2e72dab68449d2139e8709ba009b74c6c7ecd4000048d1 + languageName: node + linkType: hard + "tar@npm:^7.5.4": version: 7.5.11 resolution: "tar@npm:7.5.11" @@ -5653,6 +5657,13 @@ __metadata: languageName: node linkType: hard +"terminal-size@npm:^4.0.1": + version: 4.0.1 + resolution: "terminal-size@npm:4.0.1" + checksum: 10c0/89afd9d816dd9dbfe4499da9aeea70491bbde4ff4592226a9c8ac71074a7580afead6a78e95ecc35f6d42e09087b55ffcb1019302cd55e0cc957b6ce5c4847e8 + languageName: node + linkType: hard + "tinybench@npm:^2.9.0": version: 2.9.0 resolution: "tinybench@npm:2.9.0" @@ -5751,20 +5762,21 @@ __metadata: languageName: node linkType: hard -"twenty-client-sdk@portal:../../twenty-client-sdk::locator=hello-world%40workspace%3A.": - version: 0.0.0-use.local - resolution: "twenty-client-sdk@portal:../../twenty-client-sdk::locator=hello-world%40workspace%3A." +"twenty-client-sdk@npm:0.8.0-canary.5": + version: 0.8.0-canary.5 + resolution: "twenty-client-sdk@npm:0.8.0-canary.5" dependencies: "@genql/cli": "npm:^3.0.3" "@genql/runtime": "npm:^2.10.0" esbuild: "npm:^0.25.0" graphql: "npm:^16.8.1" + checksum: 10c0/754b92b732c8e03c9779f6557324710afe4c07f7e6efbe766bd8ff3b6dd8a00c0d9f3fecce2098d68ef9556cafa722b2189e490473e420fdb9cf30c56beb3619 languageName: node - linkType: soft + linkType: hard -"twenty-sdk@portal:../../twenty-sdk::locator=hello-world%40workspace%3A.": - version: 0.0.0-use.local - resolution: "twenty-sdk@portal:../../twenty-sdk::locator=hello-world%40workspace%3A." +"twenty-sdk@npm:0.8.0-canary.5": + version: 0.8.0-canary.5 + resolution: "twenty-sdk@npm:0.8.0-canary.5" dependencies: "@chakra-ui/react": "npm:^3.33.0" "@emotion/react": "npm:^11.14.0" @@ -5782,13 +5794,14 @@ __metadata: esbuild: "npm:^0.25.0" graphql: "npm:^16.8.1" graphql-sse: "npm:^2.5.4" - ink: "npm:^5.1.1" + ink: "npm:^6.8.0" inquirer: "npm:^10.0.0" jsonc-parser: "npm:^3.2.0" preact: "npm:^10.28.3" - react: "npm:^18.2.0" - react-dom: "npm:^18.2.0" + react: "npm:^19.0.0" + react-dom: "npm:^19.0.0" tinyglobby: "npm:^0.2.15" + twenty-client-sdk: "npm:0.8.0-canary.5" typescript: "npm:^5.9.2" uuid: "npm:^13.0.0" vite: "npm:^7.0.0" @@ -5796,8 +5809,9 @@ __metadata: zod: "npm:^4.1.11" bin: twenty: dist/cli.cjs + checksum: 10c0/47d0970c88f59c092e8eca34dca38bf88d9d52678997349068ca8a8e5cebed2ea71dbd4e8b7299f40b99b5419d4cecd53b31f821b65959267e8d97eb91d2ddde languageName: node - linkType: soft + linkType: hard "type-fest@npm:^0.21.3": version: 0.21.3 @@ -5806,10 +5820,12 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^4.27.0": - version: 4.41.0 - resolution: "type-fest@npm:4.41.0" - checksum: 10c0/f5ca697797ed5e88d33ac8f1fec21921839871f808dc59345c9cf67345bfb958ce41bd821165dbf3ae591cedec2bf6fe8882098dfdd8dc54320b859711a2c1e4 +"type-fest@npm:^5.4.1": + version: 5.5.0 + resolution: "type-fest@npm:5.5.0" + dependencies: + tagged-tag: "npm:^1.0.0" + checksum: 10c0/60bf79a8df45abf99490e3204eceb5cf7f915413f8a69fb578c75cab37ddcb7d29ee21f185f0e1617323ac0b2a441e001b8dc691e220d0b087e9c29ea205538c languageName: node linkType: hard @@ -6123,12 +6139,12 @@ __metadata: languageName: node linkType: hard -"widest-line@npm:^5.0.0": - version: 5.0.0 - resolution: "widest-line@npm:5.0.0" +"widest-line@npm:^6.0.0": + version: 6.0.0 + resolution: "widest-line@npm:6.0.0" dependencies: - string-width: "npm:^7.0.0" - checksum: 10c0/6bd6cca8cda502ef50e05353fd25de0df8c704ffc43ada7e0a9cf9a5d4f4e12520485d80e0b77cec8a21f6c3909042fcf732aa9281e5dbb98cc9384a138b2578 + string-width: "npm:^8.1.0" + checksum: 10c0/735f1fdcd97fe765a07bb8b5e73c020bed8e53ab34e83ce0ef01693ba3c914d9e7977fe5f5facf0d0b670297a82dd5e376d3efa0896860dfcdaf7cd6924c0fb7 languageName: node linkType: hard