diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 769b5ac4..00000000 --- a/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -/dist -/tmp - diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 09f99496..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": ["oclif", "oclif-typescript", "prettier"], - "rules": {}, - "overrides": [ - { - "files":[ "src/**/*.js" ] - } - ] -} diff --git a/bin/dev.js b/bin/dev.js index dd748048..1b582404 100644 --- a/bin/dev.js +++ b/bin/dev.js @@ -1,6 +1,5 @@ #!/usr/bin/env -S node --loader ts-node/esm --disable-warning=ExperimentalWarning -// eslint-disable-next-line n/shebang -import {execute} from '@oclif/core' +import {execute} from '@oclif/core'; -await execute({development: true, dir: import.meta.url}) +await execute({development: true, dir: import.meta.url}); diff --git a/bin/run.js b/bin/run.js index d176672e..32fa00d5 100644 --- a/bin/run.js +++ b/bin/run.js @@ -1,6 +1,5 @@ #!/usr/bin/env node -// eslint-disable-next-line n/shebang -import {execute} from '@oclif/core' +import {execute} from '@oclif/core'; -await execute({dir: import.meta.url}) +await execute({dir: import.meta.url}); diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..32acb847 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,34 @@ +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import stylistic from '@stylistic/eslint-plugin'; +import iTwinEslintPlugin from '@itwin/eslint-plugin'; +import { defineConfig, globalIgnores } from "eslint/config"; + +export default tseslint.config( + defineConfig([globalIgnores(["dist/*", "tmp/*"])]), + eslint.configs.recommended, + tseslint.configs.recommended, + tseslint.configs.stylistic, + iTwinEslintPlugin.configs.iTwinjsRecommendedConfig, + { + plugins: { + "@stylistic": stylistic, + }, + rules: { + '@stylistic/semi': 'error', + '@stylistic/indent': ['error', 2], + }, + languageOptions: { + parser: tseslint.parser, + parserOptions: { + project: "./tsconfig.eslint.json", + }, + }, + }, + { + files: ["integration-tests/**/*"], + rules: { + '@typescript-eslint/no-non-null-assertion': 'off' + }, + } +); \ No newline at end of file diff --git a/integration-tests/access-control-native/access-control-native.test.ts b/integration-tests/access-control-native/access-control-native.test.ts index 7b3e158b..a170fd26 100644 --- a/integration-tests/access-control-native/access-control-native.test.ts +++ b/integration-tests/access-control-native/access-control-native.test.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import runSuiteIfMainModule from '../utils/run-suite-if-main-module'; -import groupTests from './group.test' -import memberTests from './member/member.test' +import groupTests from './group.test'; +import memberTests from './member/member.test'; const tests = () => describe('Access Control Tests (Native Client)', () => { - groupTests(); - memberTests(); + groupTests(); + memberTests(); }); export default tests; diff --git a/integration-tests/access-control-native/group.test.ts b/integration-tests/access-control-native/group.test.ts index a1a0882a..085cd750 100644 --- a/integration-tests/access-control-native/group.test.ts +++ b/integration-tests/access-control-native/group.test.ts @@ -12,36 +12,36 @@ import { nativeLoginToCli } from "../utils/helpers"; import runSuiteIfMainModule from "../utils/run-suite-if-main-module"; const tests = () => describe('group', () => { - let iTwinId: string; - let groupId: string; - const groupName = "Test Group"; - const groupDescription = "Test Group Description"; - before(async function() { - this.timeout(5 * 60 * 1000); - await nativeLoginToCli(); + let iTwinId: string; + let groupId: string; + const groupName = "Test Group"; + const groupDescription = "Test Group Description"; + before(async function() { + this.timeout(5 * 60 * 1000); + await nativeLoginToCli(); - const iTwinName = `cli-itwin-integration-test-${new Date().toISOString()}`; - const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); - expect(iTwin?.id).to.not.be.undefined; - iTwinId = iTwin!.id!; - const { result: group } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name "${groupName}" --description "${groupDescription}"`); - expect(group).to.not.be.undefined; - groupId = group!.id!; - }); + const iTwinName = `cli-itwin-integration-test-${new Date().toISOString()}`; + const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); + expect(iTwin?.id).to.not.be.undefined; + iTwinId = iTwin!.id!; + const { result: group } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name "${groupName}" --description "${groupDescription}"`); + expect(group).to.not.be.undefined; + groupId = group!.id!; + }); - after(async () => { - const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); - expect(deleteResult).to.have.property('result', 'deleted'); - }); + after(async () => { + const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); + expect(deleteResult).to.have.property('result', 'deleted'); + }); - it('Should update group ims-group', async () => { - const imsGroupName = "iTwin CLI Test Group"; - const { result: groupUpdate } = await runCommand(`access-control group update --itwin-id ${iTwinId} --group-id ${groupId} --ims-group "${imsGroupName}"`); - expect(groupUpdate).to.not.be.undefined; - expect(groupUpdate!.id).to.not.be.undefined; - expect(groupUpdate!.imsGroups).to.have.lengthOf(1); - expect(groupUpdate!.imsGroups![0]).to.be.equal(imsGroupName); - }); + it('Should update group ims-group', async () => { + const imsGroupName = "iTwin CLI Test Group"; + const { result: groupUpdate } = await runCommand(`access-control group update --itwin-id ${iTwinId} --group-id ${groupId} --ims-group "${imsGroupName}"`); + expect(groupUpdate).to.not.be.undefined; + expect(groupUpdate!.id).to.not.be.undefined; + expect(groupUpdate!.imsGroups).to.have.lengthOf(1); + expect(groupUpdate!.imsGroups![0]).to.be.equal(imsGroupName); + }); }); export default tests; diff --git a/integration-tests/access-control-native/member/member.test.ts b/integration-tests/access-control-native/member/member.test.ts index f6cc114b..ca29ecbf 100644 --- a/integration-tests/access-control-native/member/member.test.ts +++ b/integration-tests/access-control-native/member/member.test.ts @@ -5,11 +5,11 @@ import runSuiteIfMainModule from '../../utils/run-suite-if-main-module'; import ownerTests from './owner.test'; -import userTests from './user.test' +import userTests from './user.test'; const tests = () => describe('member', () => { - userTests(); - ownerTests(); + userTests(); + ownerTests(); }); export default tests; diff --git a/integration-tests/access-control-native/member/owner.test.ts b/integration-tests/access-control-native/member/owner.test.ts index f71c246c..b02988e2 100644 --- a/integration-tests/access-control-native/member/owner.test.ts +++ b/integration-tests/access-control-native/member/owner.test.ts @@ -14,41 +14,41 @@ import { nativeLoginToCli } from "../../utils/helpers.js"; import runSuiteIfMainModule from "../../utils/run-suite-if-main-module.js"; const tests = () => describe('owner', () => { - let iTwinId: string; - const iTwinName: string = `cli-itwin-integration-test-${new Date().toISOString()}`; + let iTwinId: string; + const iTwinName: string = `cli-itwin-integration-test-${new Date().toISOString()}`; - before(async () => { - await nativeLoginToCli(); - - const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); - expect(iTwin).to.have.property('id'); - iTwinId = iTwin!.id!; - }); - - after(async () => { - const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); - expect(deleteResult).to.have.property('result', 'deleted'); - }); - - it('Should add an internal member to an iTwin and remove owner member', async () => { - const emailToAdd = ITP_TEST_USER_SAMEORG; - - const { result: invitedUser } = await runCommand(`access-control member owner add --itwin-id ${iTwinId} --email ${emailToAdd}`); - - expect(invitedUser).to.not.be.undefined; - expect(invitedUser!.member).to.not.be.undefined; - expect(invitedUser!.member.email.toLowerCase()).to.be.equal(emailToAdd!.toLowerCase()); - - const { result: usersInfo } = await runCommand(`access-control member owner list --itwin-id ${iTwinId}`); - expect(usersInfo).to.not.be.undefined; - expect(usersInfo).to.have.lengthOf(2); - const joinedUser = usersInfo?.filter(user => user.email.toLowerCase() === emailToAdd!.toLowerCase())[0]; - expect(joinedUser).to.not.be.undefined; - - const { result: deleteResult } = await runCommand<{result: string}>(`access-control member owner delete --itwin-id ${iTwinId} --member-id ${joinedUser?.id}`); - expect(deleteResult).to.not.be.undefined; - expect(deleteResult).to.have.property('result', "deleted"); - }); + before(async () => { + await nativeLoginToCli(); + + const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); + expect(iTwin).to.have.property('id'); + iTwinId = iTwin!.id!; + }); + + after(async () => { + const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); + expect(deleteResult).to.have.property('result', 'deleted'); + }); + + it('Should add an internal member to an iTwin and remove owner member', async () => { + const emailToAdd = ITP_TEST_USER_SAMEORG; + + const { result: invitedUser } = await runCommand(`access-control member owner add --itwin-id ${iTwinId} --email ${emailToAdd}`); + + expect(invitedUser).to.not.be.undefined; + expect(invitedUser!.member).to.not.be.undefined; + expect(invitedUser!.member.email.toLowerCase()).to.be.equal(emailToAdd!.toLowerCase()); + + const { result: usersInfo } = await runCommand(`access-control member owner list --itwin-id ${iTwinId}`); + expect(usersInfo).to.not.be.undefined; + expect(usersInfo).to.have.lengthOf(2); + const joinedUser = usersInfo?.filter(user => user.email.toLowerCase() === emailToAdd!.toLowerCase())[0]; + expect(joinedUser).to.not.be.undefined; + + const { result: deleteResult } = await runCommand<{result: string}>(`access-control member owner delete --itwin-id ${iTwinId} --member-id ${joinedUser?.id}`); + expect(deleteResult).to.not.be.undefined; + expect(deleteResult).to.have.property('result', "deleted"); + }); }); export default tests; diff --git a/integration-tests/access-control-native/member/user.test.ts b/integration-tests/access-control-native/member/user.test.ts index d8c7c721..cf518832 100644 --- a/integration-tests/access-control-native/member/user.test.ts +++ b/integration-tests/access-control-native/member/user.test.ts @@ -14,49 +14,49 @@ import { nativeLoginToCli } from "../../utils/helpers"; import runSuiteIfMainModule from "../../utils/run-suite-if-main-module"; const tests = () => describe('user', () => { - let iTwinId: string; - const iTwinName: string = `cli-itwin-integration-test-${new Date().toISOString()}`; + let iTwinId: string; + const iTwinName: string = `cli-itwin-integration-test-${new Date().toISOString()}`; - before(async () => { - await nativeLoginToCli(); + before(async () => { + await nativeLoginToCli(); - const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); - expect(iTwin, "itwin create result").to.have.property('id'); - iTwinId = iTwin!.id!; - }); + const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); + expect(iTwin, "itwin create result").to.have.property('id'); + iTwinId = iTwin!.id!; + }); - after(async () => { - const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); - expect(deleteResult).to.have.property('result', 'deleted'); - }); + after(async () => { + const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); + expect(deleteResult).to.have.property('result', 'deleted'); + }); - it('Should add an internal member to an iTwin and remove user member', async () => { - const { result: newRole } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role 1" -d "Test Role Description"`); - expect(newRole).to.not.be.undefined; - expect(newRole!.id).to.not.be.undefined; + it('Should add an internal member to an iTwin and remove user member', async () => { + const { result: newRole } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role 1" -d "Test Role Description"`); + expect(newRole).to.not.be.undefined; + expect(newRole!.id).to.not.be.undefined; - const emailToAdd = ITP_TEST_USER_SAMEORG; + const emailToAdd = ITP_TEST_USER_SAMEORG; - const { result: invitedUser } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --members "[{"email": "${emailToAdd}", "roleIds": ["${newRole!.id}"]}]"`); + const { result: invitedUser } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --members "[{"email": "${emailToAdd}", "roleIds": ["${newRole!.id}"]}]"`); - expect(invitedUser).to.not.be.undefined; - expect(invitedUser!.members).to.have.lengthOf(1); - expect(invitedUser!.members[0].email.toLowerCase()).to.be.equal(emailToAdd!.toLowerCase()); - expect(invitedUser!.members[0].roles).to.have.lengthOf(1); - expect(invitedUser!.members[0].roles[0].id).to.be.equal(newRole!.id); + expect(invitedUser).to.not.be.undefined; + expect(invitedUser!.members).to.have.lengthOf(1); + expect(invitedUser!.members[0].email.toLowerCase()).to.be.equal(emailToAdd!.toLowerCase()); + expect(invitedUser!.members[0].roles).to.have.lengthOf(1); + expect(invitedUser!.members[0].roles[0].id).to.be.equal(newRole!.id); - const { result: usersInfo } = await runCommand(`access-control member user list --itwin-id ${iTwinId}`); - expect(usersInfo).to.not.be.undefined; - expect(usersInfo).to.have.lengthOf(2); - const joinedUser = usersInfo?.filter(user => user.email.toLowerCase() === emailToAdd!.toLowerCase())[0]; - expect(joinedUser).to.not.be.undefined; - expect(joinedUser?.roles).to.have.lengthOf(1); - expect(joinedUser?.roles[0].id).to.be.equal(newRole!.id); + const { result: usersInfo } = await runCommand(`access-control member user list --itwin-id ${iTwinId}`); + expect(usersInfo).to.not.be.undefined; + expect(usersInfo).to.have.lengthOf(2); + const joinedUser = usersInfo?.filter(user => user.email.toLowerCase() === emailToAdd!.toLowerCase())[0]; + expect(joinedUser).to.not.be.undefined; + expect(joinedUser?.roles).to.have.lengthOf(1); + expect(joinedUser?.roles[0].id).to.be.equal(newRole!.id); - const { result: deleteResult } = await runCommand<{result: string}>(`access-control member user delete --itwin-id ${iTwinId} --member-id ${joinedUser?.id}`); - expect(deleteResult).to.not.be.undefined; - expect(deleteResult).to.have.property('result', "deleted"); - }); + const { result: deleteResult } = await runCommand<{result: string}>(`access-control member user delete --itwin-id ${iTwinId} --member-id ${joinedUser?.id}`); + expect(deleteResult).to.not.be.undefined; + expect(deleteResult).to.have.property('result', "deleted"); + }); }); export default tests; diff --git a/integration-tests/access-control/access-control.test.ts b/integration-tests/access-control/access-control.test.ts index a808e358..1c7bdcd8 100644 --- a/integration-tests/access-control/access-control.test.ts +++ b/integration-tests/access-control/access-control.test.ts @@ -10,21 +10,21 @@ import permissionTests from "./permissions.test"; import roleTests from "./role.test"; const tests = () => describe('Access Control Tests', () => { - describe('group', () => { - groupTests(); - }); + describe('group', () => { + groupTests(); + }); - describe('role', () => { - roleTests(); - }); + describe('role', () => { + roleTests(); + }); - describe('permissions', () => { - permissionTests(); - }); + describe('permissions', () => { + permissionTests(); + }); - describe('member', () => { - memberTests(); - }); + describe('member', () => { + memberTests(); + }); }); export default tests; diff --git a/integration-tests/access-control/group.test.ts b/integration-tests/access-control/group.test.ts index e7fcf729..d804001b 100644 --- a/integration-tests/access-control/group.test.ts +++ b/integration-tests/access-control/group.test.ts @@ -12,113 +12,113 @@ import { ITP_TEST_USER_SAMEORG } from "../utils/environment"; import runSuiteIfMainModule from "../utils/run-suite-if-main-module"; const tests = () => { - let iTwinId: string; - - before(async () => { - const iTwinName = `cli-itwin-integration-test-${new Date().toISOString()}`; - const { result: iTwin} = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); - expect(iTwin?.id).to.not.be.undefined; - iTwinId = iTwin!.id!; - }); - - after(async () => { - const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); - expect(deleteResult).to.have.property('result', 'deleted'); - }); - - it('Should create and update group info', async () => { - const groupName = "Test Group"; - const groupDescription = "Test Group Description"; - - const { result: groupCreate } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name "${groupName}" --description "${groupDescription}"`); - - expect(groupCreate).to.not.be.undefined; - expect(groupCreate!.id).to.not.be.undefined; - expect(groupCreate!.name).to.be.equal(groupName); - expect(groupCreate!.description).to.be.equal(groupDescription); + let iTwinId: string; + + before(async () => { + const iTwinName = `cli-itwin-integration-test-${new Date().toISOString()}`; + const { result: iTwin} = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); + expect(iTwin?.id).to.not.be.undefined; + iTwinId = iTwin!.id!; + }); + + after(async () => { + const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); + expect(deleteResult).to.have.property('result', 'deleted'); + }); + + it('Should create and update group info', async () => { + const groupName = "Test Group"; + const groupDescription = "Test Group Description"; + + const { result: groupCreate } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name "${groupName}" --description "${groupDescription}"`); + + expect(groupCreate).to.not.be.undefined; + expect(groupCreate!.id).to.not.be.undefined; + expect(groupCreate!.name).to.be.equal(groupName); + expect(groupCreate!.description).to.be.equal(groupDescription); - const { result: groupInfo } = await runCommand(`access-control group info --itwin-id ${iTwinId} --group-id ${groupCreate!.id}`); + const { result: groupInfo } = await runCommand(`access-control group info --itwin-id ${iTwinId} --group-id ${groupCreate!.id}`); - expect(groupInfo).to.not.be.undefined; - - expect(groupInfo?.id).to.be.equal(groupCreate!.id); - expect(groupInfo?.name).to.be.equal(groupName); - expect(groupInfo?.description).to.be.equal(groupDescription); - - const updatedGroupName = "Updated Group Name"; - const updatedGroupDescription = "Updated Group Description"; - const memberEmail = ITP_TEST_USER_SAMEORG; - - const { result: groupUpdate } = await runCommand(`access-control group update --itwin-id ${iTwinId} --group-id ${groupCreate!.id} --name "${updatedGroupName}" --description "${updatedGroupDescription}" --member ${memberEmail}`); - expect(groupUpdate).to.not.be.undefined; - expect(groupUpdate!.id).to.not.be.undefined; - expect(groupUpdate!.name).to.be.equal(updatedGroupName); - expect(groupUpdate!.description).to.be.equal(updatedGroupDescription); - expect(groupUpdate!.members).to.not.be.undefined; - expect(groupUpdate!.members!.some(member => member.email.toLowerCase() === memberEmail!.toLowerCase())).to.be.true; - }); - - it('Should list groups', async () => { - const { result: newGroup } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name Test2 --description Description2`); - expect(newGroup).to.not.be.undefined; - expect(newGroup!.id).to.not.be.undefined; - expect(newGroup!.name).to.be.equal("Test2"); - expect(newGroup!.description).to.be.equal("Description2"); - - const { result: listedGroups } = await runCommand(`access-control group list --itwin-id ${iTwinId}`); - expect(listedGroups).to.not.be.undefined; - expect(listedGroups!.length).to.be.greaterThanOrEqual(1); - - expect(listedGroups!.some(entry => entry.id === newGroup!.id), "Newly created group not found in the list").to.be.true; - }); - - it('Should delete group', async () => { - const { result: createResult } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name Test3 --description Description3`); - expect(createResult).to.not.be.undefined; - expect(createResult!.id).to.not.be.undefined; - - const { result: deleteResult } = await runCommand<{result: string}>(`access-control group delete --itwin-id ${iTwinId} --group-id ${createResult!.id}`); - expect(deleteResult).to.have.property('result', 'deleted'); - - const { error: infoError } = await runCommand(`access-control group info --itwin-id ${iTwinId} -g ${createResult!.id}`); - expect(infoError?.message).to.contain('GroupNotFound') - }); - - it('Should fail to update group and return an error if too many members are provided', async () => { - const { result: newGroup } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name Test3 --description Description3`); - expect(newGroup).to.not.be.undefined; - expect(newGroup!.id).to.not.be.undefined; - - let updateCommand = `access-control group update --itwin-id ${iTwinId} --group-id ${newGroup!.id}` - for (let i = 0; i < 51; i++) { - updateCommand += ` --member user${i}@example.com` - } - - const { error: updateError } = await runCommand(updateCommand); - const { result: deleteResult } = await runCommand<{result: string}>(`access-control group delete --itwin-id ${iTwinId} --group-id ${newGroup!.id}`); - expect(deleteResult).to.have.property('result', 'deleted'); - - expect(updateError).to.not.be.undefined; - expect(updateError?.message).to.be.equal('A maximum of 50 members can be provided.'); - }); - - it('Should fail to update group and return an error if too many ims-groups are provided', async () => { - const { result: newGroup } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name Test3 --description Description3`); - expect(newGroup).to.not.be.undefined; - expect(newGroup!.id).to.not.be.undefined; - - let updateCommand = `access-control group update --itwin-id ${iTwinId} --group-id ${newGroup!.id}` - for (let i = 0; i < 51; i++) { - updateCommand += ` --ims-group IMS_Group_${i}`; - } - - const { error: updateError } = await runCommand(updateCommand); - const { result: deleteResult } = await runCommand<{result: string}>(`access-control group delete --itwin-id ${iTwinId} --group-id ${newGroup!.id}`); - expect(deleteResult).to.have.property('result', 'deleted'); - - expect(updateError).to.not.be.undefined; - expect(updateError?.message).to.be.equal('A maximum of 50 ims groups can be provided.'); - }); + expect(groupInfo).to.not.be.undefined; + + expect(groupInfo?.id).to.be.equal(groupCreate!.id); + expect(groupInfo?.name).to.be.equal(groupName); + expect(groupInfo?.description).to.be.equal(groupDescription); + + const updatedGroupName = "Updated Group Name"; + const updatedGroupDescription = "Updated Group Description"; + const memberEmail = ITP_TEST_USER_SAMEORG; + + const { result: groupUpdate } = await runCommand(`access-control group update --itwin-id ${iTwinId} --group-id ${groupCreate!.id} --name "${updatedGroupName}" --description "${updatedGroupDescription}" --member ${memberEmail}`); + expect(groupUpdate).to.not.be.undefined; + expect(groupUpdate!.id).to.not.be.undefined; + expect(groupUpdate!.name).to.be.equal(updatedGroupName); + expect(groupUpdate!.description).to.be.equal(updatedGroupDescription); + expect(groupUpdate!.members).to.not.be.undefined; + expect(groupUpdate!.members!.some(member => member.email.toLowerCase() === memberEmail!.toLowerCase())).to.be.true; + }); + + it('Should list groups', async () => { + const { result: newGroup } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name Test2 --description Description2`); + expect(newGroup).to.not.be.undefined; + expect(newGroup!.id).to.not.be.undefined; + expect(newGroup!.name).to.be.equal("Test2"); + expect(newGroup!.description).to.be.equal("Description2"); + + const { result: listedGroups } = await runCommand(`access-control group list --itwin-id ${iTwinId}`); + expect(listedGroups).to.not.be.undefined; + expect(listedGroups!.length).to.be.greaterThanOrEqual(1); + + expect(listedGroups!.some(entry => entry.id === newGroup!.id), "Newly created group not found in the list").to.be.true; + }); + + it('Should delete group', async () => { + const { result: createResult } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name Test3 --description Description3`); + expect(createResult).to.not.be.undefined; + expect(createResult!.id).to.not.be.undefined; + + const { result: deleteResult } = await runCommand<{result: string}>(`access-control group delete --itwin-id ${iTwinId} --group-id ${createResult!.id}`); + expect(deleteResult).to.have.property('result', 'deleted'); + + const { error: infoError } = await runCommand(`access-control group info --itwin-id ${iTwinId} -g ${createResult!.id}`); + expect(infoError?.message).to.contain('GroupNotFound'); + }); + + it('Should fail to update group and return an error if too many members are provided', async () => { + const { result: newGroup } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name Test3 --description Description3`); + expect(newGroup).to.not.be.undefined; + expect(newGroup!.id).to.not.be.undefined; + + let updateCommand = `access-control group update --itwin-id ${iTwinId} --group-id ${newGroup!.id}`; + for (let i = 0; i < 51; i++) { + updateCommand += ` --member user${i}@example.com`; + } + + const { error: updateError } = await runCommand(updateCommand); + const { result: deleteResult } = await runCommand<{result: string}>(`access-control group delete --itwin-id ${iTwinId} --group-id ${newGroup!.id}`); + expect(deleteResult).to.have.property('result', 'deleted'); + + expect(updateError).to.not.be.undefined; + expect(updateError?.message).to.be.equal('A maximum of 50 members can be provided.'); + }); + + it('Should fail to update group and return an error if too many ims-groups are provided', async () => { + const { result: newGroup } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name Test3 --description Description3`); + expect(newGroup).to.not.be.undefined; + expect(newGroup!.id).to.not.be.undefined; + + let updateCommand = `access-control group update --itwin-id ${iTwinId} --group-id ${newGroup!.id}`; + for (let i = 0; i < 51; i++) { + updateCommand += ` --ims-group IMS_Group_${i}`; + } + + const { error: updateError } = await runCommand(updateCommand); + const { result: deleteResult } = await runCommand<{result: string}>(`access-control group delete --itwin-id ${iTwinId} --group-id ${newGroup!.id}`); + expect(deleteResult).to.have.property('result', 'deleted'); + + expect(updateError).to.not.be.undefined; + expect(updateError?.message).to.be.equal('A maximum of 50 ims groups can be provided.'); + }); }; export default tests; diff --git a/integration-tests/access-control/member/group.test.ts b/integration-tests/access-control/member/group.test.ts index 93a605fc..7b4a5470 100644 --- a/integration-tests/access-control/member/group.test.ts +++ b/integration-tests/access-control/member/group.test.ts @@ -12,290 +12,290 @@ import { Role } from "../../../src/services/access-control-client/models/role"; import runSuiteIfMainModule from '../../utils/run-suite-if-main-module'; const tests = () => { - let iTwinId: string; - let groupId1: string; - let groupId2: string; - let groupId3: string; - let roleId1: string; - let roleId2: string; - let roleId3: string; - - - before(async () => { - const iTwinName = `cli-itwin-integration-test-${new Date().toISOString()}`; - const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); - expect(iTwin?.id).to.not.be.undefined; - iTwinId = iTwin!.id!; - - const { result: group1 } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name "Test Group #1" --description "Test Group Description"`); - expect(group1?.id).to.not.be.undefined; - groupId1 = group1!.id!; - - const { result: group2 } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name "Test Group #2" --description "Test Group Description"`); - expect(group2?.id).to.not.be.undefined; - groupId2 = group2!.id!; - - const { result: group3 } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name "Test Group #3" --description "Test Group Description"`); - expect(group3?.id).to.not.be.undefined; - groupId3 = group3!.id!; - - const { result: role1 } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role #1" -d "Test Role Description"`); - expect(role1?.id).to.not.be.undefined; - roleId1 = role1!.id!; - - const { result: role2 } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role #2" -d "Test Role Description"`); - expect(role2?.id).to.not.be.undefined; - roleId2 = role2!.id!; - - const { result: role3 } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role #3" -d "Test Role Description"`); - expect(role3?.id).to.not.be.undefined; - roleId3 = role3!.id!; - }); - - after(async () => { - const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); - expect(deleteResult).to.have.property('result', 'deleted'); - }); - - it('Should create, update and list info and delete member group', async () => { - const serializedGroupsInfo = JSON.stringify([ - { - groupId: groupId1, - roleIds: [roleId1] - } - ]); - - const { result: createResult } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --groups ${serializedGroupsInfo}`); - expect(createResult).to.not.be.undefined; - expect(createResult).to.have.lengthOf(1); - expect(createResult![0].id).to.not.be.undefined; - expect(createResult![0].id).to.be.equal(groupId1); - expect(createResult![0].roles).to.not.be.undefined; - expect(createResult![0].roles).to.have.lengthOf(1); - expect(createResult![0].roles![0].id).to.be.equal(roleId1); - - const { result: infoResult } = await runCommand(`access-control member group info --itwin-id ${iTwinId} --group-id ${groupId1}`); - expect(infoResult).to.not.be.undefined; - expect(infoResult!.id).to.not.be.undefined; - expect(infoResult!.id).to.be.equal(groupId1); - - const { result: additionalRole } = await runCommand(`access-control role create -i ${iTwinId} -n "One More Test Role" -d "One More Test Role Description"`); - expect(additionalRole).to.not.be.undefined; - expect(additionalRole!.id).to.not.be.undefined; - - const { result: updateResult } = await runCommand(`access-control member group update --itwin-id ${iTwinId} --group-id ${groupId1} --role-id ${roleId1} --role-id ${additionalRole!.id}`); - expect(updateResult).to.not.be.undefined; - expect(updateResult!.id).to.not.be.undefined; - expect(updateResult!.id).to.be.equal(groupId1); - expect(updateResult!.roles).to.not.be.undefined; - expect(updateResult!.roles).to.have.lengthOf(2); - const assignedRoleIds = updateResult!.roles!.map(role => role.id); - expect(assignedRoleIds).to.include(roleId1); - expect(assignedRoleIds).to.include(additionalRole!.id); - - const { result: resultList } = await runCommand(`access-control member group list --itwin-id ${iTwinId}`); - expect(resultList).to.not.be.undefined; - expect(resultList).to.have.lengthOf(1); - expect(resultList![0].id).to.not.be.undefined; - expect(resultList![0].id).to.be.equal(groupId1); - expect(resultList![0].roles).to.not.be.undefined; - expect(resultList![0].roles).to.have.lengthOf(2); - expect(resultList![0].roles![0].id).to.be.equal(roleId1); - expect(resultList![0].roles![1].id).to.be.equal(additionalRole!.id); - - const { result: deleteResult } = await runCommand<{result: string}>(`access-control member group delete --itwin-id ${iTwinId} --group-id ${groupId1}`); - expect(deleteResult).to.have.property('result', 'deleted'); - }); - - it('Should create multiple member groups using `--groups` flag and delete them', async () => { - const groupsInfo = [ - { - groupId: groupId1, - roleIds: [roleId1, roleId2] - }, - { - groupId: groupId2, - roleIds: [roleId1, roleId3] - }, - { - groupId: groupId3, - roleIds: [roleId2, roleId3] - }, - ]; - - const { result: createResult } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --groups ${JSON.stringify(groupsInfo)}`); - expect(createResult).to.not.be.undefined; - expect(createResult).to.have.lengthOf(3); - for (const [i, groupInfo] of groupsInfo.entries()) { - expect(createResult![i].id).to.be.equal(groupInfo.groupId); - expect(createResult![i].roles.map(role => role.id)).to.be.deep.equal(groupInfo.roleIds); - } - - const { result: deleteResult1 } = await runCommand<{result: string}>(`access-control member group delete --itwin-id ${iTwinId} --group-id ${groupId1}`); - expect(deleteResult1).to.have.property('result', 'deleted'); - - const { result: deleteResult2 } = await runCommand<{result: string}>(`access-control member group delete --itwin-id ${iTwinId} --group-id ${groupId2}`); - expect(deleteResult2).to.have.property('result', 'deleted'); - - const { result: deleteResult3 } = await runCommand<{result: string}>(`access-control member group delete --itwin-id ${iTwinId} --group-id ${groupId3}`); - expect(deleteResult3).to.have.property('result', 'deleted'); - }); - - it('Should create multiple member groups using `--group-id` and `--role-ids` flags and delete them', async () => { - const groupIds = [groupId1, groupId2, groupId3]; - const roleIds = [roleId1, roleId2, roleId3]; - - const { result: resultCreate } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --group-id ${groupIds[0]} --group-id ${groupIds[1]} --group-id ${groupIds[2]} --role-ids ${roleIds.join(',')}`); - expect(resultCreate).to.not.be.undefined; - expect(resultCreate).to.have.lengthOf(3); - for (const memberInfo of resultCreate!) { - expect(groupIds.includes(memberInfo.id)).to.be.true; - expect(memberInfo.roles.map(role => role.id)).to.be.deep.equal(roleIds); - } - - const { result: deleteResult1} = await runCommand<{result: string}>(`access-control member group delete --itwin-id ${iTwinId} --group-id ${groupIds[0]}`); - expect(deleteResult1).to.have.property('result', 'deleted');; - - const {result: deleteResult2 } = await runCommand<{result: string}>(`access-control member group delete --itwin-id ${iTwinId} --group-id ${groupIds[1]}`); - expect(deleteResult2).to.have.property('result', 'deleted'); - - const {result: deleteResult3 } = await runCommand<{result: string}>(`access-control member group delete --itwin-id ${iTwinId} --group-id ${groupIds[2]}`); - expect(deleteResult3).to.have.property('result', 'deleted'); - }); - - it('Should return an error when all of the following flags are provided: `--groups`, `--group-id`, `--role-ids`', async () => { - const groupsInfo = [ - { - groupId: groupId1, - roleIds: [roleId1, roleId2] - }, - { - groupId: groupId2, - roleIds: [roleId1, roleId3] - }, - { - groupId: groupId3, - roleIds: [roleId2, roleId3] - }, - ]; - - const roleIds = [roleId1, roleId2, roleId3]; - - const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --groups ${JSON.stringify(groupsInfo)} --group-id ${groupsInfo[0].groupId} --group-id ${groupsInfo[1].groupId} --group-id ${groupsInfo[2].groupId} --role-ids ${roleIds.join(',')}`); - expect(createError).to.not.be.undefined; - expect(createError!.message).to.match(new RegExp(`--group-id=${groupsInfo[0].groupId},${groupsInfo[1].groupId},${groupsInfo[2].groupId} cannot also be provided when using --groups`)) - }); - - it('Should return an error when none of the following flags are provided: `--groups`, `--group-id`, `--role-ids`', async () => { - const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId}`); - expect(createError).to.not.be.undefined; - expect(createError!.message).to.match(/Exactly one of the following must be provided: --group-id, --groups/); - }); - - it('should return an error when only `--group-id` flag is provided', async () => { - const groupsInfo = [ - { - groupId: groupId1, - }, - { - groupId: groupId2, - }, - { - groupId: groupId3, - }, - ]; - - const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --group-id ${groupsInfo[0].groupId} --group-id ${groupsInfo[1].groupId} --group-id ${groupsInfo[2].groupId}`); - expect(createError).to.not.be.undefined; - expect(createError!.message).to.match(/All of the following must be provided when using --group-id: --role-ids/) - }) - - it('should return an error when only `--role-ids` flag is provided', async () => { - const roleIds = [roleId1, roleId2, roleId3]; - - const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --role-ids ${roleIds.join(',')}`); - expect(createError).to.not.be.undefined; - expect(createError?.message).to.match(/All of the following must be provided when using --role-ids: --group-id/) - }); - - it('should return an error when there are invalid UUIDs provided to `--role-ids` flag', async () => { - const groupsInfo = [ - { - groupId: groupId1, - roleIds: [roleId1, roleId2] - } - ]; - - const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --group-id ${groupsInfo[0].groupId} + let iTwinId: string; + let groupId1: string; + let groupId2: string; + let groupId3: string; + let roleId1: string; + let roleId2: string; + let roleId3: string; + + + before(async () => { + const iTwinName = `cli-itwin-integration-test-${new Date().toISOString()}`; + const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); + expect(iTwin?.id).to.not.be.undefined; + iTwinId = iTwin!.id!; + + const { result: group1 } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name "Test Group #1" --description "Test Group Description"`); + expect(group1?.id).to.not.be.undefined; + groupId1 = group1!.id!; + + const { result: group2 } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name "Test Group #2" --description "Test Group Description"`); + expect(group2?.id).to.not.be.undefined; + groupId2 = group2!.id!; + + const { result: group3 } = await runCommand(`access-control group create --itwin-id ${iTwinId} --name "Test Group #3" --description "Test Group Description"`); + expect(group3?.id).to.not.be.undefined; + groupId3 = group3!.id!; + + const { result: role1 } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role #1" -d "Test Role Description"`); + expect(role1?.id).to.not.be.undefined; + roleId1 = role1!.id!; + + const { result: role2 } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role #2" -d "Test Role Description"`); + expect(role2?.id).to.not.be.undefined; + roleId2 = role2!.id!; + + const { result: role3 } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role #3" -d "Test Role Description"`); + expect(role3?.id).to.not.be.undefined; + roleId3 = role3!.id!; + }); + + after(async () => { + const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); + expect(deleteResult).to.have.property('result', 'deleted'); + }); + + it('Should create, update and list info and delete member group', async () => { + const serializedGroupsInfo = JSON.stringify([ + { + groupId: groupId1, + roleIds: [roleId1] + } + ]); + + const { result: createResult } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --groups ${serializedGroupsInfo}`); + expect(createResult).to.not.be.undefined; + expect(createResult).to.have.lengthOf(1); + expect(createResult![0].id).to.not.be.undefined; + expect(createResult![0].id).to.be.equal(groupId1); + expect(createResult![0].roles).to.not.be.undefined; + expect(createResult![0].roles).to.have.lengthOf(1); + expect(createResult![0].roles![0].id).to.be.equal(roleId1); + + const { result: infoResult } = await runCommand(`access-control member group info --itwin-id ${iTwinId} --group-id ${groupId1}`); + expect(infoResult).to.not.be.undefined; + expect(infoResult!.id).to.not.be.undefined; + expect(infoResult!.id).to.be.equal(groupId1); + + const { result: additionalRole } = await runCommand(`access-control role create -i ${iTwinId} -n "One More Test Role" -d "One More Test Role Description"`); + expect(additionalRole).to.not.be.undefined; + expect(additionalRole!.id).to.not.be.undefined; + + const { result: updateResult } = await runCommand(`access-control member group update --itwin-id ${iTwinId} --group-id ${groupId1} --role-id ${roleId1} --role-id ${additionalRole!.id}`); + expect(updateResult).to.not.be.undefined; + expect(updateResult!.id).to.not.be.undefined; + expect(updateResult!.id).to.be.equal(groupId1); + expect(updateResult!.roles).to.not.be.undefined; + expect(updateResult!.roles).to.have.lengthOf(2); + const assignedRoleIds = updateResult!.roles!.map(role => role.id); + expect(assignedRoleIds).to.include(roleId1); + expect(assignedRoleIds).to.include(additionalRole!.id); + + const { result: resultList } = await runCommand(`access-control member group list --itwin-id ${iTwinId}`); + expect(resultList).to.not.be.undefined; + expect(resultList).to.have.lengthOf(1); + expect(resultList![0].id).to.not.be.undefined; + expect(resultList![0].id).to.be.equal(groupId1); + expect(resultList![0].roles).to.not.be.undefined; + expect(resultList![0].roles).to.have.lengthOf(2); + expect(resultList![0].roles![0].id).to.be.equal(roleId1); + expect(resultList![0].roles![1].id).to.be.equal(additionalRole!.id); + + const { result: deleteResult } = await runCommand<{result: string}>(`access-control member group delete --itwin-id ${iTwinId} --group-id ${groupId1}`); + expect(deleteResult).to.have.property('result', 'deleted'); + }); + + it('Should create multiple member groups using `--groups` flag and delete them', async () => { + const groupsInfo = [ + { + groupId: groupId1, + roleIds: [roleId1, roleId2] + }, + { + groupId: groupId2, + roleIds: [roleId1, roleId3] + }, + { + groupId: groupId3, + roleIds: [roleId2, roleId3] + }, + ]; + + const { result: createResult } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --groups ${JSON.stringify(groupsInfo)}`); + expect(createResult).to.not.be.undefined; + expect(createResult).to.have.lengthOf(3); + for (const [i, groupInfo] of groupsInfo.entries()) { + expect(createResult![i].id).to.be.equal(groupInfo.groupId); + expect(createResult![i].roles.map(role => role.id)).to.be.deep.equal(groupInfo.roleIds); + } + + const { result: deleteResult1 } = await runCommand<{result: string}>(`access-control member group delete --itwin-id ${iTwinId} --group-id ${groupId1}`); + expect(deleteResult1).to.have.property('result', 'deleted'); + + const { result: deleteResult2 } = await runCommand<{result: string}>(`access-control member group delete --itwin-id ${iTwinId} --group-id ${groupId2}`); + expect(deleteResult2).to.have.property('result', 'deleted'); + + const { result: deleteResult3 } = await runCommand<{result: string}>(`access-control member group delete --itwin-id ${iTwinId} --group-id ${groupId3}`); + expect(deleteResult3).to.have.property('result', 'deleted'); + }); + + it('Should create multiple member groups using `--group-id` and `--role-ids` flags and delete them', async () => { + const groupIds = [groupId1, groupId2, groupId3]; + const roleIds = [roleId1, roleId2, roleId3]; + + const { result: resultCreate } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --group-id ${groupIds[0]} --group-id ${groupIds[1]} --group-id ${groupIds[2]} --role-ids ${roleIds.join(',')}`); + expect(resultCreate).to.not.be.undefined; + expect(resultCreate).to.have.lengthOf(3); + for (const memberInfo of resultCreate!) { + expect(groupIds.includes(memberInfo.id)).to.be.true; + expect(memberInfo.roles.map(role => role.id)).to.be.deep.equal(roleIds); + } + + const { result: deleteResult1} = await runCommand<{result: string}>(`access-control member group delete --itwin-id ${iTwinId} --group-id ${groupIds[0]}`); + expect(deleteResult1).to.have.property('result', 'deleted');; + + const {result: deleteResult2 } = await runCommand<{result: string}>(`access-control member group delete --itwin-id ${iTwinId} --group-id ${groupIds[1]}`); + expect(deleteResult2).to.have.property('result', 'deleted'); + + const {result: deleteResult3 } = await runCommand<{result: string}>(`access-control member group delete --itwin-id ${iTwinId} --group-id ${groupIds[2]}`); + expect(deleteResult3).to.have.property('result', 'deleted'); + }); + + it('Should return an error when all of the following flags are provided: `--groups`, `--group-id`, `--role-ids`', async () => { + const groupsInfo = [ + { + groupId: groupId1, + roleIds: [roleId1, roleId2] + }, + { + groupId: groupId2, + roleIds: [roleId1, roleId3] + }, + { + groupId: groupId3, + roleIds: [roleId2, roleId3] + }, + ]; + + const roleIds = [roleId1, roleId2, roleId3]; + + const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --groups ${JSON.stringify(groupsInfo)} --group-id ${groupsInfo[0].groupId} --group-id ${groupsInfo[1].groupId} --group-id ${groupsInfo[2].groupId} --role-ids ${roleIds.join(',')}`); + expect(createError).to.not.be.undefined; + expect(createError!.message).to.match(new RegExp(`--group-id=${groupsInfo[0].groupId},${groupsInfo[1].groupId},${groupsInfo[2].groupId} cannot also be provided when using --groups`)); + }); + + it('Should return an error when none of the following flags are provided: `--groups`, `--group-id`, `--role-ids`', async () => { + const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId}`); + expect(createError).to.not.be.undefined; + expect(createError!.message).to.match(/Exactly one of the following must be provided: --group-id, --groups/); + }); + + it('should return an error when only `--group-id` flag is provided', async () => { + const groupsInfo = [ + { + groupId: groupId1, + }, + { + groupId: groupId2, + }, + { + groupId: groupId3, + }, + ]; + + const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --group-id ${groupsInfo[0].groupId} --group-id ${groupsInfo[1].groupId} --group-id ${groupsInfo[2].groupId}`); + expect(createError).to.not.be.undefined; + expect(createError!.message).to.match(/All of the following must be provided when using --group-id: --role-ids/); + }); + + it('should return an error when only `--role-ids` flag is provided', async () => { + const roleIds = [roleId1, roleId2, roleId3]; + + const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --role-ids ${roleIds.join(',')}`); + expect(createError).to.not.be.undefined; + expect(createError?.message).to.match(/All of the following must be provided when using --role-ids: --group-id/); + }); + + it('should return an error when there are invalid UUIDs provided to `--role-ids` flag', async () => { + const groupsInfo = [ + { + groupId: groupId1, + roleIds: [roleId1, roleId2] + } + ]; + + const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --group-id ${groupsInfo[0].groupId} --role-ids ${groupsInfo[0].roleIds.join(',')},some-invalid-uuid`); - expect(createError).to.not.be.undefined; - expect(createError!.message).to.match(new RegExp(`There are invalid UUIDs in '${groupsInfo[0].roleIds.join(',')},some-invalid-uuid'`)) - }); - - it('should return an error when invalid JSON is provided to `--groups` flag', async () => { - const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --groups not-a-serialized-json-string`); - expect(createError).to.not.be.undefined; - expect(createError?.message).to.match(/'not-a-serialized-json-string' is not valid serialized JSON./) - }); - - it('should return an error when JSON provided to `--groups` flag is of invalid schema', async () => { - const groupsInfo = [ - { - roleIds: ["not-a-uuid", roleId2] - }, - { - groupId: "not-a-uuid", - roleIds: [123, {}] - }, - { - groupId: true, - roleIds: [roleId2, roleId3] - }, - ]; + expect(createError).to.not.be.undefined; + expect(createError!.message).to.match(new RegExp(`There are invalid UUIDs in '${groupsInfo[0].roleIds.join(',')},some-invalid-uuid'`)); + }); + + it('should return an error when invalid JSON is provided to `--groups` flag', async () => { + const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --groups not-a-serialized-json-string`); + expect(createError).to.not.be.undefined; + expect(createError?.message).to.match(/'not-a-serialized-json-string' is not valid serialized JSON./); + }); + + it('should return an error when JSON provided to `--groups` flag is of invalid schema', async () => { + const groupsInfo = [ + { + roleIds: ["not-a-uuid", roleId2] + }, + { + groupId: "not-a-uuid", + roleIds: [123, {}] + }, + { + groupId: true, + roleIds: [roleId2, roleId3] + }, + ]; - const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --groups ${JSON.stringify(groupsInfo)}`); + const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --groups ${JSON.stringify(groupsInfo)}`); - expect(createError).to.not.be.undefined; - expect(createError!.message).to.match(/missing required property '\[0].groupId' of type 'string'/); - expect(createError!.message).to.match(/\[0].roleIds\[0] is not a valid uuid/); - expect(createError!.message).to.match(/\[1].groupId is not a valid uuid/); - expect(createError!.message).to.match(/\[1].roleIds\[0]: expected type 'string', received 'number'/); - expect(createError!.message).to.match(/\[1].roleIds\[1]: expected type 'string', received 'object'/); - expect(createError!.message).to.match(/\[2].groupId: expected type 'string', received 'boolean'/); - }); - - it('Should return an error when there are too many role assignments', async () => { - const groups: { groupId: string, roleIds: string[] }[] = []; - for (let i = 0; i < 11; i++) { - groups.push({ - groupId: crypto.randomUUID(), - roleIds: [ - crypto.randomUUID(), - crypto.randomUUID(), - crypto.randomUUID(), - crypto.randomUUID(), - crypto.randomUUID(), - ] - }) - } - - const serializedGroupsInfo = JSON.stringify(groups); - - const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --groups ${serializedGroupsInfo}`); - expect(createError).to.not.be.undefined; - expect(createError!.message).to.be.equal('A maximum of 50 role assignments can be performed.'); - }); - - it('Should return an error when there are too many roles assigned', async () => { - let command = `access-control member group update --itwin-id ${iTwinId} --group-id ${groupId1}`; - - for (let i = 0; i < 51; i++) - command += ` --role-id role${i}` - - const { error: createError } = await runCommand(command); - expect(createError).to.not.be.undefined; - expect(createError?.message).to.be.equal('A maximum of 50 roles can be assigned.'); - }); + expect(createError).to.not.be.undefined; + expect(createError!.message).to.match(/missing required property '\[0].groupId' of type 'string'/); + expect(createError!.message).to.match(/\[0].roleIds\[0] is not a valid uuid/); + expect(createError!.message).to.match(/\[1].groupId is not a valid uuid/); + expect(createError!.message).to.match(/\[1].roleIds\[0]: expected type 'string', received 'number'/); + expect(createError!.message).to.match(/\[1].roleIds\[1]: expected type 'string', received 'object'/); + expect(createError!.message).to.match(/\[2].groupId: expected type 'string', received 'boolean'/); + }); + + it('Should return an error when there are too many role assignments', async () => { + const groups: { groupId: string, roleIds: string[] }[] = []; + for (let i = 0; i < 11; i++) { + groups.push({ + groupId: crypto.randomUUID(), + roleIds: [ + crypto.randomUUID(), + crypto.randomUUID(), + crypto.randomUUID(), + crypto.randomUUID(), + crypto.randomUUID(), + ] + }); + } + + const serializedGroupsInfo = JSON.stringify(groups); + + const { error: createError } = await runCommand(`access-control member group add --itwin-id ${iTwinId} --groups ${serializedGroupsInfo}`); + expect(createError).to.not.be.undefined; + expect(createError!.message).to.be.equal('A maximum of 50 role assignments can be performed.'); + }); + + it('Should return an error when there are too many roles assigned', async () => { + let command = `access-control member group update --itwin-id ${iTwinId} --group-id ${groupId1}`; + + for (let i = 0; i < 51; i++) + command += ` --role-id role${i}`; + + const { error: createError } = await runCommand(command); + expect(createError).to.not.be.undefined; + expect(createError?.message).to.be.equal('A maximum of 50 roles can be assigned.'); + }); }; export default tests; diff --git a/integration-tests/access-control/member/invitations.test.ts b/integration-tests/access-control/member/invitations.test.ts index 02499788..8f9bc754 100644 --- a/integration-tests/access-control/member/invitations.test.ts +++ b/integration-tests/access-control/member/invitations.test.ts @@ -13,33 +13,33 @@ import { ITP_TEST_USER_EXTERNAL } from "../../utils/environment"; import runSuiteIfMainModule from "../../utils/run-suite-if-main-module"; const tests = () => { - let iTwinId: string; + let iTwinId: string; - before(async () => { - const iTwinName = `cli-itwin-integration-test-${new Date().toISOString()}`; - const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); - expect(iTwin?.id).to.not.be.undefined; - iTwinId = iTwin!.id!; - }); - - after(async () => { - const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); - expect(deleteResult).to.have.property('result', 'deleted'); - }); - - it('Should get pending invitations', async () => { - const emailToAdd = ITP_TEST_USER_EXTERNAL; - const { result: owner } = await runCommand(`access-control member owner add --itwin-id ${iTwinId} --email ${emailToAdd}`); - expect(owner).to.not.be.undefined; - expect(owner!.member).is.null; - expect(owner!.invitation).to.not.be.undefined; - expect(owner!.invitation.email.toLowerCase()).to.equal(emailToAdd!.toLowerCase()); - - const { result: invitationResults } = await runCommand(`access-control member invitations --itwin-id ${iTwinId}`); - expect(invitationResults).to.not.be.undefined; - expect(invitationResults!.length).to.be.greaterThanOrEqual(1); - expect(invitationResults!.some(invitation => invitation.email.toLowerCase() === emailToAdd!.toLowerCase())).to.be.true; - }); + before(async () => { + const iTwinName = `cli-itwin-integration-test-${new Date().toISOString()}`; + const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); + expect(iTwin?.id).to.not.be.undefined; + iTwinId = iTwin!.id!; + }); + + after(async () => { + const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); + expect(deleteResult).to.have.property('result', 'deleted'); + }); + + it('Should get pending invitations', async () => { + const emailToAdd = ITP_TEST_USER_EXTERNAL; + const { result: owner } = await runCommand(`access-control member owner add --itwin-id ${iTwinId} --email ${emailToAdd}`); + expect(owner).to.not.be.undefined; + expect(owner!.member).is.null; + expect(owner!.invitation).to.not.be.undefined; + expect(owner!.invitation.email.toLowerCase()).to.equal(emailToAdd!.toLowerCase()); + + const { result: invitationResults } = await runCommand(`access-control member invitations --itwin-id ${iTwinId}`); + expect(invitationResults).to.not.be.undefined; + expect(invitationResults!.length).to.be.greaterThanOrEqual(1); + expect(invitationResults!.some(invitation => invitation.email.toLowerCase() === emailToAdd!.toLowerCase())).to.be.true; + }); }; export default tests; diff --git a/integration-tests/access-control/member/member.test.ts b/integration-tests/access-control/member/member.test.ts index a6939d3b..2e38eb37 100644 --- a/integration-tests/access-control/member/member.test.ts +++ b/integration-tests/access-control/member/member.test.ts @@ -11,21 +11,21 @@ import userMemberTests from './user.test'; const tests = () => { - describe('group', () => { - groupMemberTests(); - }); + describe('group', () => { + groupMemberTests(); + }); - describe('user', () => { - userMemberTests(); - }); + describe('user', () => { + userMemberTests(); + }); - describe('invitations', () => { - invitationsMemberTests(); - }); + describe('invitations', () => { + invitationsMemberTests(); + }); - describe('owner', () => { - ownerMemberTests(); - }); + describe('owner', () => { + ownerMemberTests(); + }); }; export default tests; diff --git a/integration-tests/access-control/member/owner.test.ts b/integration-tests/access-control/member/owner.test.ts index fe03da78..159f074b 100644 --- a/integration-tests/access-control/member/owner.test.ts +++ b/integration-tests/access-control/member/owner.test.ts @@ -15,60 +15,58 @@ import { fetchEmailsAndGetInvitationLink } from "../../utils/helpers"; import runSuiteIfMainModule from "../../utils/run-suite-if-main-module"; const tests = () => { - let iTwinId: string; - const iTwinName: string = `cli-itwin-integration-test-${new Date().toISOString()}`; + let iTwinId: string; + const iTwinName: string = `cli-itwin-integration-test-${new Date().toISOString()}`; - before(async () => { - const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); - expect(iTwin?.id).to.not.be.undefined; - iTwinId = iTwin!.id!; - }); + before(async () => { + const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); + expect(iTwin?.id).to.not.be.undefined; + iTwinId = iTwin!.id!; + }); - after(async () => { - const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); - expect(deleteResult).to.have.property('result', 'deleted'); - }); + after(async () => { + const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); + expect(deleteResult).to.have.property('result', 'deleted'); + }); - it('Should invite an external member to an iTwin, accept invitation and remove owner member', async () => { - const emailToAdd = ITP_TEST_USER_EXTERNAL; - const { result: invitedOwner } = await runCommand(`access-control member owner add -i ${iTwinId} --email ${emailToAdd}`); - expect(invitedOwner).to.not.be.undefined; - expect(invitedOwner!.member).to.be.null; - expect(invitedOwner!.invitation).to.not.be.undefined; - expect(invitedOwner!.invitation.email.toLowerCase()).to.equal(emailToAdd!.toLowerCase()); + it('Should invite an external member to an iTwin, accept invitation and remove owner member', async () => { + const emailToAdd = ITP_TEST_USER_EXTERNAL; + const { result: invitedOwner } = await runCommand(`access-control member owner add -i ${iTwinId} --email ${emailToAdd}`); + expect(invitedOwner).to.not.be.undefined; + expect(invitedOwner!.member).to.be.null; + expect(invitedOwner!.invitation).to.not.be.undefined; + expect(invitedOwner!.invitation.email.toLowerCase()).to.equal(emailToAdd!.toLowerCase()); - const invitationLink = await fetchEmailsAndGetInvitationLink(emailToAdd!.split('@')[0], iTwinName); + const invitationLink = await fetchEmailsAndGetInvitationLink(emailToAdd!.split('@')[0], iTwinName); - await fetch(invitationLink); + await fetch(invitationLink); - let usersInfo: GroupMember[]; - do { - // eslint-disable-next-line no-await-in-loop - await new Promise(resolve => {setTimeout(_ => resolve(), 10 * 1000);}); - // eslint-disable-next-line no-await-in-loop - const { result: listResult } = await runCommand(`access-control member owner list --itwin-id ${iTwinId}`); - expect(listResult).to.not.be.undefined; - usersInfo = listResult!; - } while (usersInfo.length !== 2); + let usersInfo: GroupMember[]; + do { + await new Promise(resolve => {setTimeout(_ => resolve(), 10 * 1000);}); + const { result: listResult } = await runCommand(`access-control member owner list --itwin-id ${iTwinId}`); + expect(listResult).to.not.be.undefined; + usersInfo = listResult!; + } while (usersInfo.length !== 2); - const joinedUser = usersInfo.find(user => user.email.toLowerCase() === emailToAdd!.toLowerCase()); - expect(joinedUser).to.not.be.undefined; + const joinedUser = usersInfo.find(user => user.email.toLowerCase() === emailToAdd!.toLowerCase()); + expect(joinedUser).to.not.be.undefined; - const { result: deletionResult } = await runCommand<{result: string}>(`access-control member owner delete --itwin-id ${iTwinId} --member-id ${joinedUser?.id}`); - expect(deletionResult).to.not.be.undefined; - expect(deletionResult).to.have.property('result', "deleted"); - }).timeout(180 * 1000); + const { result: deletionResult } = await runCommand<{result: string}>(`access-control member owner delete --itwin-id ${iTwinId} --member-id ${joinedUser?.id}`); + expect(deletionResult).to.not.be.undefined; + expect(deletionResult).to.have.property('result', "deleted"); + }).timeout(180 * 1000); - it('Should list owners of an iTwin', async () => { - const { result: owners } = await runCommand(`access-control member owner list --itwin-id ${iTwinId}`); - expect(owners).to.not.be.undefined; - expect(owners!.length).to.be.greaterThanOrEqual(1); + it('Should list owners of an iTwin', async () => { + const { result: owners } = await runCommand(`access-control member owner list --itwin-id ${iTwinId}`); + expect(owners).to.not.be.undefined; + expect(owners!.length).to.be.greaterThanOrEqual(1); - const { result: userInfo } = await runCommand(`user me`); - expect(userInfo).to.not.be.undefined; - expect(userInfo!.id).to.not.be.undefined; - expect(owners!.some(owner => owner.id === userInfo!.id)).to.be.true; - }); + const { result: userInfo } = await runCommand(`user me`); + expect(userInfo).to.not.be.undefined; + expect(userInfo!.id).to.not.be.undefined; + expect(owners!.some(owner => owner.id === userInfo!.id)).to.be.true; + }); }; export default tests; diff --git a/integration-tests/access-control/member/user.test.ts b/integration-tests/access-control/member/user.test.ts index b12b39f5..2568f33f 100644 --- a/integration-tests/access-control/member/user.test.ts +++ b/integration-tests/access-control/member/user.test.ts @@ -15,295 +15,294 @@ import { fetchEmailsAndGetInvitationLink } from "../../utils/helpers"; import runSuiteIfMainModule from "../../utils/run-suite-if-main-module"; const tests = () => { - let iTwinId: string; - let roleId1: string; - let roleId2: string; - let roleId3: string; - const iTwinName: string = `cli-itwin-integration-test-${new Date().toISOString()}`; + let iTwinId: string; + let roleId1: string; + let roleId2: string; + let roleId3: string; + const iTwinName: string = `cli-itwin-integration-test-${new Date().toISOString()}`; - before(async () => { - const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); - expect(iTwin?.id).to.not.be.undefined; - iTwinId = iTwin!.id!; - - const { result: role1 } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role #1" -d "Test Role Description"`); - expect(role1?.id).to.not.be.undefined; - roleId1 = role1!.id!; - - const { result: role2 } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role #2" -d "Test Role Description"`); - expect(role2?.id).to.not.be.undefined; - roleId2 = role2!.id!; - - const { result: role3 } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role #3" -d "Test Role Description"`); - expect(role3?.id).to.not.be.undefined; - roleId3 = role3!.id!; - }); - - after(async () => { - const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); - expect(deleteResult).to.have.property('result', 'deleted'); - }); - - it('Should invite an external member to an iTwin, accept sent invitation and remove user member', async () => { - const { result: newRole } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role 1" -d "Test Role Description"`); - expect(newRole).to.not.be.undefined; - expect(newRole!.id).to.not.be.undefined; + before(async () => { + const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); + expect(iTwin?.id).to.not.be.undefined; + iTwinId = iTwin!.id!; + + const { result: role1 } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role #1" -d "Test Role Description"`); + expect(role1?.id).to.not.be.undefined; + roleId1 = role1!.id!; + + const { result: role2 } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role #2" -d "Test Role Description"`); + expect(role2?.id).to.not.be.undefined; + roleId2 = role2!.id!; + + const { result: role3 } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role #3" -d "Test Role Description"`); + expect(role3?.id).to.not.be.undefined; + roleId3 = role3!.id!; + }); + + after(async () => { + const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); + expect(deleteResult).to.have.property('result', 'deleted'); + }); + + it('Should invite an external member to an iTwin, accept sent invitation and remove user member', async () => { + const { result: newRole } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role 1" -d "Test Role Description"`); + expect(newRole).to.not.be.undefined; + expect(newRole!.id).to.not.be.undefined; - const emailToAdd = ITP_TEST_USER_EXTERNAL; - - const { result: invitedUser } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --members "[{"email": "${emailToAdd}", "roleIds": ["${newRole!.id}"]}]"`); - - expect(invitedUser).to.not.be.undefined; - expect(invitedUser!.invitations).to.have.lengthOf(1); - expect(invitedUser!.invitations[0].email.toLowerCase()).to.be.equal(emailToAdd!.toLowerCase()); - expect(invitedUser!.invitations[0].roles).to.have.lengthOf(1); - expect(invitedUser!.invitations[0].roles[0].id).to.be.equal(newRole!.id); - - const invitationLink = await fetchEmailsAndGetInvitationLink(emailToAdd!.split('@')[0], iTwinName); - - await fetch(invitationLink); - - let usersInfo: Member[]; - do { - // eslint-disable-next-line no-await-in-loop - await new Promise(resolve => {setTimeout(_ => resolve(), 10 * 1000);}); - // eslint-disable-next-line no-await-in-loop - const listResult = await runCommand(`access-control member user list --itwin-id ${iTwinId}`); - expect(listResult.result).to.not.be.undefined; - usersInfo = listResult.result! - } while (usersInfo.length !== 2); - - await new Promise(resolve => {setTimeout(_ => resolve(), 30 * 1000);}); - - const joinedUser = usersInfo.find(user => user.email.toLowerCase() === emailToAdd!.toLowerCase()); - expect(joinedUser).to.not.be.undefined; - expect(joinedUser?.roles).to.have.lengthOf(1); - expect(joinedUser?.roles[0].id).to.be.equal(newRole!.id); - - const { result: deleteResult } = await runCommand<{result: string}>(`access-control member user delete --itwin-id ${iTwinId} --member-id ${joinedUser?.id}`); - expect(deleteResult).to.not.be.undefined; - expect(deleteResult).to.have.property('result', "deleted"); - }).timeout(180 * 1000); - - it('Should display owner info of an iTwin in member info', async () => { - const { result: userInfo } = await runCommand(`user me`); - expect(userInfo).to.not.be.undefined; - - const { result: getMemberUserInfo } = await runCommand(`access-control member user info --itwin-id ${iTwinId} --member-id ${userInfo!.id}`); - expect(getMemberUserInfo).to.not.be.undefined; - expect(getMemberUserInfo!.id).to.not.be.undefined; - expect(getMemberUserInfo!.id).to.be.equal(userInfo!.id); - }); - - it('Should add a new role to a user.', async () => { - const { result: newRole } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role 2" -d "Test Role Description"`); - expect(newRole).to.not.be.undefined; - expect(newRole!.id).to.not.be.undefined; - - const { result: usersInfo } = await runCommand(`access-control member user list --itwin-id ${iTwinId}`); - expect(usersInfo).to.not.be.undefined; - expect(usersInfo).to.have.lengthOf(1); - expect(usersInfo![0].roles).to.have.lengthOf(1); - - const { result: updateMemberResult } = await runCommand(`access-control member user update --itwin-id ${iTwinId} --member-id ${usersInfo![0].id} --role-id ${usersInfo![0].roles[0].id} --role-id ${newRole!.id}`); - expect(updateMemberResult).to.not.be.undefined; - expect(updateMemberResult!.roles).to.have.lengthOf(2); - expect(updateMemberResult!.roles.some(role => role.id === newRole!.id)).to.be.true; - expect(updateMemberResult!.roles.some(role => role.id === usersInfo![0].roles[0].id)).to.be.true; - }); - - it('Should add multiple users to iTwin using `--group-id` and `--role-ids` flags and delete them', async () => { - const usersInfo = [ - { - email: `test-${crypto.randomUUID()}@example.com`, - roleIds: [roleId1, roleId2] - }, - { - email: `test-${crypto.randomUUID()}@example.com`, - roleIds: [roleId1, roleId3] - }, - { - email: `test-${crypto.randomUUID()}@example.com`, - roleIds: [roleId2, roleId3] - }, - ]; - - const { result: createResult } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --email ${usersInfo[0].email} --email ${usersInfo[1].email} --email ${usersInfo[2].email} + const emailToAdd = ITP_TEST_USER_EXTERNAL; + + const { result: invitedUser } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --members "[{"email": "${emailToAdd}", "roleIds": ["${newRole!.id}"]}]"`); + + expect(invitedUser).to.not.be.undefined; + expect(invitedUser!.invitations).to.have.lengthOf(1); + expect(invitedUser!.invitations[0].email.toLowerCase()).to.be.equal(emailToAdd!.toLowerCase()); + expect(invitedUser!.invitations[0].roles).to.have.lengthOf(1); + expect(invitedUser!.invitations[0].roles[0].id).to.be.equal(newRole!.id); + + const invitationLink = await fetchEmailsAndGetInvitationLink(emailToAdd!.split('@')[0], iTwinName); + + await fetch(invitationLink); + + let usersInfo: Member[]; + do { + await new Promise(resolve => {setTimeout(_ => resolve(), 10 * 1000);}); + + const listResult = await runCommand(`access-control member user list --itwin-id ${iTwinId}`); + expect(listResult.result).to.not.be.undefined; + usersInfo = listResult.result!; + } while (usersInfo.length !== 2); + + await new Promise(resolve => {setTimeout(_ => resolve(), 30 * 1000);}); + + const joinedUser = usersInfo.find(user => user.email.toLowerCase() === emailToAdd!.toLowerCase()); + expect(joinedUser).to.not.be.undefined; + expect(joinedUser?.roles).to.have.lengthOf(1); + expect(joinedUser?.roles[0].id).to.be.equal(newRole!.id); + + const { result: deleteResult } = await runCommand<{result: string}>(`access-control member user delete --itwin-id ${iTwinId} --member-id ${joinedUser?.id}`); + expect(deleteResult).to.not.be.undefined; + expect(deleteResult).to.have.property('result', "deleted"); + }).timeout(180 * 1000); + + it('Should display owner info of an iTwin in member info', async () => { + const { result: userInfo } = await runCommand(`user me`); + expect(userInfo).to.not.be.undefined; + + const { result: getMemberUserInfo } = await runCommand(`access-control member user info --itwin-id ${iTwinId} --member-id ${userInfo!.id}`); + expect(getMemberUserInfo).to.not.be.undefined; + expect(getMemberUserInfo!.id).to.not.be.undefined; + expect(getMemberUserInfo!.id).to.be.equal(userInfo!.id); + }); + + it('Should add a new role to a user.', async () => { + const { result: newRole } = await runCommand(`access-control role create -i ${iTwinId} -n "Test Role 2" -d "Test Role Description"`); + expect(newRole).to.not.be.undefined; + expect(newRole!.id).to.not.be.undefined; + + const { result: usersInfo } = await runCommand(`access-control member user list --itwin-id ${iTwinId}`); + expect(usersInfo).to.not.be.undefined; + expect(usersInfo).to.have.lengthOf(1); + expect(usersInfo![0].roles).to.have.lengthOf(1); + + const { result: updateMemberResult } = await runCommand(`access-control member user update --itwin-id ${iTwinId} --member-id ${usersInfo![0].id} --role-id ${usersInfo![0].roles[0].id} --role-id ${newRole!.id}`); + expect(updateMemberResult).to.not.be.undefined; + expect(updateMemberResult!.roles).to.have.lengthOf(2); + expect(updateMemberResult!.roles.some(role => role.id === newRole!.id)).to.be.true; + expect(updateMemberResult!.roles.some(role => role.id === usersInfo![0].roles[0].id)).to.be.true; + }); + + it('Should add multiple users to iTwin using `--group-id` and `--role-ids` flags and delete them', async () => { + const usersInfo = [ + { + email: `test-${crypto.randomUUID()}@example.com`, + roleIds: [roleId1, roleId2] + }, + { + email: `test-${crypto.randomUUID()}@example.com`, + roleIds: [roleId1, roleId3] + }, + { + email: `test-${crypto.randomUUID()}@example.com`, + roleIds: [roleId2, roleId3] + }, + ]; + + const { result: createResult } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --email ${usersInfo[0].email} --email ${usersInfo[1].email} --email ${usersInfo[2].email} --role-ids ${usersInfo[0].roleIds.join(',')} --role-ids ${usersInfo[1].roleIds.join(',')} --role-ids ${usersInfo[2].roleIds.join(',')}`); - expect(createResult).to.not.be.undefined; - expect(createResult!.invitations).to.have.lengthOf(3); - for (const [i, userInfo] of usersInfo.entries()) { - expect(createResult!.invitations[i].email).to.be.equal(userInfo.email); - expect(createResult!.invitations[i].roles.map(role => role.id)).to.be.deep.equal(userInfo.roleIds); - } - }); - - it('Should add multiple users to iTwin using `--group-id` and `--role-ids` (single list) flags and delete them', async () => { - const roleIds = [roleId1, roleId2]; - const usersInfo = [ - { - email: `test-${crypto.randomUUID()}@example.com`, - }, - { - email: `test-${crypto.randomUUID()}@example.com`, - }, - { - email: `test-${crypto.randomUUID()}@example.com`, - }, - ]; - - const { result: createResult } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --email ${usersInfo[0].email} --email ${usersInfo[1].email} --email ${usersInfo[2].email} --role-ids ${roleIds.join(',')}`); - expect(createResult).to.not.be.undefined; - expect(createResult!.invitations).to.have.lengthOf(3); - for (const [i, userInfo] of usersInfo.entries()) { - expect(createResult!.invitations[i].email).to.be.equal(userInfo.email); - expect(createResult!.invitations[i].roles.map(role => role.id)).to.be.deep.equal(roleIds); - } - }); - - it('Should return an error when all of the following flags are provided: `--members`, `--email`, `--role-ids`', async () => { - const usersInfo = [ - { - email: "test1@example.com", - roleIds: [roleId1, roleId2] - }, - { - email: "test2@example.com", - roleIds: [roleId1, roleId3] - }, - { - email: "test3@example.com", - roleIds: [roleId2, roleId3] - }, - ]; - - const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --members ${JSON.stringify(usersInfo)} --email ${usersInfo[0].email} --email ${usersInfo[1].email} --email ${usersInfo[2].email} + expect(createResult).to.not.be.undefined; + expect(createResult!.invitations).to.have.lengthOf(3); + for (const [i, userInfo] of usersInfo.entries()) { + expect(createResult!.invitations[i].email).to.be.equal(userInfo.email); + expect(createResult!.invitations[i].roles.map(role => role.id)).to.be.deep.equal(userInfo.roleIds); + } + }); + + it('Should add multiple users to iTwin using `--group-id` and `--role-ids` (single list) flags and delete them', async () => { + const roleIds = [roleId1, roleId2]; + const usersInfo = [ + { + email: `test-${crypto.randomUUID()}@example.com`, + }, + { + email: `test-${crypto.randomUUID()}@example.com`, + }, + { + email: `test-${crypto.randomUUID()}@example.com`, + }, + ]; + + const { result: createResult } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --email ${usersInfo[0].email} --email ${usersInfo[1].email} --email ${usersInfo[2].email} --role-ids ${roleIds.join(',')}`); + expect(createResult).to.not.be.undefined; + expect(createResult!.invitations).to.have.lengthOf(3); + for (const [i, userInfo] of usersInfo.entries()) { + expect(createResult!.invitations[i].email).to.be.equal(userInfo.email); + expect(createResult!.invitations[i].roles.map(role => role.id)).to.be.deep.equal(roleIds); + } + }); + + it('Should return an error when all of the following flags are provided: `--members`, `--email`, `--role-ids`', async () => { + const usersInfo = [ + { + email: "test1@example.com", + roleIds: [roleId1, roleId2] + }, + { + email: "test2@example.com", + roleIds: [roleId1, roleId3] + }, + { + email: "test3@example.com", + roleIds: [roleId2, roleId3] + }, + ]; + + const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --members ${JSON.stringify(usersInfo)} --email ${usersInfo[0].email} --email ${usersInfo[1].email} --email ${usersInfo[2].email} --role-ids ${usersInfo[0].roleIds.join(',')} --role-ids ${usersInfo[1].roleIds.join(',')} --role-ids ${usersInfo[2].roleIds.join(',')}`); - expect(createError).to.not.be.undefined; - expect(createError?.message).to.match(new RegExp(`--email=${usersInfo[0].email},${usersInfo[1].email},${usersInfo[2].email} cannot also be provided when using --members`)) - }); - - it('Should return an error when none of the following flags are provided: `--members`, `--member`, `--role-ids`', async () => { - const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId}`); - expect(createError).to.not.be.undefined; - expect(createError?.message).to.match(/Exactly one of the following must be provided: --email, --members/); - }); - - it('should return an error when only `--email` flag is provided', async () => { - const usersInfo = [ - { - email: "test1@example.com", - }, - { - email: "test2@example.com", - }, - { - email: "test3@example.com", - }, - ]; - - const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --email ${usersInfo[0].email} --email ${usersInfo[1].email} --email ${usersInfo[2].email}`); - expect(createError).to.not.be.undefined; - expect(createError?.message).to.match(/All of the following must be provided when using --email: --role-ids/) - }) - - it('should return an error when only `--role-ids` flag is provided', async () => { - const usersInfo = [ - { - roleIds: [roleId1, roleId2] - }, - { - roleIds: [roleId1, roleId3] - }, - { - roleIds: [roleId2, roleId3] - }, - ]; - - const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --role-ids ${usersInfo[0].roleIds.join(',')} --role-ids ${usersInfo[1].roleIds.join(',')} --role-ids ${usersInfo[2].roleIds.join(',')}`); - expect(createError).to.not.be.undefined; - expect(createError?.message).to.match(/All of the following must be provided when using --role-ids: --email/) - }); - - it('should return an error when there are invalid UUIDs provided to `--role-ids` flag', async () => { - const usersInfo = [ - { - email: 'test1@example.com', - roleIds: [roleId1, roleId2] - } - ]; - - const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --email ${usersInfo[0].email} + expect(createError).to.not.be.undefined; + expect(createError?.message).to.match(new RegExp(`--email=${usersInfo[0].email},${usersInfo[1].email},${usersInfo[2].email} cannot also be provided when using --members`)); + }); + + it('Should return an error when none of the following flags are provided: `--members`, `--member`, `--role-ids`', async () => { + const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId}`); + expect(createError).to.not.be.undefined; + expect(createError?.message).to.match(/Exactly one of the following must be provided: --email, --members/); + }); + + it('should return an error when only `--email` flag is provided', async () => { + const usersInfo = [ + { + email: "test1@example.com", + }, + { + email: "test2@example.com", + }, + { + email: "test3@example.com", + }, + ]; + + const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --email ${usersInfo[0].email} --email ${usersInfo[1].email} --email ${usersInfo[2].email}`); + expect(createError).to.not.be.undefined; + expect(createError?.message).to.match(/All of the following must be provided when using --email: --role-ids/); + }); + + it('should return an error when only `--role-ids` flag is provided', async () => { + const usersInfo = [ + { + roleIds: [roleId1, roleId2] + }, + { + roleIds: [roleId1, roleId3] + }, + { + roleIds: [roleId2, roleId3] + }, + ]; + + const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --role-ids ${usersInfo[0].roleIds.join(',')} --role-ids ${usersInfo[1].roleIds.join(',')} --role-ids ${usersInfo[2].roleIds.join(',')}`); + expect(createError).to.not.be.undefined; + expect(createError?.message).to.match(/All of the following must be provided when using --role-ids: --email/); + }); + + it('should return an error when there are invalid UUIDs provided to `--role-ids` flag', async () => { + const usersInfo = [ + { + email: 'test1@example.com', + roleIds: [roleId1, roleId2] + } + ]; + + const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --email ${usersInfo[0].email} --role-ids ${usersInfo[0].roleIds.join(',')},some-invalid-uuid`); - expect(createError).to.not.be.undefined; - expect(createError?.message).to.match(new RegExp(`There are invalid UUIDs in '${usersInfo[0].roleIds.join(',')},some-invalid-uuid'`)) - }); - - it('should return an error when invalid JSON is provided to `--members` flag', async () => { - const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --members not-valid-serialized-json`); - expect(createError).to.not.be.undefined; - expect(createError!.message).to.match(/'not-valid-serialized-json' is not valid serialized JSON./) - }); - - it('should return an error when JSON of invalid schema is provided to `--members` flag', async () => { - const usersInfo = [ - { - email: "not-an-email", - roleIds: [roleId1, roleId2] - }, - { - email: true, - roleIds: [roleId1, 123] - }, - { - email: "test3@example.com", - roleIds: ["not-a-uuid", roleId3] - }, - ]; + expect(createError).to.not.be.undefined; + expect(createError?.message).to.match(new RegExp(`There are invalid UUIDs in '${usersInfo[0].roleIds.join(',')},some-invalid-uuid'`)); + }); + + it('should return an error when invalid JSON is provided to `--members` flag', async () => { + const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --members not-valid-serialized-json`); + expect(createError).to.not.be.undefined; + expect(createError!.message).to.match(/'not-valid-serialized-json' is not valid serialized JSON./); + }); + + it('should return an error when JSON of invalid schema is provided to `--members` flag', async () => { + const usersInfo = [ + { + email: "not-an-email", + roleIds: [roleId1, roleId2] + }, + { + email: true, + roleIds: [roleId1, 123] + }, + { + email: "test3@example.com", + roleIds: ["not-a-uuid", roleId3] + }, + ]; - const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --members ${JSON.stringify(usersInfo)}`); - expect(createError).to.not.be.undefined; - expect(createError!.message).to.match(/\[0].email is not a valid email/); - expect(createError!.message).to.match(/\[1].email: expected type 'string', received 'boolean'/); - expect(createError!.message).to.match(/\[1].roleIds\[1]: expected type 'string', received 'number'/); - expect(createError!.message).to.match(/\[2].roleIds\[0] is not a valid uuid/); - }); - - it('Should fail to add iTwin user members, when there are too many role assignments', async () => { - const members: {email: string, roleIds:string[]}[] = []; - for(let i = 0; i < 11; i++) { - members.push({ - email: `email1${i}@example.com`, - roleIds: [ - crypto.randomUUID(), - crypto.randomUUID(), - crypto.randomUUID(), - crypto.randomUUID(), - crypto.randomUUID(), - ] - }) - } + const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --members ${JSON.stringify(usersInfo)}`); + expect(createError).to.not.be.undefined; + expect(createError!.message).to.match(/\[0].email is not a valid email/); + expect(createError!.message).to.match(/\[1].email: expected type 'string', received 'boolean'/); + expect(createError!.message).to.match(/\[1].roleIds\[1]: expected type 'string', received 'number'/); + expect(createError!.message).to.match(/\[2].roleIds\[0] is not a valid uuid/); + }); + + it('Should fail to add iTwin user members, when there are too many role assignments', async () => { + const members: {email: string, roleIds:string[]}[] = []; + for(let i = 0; i < 11; i++) { + members.push({ + email: `email1${i}@example.com`, + roleIds: [ + crypto.randomUUID(), + crypto.randomUUID(), + crypto.randomUUID(), + crypto.randomUUID(), + crypto.randomUUID(), + ] + }); + } - const serializedMembersInfo = JSON.stringify(members); - - const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --members ${serializedMembersInfo}`); - expect(createError).to.not.be.undefined; - expect(createError?.message).to.be.equal('A maximum of 50 role assignments can be performed.'); - }); - - it('Should fail to update iTwin group, when there are too many roles assigned', async () => { - const { result: usersInfo } = await runCommand(`access-control member user list --itwin-id ${iTwinId}`); - expect(usersInfo).to.not.be.undefined; - expect(usersInfo!).to.have.lengthOf(1); - - let command = `access-control member user update --itwin-id ${iTwinId} --member-id ${usersInfo![0].id}`; - for(let i = 0; i < 51; i++) - command += ` --role-id role${i}` - - const result = await runCommand(command); - expect(result.error).to.not.be.undefined; - expect(result.error?.message).to.be.equal('A maximum of 50 roles can be assigned.'); - }); + const serializedMembersInfo = JSON.stringify(members); + + const { error: createError } = await runCommand(`access-control member user add --itwin-id ${iTwinId} --members ${serializedMembersInfo}`); + expect(createError).to.not.be.undefined; + expect(createError?.message).to.be.equal('A maximum of 50 role assignments can be performed.'); + }); + + it('Should fail to update iTwin group, when there are too many roles assigned', async () => { + const { result: usersInfo } = await runCommand(`access-control member user list --itwin-id ${iTwinId}`); + expect(usersInfo).to.not.be.undefined; + expect(usersInfo!).to.have.lengthOf(1); + + let command = `access-control member user update --itwin-id ${iTwinId} --member-id ${usersInfo![0].id}`; + for(let i = 0; i < 51; i++) + command += ` --role-id role${i}`; + + const result = await runCommand(command); + expect(result.error).to.not.be.undefined; + expect(result.error?.message).to.be.equal('A maximum of 50 roles can be assigned.'); + }); }; export default tests; diff --git a/integration-tests/access-control/permissions.test.ts b/integration-tests/access-control/permissions.test.ts index 0d0f62b9..fc9d5124 100644 --- a/integration-tests/access-control/permissions.test.ts +++ b/integration-tests/access-control/permissions.test.ts @@ -10,31 +10,31 @@ import { expect } from "chai"; import runSuiteIfMainModule from "../utils/run-suite-if-main-module"; const tests = () => { - let iTwinId: string; - - before(async () => { - const iTwinName = `cli-itwin-integration-test-${new Date().toISOString()}`; - const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); - expect(iTwin?.id).to.not.be.undefined; - iTwinId = iTwin!.id!; - }); - - after(async () => { - const { result: deleteResult} = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); - expect(deleteResult).to.have.property('result', 'deleted'); - }); - - it('Should retrieve my permissions', async () => { - const { result: myPermissions } = await runCommand(`access-control permissions me --itwin-id ${iTwinId}`); - expect(myPermissions).to.not.be.undefined; - expect(myPermissions!.length).to.be.greaterThan(0); - }); - - it('Should list all permissions', async () => { - const { result: allPermissions } = await runCommand(`access-control permissions all`); - expect(allPermissions).to.not.be.undefined; - expect(allPermissions!.length).to.be.greaterThan(0); - }); + let iTwinId: string; + + before(async () => { + const iTwinName = `cli-itwin-integration-test-${new Date().toISOString()}`; + const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); + expect(iTwin?.id).to.not.be.undefined; + iTwinId = iTwin!.id!; + }); + + after(async () => { + const { result: deleteResult} = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); + expect(deleteResult).to.have.property('result', 'deleted'); + }); + + it('Should retrieve my permissions', async () => { + const { result: myPermissions } = await runCommand(`access-control permissions me --itwin-id ${iTwinId}`); + expect(myPermissions).to.not.be.undefined; + expect(myPermissions!.length).to.be.greaterThan(0); + }); + + it('Should list all permissions', async () => { + const { result: allPermissions } = await runCommand(`access-control permissions all`); + expect(allPermissions).to.not.be.undefined; + expect(allPermissions!.length).to.be.greaterThan(0); + }); }; export default tests; diff --git a/integration-tests/access-control/role.test.ts b/integration-tests/access-control/role.test.ts index 332baf28..9440265a 100644 --- a/integration-tests/access-control/role.test.ts +++ b/integration-tests/access-control/role.test.ts @@ -11,74 +11,74 @@ import { Role } from "../../src/services/access-control-client/models/role"; import runSuiteIfMainModule from "../utils/run-suite-if-main-module"; const tests = () => { - let iTwinId: string; - - before(async () => { - const iTwinName = `cli-itwin-integration-test-${new Date().toISOString()}`; - const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); - expect(iTwin?.id).to.not.be.undefined; - iTwinId = iTwin!.id!; - }); - - after(async () => { - const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); - expect(deleteResult).to.have.property('result', 'deleted'); - }); - - it('Should create and update role info', async () => { - const roleName = "Test Role"; - const roleDescription = "Test Role Description"; - - const { result: roleCreate } = await runCommand(`access-control role create --itwin-id ${iTwinId} --name "${roleName}" --description "${roleDescription}"`); - - expect(roleCreate).to.not.be.undefined; - expect(roleCreate!.id).to.not.be.undefined; - expect(roleCreate!.displayName).to.be.equal(roleName); - expect(roleCreate!.description).to.be.equal(roleDescription); + let iTwinId: string; + + before(async () => { + const iTwinName = `cli-itwin-integration-test-${new Date().toISOString()}`; + const { result: iTwin } = await runCommand(`itwin create --class Thing --sub-class Asset --name ${iTwinName}`); + expect(iTwin?.id).to.not.be.undefined; + iTwinId = iTwin!.id!; + }); + + after(async () => { + const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwinId}`); + expect(deleteResult).to.have.property('result', 'deleted'); + }); + + it('Should create and update role info', async () => { + const roleName = "Test Role"; + const roleDescription = "Test Role Description"; + + const { result: roleCreate } = await runCommand(`access-control role create --itwin-id ${iTwinId} --name "${roleName}" --description "${roleDescription}"`); + + expect(roleCreate).to.not.be.undefined; + expect(roleCreate!.id).to.not.be.undefined; + expect(roleCreate!.displayName).to.be.equal(roleName); + expect(roleCreate!.description).to.be.equal(roleDescription); - const { result: roleInfo } = await runCommand(`access-control role info --itwin-id ${iTwinId} --role-id ${roleCreate!.id}`); + const { result: roleInfo } = await runCommand(`access-control role info --itwin-id ${iTwinId} --role-id ${roleCreate!.id}`); - expect(roleInfo).to.not.be.undefined; - - expect(roleInfo?.id).to.be.equal(roleCreate!.id); - expect(roleInfo?.displayName).to.be.equal(roleName); - expect(roleInfo?.description).to.be.equal(roleDescription); - - const updatedRoleName = "Updated Role Name"; - const updatedRoleDescription = "Updated Role Description"; - const permissions = ["administration_invite_member"]; - - const { result: roleUpdate } = await runCommand(`access-control role update --itwin-id ${iTwinId} --role-id ${roleCreate!.id} --name "${updatedRoleName}" --description "${updatedRoleDescription}" --permission ${permissions[0]}`); - expect(roleUpdate).to.not.be.undefined; - expect(roleUpdate!.id).to.not.be.undefined; - expect(roleUpdate!.displayName).to.be.equal(updatedRoleName); - expect(roleUpdate!.description).to.be.equal(updatedRoleDescription); - expect(roleUpdate!.permissions).to.not.be.undefined; - expect(roleUpdate!.permissions).to.include.members(permissions); - }); - - it('Should list roles', async () => { - const { result: newRole } = await runCommand(`access-control role create --itwin-id ${iTwinId} --name Test2 --description Description2`); - expect(newRole).to.not.be.undefined; - expect(newRole!.id).to.not.be.undefined; - expect(newRole!.displayName).to.be.equal("Test2"); - expect(newRole!.description).to.be.equal("Description2"); - - const { result: listedRoles } = await runCommand(`access-control role list --itwin-id ${iTwinId}`); - expect(listedRoles).to.not.be.undefined; - expect(listedRoles!.length).to.be.greaterThanOrEqual(1); - - expect(listedRoles).to.deep.include(newRole); - }); - - it('Should delete role', async () => { - const { result: newRole } = await runCommand(`access-control role create --itwin-id ${iTwinId} --name Test3 --description Description3`); - expect(newRole).to.not.be.undefined; - expect(newRole!.id).to.not.be.undefined; - - const { result: deleteResult } = await runCommand<{result: string}>(`access-control role delete --itwin-id ${iTwinId} --role-id ${newRole!.id}`); - expect(deleteResult).to.have.property('result', 'deleted'); - }); + expect(roleInfo).to.not.be.undefined; + + expect(roleInfo?.id).to.be.equal(roleCreate!.id); + expect(roleInfo?.displayName).to.be.equal(roleName); + expect(roleInfo?.description).to.be.equal(roleDescription); + + const updatedRoleName = "Updated Role Name"; + const updatedRoleDescription = "Updated Role Description"; + const permissions = ["administration_invite_member"]; + + const { result: roleUpdate } = await runCommand(`access-control role update --itwin-id ${iTwinId} --role-id ${roleCreate!.id} --name "${updatedRoleName}" --description "${updatedRoleDescription}" --permission ${permissions[0]}`); + expect(roleUpdate).to.not.be.undefined; + expect(roleUpdate!.id).to.not.be.undefined; + expect(roleUpdate!.displayName).to.be.equal(updatedRoleName); + expect(roleUpdate!.description).to.be.equal(updatedRoleDescription); + expect(roleUpdate!.permissions).to.not.be.undefined; + expect(roleUpdate!.permissions).to.include.members(permissions); + }); + + it('Should list roles', async () => { + const { result: newRole } = await runCommand(`access-control role create --itwin-id ${iTwinId} --name Test2 --description Description2`); + expect(newRole).to.not.be.undefined; + expect(newRole!.id).to.not.be.undefined; + expect(newRole!.displayName).to.be.equal("Test2"); + expect(newRole!.description).to.be.equal("Description2"); + + const { result: listedRoles } = await runCommand(`access-control role list --itwin-id ${iTwinId}`); + expect(listedRoles).to.not.be.undefined; + expect(listedRoles!.length).to.be.greaterThanOrEqual(1); + + expect(listedRoles).to.deep.include(newRole); + }); + + it('Should delete role', async () => { + const { result: newRole } = await runCommand(`access-control role create --itwin-id ${iTwinId} --name Test3 --description Description3`); + expect(newRole).to.not.be.undefined; + expect(newRole!.id).to.not.be.undefined; + + const { result: deleteResult } = await runCommand<{result: string}>(`access-control role delete --itwin-id ${iTwinId} --role-id ${newRole!.id}`); + expect(deleteResult).to.have.property('result', 'deleted'); + }); }; export default tests; diff --git a/integration-tests/api.test.ts b/integration-tests/api.test.ts index 272fa67c..f84617b7 100644 --- a/integration-tests/api.test.ts +++ b/integration-tests/api.test.ts @@ -8,114 +8,114 @@ import { createITwin } from "./utils/helpers.js"; import runSuiteIfMainModule from "./utils/run-suite-if-main-module.js"; const tests = () => describe("API Integration Tests", () => { - let iTwin: ITwin; - let iModel: IModel; - - before(async () => { - const date = new Date(); - const iTwinRespone = await runCommand(`itwin create --class Thing --sub-class Asset --name itwin-cli-test-${date.toISOString()}`); - expect(iTwinRespone.error).to.be.undefined; - iTwin = iTwinRespone.result!; - const iModelResponse = await runCommand(`imodel create --name imodel-cli-test-${date.toISOString()} --itwin-id ${iTwin.id}`); - expect(iModelResponse.error).to.be.undefined; - iModel = iModelResponse.result!; - }); - - after(async () => { - const { result: itwinDeleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwin.id}`); - expect(itwinDeleteResult).to.have.property('result', 'deleted'); - }); - - it("should send a GET request and get user me info", async () => { - const apiResponse = await runCommand("api --method GET --path users/me"); - expect(apiResponse.error).to.be.undefined; - const userApiInfo = JSON.parse(apiResponse.stdout); + let iTwin: ITwin; + let iModel: IModel; + + before(async () => { + const date = new Date(); + const iTwinRespone = await runCommand(`itwin create --class Thing --sub-class Asset --name itwin-cli-test-${date.toISOString()}`); + expect(iTwinRespone.error).to.be.undefined; + iTwin = iTwinRespone.result!; + const iModelResponse = await runCommand(`imodel create --name imodel-cli-test-${date.toISOString()} --itwin-id ${iTwin.id}`); + expect(iModelResponse.error).to.be.undefined; + iModel = iModelResponse.result!; + }); + + after(async () => { + const { result: itwinDeleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${iTwin.id}`); + expect(itwinDeleteResult).to.have.property('result', 'deleted'); + }); + + it("should send a GET request and get user me info", async () => { + const apiResponse = await runCommand("api --method GET --path users/me"); + expect(apiResponse.error).to.be.undefined; + const userApiInfo = JSON.parse(apiResponse.stdout); - const userCommandInfo = await runCommand("user me"); - - expect(userApiInfo).to.have.property("user").that.is.an("object"); - expect(userApiInfo.user).to.deep.equal(userCommandInfo.result); - }); - - it("should send a GET request with query parameters", async () => { - const apiResponse = await runCommand(`api --method GET --path itwins --query displayName:${iTwin.displayName}`); - expect(apiResponse.error).to.be.undefined; - const apiResponseJSON = JSON.parse(apiResponse.stdout); - - expect(apiResponseJSON).to.have.property("iTwins").that.is.an("array").with.lengthOf(1); - expect(apiResponseJSON.iTwins[0]).to.have.property("displayName", iTwin.displayName); - expect(apiResponseJSON.iTwins[0]).to.have.property("id", iTwin.id); - }); - - it("should send a POST request with body parameters", async () => { - const user = await runCommand("user me"); - const apiResponse = await runCommand(`api --method POST --path users/getbyidlist --body ["${user.result?.id}"]`); - expect(apiResponse.error).to.be.undefined; - const apiResponseJSON = JSON.parse(apiResponse.stdout); - - expect(apiResponseJSON).to.have.property("users").that.is.an("array").with.lengthOf(1); - expect(apiResponseJSON.users[0]).to.have.property("id", user.result?.id); - expect(apiResponseJSON.users[0]).to.have.property("email", user.result?.email); - }); - - it("should update an iTwin with a PATCH request", async () => { - const updatedName = `itwin-cli-test-updated-${new Date().toISOString()}`; - // eslint-disable-next-line no-useless-escape - const apiResponse = await runCommand(`api --method PATCH --path itwins/${iTwin.id} --body "{\"displayName\": \"${updatedName}\"}"`); - expect(apiResponse.error).to.be.undefined; - const apiResponseJSON = JSON.parse(apiResponse.stdout); - - expect(apiResponseJSON).to.have.property("iTwin").that.is.an("object").and.not.undefined; - expect(apiResponseJSON.iTwin).to.have.property("id", iTwin.id); - expect(apiResponseJSON.iTwin).to.have.property("displayName", updatedName); - }); - - it("should send a DELETE request to delete the iTwin", async () => { - const createdItwin = await createITwin(`cli-itwin-integration-test-${new Date().toISOString()}`, "Thing", "Asset"); - - const {result: deleteResponse} = await runCommand(`api --method DELETE --path itwins/${createdItwin.id} --empty-response`); - expect(deleteResponse).to.have.property("result").that.is.equal("success"); - }); - - it('should send the header to the API (iModel minimal)', async () => { - const minimalApiResponse = await runCommand(`api --method GET --path imodels/?iTwinId=${iTwin.id} --header "Prefer: return=minimal"`); - expect(minimalApiResponse.error).to.be.undefined; - const minimalApiResponseJSON = JSON.parse(minimalApiResponse.stdout); - - expect(minimalApiResponseJSON).to.have.property("iModels").that.is.an("array").with.lengthOf(1); - expect(minimalApiResponseJSON.iModels[0]).to.have.property("id", iModel.id); - expect(minimalApiResponseJSON.iModels[0]).to.have.property("displayName", iModel.displayName); - expect(minimalApiResponseJSON.iModels[0]).to.not.have.property("createdDateTime"); - expect(minimalApiResponseJSON.iModels[0]).to.not.have.property("iTwinId"); - }); - - it('should send the header to the API (iModel representation)', async () => { - const minimalApiResponse = await runCommand(`api --method GET --path imodels/?iTwinId=${iTwin.id} --header "Prefer: return=representation"`); - expect(minimalApiResponse.error).to.be.undefined; - const minimalApiResponseJSON = JSON.parse(minimalApiResponse.stdout); - - expect(minimalApiResponseJSON).to.have.property("iModels").that.is.an("array").with.lengthOf(1); - expect(minimalApiResponseJSON.iModels[0]).to.have.property("id", iModel.id); - expect(minimalApiResponseJSON.iModels[0]).to.have.property("displayName", iModel.displayName); - expect(minimalApiResponseJSON.iModels[0]).to.have.property("createdDateTime"); - expect(minimalApiResponseJSON.iModels[0]).to.have.property("iTwinId", iModel.iTwinId); - }); - - it('should handle version header correctly (Echo V1)', async () => { - const apiResponse = await runCommand(`api --method GET --path echo/context --version-header application/vnd.bentley.itwin-platform.v1+json`); - expect(apiResponse.error).to.be.undefined; - const apiResponseJSON = JSON.parse(apiResponse.stdout); - - expect(apiResponseJSON).to.have.property("api").that.is.an("object").and.not.undefined; - expect(apiResponseJSON.api).to.have.property("version").that.is.an("string").and.not.undefined; - expect(apiResponseJSON.api.version).to.equal("v1"); - }); - - it('should return an error if serialized JSON provided to `--body` flag is invalid', async () => { - const apiResponse = await runCommand(`api --method PATCH --path itwins/${iTwin.id} --body not-a-serialized-json-string`); - expect(apiResponse).to.have.property('error'); - expect(apiResponse.error?.message).to.match(/'not-a-serialized-json-string' is not valid serialized JSON./) - }); + const userCommandInfo = await runCommand("user me"); + + expect(userApiInfo).to.have.property("user").that.is.an("object"); + expect(userApiInfo.user).to.deep.equal(userCommandInfo.result); + }); + + it("should send a GET request with query parameters", async () => { + const apiResponse = await runCommand(`api --method GET --path itwins --query displayName:${iTwin.displayName}`); + expect(apiResponse.error).to.be.undefined; + const apiResponseJSON = JSON.parse(apiResponse.stdout); + + expect(apiResponseJSON).to.have.property("iTwins").that.is.an("array").with.lengthOf(1); + expect(apiResponseJSON.iTwins[0]).to.have.property("displayName", iTwin.displayName); + expect(apiResponseJSON.iTwins[0]).to.have.property("id", iTwin.id); + }); + + it("should send a POST request with body parameters", async () => { + const user = await runCommand("user me"); + const apiResponse = await runCommand(`api --method POST --path users/getbyidlist --body ["${user.result?.id}"]`); + expect(apiResponse.error).to.be.undefined; + const apiResponseJSON = JSON.parse(apiResponse.stdout); + + expect(apiResponseJSON).to.have.property("users").that.is.an("array").with.lengthOf(1); + expect(apiResponseJSON.users[0]).to.have.property("id", user.result?.id); + expect(apiResponseJSON.users[0]).to.have.property("email", user.result?.email); + }); + + it("should update an iTwin with a PATCH request", async () => { + const updatedName = `itwin-cli-test-updated-${new Date().toISOString()}`; + // eslint-disable-next-line no-useless-escape + const apiResponse = await runCommand(`api --method PATCH --path itwins/${iTwin.id} --body "{\"displayName\": \"${updatedName}\"}"`); + expect(apiResponse.error).to.be.undefined; + const apiResponseJSON = JSON.parse(apiResponse.stdout); + + expect(apiResponseJSON).to.have.property("iTwin").that.is.an("object").and.not.undefined; + expect(apiResponseJSON.iTwin).to.have.property("id", iTwin.id); + expect(apiResponseJSON.iTwin).to.have.property("displayName", updatedName); + }); + + it("should send a DELETE request to delete the iTwin", async () => { + const createdItwin = await createITwin(`cli-itwin-integration-test-${new Date().toISOString()}`, "Thing", "Asset"); + + const {result: deleteResponse} = await runCommand(`api --method DELETE --path itwins/${createdItwin.id} --empty-response`); + expect(deleteResponse).to.have.property("result").that.is.equal("success"); + }); + + it('should send the header to the API (iModel minimal)', async () => { + const minimalApiResponse = await runCommand(`api --method GET --path imodels/?iTwinId=${iTwin.id} --header "Prefer: return=minimal"`); + expect(minimalApiResponse.error).to.be.undefined; + const minimalApiResponseJSON = JSON.parse(minimalApiResponse.stdout); + + expect(minimalApiResponseJSON).to.have.property("iModels").that.is.an("array").with.lengthOf(1); + expect(minimalApiResponseJSON.iModels[0]).to.have.property("id", iModel.id); + expect(minimalApiResponseJSON.iModels[0]).to.have.property("displayName", iModel.displayName); + expect(minimalApiResponseJSON.iModels[0]).to.not.have.property("createdDateTime"); + expect(minimalApiResponseJSON.iModels[0]).to.not.have.property("iTwinId"); + }); + + it('should send the header to the API (iModel representation)', async () => { + const minimalApiResponse = await runCommand(`api --method GET --path imodels/?iTwinId=${iTwin.id} --header "Prefer: return=representation"`); + expect(minimalApiResponse.error).to.be.undefined; + const minimalApiResponseJSON = JSON.parse(minimalApiResponse.stdout); + + expect(minimalApiResponseJSON).to.have.property("iModels").that.is.an("array").with.lengthOf(1); + expect(minimalApiResponseJSON.iModels[0]).to.have.property("id", iModel.id); + expect(minimalApiResponseJSON.iModels[0]).to.have.property("displayName", iModel.displayName); + expect(minimalApiResponseJSON.iModels[0]).to.have.property("createdDateTime"); + expect(minimalApiResponseJSON.iModels[0]).to.have.property("iTwinId", iModel.iTwinId); + }); + + it('should handle version header correctly (Echo V1)', async () => { + const apiResponse = await runCommand(`api --method GET --path echo/context --version-header application/vnd.bentley.itwin-platform.v1+json`); + expect(apiResponse.error).to.be.undefined; + const apiResponseJSON = JSON.parse(apiResponse.stdout); + + expect(apiResponseJSON).to.have.property("api").that.is.an("object").and.not.undefined; + expect(apiResponseJSON.api).to.have.property("version").that.is.an("string").and.not.undefined; + expect(apiResponseJSON.api.version).to.equal("v1"); + }); + + it('should return an error if serialized JSON provided to `--body` flag is invalid', async () => { + const apiResponse = await runCommand(`api --method PATCH --path itwins/${iTwin.id} --body not-a-serialized-json-string`); + expect(apiResponse).to.have.property('error'); + expect(apiResponse.error?.message).to.match(/'not-a-serialized-json-string' is not valid serialized JSON./); + }); }); export default tests; diff --git a/integration-tests/changed-elements/changesets-comparison.test.ts b/integration-tests/changed-elements/changesets-comparison.test.ts index d40ed2a1..29be208e 100644 --- a/integration-tests/changed-elements/changesets-comparison.test.ts +++ b/integration-tests/changed-elements/changesets-comparison.test.ts @@ -23,28 +23,28 @@ const tests = () => describe('changesets + comparison', () => { before(async () => { const { result: filteredITwins } = await runCommand(`itwin list --name ${testITwinName}`); - expect(filteredITwins).to.not.be.undefined + expect(filteredITwins).to.not.be.undefined; if(filteredITwins!.length === 0) { - const testITwin = await createITwin(testITwinName, 'Thing', 'Asset'); - testITwinId = testITwin.id as string; - const testIModel = await createIModel(testIModelName, testITwinId); - testIModelId = testIModel.id; + const testITwin = await createITwin(testITwinName, 'Thing', 'Asset'); + testITwinId = testITwin.id as string; + const testIModel = await createIModel(testIModelName, testITwinId); + testIModelId = testIModel.id; - await runCommand<{result: string}>(`changed-elements enable --imodel-id ${testIModelId} --itwin-id ${testITwinId}`); + await runCommand<{result: string}>(`changed-elements enable --imodel-id ${testIModelId} --itwin-id ${testITwinId}`); - const rootFolderId = await getRootFolderId(testITwinId); - await createFile(rootFolderId, testFileName, testFilePath); - const { result: populateResult } = await runCommand(`imodel populate --imodel-id ${testIModelId} --file ${testFilePath} --connector-type SPPID`); - expect(populateResult).to.have.property('iModelId', testIModelId); - expect(populateResult).to.have.property('iTwinId', testITwinId); + const rootFolderId = await getRootFolderId(testITwinId); + await createFile(rootFolderId, testFileName, testFilePath); + const { result: populateResult } = await runCommand(`imodel populate --imodel-id ${testIModelId} --file ${testFilePath} --connector-type SPPID`); + expect(populateResult).to.have.property('iModelId', testIModelId); + expect(populateResult).to.have.property('iTwinId', testITwinId); } else { - testITwinId = filteredITwins![0].id!; - const { result: iModels } = await runCommand(`imodel list --itwin-id ${testITwinId}`); - expect(iModels).to.not.be.undefined; - expect(iModels).to.have.lengthOf(1); - testIModelId = iModels![0].id; + testITwinId = filteredITwins![0].id!; + const { result: iModels } = await runCommand(`imodel list --itwin-id ${testITwinId}`); + expect(iModels).to.not.be.undefined; + expect(iModels).to.have.lengthOf(1); + testIModelId = iModels![0].id; } }); @@ -56,7 +56,7 @@ const tests = () => describe('changesets + comparison', () => { const { result: filteredResult } = await runCommand(`changed-elements changesets --imodel-id ${testIModelId} --itwin-id ${testITwinId} --skip 2 --top 2`); expect(filteredResult).to.not.be.undefined; expect(filteredResult).to.have.lengthOf(2); - expect(filteredResult?.map(x => x.id)).to.be.deep.equal(fullResult?.map(x => x.id).slice(2)) + expect(filteredResult?.map(x => x.id)).to.be.deep.equal(fullResult?.map(x => x.id).slice(2)); }); it('should compare 2 changesets', async () => { diff --git a/integration-tests/context/context.test.ts b/integration-tests/context/context.test.ts index b740fc0a..7d9afc66 100644 --- a/integration-tests/context/context.test.ts +++ b/integration-tests/context/context.test.ts @@ -6,121 +6,121 @@ import { expect } from "chai"; import runSuiteIfMainModule from "../utils/run-suite-if-main-module"; const tests = () => describe('Context Integration Tests', () => { - let iTwin: ITwin; - let iModel: IModel; - let anotherITwin: ITwin; + let iTwin: ITwin; + let iModel: IModel; + let anotherITwin: ITwin; - before(async () => { - const name = `IntegrationTestITwin_${new Date().toISOString()}`; - const iTwinResult = await runCommand(`itwin create --name "${name}" --class Thing --sub-class Asset`); - expect(iTwinResult.error).to.be.undefined; - expect(iTwinResult.result).to.not.be.undefined; - iTwin = iTwinResult.result as ITwin; - - const iModelName = `IntegrationTestIModel_${new Date().toISOString()}`; - const iModelResult = await runCommand(`imodel create --name "${iModelName}" --itwin-id ${iTwin.id}`); - expect(iModelResult.error).to.be.undefined; - expect(iModelResult.result).to.not.be.undefined; - iModel = iModelResult.result as IModel; - - const anotherITwinName = `AnotherITwin_${new Date().toISOString()}`; - const anotherITwinResult = await runCommand(`itwin create --name "${anotherITwinName}" --class Thing --sub-class Asset`); - expect(anotherITwinResult.error).to.be.undefined; - expect(anotherITwinResult.result).to.not.be.undefined; - anotherITwin = anotherITwinResult.result as ITwin; - }); - - after(async () => { - const { result: deleteResult1 } = await runCommand<{result: string}>(`itwin delete -i ${iTwin.id}`); - const { result: deleteResult2 } = await runCommand<{result: string}>(`itwin delete -i ${anotherITwin.id}`); - - expect(deleteResult1).to.have.property('result', 'deleted'); - expect(deleteResult2).to.have.property('result', 'deleted'); - }); - - beforeEach(async () => { - const output = await runCommand('context clear'); - expect(output.error).to.be.undefined; - }); + before(async () => { + const name = `IntegrationTestITwin_${new Date().toISOString()}`; + const iTwinResult = await runCommand(`itwin create --name "${name}" --class Thing --sub-class Asset`); + expect(iTwinResult.error).to.be.undefined; + expect(iTwinResult.result).to.not.be.undefined; + iTwin = iTwinResult.result as ITwin; + + const iModelName = `IntegrationTestIModel_${new Date().toISOString()}`; + const iModelResult = await runCommand(`imodel create --name "${iModelName}" --itwin-id ${iTwin.id}`); + expect(iModelResult.error).to.be.undefined; + expect(iModelResult.result).to.not.be.undefined; + iModel = iModelResult.result as IModel; + + const anotherITwinName = `AnotherITwin_${new Date().toISOString()}`; + const anotherITwinResult = await runCommand(`itwin create --name "${anotherITwinName}" --class Thing --sub-class Asset`); + expect(anotherITwinResult.error).to.be.undefined; + expect(anotherITwinResult.result).to.not.be.undefined; + anotherITwin = anotherITwinResult.result as ITwin; + }); + + after(async () => { + const { result: deleteResult1 } = await runCommand<{result: string}>(`itwin delete -i ${iTwin.id}`); + const { result: deleteResult2 } = await runCommand<{result: string}>(`itwin delete -i ${anotherITwin.id}`); + + expect(deleteResult1).to.have.property('result', 'deleted'); + expect(deleteResult2).to.have.property('result', 'deleted'); + }); + + beforeEach(async () => { + const output = await runCommand('context clear'); + expect(output.error).to.be.undefined; + }); - it('should clear the context', async () => { - const output = await runCommand('context clear'); - expect(output.error).to.be.undefined; - expect(output.stdout).to.contain('Context cleared.'); - - const outputInfo = await runCommand('context info'); - expect(outputInfo.error).to.be.undefined; - expect(outputInfo.result).to.be.undefined; - }); - - it('should set the context', async () => { - const output1 = await runCommand(`context set --itwin-id ${iTwin.id} --imodel-id ${iModel.id}`); - expect(output1.error).to.be.undefined; - expect(output1.result).to.deep.equal({ iModelId: iModel.id, iTwinId: iTwin.id }); - - const output2 = await runCommand(`context set --itwin-id ${anotherITwin.id}`); - expect(output2.error).to.be.undefined; - expect(output2.result).to.deep.equal({ iModelId: undefined, iTwinId: anotherITwin.id }); - }); - - it('should fail to set context with invalid iTwin ID', async () => { - const invalidITwinId = "invalid-id"; - const output = await runCommand(`context set --itwin-id ${invalidITwinId}`); - expect(output.error).to.not.be.undefined; - expect(output.error?.message).to.contain('Requested iTwin is not available.'); - }); - - it('should fail to set context with mismatched iModel and iTwin IDs', async () => { - const output = await runCommand(`context set --itwin-id ${anotherITwin.id} --imodel-id ${iModel.id}`); - expect(output.error).to.not.be.undefined; - expect(output.error?.message).to.contain(`The iModel ID ${iModel.id} does not belong to the specified iTwin ID ${anotherITwin.id}.`); - }); - - it('should fail to set context without iTwin or iModel ID', async () => { - const output = await runCommand('context set'); - expect(output.error).to.not.be.undefined; - expect(output.error?.message).to.contain('At least one of the following must be provided: --imodel-id, --itwin-id'); - }); - - it('should display the current context', async () => { - await runCommand(`context set --itwin-id ${iTwin.id} --imodel-id ${iModel.id}`); - const output = await runCommand('context info'); - expect(output.error).to.be.undefined; - expect(output.result).to.deep.equal({ iModelId: iModel.id, iTwinId: iTwin.id }); - }); - - it('should display undefined context after clearing', async () => { - await runCommand('context clear'); - const output = await runCommand('context info'); - expect(output.error).to.be.undefined; - expect(output.result).to.be.undefined; - }); - - it('should clear context multiple times without error', async () => { - await runCommand('context clear'); - const output = await runCommand('context clear'); - expect(output.error).to.be.undefined; - expect(output.stdout).to.contain('Context cleared.'); - }); - - it('should set the context with only an iTwin ID', async () => { - const output = await runCommand(`context set --itwin-id ${iTwin.id}`); - expect(output.error).to.be.undefined; - expect(output.result).to.deep.equal({ iModelId: undefined, iTwinId: iTwin.id }); - }); - - it('should set the context with only an iModel ID and resolve the correct iTwin ID', async () => { - const output = await runCommand(`context set --imodel-id ${iModel.id}`); - expect(output.error).to.be.undefined; - expect(output.result).to.deep.equal({ iModelId: iModel.id, iTwinId: iTwin.id }); - }); - - it('should fail to set context with only an iModel ID if the iModel does not exist', async () => { - const invalidIModelId = "invalid-id"; - const output = await runCommand(`context set --imodel-id ${invalidIModelId}`); - expect(output.error).to.not.be.undefined; - expect(output.error?.message).to.contain('Requested iModel is not available.'); - }); + it('should clear the context', async () => { + const output = await runCommand('context clear'); + expect(output.error).to.be.undefined; + expect(output.stdout).to.contain('Context cleared.'); + + const outputInfo = await runCommand('context info'); + expect(outputInfo.error).to.be.undefined; + expect(outputInfo.result).to.be.undefined; + }); + + it('should set the context', async () => { + const output1 = await runCommand(`context set --itwin-id ${iTwin.id} --imodel-id ${iModel.id}`); + expect(output1.error).to.be.undefined; + expect(output1.result).to.deep.equal({ iModelId: iModel.id, iTwinId: iTwin.id }); + + const output2 = await runCommand(`context set --itwin-id ${anotherITwin.id}`); + expect(output2.error).to.be.undefined; + expect(output2.result).to.deep.equal({ iModelId: undefined, iTwinId: anotherITwin.id }); + }); + + it('should fail to set context with invalid iTwin ID', async () => { + const invalidITwinId = "invalid-id"; + const output = await runCommand(`context set --itwin-id ${invalidITwinId}`); + expect(output.error).to.not.be.undefined; + expect(output.error?.message).to.contain('Requested iTwin is not available.'); + }); + + it('should fail to set context with mismatched iModel and iTwin IDs', async () => { + const output = await runCommand(`context set --itwin-id ${anotherITwin.id} --imodel-id ${iModel.id}`); + expect(output.error).to.not.be.undefined; + expect(output.error?.message).to.contain(`The iModel ID ${iModel.id} does not belong to the specified iTwin ID ${anotherITwin.id}.`); + }); + + it('should fail to set context without iTwin or iModel ID', async () => { + const output = await runCommand('context set'); + expect(output.error).to.not.be.undefined; + expect(output.error?.message).to.contain('At least one of the following must be provided: --imodel-id, --itwin-id'); + }); + + it('should display the current context', async () => { + await runCommand(`context set --itwin-id ${iTwin.id} --imodel-id ${iModel.id}`); + const output = await runCommand('context info'); + expect(output.error).to.be.undefined; + expect(output.result).to.deep.equal({ iModelId: iModel.id, iTwinId: iTwin.id }); + }); + + it('should display undefined context after clearing', async () => { + await runCommand('context clear'); + const output = await runCommand('context info'); + expect(output.error).to.be.undefined; + expect(output.result).to.be.undefined; + }); + + it('should clear context multiple times without error', async () => { + await runCommand('context clear'); + const output = await runCommand('context clear'); + expect(output.error).to.be.undefined; + expect(output.stdout).to.contain('Context cleared.'); + }); + + it('should set the context with only an iTwin ID', async () => { + const output = await runCommand(`context set --itwin-id ${iTwin.id}`); + expect(output.error).to.be.undefined; + expect(output.result).to.deep.equal({ iModelId: undefined, iTwinId: iTwin.id }); + }); + + it('should set the context with only an iModel ID and resolve the correct iTwin ID', async () => { + const output = await runCommand(`context set --imodel-id ${iModel.id}`); + expect(output.error).to.be.undefined; + expect(output.result).to.deep.equal({ iModelId: iModel.id, iTwinId: iTwin.id }); + }); + + it('should fail to set context with only an iModel ID if the iModel does not exist', async () => { + const invalidIModelId = "invalid-id"; + const output = await runCommand(`context set --imodel-id ${invalidIModelId}`); + expect(output.error).to.not.be.undefined; + expect(output.error?.message).to.contain('Requested iModel is not available.'); + }); }); export default tests; diff --git a/integration-tests/imodel/changeset.test.ts b/integration-tests/imodel/changeset.test.ts index cdd0f53a..d0765dd5 100644 --- a/integration-tests/imodel/changeset.test.ts +++ b/integration-tests/imodel/changeset.test.ts @@ -22,26 +22,26 @@ const tests = () => describe('changeset', () => { before(async () => { const { result: filteredITwins } = await runCommand(`itwin list --name ${testITwinName}`); - expect(filteredITwins).to.not.be.undefined + expect(filteredITwins).to.not.be.undefined; if(filteredITwins!.length === 0) { - const testITwin = await createITwin(testITwinName, 'Thing', 'Asset'); - testITwinId = testITwin.id as string; - const testIModel = await createIModel(testIModelName, testITwinId); - testIModelId = testIModel.id; + const testITwin = await createITwin(testITwinName, 'Thing', 'Asset'); + testITwinId = testITwin.id as string; + const testIModel = await createIModel(testIModelName, testITwinId); + testIModelId = testIModel.id; - await runCommand(`changed-elements enable --imodel-id ${testIModelId} --itwin-id ${testITwinId}`); + await runCommand(`changed-elements enable --imodel-id ${testIModelId} --itwin-id ${testITwinId}`); - const { result } = await runCommand(`imodel populate --imodel-id ${testIModelId} --file ${testFilePath} --connector-type MSTN`); - expect(result).to.have.property('iModelId', testIModelId); - expect(result).to.have.property('iTwinId', testITwinId); + const { result } = await runCommand(`imodel populate --imodel-id ${testIModelId} --file ${testFilePath} --connector-type MSTN`); + expect(result).to.have.property('iModelId', testIModelId); + expect(result).to.have.property('iTwinId', testITwinId); } else { - testITwinId = filteredITwins![0].id!; - const { result: iModels } = await runCommand(`imodel list --itwin-id ${testITwinId}`); - expect(iModels).to.not.be.undefined; - expect(iModels).to.have.lengthOf(1); - testIModelId = iModels![0].id; + testITwinId = filteredITwins![0].id!; + const { result: iModels } = await runCommand(`imodel list --itwin-id ${testITwinId}`); + expect(iModels).to.not.be.undefined; + expect(iModels).to.have.lengthOf(1); + testIModelId = iModels![0].id; } }); @@ -77,7 +77,7 @@ const tests = () => describe('changeset', () => { expect(listResult).to.not.be.undefined; expect(listResult).to.have.lengthOf(4); expect(listResult?.every((result) => result.index > 5 && result.index <= 9)).to.be.true; - }) + }); it('should order returned changesets by index', async () => { const { result: listResultDesc } = await runCommand(`imodel changeset list --imodel-id ${testIModelId} --order-by desc`); @@ -94,13 +94,13 @@ const tests = () => describe('changeset', () => { it(`should return an error if neither of 'changeset-id' and 'changeset-index' flags are provided`, async () => { const { error: infoError } = await runCommand(`imodel changeset info --imodel-id ${testIModelId}`); expect(infoError).to.not.be.undefined; - expect(infoError!.message).to.contain("Exactly one of the following must be provided: --changeset-id, --changeset-index") + expect(infoError!.message).to.contain("Exactly one of the following must be provided: --changeset-id, --changeset-index"); }); it(`should return an error if both of 'changeset-id' and 'changeset-index' flags are provided`, async () => { const { error: infoError } = await runCommand(`imodel changeset info --imodel-id ${testIModelId} --changeset-id a4139edd-d28d-4bb9-9260-0802dfda0413 --changeset-index 1`); expect(infoError).to.not.be.undefined; - expect(infoError!.message).to.contain("--changeset-index cannot also be provided when using --changeset-id") + expect(infoError!.message).to.contain("--changeset-index cannot also be provided when using --changeset-id"); }); }); diff --git a/integration-tests/imodel/connection/connection.test.ts b/integration-tests/imodel/connection/connection.test.ts index d8b09121..0427ef67 100644 --- a/integration-tests/imodel/connection/connection.test.ts +++ b/integration-tests/imodel/connection/connection.test.ts @@ -4,20 +4,20 @@ *--------------------------------------------------------------------------------------------*/ import runSuiteIfMainModule from "../../utils/run-suite-if-main-module"; -import createTests from './create.test' -import deleteTests from './delete.test' -import infoTests from './info.test' -import listTests from './list.test' -import sourcefileTests from './sourcefile.test' -import updateTests from './update.test' +import createTests from './create.test'; +import deleteTests from './delete.test'; +import infoTests from './info.test'; +import listTests from './list.test'; +import sourcefileTests from './sourcefile.test'; +import updateTests from './update.test'; const tests = () => describe('connection', async () => { - createTests(); - deleteTests(); - infoTests(); - listTests(); - sourcefileTests(); - updateTests(); + createTests(); + deleteTests(); + infoTests(); + listTests(); + sourcefileTests(); + updateTests(); }); export default tests; diff --git a/integration-tests/imodel/connection/create.test.ts b/integration-tests/imodel/connection/create.test.ts index 27de2b04..4dc9f3ac 100644 --- a/integration-tests/imodel/connection/create.test.ts +++ b/integration-tests/imodel/connection/create.test.ts @@ -79,7 +79,7 @@ const tests = () => describe('create', () => { const { error: createError } = await runCommand(`imodel connection create -m ${testIModelId} -f ${testFileId1} -f ${testFileId2} -f ${testFileId3} --connector-type MSTN --connector-type SPPID -n TestConnection`); expect(createError).to.not.be.undefined; expect(createError!.message).to.be.equal("When multiple connector-type options are provided, their amount must match file-id option amount. Alternatively, you can provide a single connector-type option, which will then be applied to all file-id options."); - }) + }); }); export default tests; diff --git a/integration-tests/imodel/connection/run.test.ts b/integration-tests/imodel/connection/run.test.ts index 49afc267..2a2ec786 100644 --- a/integration-tests/imodel/connection/run.test.ts +++ b/integration-tests/imodel/connection/run.test.ts @@ -54,16 +54,14 @@ const tests = () => describe('run', () => { let { result: infoResult } = await runCommand(`imodel connection run info -c ${connectionId} --connection-run-id ${listResult?.runs[0].id}`); while(infoResult?.state !== "Completed") { - // eslint-disable-next-line no-await-in-loop - await new Promise(r => {setTimeout(r, 10_000)}); - - // eslint-disable-next-line no-await-in-loop + await new Promise(r => {setTimeout(r, 10_000);}); + const { result } = await runCommand(`imodel connection run info -c ${connectionId} --connection-run-id ${listResult?.runs[0].id}`); infoResult = result; } expect(infoResult?.id).to.be.equal(listResult?.runs[0].id); - expect(infoResult?.state).to.be.equal("Completed") + expect(infoResult?.state).to.be.equal("Completed"); expect(infoResult?.result).to.be.equal("Success"); }).timeout(30 * 60 * 1000); }); diff --git a/integration-tests/imodel/connection/sourcefile.test.ts b/integration-tests/imodel/connection/sourcefile.test.ts index a92d6f27..8153b7cc 100644 --- a/integration-tests/imodel/connection/sourcefile.test.ts +++ b/integration-tests/imodel/connection/sourcefile.test.ts @@ -99,7 +99,7 @@ const tests = () => describe('sourcefile', () => { const { result: listResult } = await runCommand(`imodel connection sourcefile list -c ${connectionId}`); expect(listResult).to.not.be.undefined; expect(listResult).to.have.lengthOf(3); - expect(listResult?.some(result => result.storageFileId === testFileId && result!.connectorType === "MSTN" )) + expect(listResult?.some(result => result.storageFileId === testFileId && result!.connectorType === "MSTN" )); expect(listResult?.some(result => result.id === addResult1!.id && result.storageFileId === addResult1!.storageFileId && result!.connectorType === "IFC")).to.be.true; expect(listResult?.some(result => result.id === addResult2!.id && result.storageFileId === addResult2!.storageFileId && result!.connectorType === "MSTN")).to.be.true; diff --git a/integration-tests/imodel/create-delete.test.ts b/integration-tests/imodel/create-delete.test.ts index 6118d3ad..95652d8e 100644 --- a/integration-tests/imodel/create-delete.test.ts +++ b/integration-tests/imodel/create-delete.test.ts @@ -35,7 +35,7 @@ const tests = () => describe('create + delete', () => { latitude: 46.132_677_028_348_06, longitude: 7.672_120_009_938_448 } - } + }; const iModelName = `${testIModelName}-create1`; const { result: createdIModel} = await runCommand(`imodel create --itwin-id ${testITwinId} --name "${iModelName}" --description "${testIModelDescription}" --extent "${JSON.stringify(extent)}"`); @@ -58,7 +58,7 @@ const tests = () => describe('create + delete', () => { latitude: 46.132_677_028_348_06, longitude: 7.672_120_009_938_448 } - } + }; const iModelName = `${testIModelName}-create2`; const { result: createdIModel} = await runCommand(`imodel create --itwin-id ${testITwinId} --name "${iModelName}" --description "${testIModelDescription}" --ne-latitude ${extent.northEast.latitude} --ne-longitude ${extent.northEast.longitude} --sw-latitude ${extent.southWest.latitude} --sw-longitude ${extent.southWest.longitude}`); @@ -81,7 +81,7 @@ const tests = () => describe('create + delete', () => { latitude: 46.132_677_028_348_06, longitude: 7.672_120_009_938_448 } - } + }; const iModelName = `${testIModelName}-create2`; const { error: createError} = await runCommand(`imodel create --itwin-id ${testITwinId} --name "${iModelName}" --description "${testIModelDescription}" --extent "${JSON.stringify(extent)}" --ne-latitude ${extent.northEast.latitude} --ne-longitude ${extent.northEast.longitude} --sw-latitude ${extent.southWest.latitude} --sw-longitude ${extent.southWest.longitude}`); @@ -103,7 +103,7 @@ const tests = () => describe('create + delete', () => { latitude: 46.132_677_028_348_06, longitude: 7.672_120_009_938_448 } - } + }; const iModelName = `${testIModelName}-create2`; const { error: createError} = await runCommand(`imodel create --itwin-id ${testITwinId} --name "${iModelName}" --description "${testIModelDescription}" --ne-latitude ${extent.northEast.latitude} --ne-longitude ${extent.northEast.longitude} --sw-latitude ${extent.southWest.latitude}`); @@ -137,7 +137,7 @@ const tests = () => describe('create + delete', () => { southWest: { longitude: 7.672_120_009_938_448 }, - } + }; const iModelName = `${testIModelName}-create2`; const { error: createError} = await runCommand(`imodel create --itwin-id ${testITwinId} --name "${iModelName}" --description "${testIModelDescription}" --extent ${JSON.stringify(extent)}`); diff --git a/integration-tests/imodel/imodel.test.ts b/integration-tests/imodel/imodel.test.ts index 6df261e5..cff68e23 100644 --- a/integration-tests/imodel/imodel.test.ts +++ b/integration-tests/imodel/imodel.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import runSuiteIfMainModule from '../utils/run-suite-if-main-module'; -import changesetTests from "./changeset.test" +import changesetTests from "./changeset.test"; import connectionTests from './connection/connection.test'; import createDeleteTests from "./create-delete.test"; import infoTests from "./info.test"; diff --git a/integration-tests/imodel/list.test.ts b/integration-tests/imodel/list.test.ts index 5094e13b..24a02cd6 100644 --- a/integration-tests/imodel/list.test.ts +++ b/integration-tests/imodel/list.test.ts @@ -13,8 +13,8 @@ import runSuiteIfMainModule from '../utils/run-suite-if-main-module'; const tests = () => describe('list', () => { const testIModelName1 = `1-cli-imodel-integration-test-${new Date().toISOString()}`; const testIModelName2 = `2-cli-imodel-integration-test-${new Date().toISOString()}`; - const testIModelDescription1 = 'First iModel description.' - const testIModelDescription2 = 'Second iModel description.' + const testIModelDescription1 = 'First iModel description.'; + const testIModelDescription2 = 'Second iModel description.'; let testIModelId1: string; let testIModelId2: string; let testITwinId: string; @@ -77,13 +77,13 @@ const tests = () => describe('list', () => { const { result: iModelListAsc } = await runCommand(`imodel list --itwin-id ${testITwinId} --order-by "createdDateTime asc"`); expect(iModelListAsc).to.not.be.undefined; expect(iModelListAsc).to.have.lengthOf(2); - expect(new Date(iModelListAsc![0].createdDateTime)).to.be.lessThanOrEqual(new Date(iModelListAsc![1].createdDateTime)) + expect(new Date(iModelListAsc![0].createdDateTime)).to.be.lessThanOrEqual(new Date(iModelListAsc![1].createdDateTime)); const { result: iModelListDesc } = await runCommand(`imodel list --itwin-id ${testITwinId} --order-by "createdDateTime desc"`); expect(iModelListDesc).to.not.be.undefined; expect(iModelListDesc).to.have.lengthOf(2); expect(new Date(iModelListDesc![0].createdDateTime)).to.be.greaterThanOrEqual(new Date(iModelListDesc![1].createdDateTime)); - }) + }); it('should search iModels by name', async() => { const { result: iModelList } = await runCommand(`imodel list --itwin-id ${testITwinId} --search "1-cli-imodel-integration-test"`); diff --git a/integration-tests/imodel/named-version.test.ts b/integration-tests/imodel/named-version.test.ts index f03936b3..779e139a 100644 --- a/integration-tests/imodel/named-version.test.ts +++ b/integration-tests/imodel/named-version.test.ts @@ -7,7 +7,7 @@ import { NamedVersion } from '@itwin/imodels-client-management'; import { runCommand } from '@oclif/test'; import { expect } from 'chai'; -import { PopulateResponse } from '../../src/commands/imodel/populate' +import { PopulateResponse } from '../../src/commands/imodel/populate'; import { Changeset } from '../../src/services/changed-elements-client/tracking'; import { createIModel, createITwin } from '../utils/helpers'; import { ResultResponse } from '../utils/result-response'; diff --git a/integration-tests/imodel/populate.test.ts b/integration-tests/imodel/populate.test.ts index d90ac127..54dc1439 100644 --- a/integration-tests/imodel/populate.test.ts +++ b/integration-tests/imodel/populate.test.ts @@ -14,7 +14,7 @@ import { createIModel, createITwin } from '../utils/helpers'; import runSuiteIfMainModule from '../utils/run-suite-if-main-module'; const tests = () => describe('populate', () => { - const failingTestFilePath1 = 'integration-tests/test.zip' + const failingTestFilePath1 = 'integration-tests/test.zip'; const testFilePath1 = 'examples/datasets/ExtonCampus.dgn'; const testFilePath2 = 'examples/datasets/HouseModel.dgn'; @@ -70,10 +70,8 @@ const tests = () => describe('populate', () => { const {connectionId, runId} = populateResult!.summary[0]; let { result: infoResult } = await runCommand(`imodel connection run info -c ${connectionId} --connection-run-id ${runId}`); while(infoResult?.state !== "Completed") { - // eslint-disable-next-line no-await-in-loop - await new Promise(r => {setTimeout(r, 10_000)}); - - // eslint-disable-next-line no-await-in-loop + await new Promise(r => {setTimeout(r, 10_000);}); + const { result } = await runCommand(`imodel connection run info -c ${connectionId} --connection-run-id ${runId}`); infoResult = result; } diff --git a/integration-tests/imodel/update.test.ts b/integration-tests/imodel/update.test.ts index 7a9dfe93..1a4e3106 100644 --- a/integration-tests/imodel/update.test.ts +++ b/integration-tests/imodel/update.test.ts @@ -41,7 +41,7 @@ const tests = () => describe('update', () => { latitude: 46.132_677_028_348_06, longitude: 7.672_120_009_938_448 } - } + }; const { result: updatedIModel } = await runCommand(`imodel update --imodel-id ${testIModelId} --name ${updatedName} --description "${updatedDescription}" --extent "${JSON.stringify(updatedExtent)}"`); @@ -65,7 +65,7 @@ const tests = () => describe('update', () => { latitude: 46.132_677_028_348_06, longitude: 7.672_120_009_938_448 } - } + }; const { result: updatedIModel } = await runCommand(`imodel update --imodel-id ${testIModelId} --name ${updatedName} --description "${updatedDescription}" --ne-latitude ${updatedExtent.northEast.latitude} --ne-longitude ${updatedExtent.northEast.longitude} --sw-latitude ${updatedExtent.southWest.latitude} --sw-longitude ${updatedExtent.southWest.longitude}`); @@ -90,7 +90,7 @@ const tests = () => describe('update', () => { latitude: 46.132_677_028_348_06, longitude: 7.672_120_009_938_448 } - } + }; const { error: updateError } = await runCommand(`imodel update --imodel-id ${testIModelId} --name ${updatedName} --description "${updatedDescription}" --extent "${JSON.stringify(updatedExtent)}" --ne-latitude ${updatedExtent.northEast.latitude} --ne-longitude ${updatedExtent.northEast.longitude} --sw-latitude ${updatedExtent.southWest.latitude} --sw-longitude ${updatedExtent.southWest.longitude}`); @@ -113,13 +113,13 @@ const tests = () => describe('update', () => { latitude: 46.132_677_028_348_06, longitude: 7.672_120_009_938_448 } - } + }; const { error: updateError } = await runCommand(`imodel update --imodel-id ${testIModelId} --name ${updatedName} --description "${updatedDescription}" --ne-latitude ${updatedExtent.northEast.latitude} --ne-longitude ${updatedExtent.northEast.longitude} --sw-latitude ${updatedExtent.southWest.latitude}`); expect(updateError).to.not.be.undefined; expect(updateError?.message).to.match(/All of the following must be provided when using --sw-latitude: --ne-latitude, --ne-longitude, --sw-longitude/); - }) + }); it('should return an error if a component of the provided extent is not a valid number', async () => { const { error: createError} = await runCommand(`imodel update --imodel-id ${testIModelId} --ne-latitude 46.302abc --ne-longitude 7.835 --sw-latitude 46.132 --sw-longitude 7.672`); diff --git a/integration-tests/imodel/view-cesium-sandcastle.test.ts b/integration-tests/imodel/view-cesium-sandcastle.test.ts index 2373af7b..d5681d35 100644 --- a/integration-tests/imodel/view-cesium-sandcastle.test.ts +++ b/integration-tests/imodel/view-cesium-sandcastle.test.ts @@ -23,28 +23,28 @@ const tests = () => describe('view cesium-sandcastle', () => { before(async () => { const { result: filteredITwins } = await runCommand(`itwin list --name ${testITwinName}`); - expect(filteredITwins).to.not.be.undefined + expect(filteredITwins).to.not.be.undefined; if(filteredITwins!.length === 0) { - const testITwin = await createITwin(testITwinName, 'Thing', 'Asset'); - testITwinId = testITwin.id as string; - const testIModel = await createIModel(testIModelName, testITwinId); - testIModelId = testIModel.id; + const testITwin = await createITwin(testITwinName, 'Thing', 'Asset'); + testITwinId = testITwin.id as string; + const testIModel = await createIModel(testIModelName, testITwinId); + testIModelId = testIModel.id; - await runCommand(`changed-elements enable --imodel-id ${testIModelId} --itwin-id ${testITwinId}`); + await runCommand(`changed-elements enable --imodel-id ${testIModelId} --itwin-id ${testITwinId}`); - const rootFolderId = await getRootFolderId(testITwinId); - await createFile(rootFolderId, testFileName, testFilePath); - const { result: populateResult } = await runCommand(`imodel populate --imodel-id ${testIModelId} --file ${testFilePath} --connector-type MSTN`); - expect(populateResult).to.have.property('iModelId', testIModelId); - expect(populateResult).to.have.property('iTwinId', testITwinId); + const rootFolderId = await getRootFolderId(testITwinId); + await createFile(rootFolderId, testFileName, testFilePath); + const { result: populateResult } = await runCommand(`imodel populate --imodel-id ${testIModelId} --file ${testFilePath} --connector-type MSTN`); + expect(populateResult).to.have.property('iModelId', testIModelId); + expect(populateResult).to.have.property('iTwinId', testITwinId); } else { - testITwinId = filteredITwins![0].id!; - const { result: iModels } = await runCommand(`imodel list --itwin-id ${testITwinId}`); - expect(iModels).to.not.be.undefined; - expect(iModels).to.have.lengthOf(1); - testIModelId = iModels![0].id; + testITwinId = filteredITwins![0].id!; + const { result: iModels } = await runCommand(`imodel list --itwin-id ${testITwinId}`); + expect(iModels).to.not.be.undefined; + expect(iModels).to.have.lengthOf(1); + testIModelId = iModels![0].id; } }); @@ -56,7 +56,7 @@ const tests = () => describe('view cesium-sandcastle', () => { const base64String = result!.url.slice("https://sandcastle.cesium.com/#c=".length); const dataString = decodeCompressedBase64(base64String); const pattern = new RegExp('const viewer = new Cesium.Viewer("cesiumContainer",{})'.replaceAll("(","\\(").replaceAll(")","\\)").replaceAll("\"","\\\\\"")); - expect(dataString).to.match(pattern) + expect(dataString).to.match(pattern); }); it(`should use cesium world terrain, when '--terrain cesiumWorldTerrain' is provided`, async () => { @@ -67,7 +67,7 @@ const tests = () => describe('view cesium-sandcastle', () => { const base64String = result!.url.slice("https://sandcastle.cesium.com/#c=".length); const dataString = decodeCompressedBase64(base64String); const pattern = new RegExp('const viewer = new Cesium.Viewer("cesiumContainer",{terrain: Cesium.Terrain.fromWorldTerrain(),})'.replaceAll("(","\\(").replaceAll(")","\\)").replaceAll("\"","\\\\\"")); - expect(dataString).to.match(pattern) + expect(dataString).to.match(pattern); }); }); diff --git a/integration-tests/itwin/create.test.ts b/integration-tests/itwin/create.test.ts index 4e2ae922..f41a64e8 100644 --- a/integration-tests/itwin/create.test.ts +++ b/integration-tests/itwin/create.test.ts @@ -18,12 +18,12 @@ const tests = () => describe('create', () => { const testChildITwinName = `IntegrationTestITwinChild_${new Date().toISOString()}`; const testClass = 'Thing'; const testSubClass = 'Asset'; - const testGeographicLocation= 'San Francisco, CA' - const testDataCenterLocation = 'UK South' - const testStatus = 'Inactive' - const testIanaTimeZone = 'America/Los_Angeles' - const testType = 'Type1' - const testNumber = Math.random().toString(36).slice(2) + const testGeographicLocation= 'San Francisco, CA'; + const testDataCenterLocation = 'UK South'; + const testStatus = 'Inactive'; + const testIanaTimeZone = 'America/Los_Angeles'; + const testType = 'Type1'; + const testNumber = Math.random().toString(36).slice(2); after(async () => { const { result: deleteResult1 } = await runCommand<{result: string}>(`itwin delete --itwin-id ${testITwinChildId}`); @@ -33,7 +33,7 @@ const tests = () => describe('create', () => { expect(deleteResult1).to.have.property('result', 'deleted'); expect(deleteResult2).to.have.property('result', 'deleted'); expect(deleteResult3).to.have.property('result', 'deleted'); - }) + }); it('should create a new iTwin', async () => { const { result: iTwin } = await runCommand(`itwin create --name "${testITwinName1}" --class ${testClass} --sub-class ${testSubClass} --type ${testType} --number ${testNumber}`); diff --git a/integration-tests/itwin/itwin.test.ts b/integration-tests/itwin/itwin.test.ts index 14c6567e..cd1932f4 100644 --- a/integration-tests/itwin/itwin.test.ts +++ b/integration-tests/itwin/itwin.test.ts @@ -8,7 +8,7 @@ import createTests from "./create.test"; import deleteTests from './delete.test'; import infoTests from "./info.test"; import listTests from "./list.test"; -import repositoryTests from "./repository.test" +import repositoryTests from "./repository.test"; import updateTests from "./update.test"; const tests = () => describe('iTwin Integration Tests', () => { diff --git a/integration-tests/itwin/list.test.ts b/integration-tests/itwin/list.test.ts index 7c6049bb..1cf9198e 100644 --- a/integration-tests/itwin/list.test.ts +++ b/integration-tests/itwin/list.test.ts @@ -31,7 +31,7 @@ const tests = () => describe('list', () => { expect(deleteResult1).to.have.property('result', 'deleted'); expect(deleteResult2).to.have.property('result', 'deleted'); expect(deleteResult3).to.have.property('result', 'deleted'); - }) + }); it('should fail when provided bad subClass', async () => { const { error: listError } = await runCommand('itwin list --sub-class InvalidSubClass'); @@ -126,7 +126,7 @@ const tests = () => describe('list', () => { const { result: filteredListResult } = await runCommand(`itwin list --include-inactive --skip 1 --top 2`); const filteredITwinIds = filteredListResult!.map(itwin => itwin.id); expect(filteredITwinIds).to.be.an('array').that.is.not.empty; - expect(filteredITwinIds.toString()).to.be.equal(itwinIds.slice(1, 3).toString()) + expect(filteredITwinIds.toString()).to.be.equal(itwinIds.slice(1, 3).toString()); }); }); diff --git a/integration-tests/itwin/repository.test.ts b/integration-tests/itwin/repository.test.ts index 97a61253..c7995882 100644 --- a/integration-tests/itwin/repository.test.ts +++ b/integration-tests/itwin/repository.test.ts @@ -30,7 +30,7 @@ const tests = () => describe('repository', () => { it('should create a new iTwin repository', async () => { iModelClass = 'GeographicInformationSystem'; iModelSubclass = 'WebMapService'; - iModelUri = 'https://example.com/gis-repo' + iModelUri = 'https://example.com/gis-repo'; const { result: createdITwinRepository } = await runCommand(`itwin repository create --itwin-id ${testITwinId} --class ${iModelClass} --sub-class ${iModelSubclass} --uri ${iModelUri}`); diff --git a/integration-tests/itwin/update.test.ts b/integration-tests/itwin/update.test.ts index fad24d42..d731f6e0 100644 --- a/integration-tests/itwin/update.test.ts +++ b/integration-tests/itwin/update.test.ts @@ -30,8 +30,8 @@ const tests = () => describe('update', () => { const updatedIanaTimeZone = 'America/Los_Angeles'; const updatedDisplayName = 'UpdatedIntegrationTestITwin'; const updatedNumber = Math.random().toString(36).slice(2); - const updatedStatus = 'Trial' - const updatedType = 'Type1' + const updatedStatus = 'Trial'; + const updatedType = 'Type1'; const { result: updatedITwin } = await runCommand(`itwin update --itwin-id ${testITwinId} --geographic-location "${updatedGeographicLocation}" --iana-time-zone ${updatedIanaTimeZone} --name ${updatedDisplayName} --number ${updatedNumber} --status ${updatedStatus} --type ${updatedType}`); diff --git a/integration-tests/main-cases/formatting.test.ts b/integration-tests/main-cases/formatting.test.ts index 1951246f..69b6abda 100644 --- a/integration-tests/main-cases/formatting.test.ts +++ b/integration-tests/main-cases/formatting.test.ts @@ -7,69 +7,69 @@ import { Command, Config } from "@oclif/core"; import { expect } from "chai"; describe('Command formatting tests', async () => { - let allCommands : CommandWithFlags[] = []; + let allCommands : CommandWithFlags[] = []; - const commandToExcludeFromTests = [ - "help", - "plugins" - ]; + const commandToExcludeFromTests = [ + "help", + "plugins" + ]; - before(async () => { - const config = await Config.load({ - devPlugins: false, - root: process.cwd(), - userPlugins: false, - }); - - allCommands = config.commands.filter(command => - !commandToExcludeFromTests.some(excluded => command.id.startsWith(excluded)) && !command.hidden - ).map((command) => - ({ - cmd: command, - flags: Object.entries(command.flags), - })); + before(async () => { + const config = await Config.load({ + devPlugins: false, + root: process.cwd(), + userPlugins: false, }); - it('Should ensure all commands have a description', async () => { - for (const command of allCommands) { - expect(command.cmd.description, `Command '${command.cmd.id}' is missing a description`).to.be.a('string').and.not.be.empty; - } - }); + allCommands = config.commands.filter(command => + !commandToExcludeFromTests.some(excluded => command.id.startsWith(excluded)) && !command.hidden + ).map((command) => + ({ + cmd: command, + flags: Object.entries(command.flags), + })); + }); - it('Should ensure all flags have required properties', async () => { - for (const command of allCommands) { - for (const [flagName, flag] of command.flags) { - expect(flag.description, `Flag '${flagName}' in command '${command.cmd.id}' is missing a description`).to.be.a('string').and.not.be.empty; + it('Should ensure all commands have a description', async () => { + for (const command of allCommands) { + expect(command.cmd.description, `Command '${command.cmd.id}' is missing a description`).to.be.a('string').and.not.be.empty; + } + }); + + it('Should ensure all flags have required properties', async () => { + for (const command of allCommands) { + for (const [flagName, flag] of command.flags) { + expect(flag.description, `Flag '${flagName}' in command '${command.cmd.id}' is missing a description`).to.be.a('string').and.not.be.empty; - if(flag.type === 'option') { - expect(flag, `Flag '${flagName}' in command '${command.cmd.id}' is missing a valid 'helpValue'`).to.have.property('helpValue').to.be.a('string').and.not.be.empty; - } - } + if(flag.type === 'option') { + expect(flag, `Flag '${flagName}' in command '${command.cmd.id}' is missing a valid 'helpValue'`).to.have.property('helpValue').to.be.a('string').and.not.be.empty; } - }); + } + } + }); - it('Should ensure all itwin-id flags have env properties', async () => { - // Exclude context:set command from this test as it has a special case for itwin-id flag - for (const command of allCommands.filter(cmd => cmd.cmd.id !== "context:set")) { - const iTwinIdFlag = command.flags.find(([name, _]) => name === "itwin-id"); - if (iTwinIdFlag) { - expect(iTwinIdFlag[1].env, `Flag 'itwin-id' in command '${command.cmd.id}' is missing the 'env' property`).to.be.a('string').and.be.equals("ITP_ITWIN_ID"); - } - } - }); + it('Should ensure all itwin-id flags have env properties', async () => { + // Exclude context:set command from this test as it has a special case for itwin-id flag + for (const command of allCommands.filter(cmd => cmd.cmd.id !== "context:set")) { + const iTwinIdFlag = command.flags.find(([name, _]) => name === "itwin-id"); + if (iTwinIdFlag) { + expect(iTwinIdFlag[1].env, `Flag 'itwin-id' in command '${command.cmd.id}' is missing the 'env' property`).to.be.a('string').and.be.equals("ITP_ITWIN_ID"); + } + } + }); - it('Should ensure all imodel-id flags have env properties', async () => { - // Exclude context:set command from this test as it has a special case for imodel-id flag - for (const command of allCommands.filter(cmd => cmd.cmd.id !== "context:set")) { - const iTwinIdFlag = command.flags.find(([name, _]) => name === "imodel-id"); - if (iTwinIdFlag) { - expect(iTwinIdFlag[1].env, `Flag 'imodel-id' in command '${command.cmd.id}' is missing the 'env' property`).to.be.a('string').and.be.equals("ITP_IMODEL_ID"); - } - } - }); + it('Should ensure all imodel-id flags have env properties', async () => { + // Exclude context:set command from this test as it has a special case for imodel-id flag + for (const command of allCommands.filter(cmd => cmd.cmd.id !== "context:set")) { + const iTwinIdFlag = command.flags.find(([name, _]) => name === "imodel-id"); + if (iTwinIdFlag) { + expect(iTwinIdFlag[1].env, `Flag 'imodel-id' in command '${command.cmd.id}' is missing the 'env' property`).to.be.a('string').and.be.equals("ITP_IMODEL_ID"); + } + } + }); }); -type CommandWithFlags = { - cmd: Command.Loadable; - flags: [string, Command.Flag.Cached][]; +interface CommandWithFlags { + cmd: Command.Loadable; + flags: [string, Command.Flag.Cached][]; } \ No newline at end of file diff --git a/integration-tests/main-cases/native-client-parallel/imodel-connection-run.test.ts b/integration-tests/main-cases/native-client-parallel/imodel-connection-run.test.ts index 26531de3..34aae371 100644 --- a/integration-tests/main-cases/native-client-parallel/imodel-connection-run.test.ts +++ b/integration-tests/main-cases/native-client-parallel/imodel-connection-run.test.ts @@ -6,5 +6,5 @@ import iModelConnectionRunTests from '../../imodel/connection/run.test'; describe('Native Client Tests (imodel connection run)', async () => { - iModelConnectionRunTests(); + iModelConnectionRunTests(); }); \ No newline at end of file diff --git a/integration-tests/main-cases/native-client-parallel/imodel-populate.test.ts b/integration-tests/main-cases/native-client-parallel/imodel-populate.test.ts index 1304e635..d7acdb1d 100644 --- a/integration-tests/main-cases/native-client-parallel/imodel-populate.test.ts +++ b/integration-tests/main-cases/native-client-parallel/imodel-populate.test.ts @@ -6,5 +6,5 @@ import iModelPopulateTests from '../../imodel/populate.test'; describe('Native Client Tests (imodel populate)', async () => { - iModelPopulateTests(); + iModelPopulateTests(); }); \ No newline at end of file diff --git a/integration-tests/main-cases/native-client-parallel/named-version.test.ts b/integration-tests/main-cases/native-client-parallel/named-version.test.ts index 499867e3..c11a378a 100644 --- a/integration-tests/main-cases/native-client-parallel/named-version.test.ts +++ b/integration-tests/main-cases/native-client-parallel/named-version.test.ts @@ -6,5 +6,5 @@ import iModelNamedVersionTests from '../../imodel/named-version.test'; describe('Native Client Tests (imodel named-version)', async () => { - iModelNamedVersionTests(); + iModelNamedVersionTests(); }); \ No newline at end of file diff --git a/integration-tests/main-cases/native-client-parallel/short-running.test.ts b/integration-tests/main-cases/native-client-parallel/short-running.test.ts index 1bcfda0c..9ffc05e9 100644 --- a/integration-tests/main-cases/native-client-parallel/short-running.test.ts +++ b/integration-tests/main-cases/native-client-parallel/short-running.test.ts @@ -3,14 +3,14 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import accessControlNativeTests from '../../access-control-native/access-control-native.test' +import accessControlNativeTests from '../../access-control-native/access-control-native.test'; import imodelConnectionCreateNativeTests from '../../imodel-native/connection/create.test'; import userSearchNativeTests from '../../user-native/search.test'; import sharedQuickUseCasesParallel from '../shared-quick-use-cases-parallel'; describe('Native Client Tests', async () => { - accessControlNativeTests(); - imodelConnectionCreateNativeTests(); - userSearchNativeTests(); - sharedQuickUseCasesParallel(); + accessControlNativeTests(); + imodelConnectionCreateNativeTests(); + userSearchNativeTests(); + sharedQuickUseCasesParallel(); }); \ No newline at end of file diff --git a/integration-tests/main-cases/native-client-serial.test.ts b/integration-tests/main-cases/native-client-serial.test.ts index 76af5712..3ee4d1d4 100644 --- a/integration-tests/main-cases/native-client-serial.test.ts +++ b/integration-tests/main-cases/native-client-serial.test.ts @@ -3,17 +3,17 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import authTests from '../auth/auth.test' -import iModelConnectionAuthTests from '../imodel-native/connection/auth.test' +import authTests from '../auth/auth.test'; +import iModelConnectionAuthTests from '../imodel-native/connection/auth.test'; import { nativeLoginToCli } from '../utils/helpers'; describe('Native Client Tests (serial)', async () => { - describe('Authentication Integration Tests', async () => { - after(async () => { - await nativeLoginToCli(); - }) + describe('Authentication Integration Tests', async () => { + after(async () => { + await nativeLoginToCli(); + }); - authTests(); - }) - iModelConnectionAuthTests(); + authTests(); + }); + iModelConnectionAuthTests(); }); \ No newline at end of file diff --git a/integration-tests/main-cases/service-client-parallel/imodel-connection-run.test.ts b/integration-tests/main-cases/service-client-parallel/imodel-connection-run.test.ts index 674ac4b4..3c43d9cf 100644 --- a/integration-tests/main-cases/service-client-parallel/imodel-connection-run.test.ts +++ b/integration-tests/main-cases/service-client-parallel/imodel-connection-run.test.ts @@ -6,5 +6,5 @@ import iModelConnectionRunTests from '../../imodel/connection/run.test'; describe('Service Client Tests (imodel connection run)', async () => { - iModelConnectionRunTests(); + iModelConnectionRunTests(); }); \ No newline at end of file diff --git a/integration-tests/main-cases/service-client-parallel/imodel-populate.test.ts b/integration-tests/main-cases/service-client-parallel/imodel-populate.test.ts index a19233b6..ef5c8e57 100644 --- a/integration-tests/main-cases/service-client-parallel/imodel-populate.test.ts +++ b/integration-tests/main-cases/service-client-parallel/imodel-populate.test.ts @@ -6,5 +6,5 @@ import iModelPopulateTests from '../../imodel/populate.test'; describe('Service Client Tests (imodel populate)', async () => { - iModelPopulateTests(); + iModelPopulateTests(); }); \ No newline at end of file diff --git a/integration-tests/main-cases/service-client-parallel/named-version.test.ts b/integration-tests/main-cases/service-client-parallel/named-version.test.ts index 6f9ba0e7..9a9f193a 100644 --- a/integration-tests/main-cases/service-client-parallel/named-version.test.ts +++ b/integration-tests/main-cases/service-client-parallel/named-version.test.ts @@ -6,5 +6,5 @@ import iModelNamedVersionTests from '../../imodel/named-version.test'; describe('Service Client Tests (imodel named-version)', () => { - iModelNamedVersionTests(); + iModelNamedVersionTests(); }); \ No newline at end of file diff --git a/integration-tests/main-cases/service-client-parallel/short-running.test.ts b/integration-tests/main-cases/service-client-parallel/short-running.test.ts index 3f2a7a38..b16a8f78 100644 --- a/integration-tests/main-cases/service-client-parallel/short-running.test.ts +++ b/integration-tests/main-cases/service-client-parallel/short-running.test.ts @@ -3,10 +3,10 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import imodelConnectionCreateServiceTests from '../../imodel-service/connection/create.test' +import imodelConnectionCreateServiceTests from '../../imodel-service/connection/create.test'; import sharedQuickUseCasesParallel from '../shared-quick-use-cases-parallel'; describe('Service Client Tests', () => { - imodelConnectionCreateServiceTests(); - sharedQuickUseCasesParallel(); + imodelConnectionCreateServiceTests(); + sharedQuickUseCasesParallel(); }); \ No newline at end of file diff --git a/integration-tests/main-cases/service-client-serial.test.ts b/integration-tests/main-cases/service-client-serial.test.ts index 3ec6c8ea..2b7cc5e4 100644 --- a/integration-tests/main-cases/service-client-serial.test.ts +++ b/integration-tests/main-cases/service-client-serial.test.ts @@ -3,12 +3,12 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import authTests from '../auth/auth.test' -import authTestsService from '../auth-service/auth-service.test' +import authTests from '../auth/auth.test'; +import authTestsService from '../auth-service/auth-service.test'; describe('Service Client Tests (serial)', () => { - describe('Authentication Integration Tests', () => { - authTestsService(); - authTests(); - }); + describe('Authentication Integration Tests', () => { + authTestsService(); + authTests(); + }); }); \ No newline at end of file diff --git a/integration-tests/main-cases/shared-quick-use-cases-parallel.ts b/integration-tests/main-cases/shared-quick-use-cases-parallel.ts index 4654ff96..3f40821c 100644 --- a/integration-tests/main-cases/shared-quick-use-cases-parallel.ts +++ b/integration-tests/main-cases/shared-quick-use-cases-parallel.ts @@ -3,24 +3,24 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import accessControlTests from '../access-control/access-control.test' -import apiTests from '../api.test' -import changedElementsTests from '../changed-elements/changed-elements.test' -import contextTests from '../context/context.test' -import imodelTests from '../imodel/imodel.test' -import itwinTests from '../itwin/itwin.test' -import storageTests from '../storage/storage.test' -import userTests from '../user/user.test' +import accessControlTests from '../access-control/access-control.test'; +import apiTests from '../api.test'; +import changedElementsTests from '../changed-elements/changed-elements.test'; +import contextTests from '../context/context.test'; +import imodelTests from '../imodel/imodel.test'; +import itwinTests from '../itwin/itwin.test'; +import storageTests from '../storage/storage.test'; +import userTests from '../user/user.test'; const sharedQuickUseCasesParallel = () => { - accessControlTests(); - apiTests(); - changedElementsTests(); - contextTests(); - imodelTests(); - itwinTests(); - storageTests(); - userTests(); -} + accessControlTests(); + apiTests(); + changedElementsTests(); + contextTests(); + imodelTests(); + itwinTests(); + storageTests(); + userTests(); +}; export default sharedQuickUseCasesParallel; \ No newline at end of file diff --git a/integration-tests/storage/file/list.test.ts b/integration-tests/storage/file/list.test.ts index 92e36c38..21e7d938 100644 --- a/integration-tests/storage/file/list.test.ts +++ b/integration-tests/storage/file/list.test.ts @@ -27,7 +27,7 @@ const tests = () => describe('list', () => { const testITwin = await createITwin(`cli-itwin-integration-test-${new Date().toISOString()}`, 'Thing', 'Asset'); testITwinId = testITwin.id as string; rootFolderId = await getRootFolderId(testITwinId); - const testFolder = await createFolder(rootFolderId, "IntegrationTestFolder", "Test description") + const testFolder = await createFolder(rootFolderId, "IntegrationTestFolder", "Test description"); testFolderId = testFolder.id as string; const testFile = await createFile(rootFolderId, testFileName, testFilePath); testFileId = testFile.id as string; diff --git a/integration-tests/storage/folder/create-delete.test.ts b/integration-tests/storage/folder/create-delete.test.ts index 77cc65cb..b59d90b7 100644 --- a/integration-tests/storage/folder/create-delete.test.ts +++ b/integration-tests/storage/folder/create-delete.test.ts @@ -34,7 +34,7 @@ const tests = () => describe('create + delete', () => { it('should create a new folder', async () => { const rootFolderId = await getRootFolderId(testITwinId); const displayName = 'IntegrationTestFolder'; - const description = 'Test description' + const description = 'Test description'; const createdFolder = await createFolder(rootFolderId, displayName, description); diff --git a/integration-tests/storage/root-folder.test.ts b/integration-tests/storage/root-folder.test.ts index 0db3b918..21475962 100644 --- a/integration-tests/storage/root-folder.test.ts +++ b/integration-tests/storage/root-folder.test.ts @@ -21,7 +21,7 @@ const tests = () => describe('root-folder', () => { before(async () => { testITwin = await createITwin(`cli-itwin-integration-test-${new Date().toISOString()}`, 'Thing', 'Asset'); - rootFolderId = await getRootFolderId(testITwin.id as string) as string; + rootFolderId = await getRootFolderId(testITwin.id!); testFolder = await createFolder(rootFolderId, 'IntegrationTestFolder', 'Test description'); testFile = await createFile(rootFolderId, 'test.zip', 'integration-tests/test.zip'); }); @@ -45,8 +45,8 @@ const tests = () => describe('root-folder', () => { expect(rootFolder?._links?.folder?.href).to.be.a('string'); // check helper function - const rootFolderId = await getRootFolderId(testITwin.id!); - expect(rootFolder!._links!.folder!.href).to.contain(rootFolderId); + const fetchedRootFolderId = await getRootFolderId(testITwin.id!); + expect(rootFolder!._links!.folder!.href).to.contain(fetchedRootFolderId); }); it('should get the root folder with 2nd item only', async () => { @@ -61,8 +61,8 @@ const tests = () => describe('root-folder', () => { expect(rootFolder!._links!.folder!.href).to.be.a('string'); // check helper function - const rootFolderId = await getRootFolderId(testITwin.id as string); - expect(rootFolder!._links!.folder!.href).to.contain(rootFolderId); + const fetchedRootFolderId = await getRootFolderId(testITwin.id!); + expect(rootFolder!._links!.folder!.href).to.contain(fetchedRootFolderId); }); }); diff --git a/integration-tests/user/info.test.ts b/integration-tests/user/info.test.ts index 6f66683b..7fa28131 100644 --- a/integration-tests/user/info.test.ts +++ b/integration-tests/user/info.test.ts @@ -32,14 +32,14 @@ const tests = () => describe('info', () => { }); it('should return an error for too many user IDs', async () => { - let command = "user info" + let command = "user info"; for(let i = 0; i < 1001; i++) { - command += ` --user-id ${crypto.randomUUID()}` + command += ` --user-id ${crypto.randomUUID()}`; } const { error } = await runCommand(command); expect(error).to.be.not.undefined; - expect(error?.message).to.be.equal('A maximum of 1000 user IDs can be provided.') + expect(error?.message).to.be.equal('A maximum of 1000 user IDs can be provided.'); }); }); diff --git a/integration-tests/user/user.test.ts b/integration-tests/user/user.test.ts index f2ecbeba..797df0eb 100644 --- a/integration-tests/user/user.test.ts +++ b/integration-tests/user/user.test.ts @@ -5,7 +5,7 @@ import runSuiteIfMainModule from "../utils/run-suite-if-main-module"; import infoTests from "./info.test"; -import meTests from "./me.test" +import meTests from "./me.test"; import searchTests from "./search.test"; const tests = () => describe('User Integration Tests', () => { diff --git a/integration-tests/utils/environment.ts b/integration-tests/utils/environment.ts index 8f969695..6be733af 100644 --- a/integration-tests/utils/environment.ts +++ b/integration-tests/utils/environment.ts @@ -3,13 +3,13 @@ import * as dotenv from 'dotenv'; dotenv.config({path: '.env'}); export const { - ITP_API_URL, - ITP_ISSUER_URL, - ITP_MAILINATOR_API_KEY, - ITP_NATIVE_TEST_CLIENT_ID, - ITP_SERVICE_CLIENT_ID, - ITP_TEST_USER_EMAIL, - ITP_TEST_USER_EXTERNAL, - ITP_TEST_USER_PASSWORD, - ITP_TEST_USER_SAMEORG, + ITP_API_URL, + ITP_ISSUER_URL, + ITP_MAILINATOR_API_KEY, + ITP_NATIVE_TEST_CLIENT_ID, + ITP_SERVICE_CLIENT_ID, + ITP_TEST_USER_EMAIL, + ITP_TEST_USER_EXTERNAL, + ITP_TEST_USER_PASSWORD, + ITP_TEST_USER_SAMEORG, } = process.env; \ No newline at end of file diff --git a/integration-tests/utils/helpers.ts b/integration-tests/utils/helpers.ts index d938bbb2..613aa2af 100644 --- a/integration-tests/utils/helpers.ts +++ b/integration-tests/utils/helpers.ts @@ -3,15 +3,15 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import { IModel } from "@itwin/imodels-client-management" +import { IModel } from "@itwin/imodels-client-management"; import { ITwin } from "@itwin/itwins-client"; -import { TestBrowserAuthorizationClientConfiguration, TestUserCredentials, getTestAccessToken } from "@itwin/oidc-signin-tool"; +import { getTestAccessToken, TestBrowserAuthorizationClientConfiguration, TestUserCredentials } from "@itwin/oidc-signin-tool"; import { runCommand } from "@oclif/test"; import { expect } from "chai"; import * as dotenv from 'dotenv'; -import { GetInboxRequest, GetMessageRequest, MailinatorClient } from 'mailinator-client' -import fs from "node:fs" -import os from 'node:os' +import { GetInboxRequest, GetMessageRequest, MailinatorClient } from 'mailinator-client'; +import fs from "node:fs"; +import os from 'node:os'; import { inflate } from "pako"; import { FileTyped } from "../../src/services/storage-client/models/file-typed.js"; @@ -21,88 +21,88 @@ import { ItemsWithFolderLink } from "../../src/services/storage-client/models/it import { ITP_ISSUER_URL, ITP_MAILINATOR_API_KEY, ITP_NATIVE_TEST_CLIENT_ID, ITP_TEST_USER_EMAIL, ITP_TEST_USER_PASSWORD } from "./environment.js"; export async function serviceLoginToCli() { - const result = await runCommand('auth login'); - expect(result.stdout).to.contain('User successfully logged in using Service login'); + const result = await runCommand('auth login'); + expect(result.stdout).to.contain('User successfully logged in using Service login'); } export async function createFile(folderId: string, displayName: string, filePath: string, description?: string): Promise { - // 1. Create meta data - const {result: createdFile} = await runCommand(`storage file create --folder-id ${folderId} --name "${displayName}" --description "${description}"`); + // 1. Create meta data + const {result: createdFile} = await runCommand(`storage file create --folder-id ${folderId} --name "${displayName}" --description "${description}"`); - expect(createdFile).to.have.property('_links'); - expect(createdFile!._links).to.have.property('completeUrl'); - expect(createdFile!._links).to.have.property('uploadUrl'); - const uploadUrl = createdFile!._links!.uploadUrl!.href; + expect(createdFile).to.have.property('_links'); + expect(createdFile!._links).to.have.property('completeUrl'); + expect(createdFile!._links).to.have.property('uploadUrl'); + const uploadUrl = createdFile!._links!.uploadUrl!.href; - // extract file id from completeUrl that looks like this: "https://api.bentley.com/storage/files/TYJsPN0xtkWId0yUrXkS5pN5AQzuullIkxz5aDnDJSI/complete" - const completeUrl = createdFile!._links!.completeUrl!.href; - const fileId = completeUrl!.split('/').at(-2); + // extract file id from completeUrl that looks like this: "https://api.bentley.com/storage/files/TYJsPN0xtkWId0yUrXkS5pN5AQzuullIkxz5aDnDJSI/complete" + const completeUrl = createdFile!._links!.completeUrl!.href; + const fileId = completeUrl!.split('/').at(-2); - // 2. Upload file - const { result: uploadedFile } = await runCommand<{result: string}>(`storage file upload --upload-url "${uploadUrl}" --file-path ${filePath}`); + // 2. Upload file + const { result: uploadedFile } = await runCommand<{result: string}>(`storage file upload --upload-url "${uploadUrl}" --file-path ${filePath}`); - expect(uploadedFile).to.have.property('result', 'uploaded'); + expect(uploadedFile).to.have.property('result', 'uploaded'); - // 3. Confirm upload complete - const {result: completedFile} = await runCommand(`storage file update-complete --file-id ${fileId}`) + // 3. Confirm upload complete + const {result: completedFile} = await runCommand(`storage file update-complete --file-id ${fileId}`); - expect(completedFile).to.not.be.undefined; - expect(completedFile).to.have.property('id', fileId); + expect(completedFile).to.not.be.undefined; + expect(completedFile).to.have.property('id', fileId); - return completedFile as FileTyped; + return completedFile as FileTyped; } export async function createFolder(parentFolderId: string, displayName: string, description?: string): Promise { - const { result: createdFolder } = await runCommand(`storage folder create --parent-folder-id ${parentFolderId} --name "${displayName}" --description "${description}"`); + const { result: createdFolder } = await runCommand(`storage folder create --parent-folder-id ${parentFolderId} --name "${displayName}" --description "${description}"`); - expect(createdFolder).to.not.be.undefined; - expect(createdFolder!.type).to.be.equal('folder'); - expect(createdFolder!.displayName).to.be.equal(displayName); - expect(createdFolder!.parentFolderId).to.be.equal(parentFolderId); - return createdFolder as FolderTyped; + expect(createdFolder).to.not.be.undefined; + expect(createdFolder!.type).to.be.equal('folder'); + expect(createdFolder!.displayName).to.be.equal(displayName); + expect(createdFolder!.parentFolderId).to.be.equal(parentFolderId); + return createdFolder as FolderTyped; } export async function createITwin(displayName: string, classType: string, subClassType: string): Promise { - const { result: createdITwin } = await runCommand(`itwin create --name "${displayName}" --class ${classType} --sub-class ${subClassType}`); + const { result: createdITwin } = await runCommand(`itwin create --name "${displayName}" --class ${classType} --sub-class ${subClassType}`); - expect(createdITwin).to.not.be.undefined; - expect(createdITwin).to.have.property('id'); - return createdITwin as ITwin; + expect(createdITwin).to.not.be.undefined; + expect(createdITwin).to.have.property('id'); + return createdITwin as ITwin; } export async function createIModel(name: string, iTwinId: string): Promise { - const { result: createdIModel} = await runCommand(`imodel create --itwin-id ${iTwinId} --name "${name}"`); + const { result: createdIModel} = await runCommand(`imodel create --itwin-id ${iTwinId} --name "${name}"`); - expect(createdIModel).to.not.be.undefined; - expect(createdIModel).to.have.property('id'); - return createdIModel as IModel; + expect(createdIModel).to.not.be.undefined; + expect(createdIModel).to.have.property('id'); + return createdIModel as IModel; } export async function deleteFile(fileId: string): Promise { - const { result: deleteResult } = await runCommand<{result: string}>(`storage file delete --file-id ${fileId}`); - expect(deleteResult).to.have.property('result', 'deleted'); + const { result: deleteResult } = await runCommand<{result: string}>(`storage file delete --file-id ${fileId}`); + expect(deleteResult).to.have.property('result', 'deleted'); } export async function deleteFolder(folderId: string): Promise { - const { result: deleteResult } = await runCommand<{result: string}>(`storage folder delete --folder-id ${folderId}`); - expect(deleteResult).to.have.property('result', 'deleted'); + const { result: deleteResult } = await runCommand<{result: string}>(`storage folder delete --folder-id ${folderId}`); + expect(deleteResult).to.have.property('result', 'deleted'); } export async function deleteITwin(id: string): Promise { - const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${id}`); - expect(deleteResult).to.have.property('result', 'deleted'); + const { result: deleteResult } = await runCommand<{result: string}>(`itwin delete --itwin-id ${id}`); + expect(deleteResult).to.have.property('result', 'deleted'); } export async function deleteIModel(id: string): Promise { - const { result: deleteResult } = await runCommand<{result: string}>(`imodel delete --imodel-id ${id}`); - expect(deleteResult).to.have.property('result', 'deleted'); + const { result: deleteResult } = await runCommand<{result: string}>(`imodel delete --imodel-id ${id}`); + expect(deleteResult).to.have.property('result', 'deleted'); } export async function getRootFolderId(iTwinId: string): Promise { - const { result: topFolders } = await runCommand(`storage root-folder --itwin-id ${iTwinId}`); - const rootFolderId = topFolders?._links?.folder?.href?.split('/').pop(); - expect(rootFolderId).to.not.be.undefined; - return rootFolderId as string; + const { result: topFolders } = await runCommand(`storage root-folder --itwin-id ${iTwinId}`); + const rootFolderId = topFolders?._links?.folder?.href?.split('/').pop(); + expect(rootFolderId).to.not.be.undefined; + return rootFolderId as string; } /** @@ -113,110 +113,110 @@ export async function getRootFolderId(iTwinId: string): Promise { * @returns Invitation link for joining the iTwin. */ export async function fetchEmailsAndGetInvitationLink(inbox: string, iTwinName: string): Promise { - await new Promise(resolve => {setTimeout(_ => resolve(), 45 * 1000);}); + await new Promise(resolve => {setTimeout(_ => resolve(), 45 * 1000);}); - expect(ITP_MAILINATOR_API_KEY).to.not.be.undefined; + expect(ITP_MAILINATOR_API_KEY).to.not.be.undefined; - const client = new MailinatorClient(ITP_MAILINATOR_API_KEY); - const inboxResponse = await client.request(new GetInboxRequest("private", inbox, undefined, 10)); - expect(inboxResponse.result).to.not.be.null; + const client = new MailinatorClient(ITP_MAILINATOR_API_KEY); + const inboxResponse = await client.request(new GetInboxRequest("private", inbox, undefined, 10)); + expect(inboxResponse.result).to.not.be.null; - for (let i = 0; i < inboxResponse.result!.msgs.length; i++) { - if (inboxResponse.result!.msgs[i].subject !== "You have been invited to collaborate") - continue; + for (const message of inboxResponse.result!.msgs) { + if (message.subject !== "You have been invited to collaborate") + continue; - // eslint-disable-next-line no-await-in-loop - const messageResponse = await client.request(new GetMessageRequest("private", inboxResponse.result!.msgs[i].id )); - expect(messageResponse.result).to.not.be.null; - const messageBody = messageResponse.result!.parts[0].body; - if (!messageBody.includes(iTwinName)) - continue; - - const invitationTokenRegex = /href=".*?invitationToken.*?"/; - const matches = messageBody.match(invitationTokenRegex); - expect(matches).to.not.be.null; - expect(matches).to.have.lengthOf(1); - return matches![0].slice("href=\"".length, -1); - } - - throw new Error("Email was not found in inbox.") + + const messageResponse = await client.request(new GetMessageRequest("private", message.id)); + expect(messageResponse.result).to.not.be.null; + const messageBody = messageResponse.result!.parts[0].body; + if (!messageBody.includes(iTwinName)) + continue; + + const invitationTokenRegex = /href=".*?invitationToken.*?"/; + const matches = messageBody.match(invitationTokenRegex); + expect(matches).to.not.be.null; + expect(matches).to.have.lengthOf(1); + return matches![0].slice("href=\"".length, -1); + } + + throw new Error("Email was not found in inbox."); } export async function nativeLoginToCli() { - if(isNativeAuthAccessTokenCached()) - return; - - const authTokenObject = { - authToken: await getNativeAuthAccessToken(), - authenticationType: "Interactive", - expirationDate: new Date(Date.now() + 1000 * 60 * 59), - manuallyWritten: true - } + if(isNativeAuthAccessTokenCached()) + return; + + const authTokenObject = { + authToken: await getNativeAuthAccessToken(), + authenticationType: "Interactive", + expirationDate: new Date(Date.now() + 1000 * 60 * 59), + manuallyWritten: true + }; - fs.writeFileSync(getTokenPathByOS(), JSON.stringify(authTokenObject), 'utf8'); + fs.writeFileSync(getTokenPathByOS(), JSON.stringify(authTokenObject), 'utf8'); } export async function logoutFromCLI() { - const result = await runCommand('auth logout'); - expect(result.stdout).to.contain('User successfully logged out'); + const result = await runCommand('auth logout'); + expect(result.stdout).to.contain('User successfully logged out'); } const getNativeAuthAccessToken = async (): Promise => { - dotenv.config({path: '.env'}); - expect(ITP_NATIVE_TEST_CLIENT_ID, "ITP_NATIVE_TEST_CLIENT_ID").to.not.be.undefined; - expect(ITP_ISSUER_URL, "ITP_ISSUER_URL").to.not.be.undefined; - const config: TestBrowserAuthorizationClientConfiguration = { - authority: ITP_ISSUER_URL, - clientId: ITP_NATIVE_TEST_CLIENT_ID!, - redirectUri: "http://localhost:3301/signin-callback", - scope: "itwin-platform", - } - - expect(ITP_TEST_USER_EMAIL, "ITP_TEST_USER_EMAIL").to.not.be.undefined; - expect(ITP_TEST_USER_PASSWORD, "ITP_TEST_USER_PASSWORD").to.not.be.undefined; - const user: TestUserCredentials = { - email: ITP_TEST_USER_EMAIL!, - password: ITP_TEST_USER_PASSWORD! - } - - const accessToken = await getTestAccessToken(config, user); - expect(accessToken, "Access token").to.not.be.undefined; - return accessToken!; -} + dotenv.config({path: '.env'}); + expect(ITP_NATIVE_TEST_CLIENT_ID, "ITP_NATIVE_TEST_CLIENT_ID").to.not.be.undefined; + expect(ITP_ISSUER_URL, "ITP_ISSUER_URL").to.not.be.undefined; + const config: TestBrowserAuthorizationClientConfiguration = { + authority: ITP_ISSUER_URL, + clientId: ITP_NATIVE_TEST_CLIENT_ID!, + redirectUri: "http://localhost:3301/signin-callback", + scope: "itwin-platform", + }; + + expect(ITP_TEST_USER_EMAIL, "ITP_TEST_USER_EMAIL").to.not.be.undefined; + expect(ITP_TEST_USER_PASSWORD, "ITP_TEST_USER_PASSWORD").to.not.be.undefined; + const user: TestUserCredentials = { + email: ITP_TEST_USER_EMAIL!, + password: ITP_TEST_USER_PASSWORD! + }; + + const accessToken = await getTestAccessToken(config, user); + expect(accessToken, "Access token").to.not.be.undefined; + return accessToken!; +}; export const isNativeAuthAccessTokenCached = (): boolean => { - const tokenPath = getTokenPathByOS(); - if(fs.existsSync(tokenPath)) { - const tokenJson = fs.readFileSync(tokenPath, 'utf8'); - const tokenObj = JSON.parse(tokenJson); - if (tokenObj.manuallyWritten !== undefined && new Date(tokenObj.expirationDate).getTime() > Date.now()) - return true; - fs.rmSync(tokenPath); + const tokenPath = getTokenPathByOS(); + if(fs.existsSync(tokenPath)) { + const tokenJson = fs.readFileSync(tokenPath, 'utf8'); + const tokenObj = JSON.parse(tokenJson); + if (tokenObj.manuallyWritten !== undefined && new Date(tokenObj.expirationDate).getTime() > Date.now()) + return true; + fs.rmSync(tokenPath); + } + + return false; +}; + +const getTokenPathByOS = () => { + switch (os.type()) { + case 'Linux': { + const cachePath = `${os.homedir()}/.cache/itp`; + if(!fs.existsSync(cachePath)) + fs.mkdirSync(cachePath, {recursive: true}); + return `${cachePath}/token.json`; } - return false; -} + case 'Windows_NT': { + return `${process.env.LOCALAPPDATA}/itp/token.json`; + } -const getTokenPathByOS = () => { - switch (os.type()) { - case 'Linux': { - const cachePath = `${os.homedir()}/.cache/itp` - if(!fs.existsSync(cachePath)) - fs.mkdirSync(cachePath, {recursive: true}) - return `${cachePath}/token.json` - } - - case 'Windows_NT': { - return `${process.env.LOCALAPPDATA}/itp/token.json` - } - - default: { - throw new Error("Unknown OS"); - } + default: { + throw new Error("Unknown OS"); } -} + } +}; export const decodeCompressedBase64 = (base64String: string) => { - const buffer = Buffer.from(base64String!, "base64"); - return inflate(buffer, {raw: true, to: 'string'}); -} \ No newline at end of file + const buffer = Buffer.from(base64String, "base64"); + return inflate(buffer, {raw: true, to: 'string'}); +}; \ No newline at end of file diff --git a/integration-tests/utils/mocha-global-setup-native.ts b/integration-tests/utils/mocha-global-setup-native.ts index ff62735d..f7767dce 100644 --- a/integration-tests/utils/mocha-global-setup-native.ts +++ b/integration-tests/utils/mocha-global-setup-native.ts @@ -5,8 +5,10 @@ import { AuthInfo } from '../../src/services/synchronizationClient/models/connec import { nativeLoginToCli } from "./helpers"; export async function mochaGlobalSetup() { - await nativeLoginToCli(); - const { result } = await runCommand(`imodel connection auth`); - expect(result?.isUserAuthorized).to.be.equal(true); - console.log("\n\nRunning tests with native client") + await nativeLoginToCli(); + const { result } = await runCommand(`imodel connection auth`); + expect(result?.isUserAuthorized).to.be.equal(true); + + // eslint-disable-next-line no-console + console.log("\n\nRunning tests with native client"); } \ No newline at end of file diff --git a/integration-tests/utils/mocha-global-setup-service.ts b/integration-tests/utils/mocha-global-setup-service.ts index 31605d9e..fe87d6e7 100644 --- a/integration-tests/utils/mocha-global-setup-service.ts +++ b/integration-tests/utils/mocha-global-setup-service.ts @@ -1,7 +1,9 @@ import { logoutFromCLI, serviceLoginToCli } from "./helpers"; export async function mochaGlobalSetup() { - await logoutFromCLI(); - await serviceLoginToCli(); - console.log("\n\nRunning tests with service client") + await logoutFromCLI(); + await serviceLoginToCli(); + + // eslint-disable-next-line no-console + console.log("\n\nRunning tests with service client"); } \ No newline at end of file diff --git a/integration-tests/utils/result-response.ts b/integration-tests/utils/result-response.ts index 4edea18b..37d6947b 100644 --- a/integration-tests/utils/result-response.ts +++ b/integration-tests/utils/result-response.ts @@ -1,3 +1,3 @@ -export type ResultResponse = { - result: string; +export interface ResultResponse { + result: string; } \ No newline at end of file diff --git a/integration-tests/utils/run-suite-if-main-module.ts b/integration-tests/utils/run-suite-if-main-module.ts index 3597e656..74e651d5 100644 --- a/integration-tests/utils/run-suite-if-main-module.ts +++ b/integration-tests/utils/run-suite-if-main-module.ts @@ -13,40 +13,39 @@ import {fileURLToPath} from 'node:url'; * @returns `true`, if the current file is not an import, otherwise `false` */ function isMainModule(meta: {url: string}) { - for (const arg of process.argv) { - if(arg.match(/integration-tests(\/|\\).*\.test\.ts/) === null) { - continue; - } + for (const arg of process.argv) { + if(arg.match(/integration-tests(\/|\\).*\.test\.ts/) === null) { + continue; + } - if (!meta || !arg) { - return false; - } + if (!meta || !arg) { + return false; + } - const currentFilePath = fileURLToPath(meta.url) - .replaceAll("\\", "/"); + const currentFilePath = fileURLToPath(meta.url) + .replaceAll("\\", "/"); - const mainFilePath = arg; - const mainFilePathRegex = mainFilePath - .replaceAll("\\", "/") - .replaceAll(".", "\\.") - .replaceAll("**", ".*?") - .replaceAll("*", ".*?"); + const mainFilePath = arg; + const mainFilePathRegex = mainFilePath + .replaceAll("\\", "/") + .replaceAll(".", "\\.") + .replaceAll("**", ".*?") + .replaceAll("*", ".*?"); - if(currentFilePath.match(mainFilePathRegex) !== null) - return true; - } + if(currentFilePath.match(mainFilePathRegex) !== null) + return true; + } - return false; + return false; } -// eslint-disable-next-line valid-jsdoc /** * Run the provided test suite if provided meta object is main module. * @param meta Provided `import.meta` object. * @param testSuite Test suite that should be executed. */ export default function runSuiteIfMainModule(meta: {url: string}, testSuite: () => Mocha.Suite): void { - if (isMainModule(meta)) { - testSuite(); - } + if (isMainModule(meta)) { + testSuite(); + } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0c0920b8..a3672f3d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,24 +30,25 @@ "itp": "bin/run.js" }, "devDependencies": { + "@eslint/js": "^9.28.0", + "@itwin/eslint-plugin": "^5.2.1", "@itwin/oidc-signin-tool": "^4.4.1", "@oclif/prettier-config": "^0.2.1", "@oclif/test": "^4", + "@stylistic/eslint-plugin": "^4.4.1", "@types/chai": "^4", "@types/mocha": "^10", "@types/node": "^18.19.64", "@types/pako": "^2.0.3", "chai": "^4", - "eslint": "^8", - "eslint-config-oclif": "^5", - "eslint-config-oclif-typescript": "^3", - "eslint-config-prettier": "^9", + "eslint": "^9.28.0", "mailinator-client": "^1.0.5", "mocha": "^10", "oclif": "^4", "shx": "^0.3.3", "ts-node": "^10", - "typescript": "^5" + "typescript": "^5", + "typescript-eslint": "^8.33.1" }, "engines": { "node": ">=20.16.0" @@ -1004,46 +1005,55 @@ "node": ">=18.0.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@jridgewell/trace-mapping": "0.3.9" }, "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "node_modules/@es-joy/jsdoccomment": { + "version": "0.50.2", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.50.2.tgz", + "integrity": "sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==", "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.6", + "@typescript-eslint/types": "^8.11.0", + "comment-parser": "1.4.1", + "esquery": "^1.6.0", + "jsdoc-type-pratt-parser": "~4.1.0" + }, "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "node_modules/@es-joy/jsdoccomment/node_modules/@typescript-eslint/types": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", + "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, + "license": "MIT", "engines": { - "node": ">=12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" }, @@ -1066,16 +1076,79 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", + "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", + "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", + "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -1083,7 +1156,7 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -1094,16 +1167,31 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1112,49 +1200,78 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "version": "9.28.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.28.0.tgz", + "integrity": "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz", + "integrity": "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@eslint/core": "^0.14.0", + "levn": "^0.4.1" }, "engines": { - "node": ">=10.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "brace-expansion": "^1.1.7" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" }, "engines": { - "node": "*" + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/module-importer": { @@ -1170,12 +1287,19 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@inquirer/checkbox": { "version": "4.1.2", @@ -2278,6 +2402,36 @@ "flatbuffers": "~1.12.0" } }, + "node_modules/@itwin/eslint-plugin": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@itwin/eslint-plugin/-/eslint-plugin-5.2.1.tgz", + "integrity": "sha512-iFmxAXzBYUm/yHiyp37V8Qn2oZ9iqwB1HxWX1AAhewk77JUIhO1KLY2hrBNisHx49giy7hZmIOBEaXc357z+Uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "^8.26.1", + "@typescript-eslint/parser": "^8.26.1", + "eslint-formatter-visualstudio": "^8.40.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jam3": "^0.2.3", + "eslint-plugin-jsdoc": "^50.6.6", + "eslint-plugin-jsx-a11y": "^6.10.2", + "eslint-plugin-prefer-arrow": "^1.2.3", + "eslint-plugin-react": "^7.37.4", + "eslint-plugin-react-hooks": "^5.2.0", + "workspace-tools": "^0.36.4" + }, + "bin": { + "no-internal-report": "dist/bin/no-internal-report.js" + }, + "engines": { + "node": "^18.18.0 || ^20.0.0 || ^22.0.0" + }, + "peerDependencies": { + "eslint": "^9.11.1", + "typescript": "^3.7.0 || ^4.0.0 || ^5.0.0" + } + }, "node_modules/@itwin/imodels-client-management": { "version": "5.9.0", "resolved": "https://registry.npmjs.org/@itwin/imodels-client-management/-/imodels-client-management-5.9.0.tgz", @@ -2472,15 +2626,6 @@ "node": ">= 8" } }, - "node_modules/@nolyfill/is-core-module": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", - "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", - "dev": true, - "engines": { - "node": ">=12.4.0" - } - }, "node_modules/@oclif/core": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/@oclif/core/-/core-4.2.10.tgz", @@ -3521,6 +3666,52 @@ "node": ">=18.0.0" } }, + "node_modules/@stylistic/eslint-plugin": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-4.4.1.tgz", + "integrity": "sha512-CEigAk7eOLyHvdgmpZsKFwtiqS2wFwI1fn4j09IU9GmD4euFM4jEBAViWeCqaNLlbX2k2+A/Fq9cje4HQBXuJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.32.1", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@szmarczak/http-timer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", @@ -3584,6 +3775,13 @@ "@types/node": "*" } }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", @@ -3628,7 +3826,8 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/json5": { "version": "0.0.29", @@ -3672,12 +3871,6 @@ "undici-types": "~5.26.4" } }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true - }, "node_modules/@types/pako": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/pako/-/pako-2.0.3.tgz", @@ -3695,12 +3888,6 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", @@ -3732,218 +3919,553 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", - "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.1.tgz", + "integrity": "sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/type-utils": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/type-utils": "8.33.1", + "@typescript-eslint/utils": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^7.0.0", "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^2.1.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.33.1", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, - "node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", + "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4" + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", + "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, + "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", - "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", + "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "@typescript-eslint/types": "8.33.1", + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } } }, - "node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, + "license": "Apache-2.0", "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://opencollective.com/eslint" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, + "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">= 4" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, + "license": "MIT", "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=18.12" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "typescript": ">=4.8.4" } }, - "node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "node_modules/@typescript-eslint/parser": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.1.tgz", + "integrity": "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", + "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", + "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/accepts": { - "version": "1.3.8", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", + "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", + "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.33.1", + "@typescript-eslint/tsconfig-utils": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", + "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.33.1", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.1.tgz", + "integrity": "sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.33.1", + "@typescript-eslint/types": "^8.33.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", + "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.1.tgz", + "integrity": "sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.1.tgz", + "integrity": "sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/utils": "8.33.1", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", + "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", + "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.33.1", + "@typescript-eslint/tsconfig-utils": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", + "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.33.1", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.1.tgz", + "integrity": "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/typescript-estree": "8.33.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", + "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", + "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", + "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.33.1", + "@typescript-eslint/tsconfig-utils": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", + "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.33.1", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/accepts": { + "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, @@ -3973,6 +4495,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -4004,6 +4527,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4082,6 +4606,16 @@ "node": ">= 8" } }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -4094,14 +4628,25 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { "node": ">= 0.4" @@ -4145,6 +4690,27 @@ "node": ">=8" } }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.findlastindex": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", @@ -4184,15 +4750,16 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4201,20 +4768,37 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -4232,11 +4816,28 @@ "node": "*" } }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, "node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/async-retry": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", @@ -4256,6 +4857,7 @@ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -4266,6 +4868,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/axe-core": { + "version": "4.10.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", + "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, "node_modules/axios": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.3.tgz", @@ -4277,6 +4889,16 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -4415,27 +5037,6 @@ "dev": true, "license": "MIT" }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/builtins": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", - "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", - "dev": true, - "dependencies": { - "semver": "^7.0.0" - } - }, "node_modules/bundle-name": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", @@ -4486,16 +5087,16 @@ } }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, + "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" }, "engines": { "node": ">= 0.4" @@ -4540,6 +5141,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4703,42 +5305,6 @@ "node": ">= 6" } }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/clean-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", - "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/clean-regexp/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/clean-stack": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", @@ -4811,6 +5377,16 @@ "node": ">= 0.8" } }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4827,12 +5403,6 @@ "proto-list": "~1.2.1" } }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true - }, "node_modules/console-table-printer": { "version": "2.12.1", "resolved": "https://registry.npmjs.org/console-table-printer/-/console-table-printer-2.12.1.tgz", @@ -5153,15 +5723,23 @@ "dev": true, "license": "MIT" }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -5171,29 +5749,31 @@ } }, "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/inspect-js" } }, "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" }, @@ -5205,9 +5785,9 @@ } }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -5462,18 +6042,6 @@ "node": ">=8" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", @@ -5567,20 +6135,7 @@ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "license": "MIT", "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" + "once": "^1.4.0" } }, "node_modules/error-ex": { @@ -5593,57 +6148,66 @@ } }, "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", "dev": true, + "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", + "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" }, "engines": { "node": ">= 0.4" @@ -5671,6 +6235,34 @@ "node": ">= 0.4" } }, + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -5685,14 +6277,16 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -5708,14 +6302,15 @@ } }, "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, + "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -5752,141 +6347,74 @@ } }, "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "version": "9.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.28.0.tgz", + "integrity": "sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.20.0", + "@eslint/config-helpers": "^0.2.1", + "@eslint/core": "^0.14.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.28.0", + "@eslint/plugin-kit": "^0.3.1", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.3.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-oclif": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-oclif/-/eslint-config-oclif-5.2.1.tgz", - "integrity": "sha512-f0I7oB3lkbEnTqH+F18tKNmZG78aDjiCWz7co0Zbz6s12k655jUvb6FtzHniCmATqaHfcVVdrOldBT6P3bKpxA==", - "dev": true, - "dependencies": { - "eslint-config-xo-space": "^0.35.0", - "eslint-plugin-mocha": "^10.5.0", - "eslint-plugin-n": "^15.1.0", - "eslint-plugin-unicorn": "^48.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/eslint-config-oclif-typescript": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/eslint-config-oclif-typescript/-/eslint-config-oclif-typescript-3.1.12.tgz", - "integrity": "sha512-hEXU/PEJyjeLiTrCmgcmx0+FHwVpqipkKSykesdMsk2v43Mqh5bq2j3cyxHXZBCOxpTACVlM6KG7d4LFaWoVHQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/eslint-plugin": "^6.21.0", - "@typescript-eslint/parser": "^6.21.0", - "eslint-config-xo-space": "^0.35.0", - "eslint-import-resolver-typescript": "^3.6.3", - "eslint-plugin-import": "^2.31.0", - "eslint-plugin-mocha": "^10.5.0", - "eslint-plugin-n": "^15", - "eslint-plugin-perfectionist": "^2.11.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" + "url": "https://eslint.org/donate" }, "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-config-xo": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.44.0.tgz", - "integrity": "sha512-YG4gdaor0mJJi8UBeRJqDPO42MedTWYMaUyucF5bhm2pi/HS98JIxfFQmTLuyj6hGpQlAazNfyVnn7JuDn+Sew==", - "dev": true, - "dependencies": { - "confusing-browser-globals": "1.0.11" - }, - "engines": { - "node": ">=18" + "jiti": "*" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - }, - "peerDependencies": { - "eslint": ">=8.56.0" + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/eslint-config-xo-space": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/eslint-config-xo-space/-/eslint-config-xo-space-0.35.0.tgz", - "integrity": "sha512-+79iVcoLi3PvGcjqYDpSPzbLfqYpNcMlhsCBRsnmDoHAn4npJG6YxmHpelQKpXM7v/EeZTUKb4e1xotWlei8KA==", + "node_modules/eslint-formatter-visualstudio": { + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/eslint-formatter-visualstudio/-/eslint-formatter-visualstudio-8.40.0.tgz", + "integrity": "sha512-TsbZJpvu0wclOoy5MEhETzxrVWMPDg5sejowvQfbqw9e0ooozbnX/1STGiGaO/fH1JWLQvqQ4qAmai2u/Kep1g==", "dev": true, - "dependencies": { - "eslint-config-xo": "^0.44.0" - }, + "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - }, - "peerDependencies": { - "eslint": ">=8.56.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/eslint-import-resolver-node": { @@ -5909,41 +6437,6 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-import-resolver-typescript": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.3.tgz", - "integrity": "sha512-ud9aw4szY9cCT1EWWdGv1L1XR6hh2PaRWif0j2QjQ0pgTY/69iw+W0Z4qZv5wHahOl8isEr+k/JnyAqNQkLkIA==", - "dev": true, - "dependencies": { - "@nolyfill/is-core-module": "1.0.39", - "debug": "^4.3.5", - "enhanced-resolve": "^5.15.0", - "eslint-module-utils": "^2.8.1", - "fast-glob": "^3.3.2", - "get-tsconfig": "^4.7.5", - "is-bun-module": "^1.0.2", - "is-glob": "^4.0.3" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*", - "eslint-plugin-import-x": "*" - }, - "peerDependenciesMeta": { - "eslint-plugin-import": { - "optional": true - }, - "eslint-plugin-import-x": { - "optional": true - } - } - }, "node_modules/eslint-module-utils": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", @@ -5970,118 +6463,222 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-plugin-es": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", - "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", "dev": true, "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" }, "engines": { - "node": ">=8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "node": ">=4" }, "peerDependencies": { - "eslint": ">=4.19.1" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" } }, - "node_modules/eslint-plugin-es/node_modules/eslint-utils": { + "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "esutils": "^2.0.2" }, "engines": { - "node": ">=6" + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "engines": { + "node": "*" } }, - "node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jam3": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jam3/-/eslint-plugin-jam3-0.2.3.tgz", + "integrity": "sha512-aW1L8C96fsRji0c8ZAgqtJVIu5p2IaNbeT2kuHNS6p5tontAVK1yP1W4ECjq3BHOv/GgAWvBVIx7kQI0kG2Rew==", "dev": true, + "license": "MIT", + "dependencies": { + "doctrine": "^2.1.0", + "has": "^1.0.3", + "requireindex": "~1.1.0" + }, "engines": { "node": ">=4" } }, - "node_modules/eslint-plugin-import": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", - "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "node_modules/eslint-plugin-jam3/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@rtsao/scc": "^1.1.0", + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "50.7.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.7.1.tgz", + "integrity": "sha512-XBnVA5g2kUVokTNUiE1McEPse5n9/mNUmuJcx52psT6zBs2eVcXSmQBvjfa7NZdfLVSy3u1pEDDUxoxpwy89WA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@es-joy/jsdoccomment": "~0.50.2", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.4.1", + "escape-string-regexp": "^4.0.0", + "espree": "^10.3.0", + "esquery": "^1.6.0", + "parse-imports-exports": "^0.2.4", + "semver": "^7.7.2", + "spdx-expression-parse": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", "array-includes": "^3.1.8", - "array.prototype.findlastindex": "^1.2.5", - "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.0", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", "hasown": "^2.0.2", - "is-core-module": "^2.15.1", - "is-glob": "^4.0.3", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", - "object.groupby": "^1.0.3", - "object.values": "^1.2.0", - "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.8", - "tsconfig-paths": "^3.15.0" + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=4.0" }, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { + "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6089,72 +6686,92 @@ "node": "*" } }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/eslint-plugin-prefer-arrow": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.2.3.tgz", + "integrity": "sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "license": "MIT", + "peerDependencies": { + "eslint": ">=2.0.0" } }, - "node_modules/eslint-plugin-mocha": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.5.0.tgz", - "integrity": "sha512-F2ALmQVPT1GoP27O1JTZGrV9Pqg8k79OeIuvw63UxMtQKREZtmkK1NFgkZQ2TW7L2JSSFKHFPTtHu5z8R9QNRw==", + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", "dev": true, + "license": "MIT", "dependencies": { - "eslint-utils": "^3.0.0", - "globals": "^13.24.0", - "rambda": "^7.4.0" + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=4" }, "peerDependencies": { - "eslint": ">=7.0.0" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, - "node_modules/eslint-plugin-n": { - "version": "15.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz", - "integrity": "sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==", + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", "dev": true, - "dependencies": { - "builtins": "^5.0.1", - "eslint-plugin-es": "^4.1.0", - "eslint-utils": "^3.0.0", - "ignore": "^5.1.1", - "is-core-module": "^2.11.0", - "minimatch": "^3.1.2", - "resolve": "^1.22.1", - "semver": "^7.3.8" - }, + "license": "MIT", "engines": { - "node": ">=12.22.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "node": ">=10" }, "peerDependencies": { - "eslint": ">=7.0.0" + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, - "node_modules/eslint-plugin-n/node_modules/brace-expansion": { + "node_modules/eslint-plugin-react/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "node_modules/eslint-plugin-n/node_modules/minimatch": { + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6162,113 +6779,51 @@ "node": "*" } }, - "node_modules/eslint-plugin-perfectionist": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-2.11.0.tgz", - "integrity": "sha512-XrtBtiu5rbQv88gl+1e2RQud9te9luYNvKIgM9emttQ2zutHPzY/AQUucwxscDKV4qlTkvLTxjOFvxqeDpPorw==", + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "^6.13.0 || ^7.0.0", - "minimatch": "^9.0.3", - "natural-compare-lite": "^1.4.0" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, - "peerDependencies": { - "astro-eslint-parser": "^1.0.2", - "eslint": ">=8.0.0", - "svelte": ">=3.0.0", - "svelte-eslint-parser": "^0.37.0", - "vue-eslint-parser": ">=9.0.0" + "bin": { + "resolve": "bin/resolve" }, - "peerDependenciesMeta": { - "astro-eslint-parser": { - "optional": true - }, - "svelte": { - "optional": true - }, - "svelte-eslint-parser": { - "optional": true - }, - "vue-eslint-parser": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-unicorn": { - "version": "48.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-48.0.1.tgz", - "integrity": "sha512-FW+4r20myG/DqFcCSzoumaddKBicIPeFnTrifon2mWIzlfyvzwyqZjqVP7m4Cqr/ZYisS2aiLghkUWaPg6vtCw==", + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "@eslint-community/eslint-utils": "^4.4.0", - "ci-info": "^3.8.0", - "clean-regexp": "^1.0.0", - "esquery": "^1.5.0", - "indent-string": "^4.0.0", - "is-builtin-module": "^3.2.1", - "jsesc": "^3.0.2", - "lodash": "^4.17.21", - "pluralize": "^8.0.0", - "read-pkg-up": "^7.0.1", - "regexp-tree": "^0.1.27", - "regjsparser": "^0.10.0", - "semver": "^7.5.4", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" - }, - "peerDependencies": { - "eslint": ">=8.44.0" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", @@ -6291,6 +6846,19 @@ "concat-map": "0.0.1" } }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -6304,17 +6872,31 @@ } }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -6337,6 +6919,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -6471,7 +7054,8 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", @@ -6503,7 +7087,8 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "3.0.0", @@ -6557,15 +7142,16 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, + "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/filelist": { @@ -6669,17 +7255,17 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatbuffers": { @@ -6688,10 +7274,11 @@ "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==" }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" }, "node_modules/follow-redirects": { "version": "1.15.9", @@ -6713,12 +7300,19 @@ } }, "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, + "license": "MIT", "dependencies": { - "is-callable": "^1.1.3" + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/form-data": { @@ -6812,15 +7406,18 @@ } }, "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -6928,14 +7525,15 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -6944,18 +7542,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-tsconfig": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", - "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", - "dev": true, - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, "node_modules/git-hooks-list": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-3.2.0.tgz", @@ -6966,6 +7552,27 @@ "url": "https://github.com/fisker/git-hooks-list?sponsor=1" } }, + "node_modules/git-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", + "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-ssh": "^1.4.0", + "parse-url": "^8.1.0" + } + }, + "node_modules/git-url-parse": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-13.1.1.tgz", + "integrity": "sha512-PCFJyeSSdtnbfhSNRw9Wk96dDCNx+sogTe4YNXeXSJxt7xz5hvXekuRn9JX7m+Mf4OscCu8h+mtAl3+h5Fo8lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "git-up": "^7.0.0" + } + }, "node_modules/github-slugger": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", @@ -7016,33 +7623,6 @@ "node": ">=10" } }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/globalthis": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", @@ -7127,11 +7707,25 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "node_modules/has": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7157,10 +7751,14 @@ } }, "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -7312,10 +7910,11 @@ } }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -7369,14 +7968,15 @@ "license": "ISC" }, "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -7412,13 +8012,15 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -7433,13 +8035,37 @@ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, + "license": "MIT", "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7458,13 +8084,14 @@ } }, "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7473,35 +8100,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-bun-module": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.2.1.tgz", - "integrity": "sha512-AmidtEM6D6NmUiLOvvU7+IePxjEjOzra2h0pSrsfSAcXwl/83zLLXDByafUJy9k/rKK0pvXMLdwKwGHlX2Ke6Q==", - "dev": true, - "dependencies": { - "semver": "^7.6.3" - } - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -7525,11 +8129,14 @@ } }, "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, + "license": "MIT", "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" }, "engines": { @@ -7540,12 +8147,14 @@ } }, "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7576,6 +8185,22 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -7584,6 +8209,25 @@ "node": ">=8" } }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -7626,6 +8270,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", @@ -7647,12 +8304,14 @@ } }, "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7661,15 +8320,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", @@ -7684,13 +8334,16 @@ } }, "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -7709,13 +8362,27 @@ "node": ">=0.10.0" } }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -7724,6 +8391,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-ssh": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.1.tgz", + "integrity": "sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "protocols": "^2.0.1" + } + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -7738,12 +8415,14 @@ } }, "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7753,12 +8432,15 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, + "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -7768,12 +8450,13 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, + "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -7794,13 +8477,47 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7821,7 +8538,8 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/isexe": { "version": "3.1.1", @@ -7831,6 +8549,24 @@ "node": ">=16" } }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/jake": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", @@ -7868,6 +8604,13 @@ "node": "*" } }, + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", + "dev": true, + "license": "MIT" + }, "node_modules/jose": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.7.tgz", @@ -7905,16 +8648,14 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", + "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=12.0.0" } }, "node_modules/json-buffer": { @@ -7929,17 +8670,12 @@ "dev": true, "license": "MIT" }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -7995,6 +8731,22 @@ "npm": ">=6" } }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, "node_modules/jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", @@ -8046,6 +8798,26 @@ "json-buffer": "3.0.1" } }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -8076,12 +8848,6 @@ "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -8165,6 +8931,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/loupe": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", @@ -8385,15 +9164,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", @@ -8494,12 +9264,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -11152,6 +11916,16 @@ "inBundle": true, "license": "ISC" }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -11183,14 +11957,17 @@ } }, "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -11200,6 +11977,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/object.fromentries": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", @@ -11233,12 +12026,14 @@ } }, "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, @@ -11402,6 +12197,24 @@ "node": ">=0.10.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-cancelable": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", @@ -11495,6 +12308,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -11502,6 +12316,16 @@ "node": ">=6" } }, + "node_modules/parse-imports-exports": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/parse-imports-exports/-/parse-imports-exports-0.2.4.tgz", + "integrity": "sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-statements": "1.0.11" + } + }, "node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -11516,6 +12340,33 @@ "node": ">=4" } }, + "node_modules/parse-path": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.1.0.tgz", + "integrity": "sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "protocols": "^2.0.0" + } + }, + "node_modules/parse-statements": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/parse-statements/-/parse-statements-1.0.11.tgz", + "integrity": "sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", + "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-path": "^7.0.0" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -11603,12 +12454,6 @@ "node": "*" } }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -11667,20 +12512,12 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -11702,6 +12539,18 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", @@ -11709,6 +12558,13 @@ "dev": true, "license": "ISC" }, + "node_modules/protocols": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.2.tgz", + "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", + "dev": true, + "license": "MIT" + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -11743,6 +12599,7 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -11793,12 +12650,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/rambda": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/rambda/-/rambda-7.5.0.tgz", - "integrity": "sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA==", - "dev": true - }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -11834,152 +12685,12 @@ "node": ">= 0.8" } }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/read-pkg/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true, - "engines": { - "node": ">=8" - } + "license": "MIT" }, "node_modules/readdirp": { "version": "3.6.0", @@ -12011,25 +12722,21 @@ "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==", "peer": true }, - "node_modules/regexp-tree": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", - "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", - "dev": true, - "bin": { - "regexp-tree": "bin/regexp-tree" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", - "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", "es-errors": "^1.3.0", - "set-function-name": "^2.0.2" + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -12038,16 +12745,25 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/registry-auth-token": { @@ -12063,27 +12779,6 @@ "node": ">=14" } }, - "node_modules/regjsparser": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz", - "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==", - "dev": true, - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -12100,6 +12795,16 @@ "dev": true, "license": "ISC" }, + "node_modules/requireindex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz", + "integrity": "sha512-LBnkqsDE7BZKvqylbmn7lTIVdpx4K/QCduRATpO5R+wtPmky/a8pN1bO2D6wXppn1497AJF9mNjqAXr6bdl9jg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.5" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -12125,110 +12830,43 @@ "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "dependencies": { - "lowercase-keys": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" } }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "lowercase-keys": "^3.0.0" }, "engines": { - "node": "*" + "node": ">=14.16" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, "engines": { - "node": "*" + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, "node_modules/run-applescript": { @@ -12265,14 +12903,16 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -12301,15 +12941,33 @@ } ] }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "is-regex": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -12464,6 +13122,21 @@ "node": ">= 0.4" } }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -12769,6 +13442,20 @@ "node": ">= 0.8" } }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -12782,16 +13469,74 @@ "node": ">=8" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -12801,15 +13546,20 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -12860,18 +13610,6 @@ "node": ">=0.10.0" } }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -12923,21 +13661,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, "node_modules/tiny-jsonc": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tiny-jsonc/-/tiny-jsonc-1.0.1.tgz", @@ -13023,18 +13746,6 @@ "node": ">=0.6" } }, - "node_modules/ts-api-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", - "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", - "dev": true, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -13175,30 +13886,32 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -13208,17 +13921,19 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -13228,17 +13943,18 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -13272,16 +13988,43 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.33.1.tgz", + "integrity": "sha512-AgRnV4sKkWOiZ0Kjbnf5ytTJXMUZQ0qhSVdQtDNYLPLnjsATEYhaO94GlRQwi4t4gO8FfjM6NnikHeKjUm8D7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.33.1", + "@typescript-eslint/parser": "8.33.1", + "@typescript-eslint/utils": "8.33.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "call-bound": "^1.0.3", "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -13340,6 +14083,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -13559,16 +14303,67 @@ } }, "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, + "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -13582,15 +14377,18 @@ "license": "ISC" }, "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { @@ -13631,6 +14429,22 @@ "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true }, + "node_modules/workspace-tools": { + "version": "0.36.4", + "resolved": "https://registry.npmjs.org/workspace-tools/-/workspace-tools-0.36.4.tgz", + "integrity": "sha512-v0UFVvw9BjHtRu2Dau5PEJKkuG8u4jPlpXZQWjSz9XgbSutpPURqtO2P0hp3cVmQVATh8lkMFCewFgJuDnyC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "fast-glob": "^3.3.1", + "git-url-parse": "^13.0.0", + "globby": "^11.0.0", + "jju": "^1.4.0", + "js-yaml": "^4.1.0", + "micromatch": "^4.0.0" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index 5184ae77..a5fc6901 100644 --- a/package.json +++ b/package.json @@ -26,24 +26,25 @@ "zod": "^3.25.30" }, "devDependencies": { + "@eslint/js": "^9.28.0", + "@itwin/eslint-plugin": "^5.2.1", "@itwin/oidc-signin-tool": "^4.4.1", "@oclif/prettier-config": "^0.2.1", "@oclif/test": "^4", + "@stylistic/eslint-plugin": "^4.4.1", "@types/chai": "^4", "@types/mocha": "^10", "@types/node": "^18.19.64", "@types/pako": "^2.0.3", "chai": "^4", - "eslint": "^8", - "eslint-config-oclif": "^5", - "eslint-config-oclif-typescript": "^3", - "eslint-config-prettier": "^9", + "eslint": "^9.28.0", "mailinator-client": "^1.0.5", "mocha": "^10", "oclif": "^4", "shx": "^0.3.3", "ts-node": "^10", - "typescript": "^5" + "typescript": "^5", + "typescript-eslint": "^8.33.1" }, "engines": { "node": ">=20.16.0" @@ -159,6 +160,7 @@ "clean": "shx rm -rf dist tsconfig.tsbuildinfo", "build": "npm run clean && tsc -b", "lint": "eslint . --ext .ts", + "lint:fix": "eslint . --ext .ts --fix", "postpack": "shx rm -f oclif.manifest.json", "posttest": "npm run lint", "prepack": "oclif manifest && oclif readme", diff --git a/src/commands/access-control/group/create.ts b/src/commands/access-control/group/create.ts index dd40bbb8..5e60a422 100644 --- a/src/commands/access-control/group/create.ts +++ b/src/commands/access-control/group/create.ts @@ -7,51 +7,51 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class CreateAccessControlGroup extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/create-itwin-group/", - name: "Create iTwin Group", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/create-itwin-group/", + name: "Create iTwin Group", + }; - static description = 'Create a new group for an iTwin.'; + public static description = 'Create a new group for an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --name "Engineering Team" --description "Group handling engineering tasks"`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --name "Engineering Team" --description "Group handling engineering tasks"`, + description: 'Example 1:' + } + ]; - static flags = { - description: Flags.string({ - char: 'd', - description: 'A description of the group.', - helpValue: '', - required: true, - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin where the group is being created.' - }), - name: Flags.string({ - char: 'n', - description: 'The name of the group to be created.', - helpValue: '', - required: true, - }), - }; + public static flags = { + description: Flags.string({ + char: 'd', + description: 'A description of the group.', + helpValue: '', + required: true, + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin where the group is being created.' + }), + name: Flags.string({ + char: 'n', + description: 'The name of the group to be created.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(CreateAccessControlGroup); + public async run() { + const { flags } = await this.parse(CreateAccessControlGroup); - const client = await this.getAccessControlApiClient(); + const client = await this.getAccessControlApiClient(); - const response = await client.createGroup(flags["itwin-id"], { - description: flags.description, - name: flags.name, - }); + const response = await client.createGroup(flags["itwin-id"], { + description: flags.description, + name: flags.name, + }); - return this.logAndReturnResult(response.group); - } + return this.logAndReturnResult(response.group); } +} diff --git a/src/commands/access-control/group/delete.ts b/src/commands/access-control/group/delete.ts index 19c1352c..883b321e 100644 --- a/src/commands/access-control/group/delete.ts +++ b/src/commands/access-control/group/delete.ts @@ -7,42 +7,42 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class DeleteAccessControlGroup extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/delete-itwin-group/", - name: "Delete iTwin Group", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/delete-itwin-group/", + name: "Delete iTwin Group", + }; - static description = 'Delete an existing group from an iTwin.'; + public static description = 'Delete an existing group from an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --group-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --group-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, + description: 'Example 1:' + } + ]; - static flags = { - "group-id": Flags.string({ - char: 'g', - description: 'The ID of the group to be deleted.', - helpValue: '', - required: true, - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin where the group exists.', - }), - }; + public static flags = { + "group-id": Flags.string({ + char: 'g', + description: 'The ID of the group to be deleted.', + helpValue: '', + required: true, + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin where the group exists.', + }), + }; - async run() { - const { flags } = await this.parse(DeleteAccessControlGroup); + public async run() { + const { flags } = await this.parse(DeleteAccessControlGroup); - const client = await this.getAccessControlApiClient(); + const client = await this.getAccessControlApiClient(); - await client.deleteGroup(flags["itwin-id"], flags["group-id"]); + await client.deleteGroup(flags["itwin-id"], flags["group-id"]); - return this.logAndReturnResult({ result: 'deleted' }); - } + return this.logAndReturnResult({ result: 'deleted' }); } +} diff --git a/src/commands/access-control/group/info.ts b/src/commands/access-control/group/info.ts index bb4e414e..87633d6e 100644 --- a/src/commands/access-control/group/info.ts +++ b/src/commands/access-control/group/info.ts @@ -7,42 +7,42 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class AccessControlGroupInfo extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-group/", - name: "Get iTwin Group Info", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-group/", + name: "Get iTwin Group Info", + }; - static description = 'Retrieve details about a specific group in an iTwin.'; + public static description = 'Retrieve details about a specific group in an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --group-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --group-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, + description: 'Example 1:' + } + ]; - static flags = { - "group-id": Flags.string({ - char: 'g', - description: 'The ID of the group to retrieve information about.', - helpValue: '', - required: true, - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin where the group exists.' - }), - }; + public static flags = { + "group-id": Flags.string({ + char: 'g', + description: 'The ID of the group to retrieve information about.', + helpValue: '', + required: true, + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin where the group exists.' + }), + }; - async run() { - const { flags } = await this.parse(AccessControlGroupInfo); + public async run() { + const { flags } = await this.parse(AccessControlGroupInfo); - const client = await this.getAccessControlApiClient(); + const client = await this.getAccessControlApiClient(); - const response = await client.getGroup(flags["itwin-id"], flags["group-id"]); + const response = await client.getGroup(flags["itwin-id"], flags["group-id"]); - return this.logAndReturnResult(response.group); - } + return this.logAndReturnResult(response.group); } +} diff --git a/src/commands/access-control/group/list.ts b/src/commands/access-control/group/list.ts index e4cb4dec..121b8499 100644 --- a/src/commands/access-control/group/list.ts +++ b/src/commands/access-control/group/list.ts @@ -5,36 +5,36 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class ListAccessControlGroups extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-groups/", - name: "Get iTwin Groups", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-groups/", + name: "Get iTwin Groups", + }; - static description = 'List all groups for a specific iTwin.'; + public static description = 'List all groups for a specific iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin whose groups you want to list.' - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin whose groups you want to list.' + }), + }; - async run() { - const { flags } = await this.parse(ListAccessControlGroups); + public async run() { + const { flags } = await this.parse(ListAccessControlGroups); - const client = await this.getAccessControlApiClient(); + const client = await this.getAccessControlApiClient(); - const response = await client.getGroups(flags["itwin-id"]); + const response = await client.getGroups(flags["itwin-id"]); - return this.logAndReturnResult(response.groups); - } + return this.logAndReturnResult(response.groups); } +} diff --git a/src/commands/access-control/group/update.ts b/src/commands/access-control/group/update.ts index 3a7f0a04..b5f10cb0 100644 --- a/src/commands/access-control/group/update.ts +++ b/src/commands/access-control/group/update.ts @@ -7,79 +7,79 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class UpdateAccessControlGroup extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/update-itwin-group/", - name: "Update iTwin Group", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/update-itwin-group/", + name: "Update iTwin Group", + }; - static description = 'Update the details of an existing group in an iTwin.'; + public static description = 'Update the details of an existing group in an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --group-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --name "Updated Engineering Team" --description "Updated description"`, - description: 'Example 1: Update group name and description' - }, - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --group-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --member john.doe@example.com --member jane.doe@example.com --ims-group "Sample IMS Group" --ims-group "Sample IMS Group"`, - description: 'Example 2: Update group members and IMS groups' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --group-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --name "Updated Engineering Team" --description "Updated description"`, + description: 'Example 1: Update group name and description' + }, + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --group-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --member john.doe@example.com --member jane.doe@example.com --ims-group "Sample IMS Group" --ims-group "Sample IMS Group"`, + description: 'Example 2: Update group members and IMS groups' + } + ]; - static flags = { - description: Flags.string({ - char: 'd', - description: 'The updated description of the group.', - helpValue: '', - }), - "group-id": Flags.string({ - char: 'g', - description: 'The ID of the group to be updated.', - helpValue: '', - required: true, - }), - "ims-group": Flags.string({ - description: 'A list of IMS Groups to be linked to the group. Max amount of 50.', - helpValue: '', - multiple: true, - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin where the group exists.' - }), - member: Flags.string({ - description: 'A list of members (emails) to be assigned to the group. Max amount of 50.', - helpValue: '', - multiple: true, - }), - name: Flags.string({ - char: 'n', - description: 'The updated name of the group.', - helpValue: '', - }), - }; + public static flags = { + description: Flags.string({ + char: 'd', + description: 'The updated description of the group.', + helpValue: '', + }), + "group-id": Flags.string({ + char: 'g', + description: 'The ID of the group to be updated.', + helpValue: '', + required: true, + }), + "ims-group": Flags.string({ + description: 'A list of IMS Groups to be linked to the group. Max amount of 50.', + helpValue: '', + multiple: true, + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin where the group exists.' + }), + member: Flags.string({ + description: 'A list of members (emails) to be assigned to the group. Max amount of 50.', + helpValue: '', + multiple: true, + }), + name: Flags.string({ + char: 'n', + description: 'The updated name of the group.', + helpValue: '', + }), + }; - async run() { - const { flags } = await this.parse(UpdateAccessControlGroup); + public async run() { + const { flags } = await this.parse(UpdateAccessControlGroup); - if(flags['ims-group'] !== undefined && flags["ims-group"]!.length > 50) { - this.error("A maximum of 50 ims groups can be provided."); - } + if(flags['ims-group'] !== undefined && flags["ims-group"].length > 50) { + this.error("A maximum of 50 ims groups can be provided."); + } - if(flags.member !== undefined && flags.member!.length > 50) { - this.error("A maximum of 50 members can be provided."); - } + if(flags.member !== undefined && flags.member.length > 50) { + this.error("A maximum of 50 members can be provided."); + } - const client = await this.getAccessControlApiClient(); + const client = await this.getAccessControlApiClient(); - const response = await client.updateGroup(flags["itwin-id"], flags["group-id"], { - description: flags.description, - imsGroups: flags["ims-group"], - members: flags.member, - name: flags.name, - }); + const response = await client.updateGroup(flags["itwin-id"], flags["group-id"], { + description: flags.description, + imsGroups: flags["ims-group"], + members: flags.member, + name: flags.name, + }); - return this.logAndReturnResult(response.group); - } + return this.logAndReturnResult(response.group); } +} diff --git a/src/commands/access-control/member/group/add.ts b/src/commands/access-control/member/group/add.ts index 3dd42360..77025b97 100644 --- a/src/commands/access-control/member/group/add.ts +++ b/src/commands/access-control/member/group/add.ts @@ -7,19 +7,19 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; -import { CustomFlags } from "../../../../extensions/custom-flags.js"; +import { customFlags } from "../../../../extensions/custom-flags.js"; import { validateUuidCSV } from "../../../../extensions/validation/validate-uuid-csv.js"; import { GroupMember } from "../../../../services/access-control-client/models/group.js"; export default class AddGroupMembers extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/add-itwin-group-members/", - name: "Add iTwin Group Members", + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/add-itwin-group-members/", + name: "Add iTwin Group Members", }; - static description = 'Add one or more groups as members to an iTwin.\n\nGroups and their roles can be provided to this command in multiple ways:\n1) Utilizing the `--groups` option, where the necessary data in provided in form of serialized JSON.\n2) Utilizing `--group-id` and `--role-ids` options, in which case all of `--role-id` roles will be applied to each `--group-id` group.'; + public static description = 'Add one or more groups as members to an iTwin.\n\nGroups and their roles can be provided to this command in multiple ways:\n1) Utilizing the `--groups` option, where the necessary data in provided in form of serialized JSON.\n2) Utilizing `--group-id` and `--role-ids` options, in which case all of `--role-id` roles will be applied to each `--group-id` group.'; - static examples = [ + public static examples = [ { command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --groups '[{"groupId": "605e6f1e-b774-40f4-87cb-94ca7392c182", "roleIds": ["5abbfcef-0eab-472a-b5f5-5c5a43df34b1", "83ee0d80-dea3-495a-b6c0-7bb102ebbcc3"]}, {"groupId": "fb23fed5-182a-4ed1-b378-3b214fd3f043", "roleIds": ["5abbfcef-0eab-472a-b5f5-5c5a43df34b1"]}]'`, description: 'Example 1: Add multiple groups as members to an iTwin using `--groups` option. Each specified group can be assigned different lists of roles.' @@ -30,7 +30,7 @@ export default class AddGroupMembers extends BaseCommand { } ]; - static flags = { + public static flags = { "group-id": Flags.string({ dependsOn: ['role-ids'], description: 'Specify id of the group to add roles to. This flag can be provided multiple times.', @@ -38,26 +38,26 @@ export default class AddGroupMembers extends BaseCommand { multiple: true, required: false, }), - groups: CustomFlags.groupMembers({ + groups: customFlags.groupMembers({ description: 'A list of groups to add, each with a groupId and roleIds. A maximum of 50 role assignments can be performed. Provided in serialized JSON format.', exactlyOne: ['groups', 'group-id'], exclusive: ['group-id', "role-ids"], helpValue: '', required: false, }), - "itwin-id": CustomFlags.iTwinIDFlag({ + "itwin-id": customFlags.iTwinIDFlag({ description: 'The ID of the iTwin to which the groups will be added.' }), "role-ids": Flags.string({ dependsOn: ['group-id'], description: `Specify a list of role IDs to be assigned to all of 'group-id' groups. Provided in CSV format without whitespaces.`, helpValue: "", - parse: input => validateUuidCSV(input), + parse: async input => validateUuidCSV(input), required: false, }) }; - async run() { + public async run() { const { flags } = await this.parse(AddGroupMembers); const client = await this.getAccessControlMemberClient(); @@ -84,7 +84,9 @@ export default class AddGroupMembers extends BaseCommand { return groups; groups = []; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion for (const groupId of groupIds!) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const currentRoleIds = roleIds!.split(','); groups.push({groupId, roleIds: currentRoleIds}); } diff --git a/src/commands/access-control/member/group/delete.ts b/src/commands/access-control/member/group/delete.ts index 5321203c..53782393 100644 --- a/src/commands/access-control/member/group/delete.ts +++ b/src/commands/access-control/member/group/delete.ts @@ -7,42 +7,42 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; -import { CustomFlags } from "../../../../extensions/custom-flags.js"; +import { customFlags } from "../../../../extensions/custom-flags.js"; export default class DeleteGroupMember extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/remove-itwin-group-member/", - name: "Remove iTwin Group Member", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/remove-itwin-group-member/", + name: "Remove iTwin Group Member", + }; - static description = 'Remove a group from an iTwin.'; + public static description = 'Remove a group from an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --group-id group1-id`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --group-id group1-id`, + description: 'Example 1:' + } + ]; - static flags = { - "group-id": Flags.string({ - char: 'g', - description: 'The ID of the group to remove from the iTwin.', - helpValue: '', - required: true, - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin where the group is a member.' - }), - }; + public static flags = { + "group-id": Flags.string({ + char: 'g', + description: 'The ID of the group to remove from the iTwin.', + helpValue: '', + required: true, + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin where the group is a member.' + }), + }; - async run() { - const { flags } = await this.parse(DeleteGroupMember); + public async run() { + const { flags } = await this.parse(DeleteGroupMember); - const client = await this.getAccessControlMemberClient(); + const client = await this.getAccessControlMemberClient(); - await client.deleteGroupMember(flags["itwin-id"], flags["group-id"]); + await client.deleteGroupMember(flags["itwin-id"], flags["group-id"]); - return this.logAndReturnResult({ result: 'deleted' }); - } + return this.logAndReturnResult({ result: 'deleted' }); } +} diff --git a/src/commands/access-control/member/group/info.ts b/src/commands/access-control/member/group/info.ts index 338a63de..c9a8b301 100644 --- a/src/commands/access-control/member/group/info.ts +++ b/src/commands/access-control/member/group/info.ts @@ -7,42 +7,42 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; -import { CustomFlags } from "../../../../extensions/custom-flags.js"; +import { customFlags } from "../../../../extensions/custom-flags.js"; export default class InfoGroupMember extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-group-member/", - name: "Get iTwin Group Member", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-group-member/", + name: "Get iTwin Group Member", + }; - static description = 'Retrieve details about a specific group member in an iTwin.'; + public static description = 'Retrieve details about a specific group member in an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --group-id group1-id`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --group-id group1-id`, + description: 'Example 1:' + } + ]; - static flags = { - "group-id": Flags.string({ - char: 'g', - description: 'The ID of the group to retrieve information about.', - helpValue: '', - required: true, - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin where the group is a member.' - }), - }; + public static flags = { + "group-id": Flags.string({ + char: 'g', + description: 'The ID of the group to retrieve information about.', + helpValue: '', + required: true, + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin where the group is a member.' + }), + }; - async run() { - const { flags } = await this.parse(InfoGroupMember); + public async run() { + const { flags } = await this.parse(InfoGroupMember); - const client = await this.getAccessControlMemberClient(); + const client = await this.getAccessControlMemberClient(); - const result = await client.getGroupMember(flags["itwin-id"], flags["group-id"]); + const result = await client.getGroupMember(flags["itwin-id"], flags["group-id"]); - return this.logAndReturnResult(result.member); - } + return this.logAndReturnResult(result.member); } +} diff --git a/src/commands/access-control/member/group/list.ts b/src/commands/access-control/member/group/list.ts index 56a7f0a2..4733b574 100644 --- a/src/commands/access-control/member/group/list.ts +++ b/src/commands/access-control/member/group/list.ts @@ -5,36 +5,36 @@ import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; -import { CustomFlags } from "../../../../extensions/custom-flags.js"; +import { customFlags } from "../../../../extensions/custom-flags.js"; export default class ListGroupMembers extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-group-members/", - name: "Get iTwin Group Members", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-group-members/", + name: "Get iTwin Group Members", + }; - static description = 'List all group members of an iTwin.'; + public static description = 'List all group members of an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin whose group members you want to list.', - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin whose group members you want to list.', + }), + }; - async run() { - const { flags } = await this.parse(ListGroupMembers); + public async run() { + const { flags } = await this.parse(ListGroupMembers); - const client = await this.getAccessControlMemberClient(); + const client = await this.getAccessControlMemberClient(); - const result = await client.getGroupMembers(flags["itwin-id"]); + const result = await client.getGroupMembers(flags["itwin-id"]); - return this.logAndReturnResult(result.members); - } + return this.logAndReturnResult(result.members); } +} diff --git a/src/commands/access-control/member/group/update.ts b/src/commands/access-control/member/group/update.ts index 65b90390..8b09d1cc 100644 --- a/src/commands/access-control/member/group/update.ts +++ b/src/commands/access-control/member/group/update.ts @@ -7,52 +7,52 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; -import { CustomFlags } from "../../../../extensions/custom-flags.js"; +import { customFlags } from "../../../../extensions/custom-flags.js"; export default class UpdateGroupMember extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/update-itwin-group-member/", - name: "Update iTwin Group Member", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/update-itwin-group-member/", + name: "Update iTwin Group Member", + }; - static description = 'Update the role assignments for a group in an iTwin.'; + public static description = 'Update the role assignments for a group in an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --group-id group1-id --role-id role1-id --role-id role2-id`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --group-id group1-id --role-id role1-id --role-id role2-id`, + description: 'Example 1:' + } + ]; - static flags = { - "group-id": Flags.string({ - char: 'g', - description: 'The ID of the group whose roles will be updated.', - helpValue: '', - required: true, - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin to which the groups will be added.' - }), - "role-id": Flags.string({ - description: 'A list of role IDs to assign to the group. Max amount of 50.', - helpValue: '', - multiple: true, - required: true, - }), - }; + public static flags = { + "group-id": Flags.string({ + char: 'g', + description: 'The ID of the group whose roles will be updated.', + helpValue: '', + required: true, + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin to which the groups will be added.' + }), + "role-id": Flags.string({ + description: 'A list of role IDs to assign to the group. Max amount of 50.', + helpValue: '', + multiple: true, + required: true, + }), + }; - async run() { - const { flags } = await this.parse(UpdateGroupMember); + public async run() { + const { flags } = await this.parse(UpdateGroupMember); - if(flags['role-id'] !== undefined && flags["role-id"]!.length > 50) { - this.error("A maximum of 50 roles can be assigned."); - } + if(flags['role-id'] !== undefined && flags["role-id"].length > 50) { + this.error("A maximum of 50 roles can be assigned."); + } - const client = await this.getAccessControlMemberClient(); + const client = await this.getAccessControlMemberClient(); - const response = await client.updateGroupMember(flags["itwin-id"], flags["group-id"], flags["role-id"]); + const response = await client.updateGroupMember(flags["itwin-id"], flags["group-id"], flags["role-id"]); - return this.logAndReturnResult(response.member); - } + return this.logAndReturnResult(response.member); } +} diff --git a/src/commands/access-control/member/invitations.ts b/src/commands/access-control/member/invitations.ts index 63e86191..3150ff40 100644 --- a/src/commands/access-control/member/invitations.ts +++ b/src/commands/access-control/member/invitations.ts @@ -5,36 +5,36 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class AccessControlMemberInvitations extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-member-invitations/", - name: "Get iTwin Member Invitations", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-member-invitations/", + name: "Get iTwin Member Invitations", + }; - static description = "Retrieve the list of pending invitations for an iTwin's members."; + public static description = "Retrieve the list of pending invitations for an iTwin's members."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: "The ID of the iTwin whose member invitations you want to retrieve.", - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: "The ID of the iTwin whose member invitations you want to retrieve.", + }), + }; - async run() { - const { flags } = await this.parse(AccessControlMemberInvitations); + public async run() { + const { flags } = await this.parse(AccessControlMemberInvitations); - const client = await this.getAccessControlMemberClient(); + const client = await this.getAccessControlMemberClient(); - const response = await client.getMemberInvitations(flags["itwin-id"]); + const response = await client.getMemberInvitations(flags["itwin-id"]); - return this.logAndReturnResult(response.invitations); - } + return this.logAndReturnResult(response.invitations); } +} diff --git a/src/commands/access-control/member/owner/add.ts b/src/commands/access-control/member/owner/add.ts index 6a4704c4..c52ad739 100644 --- a/src/commands/access-control/member/owner/add.ts +++ b/src/commands/access-control/member/owner/add.ts @@ -7,41 +7,41 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; -import { CustomFlags } from "../../../../extensions/custom-flags.js"; +import { customFlags } from "../../../../extensions/custom-flags.js"; export default class AddOwner extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/add-itwin-owner-member/", - name: "Add iTwin Owner", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/add-itwin-owner-member/", + name: "Add iTwin Owner", + }; - static description = 'Add or invite a new owner to an iTwin by email. When using interactive login, specified user is directly added to the iTwin as an owner if they are in the same organization and sent an invitation email otherwise. When using a service client, specified user is sent an invitation email.'; + public static description = 'Add or invite a new owner to an iTwin by email. When using interactive login, specified user is directly added to the iTwin as an owner if they are in the same organization and sent an invitation email otherwise. When using a service client, specified user is sent an invitation email.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --email john.owner@example.com`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --email john.owner@example.com`, + description: 'Example 1:' + } + ]; - static flags = { - email: Flags.string({ - description: 'The email address of the new owner.', - helpValue: '', - required: true, - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin to which the owner will be added.' - }), - }; + public static flags = { + email: Flags.string({ + description: 'The email address of the new owner.', + helpValue: '', + required: true, + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin to which the owner will be added.' + }), + }; - async run() { - const { flags } = await this.parse(AddOwner); + public async run() { + const { flags } = await this.parse(AddOwner); - const client = await this.getAccessControlMemberClient(); + const client = await this.getAccessControlMemberClient(); - const response = await client.addOwner(flags["itwin-id"], flags.email); + const response = await client.addOwner(flags["itwin-id"], flags.email); - return this.logAndReturnResult(response); - } + return this.logAndReturnResult(response); } +} diff --git a/src/commands/access-control/member/owner/delete.ts b/src/commands/access-control/member/owner/delete.ts index 79e2cfdd..9926a9df 100644 --- a/src/commands/access-control/member/owner/delete.ts +++ b/src/commands/access-control/member/owner/delete.ts @@ -7,41 +7,41 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; -import { CustomFlags } from "../../../../extensions/custom-flags.js"; +import { customFlags } from "../../../../extensions/custom-flags.js"; export default class DeleteOwner extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/remove-itwin-owner-member/", - name: "Remove iTwin Owner", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/remove-itwin-owner-member/", + name: "Remove iTwin Owner", + }; - static description = 'Remove an owner from an iTwin by their member ID.'; + public static description = 'Remove an owner from an iTwin by their member ID.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --member-id user1-id`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --member-id user1-id`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin from which the owner will be removed.' - }), - "member-id": Flags.string({ - description: 'The ID of the owner to be removed.', - helpValue: '', - required: true, - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin from which the owner will be removed.' + }), + "member-id": Flags.string({ + description: 'The ID of the owner to be removed.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(DeleteOwner); + public async run() { + const { flags } = await this.parse(DeleteOwner); - const client = await this.getAccessControlMemberClient(); + const client = await this.getAccessControlMemberClient(); - await client.deleteOwner(flags["itwin-id"], flags["member-id"]); + await client.deleteOwner(flags["itwin-id"], flags["member-id"]); - return this.logAndReturnResult({ result: 'deleted' }); - } + return this.logAndReturnResult({ result: 'deleted' }); } +} diff --git a/src/commands/access-control/member/owner/list.ts b/src/commands/access-control/member/owner/list.ts index 5738c2a2..35a51193 100644 --- a/src/commands/access-control/member/owner/list.ts +++ b/src/commands/access-control/member/owner/list.ts @@ -5,36 +5,36 @@ import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; -import { CustomFlags } from "../../../../extensions/custom-flags.js"; +import { customFlags } from "../../../../extensions/custom-flags.js"; export default class ListOwners extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-owner-members/", - name: "Get iTwin Owner Members", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-owner-members/", + name: "Get iTwin Owner Members", + }; - static description = 'List all owners of a specific iTwin.'; + public static description = 'List all owners of a specific iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin whose owners you want to list.', - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin whose owners you want to list.', + }), + }; - async run() { - const { flags } = await this.parse(ListOwners); + public async run() { + const { flags } = await this.parse(ListOwners); - const client = await this.getAccessControlMemberClient(); + const client = await this.getAccessControlMemberClient(); - const result = await client.getOwnerList(flags["itwin-id"]); + const result = await client.getOwnerList(flags["itwin-id"]); - return this.logAndReturnResult(result.members); - } + return this.logAndReturnResult(result.members); } +} diff --git a/src/commands/access-control/member/user/add.ts b/src/commands/access-control/member/user/add.ts index 368339b5..a9671773 100644 --- a/src/commands/access-control/member/user/add.ts +++ b/src/commands/access-control/member/user/add.ts @@ -7,19 +7,19 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; -import { CustomFlags } from "../../../../extensions/custom-flags.js"; +import { customFlags } from "../../../../extensions/custom-flags.js"; import { validateUuidCSV } from "../../../../extensions/validation/validate-uuid-csv.js"; import { UserMember } from "../../../../services/access-control-client/models/members.js"; export default class AddUserMembers extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/add-itwin-user-members/", - name: "Add iTwin User Members", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/add-itwin-user-members/", + name: "Add iTwin User Members", + }; - static description = 'Add and/or invite one or more user members to an iTwin. When using interactive login, specified users are directly added to the iTwin if they are in the same organization and sent invitation emails otherwise. When using a service client, specified users are sent invitation emails.\n\nUsers and their roles can be provided to this command in multiple ways:\n1) Utilizing the `--members` flag, where the necessary data in provided in form of serialized JSON.\n2) Utilizing `--email` and `--role-ids` flags.'; + public static description = 'Add and/or invite one or more user members to an iTwin. When using interactive login, specified users are directly added to the iTwin if they are in the same organization and sent invitation emails otherwise. When using a service client, specified users are sent invitation emails.\n\nUsers and their roles can be provided to this command in multiple ways:\n1) Utilizing the `--members` flag, where the necessary data in provided in form of serialized JSON.\n2) Utilizing `--email` and `--role-ids` flags.'; - static examples = [ + public static examples = [ { command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --members '[{"email": "user1@example.com", "roleIds": ["5abbfcef-0eab-472a-b5f5-5c5a43df34b1", "83ee0d80-dea3-495a-b6c0-7bb102ebbcc3"]}, {"email": "user2@example.com", "roleIds": ["5abbfcef-0eab-472a-b5f5-5c5a43df34b1"]}]'`, description: 'Example 1: Add multiple users to an iTwin with role IDs using `--members` flag.' @@ -34,7 +34,7 @@ export default class AddUserMembers extends BaseCommand { } ]; - static flags = { + public static flags = { "email": Flags.string({ dependsOn: ['role-ids'], description: 'Specify emails of the user to add roles to. This flag can be provided multiple times.', @@ -42,10 +42,10 @@ export default class AddUserMembers extends BaseCommand { multiple: true, required: false, }), - "itwin-id": CustomFlags.iTwinIDFlag({ + "itwin-id": customFlags.iTwinIDFlag({ description: 'The ID of the iTwin to which the users will be added.' }), - members: CustomFlags.userMembers({ + members: customFlags.userMembers({ description: 'A list of members to add, each with an email and a list of role IDs. A maximum of 50 role assignments can be performed. Provided in serialized JSON format.', exactlyOne: ['members', 'email'], exclusive: ['email', "role-ids"], @@ -57,12 +57,13 @@ export default class AddUserMembers extends BaseCommand { description: 'Specify IDs of roles to be assigned to a user in CSV format without any whitespaces. This flag can be provided multiple times. If the flag is provided only once, the contained list of role IDs will be assigned to all provided group-ids list. If flag is provided multiple times, each role-ids will be used for the corresponding group-id (fist role-ids list for the first group-id, second role-ids list for the second group-id and so on).', helpValue: "", multiple: true, + // eslint-disable-next-line @typescript-eslint/promise-function-async parse: input => validateUuidCSV(input), required: false, }) }; - async run() { + public async run() { const { flags } = await this.parse(AddUserMembers); const client = await this.getAccessControlMemberClient(); @@ -88,12 +89,15 @@ export default class AddUserMembers extends BaseCommand { if (members !== undefined) return members; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion if(roleIds!.length !== 1 && emails!.length !== roleIds!.length) { - this.error("Number of `--role-ids` flags must match the amount of `--group-id` flags or be equal to 1.") + this.error("Number of `--role-ids` flags must match the amount of `--group-id` flags or be equal to 1."); } members = []; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion for (const [i, email] of emails!.entries()) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const currentRoleIds = roleIds!.length === 1 ? roleIds![0].split(','): roleIds![i].split(','); members.push({email, roleIds: currentRoleIds}); } diff --git a/src/commands/access-control/member/user/delete.ts b/src/commands/access-control/member/user/delete.ts index 78482627..08bf2916 100644 --- a/src/commands/access-control/member/user/delete.ts +++ b/src/commands/access-control/member/user/delete.ts @@ -7,41 +7,41 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; -import { CustomFlags } from "../../../../extensions/custom-flags.js"; +import { customFlags } from "../../../../extensions/custom-flags.js"; export default class DeleteUserMember extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/remove-itwin-user-member/", - name: "Remove iTwin User Member", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/remove-itwin-user-member/", + name: "Remove iTwin User Member", + }; - static description = 'Remove a user from an iTwin.'; + public static description = 'Remove a user from an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --member-id user1-id`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --member-id user1-id`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin where the user is a member.' - }), - "member-id": Flags.string({ - description: 'The ID of the user to remove from the iTwin.', - helpValue: '', - required: true, - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin where the user is a member.' + }), + "member-id": Flags.string({ + description: 'The ID of the user to remove from the iTwin.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(DeleteUserMember); + public async run() { + const { flags } = await this.parse(DeleteUserMember); - const client = await this.getAccessControlMemberClient(); + const client = await this.getAccessControlMemberClient(); - await client.deleteUserMember(flags["itwin-id"], flags["member-id"]); + await client.deleteUserMember(flags["itwin-id"], flags["member-id"]); - return this.logAndReturnResult({ result: 'deleted' }); - } + return this.logAndReturnResult({ result: 'deleted' }); } +} diff --git a/src/commands/access-control/member/user/info.ts b/src/commands/access-control/member/user/info.ts index 6a87605d..012c2dbb 100644 --- a/src/commands/access-control/member/user/info.ts +++ b/src/commands/access-control/member/user/info.ts @@ -7,41 +7,41 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; -import { CustomFlags } from "../../../../extensions/custom-flags.js"; +import { customFlags } from "../../../../extensions/custom-flags.js"; export default class InfoUserMember extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-user-member/", - name: "Get iTwin User Member", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-user-member/", + name: "Get iTwin User Member", + }; - static description = 'Retrieve details about a specific user member in an iTwin.'; + public static description = 'Retrieve details about a specific user member in an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --member-id user1-id`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --member-id user1-id`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin where the user is a member.' - }), - "member-id": Flags.string({ - description: 'The ID of the user to retrieve information about.', - helpValue: '', - required: true, - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin where the user is a member.' + }), + "member-id": Flags.string({ + description: 'The ID of the user to retrieve information about.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(InfoUserMember); + public async run() { + const { flags } = await this.parse(InfoUserMember); - const client = await this.getAccessControlMemberClient(); + const client = await this.getAccessControlMemberClient(); - const result = await client.getUserMember(flags["itwin-id"], flags["member-id"]); + const result = await client.getUserMember(flags["itwin-id"], flags["member-id"]); - return this.logAndReturnResult(result.member); - } + return this.logAndReturnResult(result.member); } +} diff --git a/src/commands/access-control/member/user/list.ts b/src/commands/access-control/member/user/list.ts index af96b8de..89cc77bc 100644 --- a/src/commands/access-control/member/user/list.ts +++ b/src/commands/access-control/member/user/list.ts @@ -5,36 +5,36 @@ import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; -import { CustomFlags } from "../../../../extensions/custom-flags.js"; +import { customFlags } from "../../../../extensions/custom-flags.js"; export default class ListUserMembers extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-user-members/", - name: "Get iTwin User Members", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-user-members/", + name: "Get iTwin User Members", + }; - static description = 'List all user members of an iTwin.'; + public static description = 'List all user members of an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin whose user members you want to list.' - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin whose user members you want to list.' + }), + }; - async run() { - const { flags } = await this.parse(ListUserMembers); + public async run() { + const { flags } = await this.parse(ListUserMembers); - const client = await this.getAccessControlMemberClient(); + const client = await this.getAccessControlMemberClient(); - const result = await client.getUserMembers(flags["itwin-id"]); + const result = await client.getUserMembers(flags["itwin-id"]); - return this.logAndReturnResult(result.members); - } + return this.logAndReturnResult(result.members); } +} diff --git a/src/commands/access-control/member/user/update.ts b/src/commands/access-control/member/user/update.ts index 4260bcc6..cde49068 100644 --- a/src/commands/access-control/member/user/update.ts +++ b/src/commands/access-control/member/user/update.ts @@ -7,51 +7,51 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; -import { CustomFlags } from "../../../../extensions/custom-flags.js"; +import { customFlags } from "../../../../extensions/custom-flags.js"; export default class UpdateUserMember extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/update-itwin-user-member/", - name: "Update iTwin User Member", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/update-itwin-user-member/", + name: "Update iTwin User Member", + }; - static description = 'Update the role assignments for a user in an iTwin.'; + public static description = 'Update the role assignments for a user in an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --member-id user1-id --role-id role1-id --role-id role2-id`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --member-id user1-id --role-id role1-id --role-id role2-id`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin where the user is a member.', - }), - "member-id": Flags.string({ - description: 'The ID of the user whose roles will be updated.', - helpValue: '', - required: true, - }), - "role-id": Flags.string({ - description: 'A list of role IDs to assign to the user. Max amount of 50.', - helpValue: '', - multiple: true, - required: true, - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin where the user is a member.', + }), + "member-id": Flags.string({ + description: 'The ID of the user whose roles will be updated.', + helpValue: '', + required: true, + }), + "role-id": Flags.string({ + description: 'A list of role IDs to assign to the user. Max amount of 50.', + helpValue: '', + multiple: true, + required: true, + }), + }; - async run() { - const { flags } = await this.parse(UpdateUserMember); + public async run() { + const { flags } = await this.parse(UpdateUserMember); - if(flags['role-id'] !== undefined && flags["role-id"]!.length > 50) { - this.error("A maximum of 50 roles can be assigned."); - } + if(flags['role-id'] !== undefined && flags["role-id"].length > 50) { + this.error("A maximum of 50 roles can be assigned."); + } - const client = await this.getAccessControlMemberClient(); + const client = await this.getAccessControlMemberClient(); - const response = await client.updateUserMember(flags["itwin-id"], flags["member-id"], flags["role-id"]); + const response = await client.updateUserMember(flags["itwin-id"], flags["member-id"], flags["role-id"]); - return this.logAndReturnResult(response.member); - } + return this.logAndReturnResult(response.member); } +} diff --git a/src/commands/access-control/permissions/all.ts b/src/commands/access-control/permissions/all.ts index a6d448e4..15fef4eb 100644 --- a/src/commands/access-control/permissions/all.ts +++ b/src/commands/access-control/permissions/all.ts @@ -7,27 +7,27 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class ListAllPermissions extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/get-all-permissions/", - name: "Get All Permissions", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/get-all-permissions/", + name: "Get All Permissions", + }; - static description = 'Retrieve a list of all iTwin Platform permissions.'; + public static description = 'Retrieve a list of all iTwin Platform permissions.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %>`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %>`, + description: 'Example 1:' + } + ]; - async run() { - await this.parse(ListAllPermissions); + public async run() { + await this.parse(ListAllPermissions); - const client = await this.getAccessControlApiClient(); + const client = await this.getAccessControlApiClient(); - const response = await client.getAllAvailableiTwinPermissions(); + const response = await client.getAllAvailableiTwinPermissions(); - return this.logAndReturnResult(response.permissions); - } + return this.logAndReturnResult(response.permissions); } +} diff --git a/src/commands/access-control/permissions/me.ts b/src/commands/access-control/permissions/me.ts index 5a93b866..3ca8aa9e 100644 --- a/src/commands/access-control/permissions/me.ts +++ b/src/commands/access-control/permissions/me.ts @@ -5,36 +5,36 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class MyPermissions extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/get-iTwin-permissions/", - name: "Get My iTwin Permissions", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/get-iTwin-permissions/", + name: "Get My iTwin Permissions", + }; - static description = 'Retrieve a list of your permissions on a specified iTwin.'; + public static description = 'Retrieve a list of your permissions on a specified iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id e9a0d55a-65aa-42bd-9aa3-fd1c68d5e7b5`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id e9a0d55a-65aa-42bd-9aa3-fd1c68d5e7b5`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin for which the role is being created.' - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin for which the role is being created.' + }), + }; - async run() { - const { flags } = await this.parse(MyPermissions); + public async run() { + const { flags } = await this.parse(MyPermissions); - const client = await this.getAccessControlApiClient(); + const client = await this.getAccessControlApiClient(); - const response = await client.getAlliTwinPermissions(flags["itwin-id"]); + const response = await client.getAlliTwinPermissions(flags["itwin-id"]); - return this.logAndReturnResult(response.permissions); - } + return this.logAndReturnResult(response.permissions); } +} diff --git a/src/commands/access-control/role/create.ts b/src/commands/access-control/role/create.ts index 7ce1e50f..4916de64 100644 --- a/src/commands/access-control/role/create.ts +++ b/src/commands/access-control/role/create.ts @@ -7,51 +7,51 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class CreateRole extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/create-iTwin-role/", - name: "Create iTwin Role", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/create-iTwin-role/", + name: "Create iTwin Role", + }; - static description = 'Create a new role for an iTwin. To assign permissions after creation, use `itp access-control role update`.'; + public static description = 'Create a new role for an iTwin. To assign permissions after creation, use `itp access-control role update`.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --name "Project Manager" --description "Manages all aspects of the project"`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --name "Project Manager" --description "Manages all aspects of the project"`, + description: 'Example 1:' + } + ]; - static flags = { - description: Flags.string({ - char: 'd', - description: 'A description of the role.', - helpValue: '', - required: true, - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin for which the role is being created.' - }), - name: Flags.string({ - char: 'n', - description: 'The name of the role to be created.', - helpValue: '', - required: true, - }), - }; + public static flags = { + description: Flags.string({ + char: 'd', + description: 'A description of the role.', + helpValue: '', + required: true, + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin for which the role is being created.' + }), + name: Flags.string({ + char: 'n', + description: 'The name of the role to be created.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(CreateRole); + public async run() { + const { flags } = await this.parse(CreateRole); - const client = await this.getAccessControlApiClient(); + const client = await this.getAccessControlApiClient(); - const response = await client.createiTwinRole(flags["itwin-id"], { - description: flags.description, - displayName: flags.name, - }); + const response = await client.createiTwinRole(flags["itwin-id"], { + description: flags.description, + displayName: flags.name, + }); - return this.logAndReturnResult(response.role); - } + return this.logAndReturnResult(response.role); } +} diff --git a/src/commands/access-control/role/delete.ts b/src/commands/access-control/role/delete.ts index a1491384..8c52338d 100644 --- a/src/commands/access-control/role/delete.ts +++ b/src/commands/access-control/role/delete.ts @@ -7,41 +7,41 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class DeleteRole extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/delete-itwin-role/", - name: "Delete iTwin Role", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/delete-itwin-role/", + name: "Delete iTwin Role", + }; - static description = 'Delete an existing role from an iTwin.'; + public static description = 'Delete an existing role from an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --role-id role1-id`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --role-id role1-id`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin where the role exists.' - }), - "role-id": Flags.string({ - description: 'The ID of the role to be deleted.', - helpValue: '', - required: true, - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin where the role exists.' + }), + "role-id": Flags.string({ + description: 'The ID of the role to be deleted.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(DeleteRole); + public async run() { + const { flags } = await this.parse(DeleteRole); - const client = await this.getAccessControlApiClient(); + const client = await this.getAccessControlApiClient(); - await client.deleteiTwinRole(flags["itwin-id"], flags["role-id"]); + await client.deleteiTwinRole(flags["itwin-id"], flags["role-id"]); - return this.logAndReturnResult({ result: 'deleted' }); - } + return this.logAndReturnResult({ result: 'deleted' }); } +} diff --git a/src/commands/access-control/role/info.ts b/src/commands/access-control/role/info.ts index d423153b..db4e5671 100644 --- a/src/commands/access-control/role/info.ts +++ b/src/commands/access-control/role/info.ts @@ -7,41 +7,41 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class InfoRole extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-role/", - name: "Get iTwin Role Info", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-role/", + name: "Get iTwin Role Info", + }; - static description = 'Retrieve details about a specific role in an iTwin.'; + public static description = 'Retrieve details about a specific role in an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --role-id role1-id`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --role-id role1-id`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin where the role exists.', - }), - "role-id": Flags.string({ - description: 'The ID of the role to retrieve information about.', - helpValue: '', - required: true, - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin where the role exists.', + }), + "role-id": Flags.string({ + description: 'The ID of the role to retrieve information about.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(InfoRole); + public async run() { + const { flags } = await this.parse(InfoRole); - const client = await this.getAccessControlApiClient(); + const client = await this.getAccessControlApiClient(); - const response = await client.getiTwinRole(flags["itwin-id"], flags["role-id"]); + const response = await client.getiTwinRole(flags["itwin-id"], flags["role-id"]); - return this.logAndReturnResult(response.role); - } + return this.logAndReturnResult(response.role); } +} diff --git a/src/commands/access-control/role/list.ts b/src/commands/access-control/role/list.ts index 9009390a..533282a1 100644 --- a/src/commands/access-control/role/list.ts +++ b/src/commands/access-control/role/list.ts @@ -5,36 +5,36 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class ListRoles extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-roles/", - name: "Get iTwin Roles", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/get-itwin-roles/", + name: "Get iTwin Roles", + }; - static description = 'List all roles for a specific iTwin.'; + public static description = 'List all roles for a specific iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin whose roles you want to list.', - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin whose roles you want to list.', + }), + }; - async run() { - const { flags } = await this.parse(ListRoles); + public async run() { + const { flags } = await this.parse(ListRoles); - const client = await this.getAccessControlApiClient(); + const client = await this.getAccessControlApiClient(); - const response = await client.getiTwinRoles(flags["itwin-id"]); + const response = await client.getiTwinRoles(flags["itwin-id"]); - return this.logAndReturnResult(response.roles); - } + return this.logAndReturnResult(response.roles); } +} diff --git a/src/commands/access-control/role/update.ts b/src/commands/access-control/role/update.ts index 6e8c6f72..c9bb9dfb 100644 --- a/src/commands/access-control/role/update.ts +++ b/src/commands/access-control/role/update.ts @@ -7,67 +7,67 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class UpdateRole extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/access-control-v2/operations/update-itwin-role/", - name: "Update iTwin Role", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/access-control-v2/operations/update-itwin-role/", + name: "Update iTwin Role", + }; - static description = 'Update the details of an existing role in an iTwin.'; + public static description = 'Update the details of an existing role in an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --role-id role1-id --name "Lead Engineer" --description "Oversees engineering tasks"`, - description: 'Example 1: Update role name and description' - }, - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --role-id role1-id --name "Admin Role" --permission Permission1 --permission Permission2 --permission Permission3`, - description: 'Example 2: Update role permissions along with the name' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --role-id role1-id --name "Lead Engineer" --description "Oversees engineering tasks"`, + description: 'Example 1: Update role name and description' + }, + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --role-id role1-id --name "Admin Role" --permission Permission1 --permission Permission2 --permission Permission3`, + description: 'Example 2: Update role permissions along with the name' + } + ]; - static flags = { - description: Flags.string({ - char: 'd', - description: 'The updated description of the role.', - helpValue: '', - required: false, - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin where the role exists.' - }), - name: Flags.string({ - char: 'n', - description: 'The updated name of the role.', - helpValue: '', - required: false, - }), - permission: Flags.string({ - description: 'A list of permissions to assign to the role.', - helpValue: '', - multiple: true, - required: false, - }), - "role-id": Flags.string({ - description: 'The ID of the role to be updated.', - helpValue: '', - required: true, - }), - }; + public static flags = { + description: Flags.string({ + char: 'd', + description: 'The updated description of the role.', + helpValue: '', + required: false, + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin where the role exists.' + }), + name: Flags.string({ + char: 'n', + description: 'The updated name of the role.', + helpValue: '', + required: false, + }), + permission: Flags.string({ + description: 'A list of permissions to assign to the role.', + helpValue: '', + multiple: true, + required: false, + }), + "role-id": Flags.string({ + description: 'The ID of the role to be updated.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(UpdateRole); + public async run() { + const { flags } = await this.parse(UpdateRole); - const client = await this.getAccessControlApiClient(); + const client = await this.getAccessControlApiClient(); - const response = await client.updateiTwinRole(flags["itwin-id"], flags["role-id"], { - description: flags.description, - displayName: flags.name, - permissions: flags.permission, - }); + const response = await client.updateiTwinRole(flags["itwin-id"], flags["role-id"], { + description: flags.description, + displayName: flags.name, + permissions: flags.permission, + }); - return this.logAndReturnResult(response.role); - } + return this.logAndReturnResult(response.role); } +} diff --git a/src/commands/api/index.ts b/src/commands/api/index.ts index 9f9d2b6f..b7d1f88f 100644 --- a/src/commands/api/index.ts +++ b/src/commands/api/index.ts @@ -7,117 +7,117 @@ import { Command, Flags } from "@oclif/core"; import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; -import { CustomFlags } from "../../extensions/custom-flags.js"; +import { customFlags } from "../../extensions/custom-flags.js"; import { Query } from "../../services/iTwin-api-client.js"; export default class ApiRequest extends BaseCommand { - static apiReference : ApiReference = { - link: "https://developer.bentley.com/apis/", - name: "ITwin Platform APIs docs", - sectionName: "APIs Docs Reference", - }; + public static apiReference : ApiReference = { + link: "https://developer.bentley.com/apis/", + name: "ITwin Platform APIs docs", + sectionName: "APIs Docs Reference", + }; - static description = "Make direct HTTP requests to any iTwin Platform API endpoint. Useful for custom operations or accessing APIs without dedicated commands."; + public static description = "Make direct HTTP requests to any iTwin Platform API endpoint. Useful for custom operations or accessing APIs without dedicated commands."; - static examples: Command.Example[] = [ - { - command: "itp api --method GET --path users/me", - description: "Example 1: Sending a GET request", - }, - { - command: 'itp api --method GET --path itwins/favorite --query subClass:Account --query "$top:10" --header "Prefer: return=minimal"', - description: "Example 2: Sending a request with headers and query parameters", - }, - { - command: "itp api --method DELETE --path itwins/favorites/dc914a84-e0c9-40e2-9d14-faf5ed84147f --empty-response", - description: "Example 3: Sending a delete request without response body", - }, - { - command: 'itp api --method POST --path itwins/exports --body \'{"outputFormat": "JsonGZip"}\'', - description: "Example 4: Sending a post request", - }, - { - // eslint-disable-next-line no-useless-escape - command: 'itp api --method POST --path users/getbyidlist --body "[\\`\"b644de17-f07e-4b43-8c33-ad2b1bacee3b\\`\"]"', - description: "Example 5: Sending a post request (Windows PowerShell)", - }, - ]; + public static examples: Command.Example[] = [ + { + command: "itp api --method GET --path users/me", + description: "Example 1: Sending a GET request", + }, + { + command: 'itp api --method GET --path itwins/favorite --query subClass:Account --query "$top:10" --header "Prefer: return=minimal"', + description: "Example 2: Sending a request with headers and query parameters", + }, + { + command: "itp api --method DELETE --path itwins/favorites/dc914a84-e0c9-40e2-9d14-faf5ed84147f --empty-response", + description: "Example 3: Sending a delete request without response body", + }, + { + command: 'itp api --method POST --path itwins/exports --body \'{"outputFormat": "JsonGZip"}\'', + description: "Example 4: Sending a post request", + }, + { + // eslint-disable-next-line no-useless-escape + command: 'itp api --method POST --path users/getbyidlist --body "[\\`\"b644de17-f07e-4b43-8c33-ad2b1bacee3b\\`\"]"', + description: "Example 5: Sending a post request (Windows PowerShell)", + }, + ]; - static flags = { - body: CustomFlags.noSchemaJson({ - description: "The body to include in the request. It must be serialized JSON.", - helpValue: '', - }), - "empty-response": Flags.boolean({ - description: "Indicates the request will not return a response body.", - }), - header: Flags.string({ - description: "Headers to include in the request. Use the format 'HeaderName: value'.", - flag: "h", - helpValue: '', - multiple: true, - }), - method: Flags.string({ - description: "HTTP method for the request.", - helpValue: '', - options: ["GET", "POST", "PUT", "DELETE", "PATCH"], - required: true, - }), - path: Flags.string({ - description: "API endpoint path to send the request to.", - helpValue: '', - required: true, - }), - query: Flags.string({ - description: "URL query parameters for the request. Use format 'QueryKey:value'.", - helpValue: '', - multiple: true, - }), - "version-header": Flags.string({ - description: "API version header for versioned endpoints.", - helpValue: '', - }), - }; + public static flags = { + body: customFlags.noSchemaJson({ + description: "The body to include in the request. It must be serialized JSON.", + helpValue: '', + }), + "empty-response": Flags.boolean({ + description: "Indicates the request will not return a response body.", + }), + header: Flags.string({ + description: "Headers to include in the request. Use the format 'HeaderName: value'.", + flag: "h", + helpValue: '', + multiple: true, + }), + method: Flags.string({ + description: "HTTP method for the request.", + helpValue: '', + options: ["GET", "POST", "PUT", "DELETE", "PATCH"], + required: true, + }), + path: Flags.string({ + description: "API endpoint path to send the request to.", + helpValue: '', + required: true, + }), + query: Flags.string({ + description: "URL query parameters for the request. Use format 'QueryKey:value'.", + helpValue: '', + multiple: true, + }), + "version-header": Flags.string({ + description: "API version header for versioned endpoints.", + helpValue: '', + }), + }; - async run() { - const { flags } = await this.parse(ApiRequest); + public async run() { + const { flags } = await this.parse(ApiRequest); - const mappedHeaders: Record = flags.header?.reduce((acc, header) => { - const [key, value] = header.split(":"); - acc[key] = value.trim(); - return acc; - }, {} as Record) || {}; + const mappedHeaders: Record = flags.header?.reduce((acc, header) => { + const [key, value] = header.split(":"); + acc[key] = value.trim(); + return acc; + }, {} as Record) || {}; - const query: Query[] | undefined = flags.query?.map((query) => { - const indexOfColon = query.indexOf(":"); - if (indexOfColon === -1) { - this.error(`Invalid query format: ${query}. Expected format is 'key:value'.`); - } + const queries: Query[] | undefined = flags.query?.map((query) => { + const indexOfColon = query.indexOf(":"); + if (indexOfColon === -1) { + this.error(`Invalid query format: ${query}. Expected format is 'key:value'.`); + } - // Split the query string into key and value - const key = query.slice(0, indexOfColon).trim(); - const value = query.slice(indexOfColon + 1).trim(); - - return { key, value }; - }) || undefined; + // Split the query string into key and value + const key = query.slice(0, indexOfColon).trim(); + const value = query.slice(indexOfColon + 1).trim(); - const client = await this.getITwinApiClient(); + return { key, value }; + }) || undefined; - const requestOptions = { - apiPath: flags.path, - apiVersionHeader: flags["version-header"], - body: flags.body, - headers: mappedHeaders, - method: flags.method as "DELETE" | "GET" | "PATCH" | "POST" | "PUT", - query - }; + const client = await this.getITwinApiClient(); - if (flags["empty-response"]) { - await client.sendRequestNoResponse(requestOptions); - return this.logAndReturnResult({result: "success"}); - } + const requestOptions = { + apiPath: flags.path, + apiVersionHeader: flags["version-header"], + body: flags.body, + headers: mappedHeaders, + method: flags.method as "DELETE" | "GET" | "PATCH" | "POST" | "PUT", + query: queries + }; - const response = await client.sendRequest(requestOptions); - return this.logAndReturnResult(response); + if (flags["empty-response"]) { + await client.sendRequestNoResponse(requestOptions); + return this.logAndReturnResult({result: "success"}); } + + const response = await client.sendRequest(requestOptions); + return this.logAndReturnResult(response); } +} diff --git a/src/commands/auth/info.ts b/src/commands/auth/info.ts index 594391ba..332b7b6e 100644 --- a/src/commands/auth/info.ts +++ b/src/commands/auth/info.ts @@ -6,20 +6,20 @@ import BaseCommand from '../../extensions/base-command.js'; export default class Info extends BaseCommand { - static args = {} + public static args = {}; - static description = 'Display authentication information. This command access current authentication storage and returns cached information about the current auth profile.' + public static description = 'Display authentication information. This command access current authentication storage and returns cached information about the current auth profile.'; - static examples = [ + public static examples = [ { command: `<%= config.bin %> <%= command.id %>`, description: 'Example 1:' } ]; - static flags = {} + public static flags = {}; - async run() { + public async run() { const authClient = this.getAuthorizationClient(); const authInfo = authClient.info(); return this.logAndReturnResult(authInfo); diff --git a/src/commands/auth/login.ts b/src/commands/auth/login.ts index fbc10927..e5e50c9b 100644 --- a/src/commands/auth/login.ts +++ b/src/commands/auth/login.ts @@ -8,13 +8,11 @@ import { Flags } from '@oclif/core'; import BaseCommand from '../../extensions/base-command.js'; export default class Login extends BaseCommand { - static args = {} + public static customDocs = true; - static customDocs = true; + public static description = 'Authenticate itp with Bentley. This command initiates the login process to obtain the necessary authentication tokens.'; - static description = 'Authenticate itp with Bentley. This command initiates the login process to obtain the necessary authentication tokens.' - - static examples = [ + public static examples = [ { command: `<%= config.bin %> <%= command.id %>`, description: 'Example 1:' @@ -29,7 +27,7 @@ export default class Login extends BaseCommand { } ]; - static flags = { + public static flags = { "client-id": Flags.string({ description: 'Provided client id that will be used for service or website login', helpValue: '', @@ -40,9 +38,9 @@ export default class Login extends BaseCommand { helpValue: '', required: false }) - } + }; - async run(): Promise { + public async run(): Promise { const { flags } = await this.parse(Login); const authClient = this.getAuthorizationClient(); diff --git a/src/commands/auth/logout.ts b/src/commands/auth/logout.ts index 642b7c89..fb9de581 100644 --- a/src/commands/auth/logout.ts +++ b/src/commands/auth/logout.ts @@ -6,27 +6,25 @@ import BaseCommand from '../../extensions/base-command.js'; export default class Logout extends BaseCommand { - static args = {} + public static description = 'Log out of the Bentley authentication session. This command clears the current authentication tokens and configuration.'; - static description = 'Log out of the Bentley authentication session. This command clears the current authentication tokens and configuration.' - - static examples = [ + public static examples = [ { command: `<%= config.bin %> <%= command.id %>`, description: 'Example 1:' } ]; - static flags = {} + public static flags = {}; - async run(): Promise { + public async run(): Promise { const authClient = this.getAuthorizationClient(); try { await authClient.logout(); this.log('User successfully logged out'); } catch (error) { - this.error(`User logout encountered an error: ${error}`); + this.error(`User logout encountered an error: ${JSON.stringify(error)}`); } } } diff --git a/src/commands/changed-elements/changesets.ts b/src/commands/changed-elements/changesets.ts index 14461adc..5704438c 100644 --- a/src/commands/changed-elements/changesets.ts +++ b/src/commands/changed-elements/changesets.ts @@ -7,54 +7,54 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; -import { CustomFlags } from "../../extensions/custom-flags.js"; +import { customFlags } from "../../extensions/custom-flags.js"; export default class GetChangesetStatus extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/changed-elements/operations/get-changesets/", - name: "Get Changeset Status", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/changed-elements/operations/get-changesets/", + name: "Get Changeset Status", + }; - static description = 'Get the processing status of changesets in an iModel to see which are ready for comparison.'; + public static description = 'Get the processing status of changesets in an iModel to see which are ready for comparison.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id 1a2b3c4d-5678-90ab-cdef-1234567890ab --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --top 10`, - description: 'Example 1: Retrieve the processing status of the first 10 changesets for a specific iModel' - }, - { - command: `<%= config.bin %> <%= command.id %> --itwin-id 1a2b3c4d-5678-90ab-cdef-1234567890ab --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --skip 5 --top 10`, - description: 'Example 2: Skip the first 5 changesets and return the next set' - }, - { - command: `<%= config.bin %> <%= command.id %> --itwin-id 1a2b3c4d-5678-90ab-cdef-1234567890ab --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, - description: 'Example 3: Retrieve all changesets for a specific iModel' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id 1a2b3c4d-5678-90ab-cdef-1234567890ab --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --top 10`, + description: 'Example 1: Retrieve the processing status of the first 10 changesets for a specific iModel' + }, + { + command: `<%= config.bin %> <%= command.id %> --itwin-id 1a2b3c4d-5678-90ab-cdef-1234567890ab --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --skip 5 --top 10`, + description: 'Example 2: Skip the first 5 changesets and return the next set' + }, + { + command: `<%= config.bin %> <%= command.id %> --itwin-id 1a2b3c4d-5678-90ab-cdef-1234567890ab --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, + description: 'Example 3: Retrieve all changesets for a specific iModel' + } + ]; - static flags = { - "imodel-id": CustomFlags.iModelIDFlag({ - description: 'The ID of the iModel.' - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin.' - }), - skip: Flags.integer({ - description: 'Skip a number of changesets in the result.', - helpValue: '' - }), - top: Flags.integer({ - description: 'Limit the number of changesets returned.', - helpValue: '' - }), - }; + public static flags = { + "imodel-id": customFlags.iModelIDFlag({ + description: 'The ID of the iModel.' + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin.' + }), + skip: Flags.integer({ + description: 'Skip a number of changesets in the result.', + helpValue: '' + }), + top: Flags.integer({ + description: 'Limit the number of changesets returned.', + helpValue: '' + }), + }; - async run() { - const { flags } = await this.parse(GetChangesetStatus); + public async run() { + const { flags } = await this.parse(GetChangesetStatus); - const client = await this.getChangeElementApiClient(); - const result = await client.listChangesets(flags["imodel-id"], flags["itwin-id"], flags.top, flags.skip); + const client = await this.getChangeElementApiClient(); + const result = await client.listChangesets(flags["imodel-id"], flags["itwin-id"], flags.top, flags.skip); - return this.logAndReturnResult(result.changesetStatus); - } + return this.logAndReturnResult(result.changesetStatus); } +} diff --git a/src/commands/changed-elements/comparison.ts b/src/commands/changed-elements/comparison.ts index c55d53ed..9022974f 100644 --- a/src/commands/changed-elements/comparison.ts +++ b/src/commands/changed-elements/comparison.ts @@ -7,52 +7,52 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; -import { CustomFlags } from "../../extensions/custom-flags.js"; +import { customFlags } from "../../extensions/custom-flags.js"; export default class ChangedElementsComparison extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/changed-elements/operations/get-comparison/", - name: "Get Comparison", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/changed-elements/operations/get-comparison/", + name: "Get Comparison", + }; - static description = 'Compare changes between two changesets in an iModel.'; + public static description = 'Compare changes between two changesets in an iModel.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id 89337c07-ab59-4080-81cc-5e237be55369 --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --changeset-id1 2f3b4a8c92d747d5c8a8b2f9cde6742e5d74b3b5 --changeset-id2 4b8a5d9e8d534a71b02894f2a2b4e91d`, - description: 'Example 1: Compare two changesets in an iModel' - }, - { - command: `<%= config.bin %> <%= command.id %> --itwin-id 89337c07-ab59-4080-81cc-5e237be55369 --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --changeset-id1 5d9e8b2f6744a71b02894f1a2b4e91d7 --changeset-id2 6b8e4f7a7348a81b93754c2d5d8f7e12`, - description: 'Example 2: Comparing another set of changesets in the same iModel' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id 89337c07-ab59-4080-81cc-5e237be55369 --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --changeset-id1 2f3b4a8c92d747d5c8a8b2f9cde6742e5d74b3b5 --changeset-id2 4b8a5d9e8d534a71b02894f2a2b4e91d`, + description: 'Example 1: Compare two changesets in an iModel' + }, + { + command: `<%= config.bin %> <%= command.id %> --itwin-id 89337c07-ab59-4080-81cc-5e237be55369 --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --changeset-id1 5d9e8b2f6744a71b02894f1a2b4e91d7 --changeset-id2 6b8e4f7a7348a81b93754c2d5d8f7e12`, + description: 'Example 2: Comparing another set of changesets in the same iModel' + } + ]; - static flags = { - "changeset-id1": Flags.string({ - description: 'The ID of the first changeset to compare.', - helpValue: '', - required: true - }), - "changeset-id2": Flags.string({ - description: 'The ID of the second changeset to compare.', - helpValue: '', - required: true - }), - "imodel-id": CustomFlags.iModelIDFlag({ - description: 'The ID of the iModel to compare changesets for.' - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin associated with the iModel.' - }) - }; + public static flags = { + "changeset-id1": Flags.string({ + description: 'The ID of the first changeset to compare.', + helpValue: '', + required: true + }), + "changeset-id2": Flags.string({ + description: 'The ID of the second changeset to compare.', + helpValue: '', + required: true + }), + "imodel-id": customFlags.iModelIDFlag({ + description: 'The ID of the iModel to compare changesets for.' + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin associated with the iModel.' + }) + }; - async run() { - const { flags } = await this.parse(ChangedElementsComparison); + public async run() { + const { flags } = await this.parse(ChangedElementsComparison); - const client = await this.getChangeElementApiClient(); - const result = await client.getComparison(flags["itwin-id"], flags["imodel-id"], flags["changeset-id1"], flags["changeset-id2"]); + const client = await this.getChangeElementApiClient(); + const result = await client.getComparison(flags["itwin-id"], flags["imodel-id"], flags["changeset-id1"], flags["changeset-id2"]); - return this.logAndReturnResult(result.changedElements); - } + return this.logAndReturnResult(result.changedElements); } +} diff --git a/src/commands/changed-elements/disable.ts b/src/commands/changed-elements/disable.ts index 86dc30e3..b240376b 100644 --- a/src/commands/changed-elements/disable.ts +++ b/src/commands/changed-elements/disable.ts @@ -5,43 +5,43 @@ import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; -import { CustomFlags } from "../../extensions/custom-flags.js"; +import { customFlags } from "../../extensions/custom-flags.js"; export default class ChangedElementsDisable extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/changed-elements/operations/enable-change-tracking/", - name: "Disable Change Tracking", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/changed-elements/operations/enable-change-tracking/", + name: "Disable Change Tracking", + }; - static description = "Disable change tracking for a specified iModel."; + public static description = "Disable change tracking for a specified iModel."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id 1a2b3c4d-5678-90ab-cdef-1234567890ab --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id 1a2b3c4d-5678-90ab-cdef-1234567890ab --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, + description: 'Example 1:' + } + ]; - static flags = { - "imodel-id": CustomFlags.iModelIDFlag({ - description: "The ID of the iModel where change tracking should be disabled." - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: "The ID of the iTwin associated with the iModel." - }), - }; + public static flags = { + "imodel-id": customFlags.iModelIDFlag({ + description: "The ID of the iModel where change tracking should be disabled." + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: "The ID of the iTwin associated with the iModel." + }), + }; - async run() { - const { flags } = await this.parse(ChangedElementsDisable); + public async run() { + const { flags } = await this.parse(ChangedElementsDisable); - const client = await this.getChangeElementApiClient(); + const client = await this.getChangeElementApiClient(); - await client.changeTracking({ - enable: false, - iModelId: flags["imodel-id"], - iTwinId: flags["itwin-id"], - }); + await client.changeTracking({ + enable: false, + iModelId: flags["imodel-id"], + iTwinId: flags["itwin-id"], + }); - return this.logAndReturnResult({ result: 'disabled' }); - } + return this.logAndReturnResult({ result: 'disabled' }); } +} diff --git a/src/commands/changed-elements/enable.ts b/src/commands/changed-elements/enable.ts index af798a0a..9f46daa0 100644 --- a/src/commands/changed-elements/enable.ts +++ b/src/commands/changed-elements/enable.ts @@ -5,43 +5,43 @@ import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; -import { CustomFlags } from "../../extensions/custom-flags.js"; +import { customFlags } from "../../extensions/custom-flags.js"; export default class ChangedElementsEnable extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/changed-elements/operations/enable-change-tracking/", - name: "Enable Change Tracking", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/changed-elements/operations/enable-change-tracking/", + name: "Enable Change Tracking", + }; - static description = "Enable change tracking for a specified iModel."; + public static description = "Enable change tracking for a specified iModel."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id 1a2b3c4d-5678-90ab-cdef-1234567890ab --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id 1a2b3c4d-5678-90ab-cdef-1234567890ab --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, + description: 'Example 1:' + } + ]; - static flags = { - "imodel-id": CustomFlags.iModelIDFlag({ - description: "The ID of the iModel where change tracking should be enabled." - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: "The ID of the iTwin associated with the iModel." - }), - }; + public static flags = { + "imodel-id": customFlags.iModelIDFlag({ + description: "The ID of the iModel where change tracking should be enabled." + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: "The ID of the iTwin associated with the iModel." + }), + }; - async run() { - const { flags } = await this.parse(ChangedElementsEnable); + public async run() { + const { flags } = await this.parse(ChangedElementsEnable); - const client = await this.getChangeElementApiClient(); + const client = await this.getChangeElementApiClient(); - await client.changeTracking({ - enable: true, - iModelId: flags["imodel-id"], - iTwinId: flags["itwin-id"], - }); + await client.changeTracking({ + enable: true, + iModelId: flags["imodel-id"], + iTwinId: flags["itwin-id"], + }); - return this.logAndReturnResult({ result: 'enabled' }); - } + return this.logAndReturnResult({ result: 'enabled' }); } +} diff --git a/src/commands/changed-elements/info.ts b/src/commands/changed-elements/info.ts index e51ac8a5..e88d75ad 100644 --- a/src/commands/changed-elements/info.ts +++ b/src/commands/changed-elements/info.ts @@ -5,38 +5,38 @@ import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; -import { CustomFlags } from "../../extensions/custom-flags.js"; +import { customFlags } from "../../extensions/custom-flags.js"; export default class ChangedElementsInfo extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/changed-elements/operations/get-tracking/", - name: "Get Tracking Info", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/changed-elements/operations/get-tracking/", + name: "Get Tracking Info", + }; - static description = "Retrieve change tracking information for a specified iModel."; + public static description = "Retrieve change tracking information for a specified iModel."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id 1a2b3c4d-5678-90ab-cdef-1234567890ab --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id 1a2b3c4d-5678-90ab-cdef-1234567890ab --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, + description: 'Example 1:' + } + ]; - static flags = { - "imodel-id": CustomFlags.iModelIDFlag({ - description: "The ID of the iModel to retrieve tracking information for." - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: "The ID of the iTwin associated with the iModel." - }), - }; + public static flags = { + "imodel-id": customFlags.iModelIDFlag({ + description: "The ID of the iModel to retrieve tracking information for." + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: "The ID of the iTwin associated with the iModel." + }), + }; - async run() { - const { flags } = await this.parse(ChangedElementsInfo); + public async run() { + const { flags } = await this.parse(ChangedElementsInfo); - const client = await this.getChangeElementApiClient(); - const result = await client.getTracking(flags["imodel-id"], flags["itwin-id"]); + const client = await this.getChangeElementApiClient(); + const result = await client.getTracking(flags["imodel-id"], flags["itwin-id"]); - return this.logAndReturnResult(result); - } + return this.logAndReturnResult(result); } +} diff --git a/src/commands/context/clear.ts b/src/commands/context/clear.ts index 298f1af2..3a39c0ed 100644 --- a/src/commands/context/clear.ts +++ b/src/commands/context/clear.ts @@ -6,17 +6,17 @@ import BaseCommand from "../../extensions/base-command.js"; export default class ClearContext extends BaseCommand { - static description = "Clear the cached context."; + public static description = "Clear the cached context."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %>`, - description: 'Example 1: Clear the cached context' - } - ]; - - async run() { - this.clearContext(); - return this.logAndReturnResult({ result: "Context cleared." }); + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %>`, + description: 'Example 1: Clear the cached context' } + ]; + + public async run() { + await this.clearContext(); + return this.logAndReturnResult({ result: "Context cleared." }); + } } \ No newline at end of file diff --git a/src/commands/context/info.ts b/src/commands/context/info.ts index 96733b23..189b2780 100644 --- a/src/commands/context/info.ts +++ b/src/commands/context/info.ts @@ -6,17 +6,17 @@ import BaseCommand from "../../extensions/base-command.js"; export default class InfoContext extends BaseCommand { - static description = "Display the cached context."; + public static description = "Display the cached context."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %>`, - description: 'Example 1: Display the cached context' - } - ]; - - async run() { - const context = this.getContext(); - return this.logAndReturnResult(context); + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %>`, + description: 'Example 1: Display the cached context' } + ]; + + public async run() { + const context = this.getContext(); + return this.logAndReturnResult(context); + } } \ No newline at end of file diff --git a/src/commands/context/set.ts b/src/commands/context/set.ts index 2494604f..6f8d6781 100644 --- a/src/commands/context/set.ts +++ b/src/commands/context/set.ts @@ -10,60 +10,61 @@ import { Flags } from "@oclif/core"; import BaseCommand from "../../extensions/base-command.js"; export default class SetContext extends BaseCommand { - static description = "Set a new cached context. This works by saving iModel and/or iTwin IDs to a file in CLI cache directory.\nNOTE: CLI cache directory can usually be found at: `%LOCALAPPDATA%/itp` on windows, `~/.cache/itp` on UNIX and `~/Library/Caches/itp` on macOS.\nNOTE2: CLI cache directory can be overriden by setting `XDG_CACHE_HOME` environment variable, which is useful in case there is a need to use context in multiple concurrent workflows."; + public static description = "Set a new cached context. This works by saving iModel and/or iTwin IDs to a file in CLI cache directory.\nNOTE: CLI cache directory can usually be found at: `%LOCALAPPDATA%/itp` on windows, `~/.cache/itp` on UNIX and `~/Library/Caches/itp` on macOS.\nNOTE2: CLI cache directory can be overriden by setting `XDG_CACHE_HOME` environment variable, which is useful in case there is a need to use context in multiple concurrent workflows."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id 12345`, - description: 'Example 1: Set a new cached context using an iTwin ID' - }, - { - command: `<%= config.bin %> <%= command.id %> --imodel-id 67890`, - description: 'Example 2: Set a new cached context using an iModel ID' - }, - { - command: `<%= config.bin %> <%= command.id %>`, - description: 'Example 3: Error when neither --itwin-id nor --imodel-id is provided' - } - ]; - - static flags = { - "imodel-id": Flags.string({ - atLeastOne: ['imodel-id', 'itwin-id'], - char: 'm', - description: "The ID of the iModel to create a context for.", - helpValue: '', - required: false - }), - "itwin-id": Flags.string({ - char: 'i', - description: "The ID of the iTwin to create a context for.", - helpValue: '', - required: false, - }), - }; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id 12345`, + description: 'Example 1: Set a new cached context using an iTwin ID' + }, + { + command: `<%= config.bin %> <%= command.id %> --imodel-id 67890`, + description: 'Example 2: Set a new cached context using an iModel ID' + }, + { + command: `<%= config.bin %> <%= command.id %>`, + description: 'Example 3: Error when neither --itwin-id nor --imodel-id is provided' + } + ]; - async run() { - const { flags } = await this.parseWithoutContext(SetContext); - const iModelId = flags["imodel-id"]; - let iTwinId = flags["itwin-id"]; + public static flags = { + "imodel-id": Flags.string({ + atLeastOne: ['imodel-id', 'itwin-id'], + char: 'm', + description: "The ID of the iModel to create a context for.", + helpValue: '', + required: false + }), + "itwin-id": Flags.string({ + char: 'i', + description: "The ID of the iTwin to create a context for.", + helpValue: '', + required: false, + }), + }; - // If iModelId is provided, check if it exists - // and verify that it belongs to the specified iTwinId - if(iModelId) { - const iModel = await this.runCommand("imodel:info", ["--imodel-id", iModelId]); - if(iTwinId && iModel.iTwinId !== flags["itwin-id"]) { - this.error(`The iModel ID ${iModelId} does not belong to the specified iTwin ID ${iTwinId}.`); - } + public async run() { + const { flags } = await this.parseWithoutContext(SetContext); + const iModelId = flags["imodel-id"]; + let iTwinId = flags["itwin-id"]; - iTwinId = iModel.iTwinId; - } - // If iTwinId is provided, check if it exists - else if (iTwinId) { - await this.runCommand("itwin:info", ["--itwin-id", iTwinId]); - } + // If iModelId is provided, check if it exists + // and verify that it belongs to the specified iTwinId + if(iModelId) { + const iModel = await this.runCommand("imodel:info", ["--imodel-id", iModelId]); + if(iTwinId && iModel.iTwinId !== flags["itwin-id"]) { + this.error(`The iModel ID ${iModelId} does not belong to the specified iTwin ID ${iTwinId}.`); + } - const context = await this.setContext(iTwinId!, iModelId); - return this.logAndReturnResult(context); + iTwinId = iModel.iTwinId; } + // If iTwinId is provided, check if it exists + else if (iTwinId) { + await this.runCommand("itwin:info", ["--itwin-id", iTwinId]); + } + + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const context = await this.setContext(iTwinId!, iModelId); + return this.logAndReturnResult(context); + } } \ No newline at end of file diff --git a/src/commands/docs-generator.ts b/src/commands/docs-generator.ts index 2f296b1b..12e9aa11 100644 --- a/src/commands/docs-generator.ts +++ b/src/commands/docs-generator.ts @@ -6,161 +6,161 @@ import { ApiReference } from "../extensions/api-reference.js"; import BaseCommand from "../extensions/base-command.js"; export default class DocsGenerator extends BaseCommand { - static description = "Generate command and overview markdown files for the CLI."; + public static description = "Generate command and overview markdown files for the CLI."; + + public static flags = { + "output-dir": Flags.string({ + char: "o", + description: "The output directory for the documentation files.", + }), + }; + + public static hidden = true; + + private generateCommandMarkdown(command: Command.Loadable, flags: [string, Command.Flag.Cached][]): string { + const options = flags.length > 0 + ? + flags.filter(([_, flag]) => !flag.hidden && flag.helpGroup !== "GLOBAL") + .sort(([nameA, flagA], [nameB, flagB]) => { + if (flagA.required !== flagB.required) { + return flagA.required ? -1 : 1; + } + + return nameA.localeCompare(nameB); + }) + .map(([name, flag]) => { + const required = flag.required ? "**Required:** Yes" : "**Required:** No"; + const multipleProperty = flag.type === "option" && flag.multiple ? "**Multiple:** Yes" : ""; + let type = ""; + let validValues = ""; + if(flag.type === "option") { + type = `**Type:** \`${typeof flag.helpValue === 'string' ? flag.helpValue?.slice(1, -1): new Error("Not Implemented")}\``; + if(Array.isArray(flag.options)) { + validValues = `\n **Valid Values:** \`"${flag.options.join('"`, `"')}"\``; + } + } + else { + type = '**Type:** `flag`'; + } - static flags = { - "output-dir": Flags.string({ - char: "o", - description: "The output directory for the documentation files.", - }), - } + const description = flag.description ?? ""; + const flagName = flag.char ? `-${flag.char}, --${name}` : `--${name}`; + const finalResult = `- **\`${flagName}\`** \n ${description} \n ${type} ${required} ${multipleProperty} ${validValues}`; + return finalResult.trim(); + }) + .join("\n\n") + : ""; - static hidden = true; - - generateCommandMarkdown(command: Command.Loadable, flags: [string, Command.Flag.Cached][]): string { - const options = flags.length > 0 - ? - flags.filter(([_, flag]) => !flag.hidden && flag.helpGroup !== "GLOBAL") - .sort(([nameA, flagA], [nameB, flagB]) => { - if (flagA.required !== flagB.required) { - return flagA.required ? -1 : 1; - } - - return nameA.localeCompare(nameB); - }) - .map(([name, flag]) => { - const required = flag.required ? "**Required:** Yes" : "**Required:** No"; - const multipleProperty = flag.type === "option" && flag.multiple ? "**Multiple:** Yes" : ""; - let type = ""; - let validValues = ""; - if(flag.type === "option") { - type = `**Type:** \`${flag.helpValue?.slice(1, -1)}\``; - if(Array.isArray(flag.options)) { - validValues = `\n **Valid Values:** \`"${flag.options.join('"`, `"')}"\``; - } - } - else { - type = '**Type:** `flag`'; - } - - const description = flag.description ?? ""; - const flagName = flag.char ? `-${flag.char}, --${name}` : `--${name}`; - const finalResult = `- **\`${flagName}\`** \n ${description} \n ${type} ${required} ${multipleProperty} ${validValues}`; - return finalResult.trim(); - }) - .join("\n\n") - : ""; - - - - let examplesText = ""; - - if (command.examples) { - for (const example of command.examples) { - if (typeof example === "string") { - examplesText += `\n${example}`; - } - - if (typeof example === "object") { - // Do not display description for examples where only "Example #:" is present - examplesText += example.description.slice(0, -2) === "Example " ? `\n${example.command}\n` : `\n# ${example.description}\n${example.command}\n`; - } - } + + + let examplesText = ""; + + if (command.examples) { + for (const example of command.examples) { + if (typeof example === "string") { + examplesText += `\n${example}`; + } + + if (typeof example === "object") { + // Do not display description for examples where only "Example #:" is present + examplesText += example.description.slice(0, -2) === "Example " ? `\n${example.command}\n` : `\n# ${example.description}\n${example.command}\n`; } + } + } - const commandName = command.id.split(":").join(" "); + const commandName = command.id.split(":").join(" "); - examplesText = examplesText.replaceAll("<%= config.bin %>", "itp").replaceAll("<%= command.id %>", commandName).trimEnd(); + examplesText = examplesText.replaceAll("<%= config.bin %>", "itp").replaceAll("<%= command.id %>", commandName).trimEnd(); - const returnContent : string[] = []; + const returnContent : string[] = []; - returnContent.push(`# itp ${commandName}`); + returnContent.push(`# itp ${commandName}`); - if(command.description) { - returnContent.push(command.description); - } + if(command.description) { + returnContent.push(command.description); + } - returnContent.push('## Options'); + returnContent.push('## Options'); - if(options.length > 1) { - returnContent.push(options); - } - else { - returnContent.push("(This command does not have any options)"); - } + if(options.length > 1) { + returnContent.push(options); + } + else { + returnContent.push("(This command does not have any options)"); + } - returnContent.push('## Examples', - `\`\`\`bash${examplesText}\n\`\`\``); + returnContent.push('## Examples', + `\`\`\`bash${examplesText}\n\`\`\``); - if(command.apiReference) { - if(Array.isArray(command.apiReference)) { - const apiReferences = command.apiReference as ApiReference[]; - returnContent.push(`## ${command.apiReference[0].sectionName ?? 'API Reference'}`); - for (const apiRef of apiReferences) { - returnContent.push(`[${apiRef.name}](${apiRef.link})`); - } - } - else { - const apiReference = command.apiReference as ApiReference; - returnContent.push(`## ${apiReference.sectionName ?? 'API Reference'}`, `[${apiReference.name}](${apiReference.link})`); - } + if(command.apiReference) { + if(Array.isArray(command.apiReference)) { + const apiReferences = command.apiReference as ApiReference[]; + returnContent.push(`## ${command.apiReference[0].sectionName ?? 'API Reference'}`); + for (const apiRef of apiReferences) { + returnContent.push(`[${apiRef.name}](${apiRef.link})`); } - - return returnContent.join("\n\n"); + } + else { + const apiReference = command.apiReference as ApiReference; + returnContent.push(`## ${apiReference.sectionName ?? 'API Reference'}`, `[${apiReference.name}](${apiReference.link})`); + } } + + return returnContent.join("\n\n"); + } - async generateDocs(config: Config, basePath: string) { - const filteredCommands = config.commands.filter(c => !c.id.includes("help") && !c.id.includes("plugins") && !c.hidden); - if(!filteredCommands) { - return; - } + private async generateDocs(config: Config, basePath: string) { + const filteredCommands = config.commands.filter(c => !c.id.includes("help") && !c.id.includes("plugins") && !c.hidden); + if(!filteredCommands) { + return; + } - for (const command of filteredCommands) { - this.log(`Generating docs for command: ${command.id}`); - if(command.customDocs) { - this.log(`Skipping command ${command.id} as it has custom docs`); - continue; - } + for (const command of filteredCommands) { + this.log(`Generating docs for command: ${command.id}`); + if(command.customDocs) { + this.log(`Skipping command ${command.id} as it has custom docs`); + continue; + } - const markdown: string = this.generateCommandMarkdown(command, Object.entries(command.flags)); + const markdown: string = this.generateCommandMarkdown(command, Object.entries(command.flags)); - const commandDepth = command.id.split(":"); - let filePath = basePath; - for (const depth of commandDepth) { - filePath = `${filePath}/${depth}`; - } + const commandDepth = command.id.split(":"); + let filePath = basePath; + for (const depth of commandDepth) { + filePath = `${filePath}/${depth}`; + } - this.writeToFile(filePath, markdown); - } - } - - async run() { - const {flags} = await this.parse(DocsGenerator); - - const config = await Config.load( - { - devPlugins: false, - root: process.cwd(), - userPlugins: false, - } - ); - - this.generateDocs(config, flags["output-dir"] ?? `${config.root}/docs`); - } + this.writeToFile(filePath, markdown); + } + } + + public async run() { + const {flags} = await this.parse(DocsGenerator); + + const config = await Config.load( + { + devPlugins: false, + root: process.cwd(), + userPlugins: false, + } + ); + + await this.generateDocs(config, flags["output-dir"] ?? `${config.root}/docs`); + } - writeToFile(filePath: string, markdown: string) { - const finalPath = `${filePath}.md`; - this.log(`Writing to directory: ${finalPath}`); - - const dirName = path.dirname(finalPath); - if (!fs.existsSync(dirName)) { - fs.mkdirSync(dirName, { - recursive: true, - }); - } - - fs.writeFileSync(finalPath, markdown); + private writeToFile(filePath: string, markdown: string) { + const finalPath = `${filePath}.md`; + this.log(`Writing to directory: ${finalPath}`); + + const dirName = path.dirname(finalPath); + if (!fs.existsSync(dirName)) { + fs.mkdirSync(dirName, { + recursive: true, + }); } + + fs.writeFileSync(finalPath, markdown); + } } diff --git a/src/commands/imodel/changeset/info.ts b/src/commands/imodel/changeset/info.ts index 5c6d6b72..218bcbfe 100644 --- a/src/commands/imodel/changeset/info.ts +++ b/src/commands/imodel/changeset/info.ts @@ -7,63 +7,64 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class ChangesetInfo extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/imodels-v2/operations/get-imodel-changeset-details/", - name: "Get Changeset Details", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/imodels-v2/operations/get-imodel-changeset-details/", + name: "Get Changeset Details", + }; - static description = `Retrieve details about a specific changeset of an iModel. Exactly one of ['changeset-id', 'changeset-index'] flags needs to be provided.`; + public static description = `Retrieve details about a specific changeset of an iModel. Exactly one of ['changeset-id', 'changeset-index'] flags needs to be provided.`; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --changeset-id 2f3b4a8c92d747d5c8a8b2f9cde6742e5d74b3b5`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --changeset-id 2f3b4a8c92d747d5c8a8b2f9cde6742e5d74b3b5`, + description: 'Example 1:' + } + ]; - static flags = { - "changeset-id": Flags.string({ - description: 'The ID of the changeset. Mutually exclusive with --changeset-index flag.', - exactlyOne: ["changeset-id", "changeset-index"], - helpValue: '', - required: false, - }), - "changeset-index": Flags.integer({ - description: 'The index of the changeset. Mutually exclusive with --changeset-id flag.', - helpValue: '', - required: false, - }), - "imodel-id": CustomFlags.iModelIDFlag({ - description: 'The ID of the iModel whose changeset you want to retrieve.', - }), - }; + public static flags = { + "changeset-id": Flags.string({ + description: 'The ID of the changeset. Mutually exclusive with --changeset-index flag.', + exactlyOne: ["changeset-id", "changeset-index"], + helpValue: '', + required: false, + }), + "changeset-index": Flags.integer({ + description: 'The index of the changeset. Mutually exclusive with --changeset-id flag.', + helpValue: '', + required: false, + }), + "imodel-id": customFlags.iModelIDFlag({ + description: 'The ID of the iModel whose changeset you want to retrieve.', + }), + }; - async run() { - const { flags } = await this.parse(ChangesetInfo); + public async run() { + const { flags } = await this.parse(ChangesetInfo); - const client = this.getIModelClient(); - const authorization = await this.getAuthorizationCallback(); + const client = this.getIModelClient(); + const authorization = await this.getAuthorizationCallback(); - if(flags["changeset-id"]) { - const changesetInfo = await client.changesets.getSingle({ - authorization, - changesetId: flags["changeset-id"], - iModelId: flags["imodel-id"], - }); + if(flags["changeset-id"]) { + const changesetInfo = await client.changesets.getSingle({ + authorization, + changesetId: flags["changeset-id"], + iModelId: flags["imodel-id"], + }); - return this.logAndReturnResult(changesetInfo); - } + return this.logAndReturnResult(changesetInfo); + } + if(flags["changeset-index"]) { const changesetInfo = await client.changesets.getSingle({ authorization, - changesetIndex: flags["changeset-index"]!, + changesetIndex: flags["changeset-index"], iModelId: flags["imodel-id"], }); - + return this.logAndReturnResult(changesetInfo); - } } +} diff --git a/src/commands/imodel/changeset/list.ts b/src/commands/imodel/changeset/list.ts index 1fc666d4..0f087354 100644 --- a/src/commands/imodel/changeset/list.ts +++ b/src/commands/imodel/changeset/list.ts @@ -8,94 +8,94 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class ListChangesets extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/imodels-v2/operations/get-imodel-changesets/", - name: "List Changesets", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/imodels-v2/operations/get-imodel-changesets/", + name: "List Changesets", + }; - static description = 'List all changesets for a specific iModel.'; + public static description = 'List all changesets for a specific iModel.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --top 10`, - description: 'Example 1: List the first 10 changesets for a specific iModel' - }, - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --skip 5 --top 10`, - description: 'Example 2: Skip the first 5 changesets and return the next 10' - }, - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --after-index 100 --order-by asc`, - description: 'Example 3: List all changesets after a specific index in ascending order' - }, - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --last-index 200 --order-by desc`, - description: 'Example 4: List all changesets up to a specific index in descending order' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --top 10`, + description: 'Example 1: List the first 10 changesets for a specific iModel' + }, + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --skip 5 --top 10`, + description: 'Example 2: Skip the first 5 changesets and return the next 10' + }, + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --after-index 100 --order-by asc`, + description: 'Example 3: List all changesets after a specific index in ascending order' + }, + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --last-index 200 --order-by desc`, + description: 'Example 4: List all changesets up to a specific index in descending order' + } + ]; - static flags = { - "after-index": Flags.integer({ - description: 'List changesets after a specific index (exclusive).', - helpValue: '', - required: false, - }), - "imodel-id": CustomFlags.iModelIDFlag({ - description: 'The ID of the iModel whose changesets you want to list.' - }), - "last-index": Flags.integer({ - description: 'List changesets up to a specific index (inclusive).', - helpValue: '', - required: false, - }), - "order-by": Flags.string({ - description: 'Order the changesets by their index. Can be asc for ascending or desc for descending order.', - helpValue: '', - options: ["asc", "desc"], - required: false, - }), - skip: Flags.integer({ - description: 'The number of changesets to skip.', - helpValue: '', - required: false, - }), - top: Flags.integer({ - description: 'The maximum number of changesets to return.', - helpValue: '', - required: false, - }), - }; + public static flags = { + "after-index": Flags.integer({ + description: 'List changesets after a specific index (exclusive).', + helpValue: '', + required: false, + }), + "imodel-id": customFlags.iModelIDFlag({ + description: 'The ID of the iModel whose changesets you want to list.' + }), + "last-index": Flags.integer({ + description: 'List changesets up to a specific index (inclusive).', + helpValue: '', + required: false, + }), + "order-by": Flags.string({ + description: 'Order the changesets by their index. Can be asc for ascending or desc for descending order.', + helpValue: '', + options: ["asc", "desc"], + required: false, + }), + skip: Flags.integer({ + description: 'The number of changesets to skip.', + helpValue: '', + required: false, + }), + top: Flags.integer({ + description: 'The maximum number of changesets to return.', + helpValue: '', + required: false, + }), + }; - async run() { - const { flags } = await this.parse(ListChangesets); + public async run() { + const { flags } = await this.parse(ListChangesets); - const client = this.getIModelClient(); - const authorization = await this.getAuthorizationCallback(); + const client = this.getIModelClient(); + const authorization = await this.getAuthorizationCallback(); - const orderBy: OrderBy | undefined= flags["order-by"] ? { - operator: flags["order-by"] as OrderByOperator, - property: ChangesetOrderByProperty.Index - } : undefined; + const orderBy: OrderBy | undefined= flags["order-by"] ? { + operator: flags["order-by"] as OrderByOperator, + property: ChangesetOrderByProperty.Index + } : undefined; - const urlParams = { - $orderBy: orderBy, - $skip: flags.skip, - $top: flags.top, - afterIndex: flags["after-index"], - lastIndex: flags["last-index"] - }; + const urlParams = { + $orderBy: orderBy, + $skip: flags.skip, + $top: flags.top, + afterIndex: flags["after-index"], + lastIndex: flags["last-index"] + }; - const changesetList = client.changesets.getRepresentationList({ - authorization, - iModelId: flags["imodel-id"], - urlParams - }); + const changesetList = client.changesets.getRepresentationList({ + authorization, + iModelId: flags["imodel-id"], + urlParams + }); - const result : Changeset[] = await (flags.top ? take(changesetList, flags.top) : toArray(changesetList)); + const result : Changeset[] = await (flags.top ? take(changesetList, flags.top) : toArray(changesetList)); - return this.logAndReturnResult(result); - } + return this.logAndReturnResult(result); } +} diff --git a/src/commands/imodel/connection/auth.ts b/src/commands/imodel/connection/auth.ts index 9ec020e1..152a01a2 100644 --- a/src/commands/imodel/connection/auth.ts +++ b/src/commands/imodel/connection/auth.ts @@ -1,5 +1,3 @@ -/* eslint-disable no-await-in-loop */ - /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. @@ -12,21 +10,21 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class ConnectionAuth extends BaseCommand { - static apiReference: ApiReference = { + public static apiReference: ApiReference = { link: "https://developer.bentley.com/apis/synchronization/operations/get-authorization-information/", name: "Get Authorization Information", }; - static description = 'Ensures the user has a valid token for long-running connection tasks. This must be called before starting a connection run with User authenticationType.'; + public static description = 'Ensures the user has a valid token for long-running connection tasks. This must be called before starting a connection run with User authenticationType.'; - static examples = [ + public static examples = [ { command: `<%= config.bin %> <%= command.id %>`, description: 'Example 1:' } ]; - async run() { + public async run() { await this.parse(ConnectionAuth); const client = await this.getSynchronizationClient(); @@ -69,7 +67,7 @@ export default class ConnectionAuth extends BaseCommand { { response = await client.authorizeUserForConnection(); this.debug(`Current state of user connection authentication is ${response.authorizationInformation.isUserAuthorized}`); - await new Promise(r => {setTimeout(r, 3000 * index)}); + await new Promise(r => {setTimeout(r, 3000 * index);}); } server.close(); diff --git a/src/commands/imodel/connection/create.ts b/src/commands/imodel/connection/create.ts index aa65b297..5fa1ff38 100644 --- a/src/commands/imodel/connection/create.ts +++ b/src/commands/imodel/connection/create.ts @@ -7,21 +7,21 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; import { AuthorizationInformation, AuthorizationType } from "../../../services/authorization-client/authorization-type.js"; import { AuthenticationType } from "../../../services/synchronizationClient/models/authentication-type.js"; import { ConnectorType } from "../../../services/synchronizationClient/models/connector-type.js"; import { StorageFileCreate } from "../../../services/synchronizationClient/models/storage-file-create.js"; export default class CreateConnection extends BaseCommand { - static apiReference: ApiReference = { + public static apiReference: ApiReference = { link: "https://developer.bentley.com/apis/synchronization/operations/create-storage-connection/", name: "Create Storage Connection", }; - static description = 'Create a storage connection that describes files from storage to synchronize with an iModel.'; + public static description = 'Create a storage connection that describes files from storage to synchronize with an iModel.'; - static examples = [ + public static examples = [ { command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --file-id t5bDFuN4qUa9ojVw1E5FGtldp8BgSbNCiJ2XMdiT-cA --connector-type MSTN`, description: 'Example 1: Minimal example with only required options' @@ -32,7 +32,7 @@ export default class CreateConnection extends BaseCommand { } ]; - static flags = { + public static flags = { "authentication-type": Flags.string({ description: `The authorization workflow type. Default value depends on currently used authentication type as follows: Interactive login -> 'User', Service Client login -> 'Service'`, helpValue: '', @@ -68,7 +68,7 @@ export default class CreateConnection extends BaseCommand { multiple: true, required: true }), - "imodel-id": CustomFlags.iModelIDFlag({ + "imodel-id": customFlags.iModelIDFlag({ description: 'The ID of the iModel.' }), name: Flags.string({ @@ -79,7 +79,7 @@ export default class CreateConnection extends BaseCommand { }), }; - async run() { + public async run() { const { flags } = await this.parse(CreateConnection); const client = await this.getSynchronizationClient(); @@ -92,7 +92,7 @@ export default class CreateConnection extends BaseCommand { const isSingleConnectorTypeProvided = flags["connector-type"].length === 1; for (let i = 0; i < flags["file-id"].length; i++) { - const connectorType = isSingleConnectorTypeProvided ? flags["connector-type"][0] as ConnectorType : flags["connector-type"][i] as ConnectorType + const connectorType = isSingleConnectorTypeProvided ? flags["connector-type"][0] as ConnectorType : flags["connector-type"][i] as ConnectorType; sourceFiles.push({ connectorType, storageFileId: flags["file-id"][i] diff --git a/src/commands/imodel/connection/delete.ts b/src/commands/imodel/connection/delete.ts index b4fd3720..7d0985f8 100644 --- a/src/commands/imodel/connection/delete.ts +++ b/src/commands/imodel/connection/delete.ts @@ -9,37 +9,37 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class DeleteConnection extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/synchronization/operations/delete-storage-connection/", - name: "Delete Storage Connection", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/synchronization/operations/delete-storage-connection/", + name: "Delete Storage Connection", + }; - static description = 'Delete a storage connection of an iModel.'; + public static description = 'Delete a storage connection of an iModel.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, + description: 'Example 1:' + } + ]; - static flags = { - "connection-id": Flags.string({ - char: 'c', - description: 'The ID of the storage connection to delete.', - helpValue: '', - required: true, - }), - }; + public static flags = { + "connection-id": Flags.string({ + char: 'c', + description: 'The ID of the storage connection to delete.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(DeleteConnection); + public async run() { + const { flags } = await this.parse(DeleteConnection); - const client = await this.getSynchronizationClient(); + const client = await this.getSynchronizationClient(); - await client.deleteStorageConnection(flags["connection-id"]); + await client.deleteStorageConnection(flags["connection-id"]); - return this.logAndReturnResult({ result: 'deleted' }); - } + return this.logAndReturnResult({ result: 'deleted' }); } +} \ No newline at end of file diff --git a/src/commands/imodel/connection/info.ts b/src/commands/imodel/connection/info.ts index 19ca5b17..b1d91d1b 100644 --- a/src/commands/imodel/connection/info.ts +++ b/src/commands/imodel/connection/info.ts @@ -9,37 +9,37 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class ConnectionInfo extends BaseCommand { - static apiReference : ApiReference = { - link: "https://developer.bentley.com/apis/synchronization/operations/get-storage-connection/", - name: "Get Storage Connection", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/synchronization/operations/get-storage-connection/", + name: "Get Storage Connection", + }; - static description = 'Retrieve details about a specific storage connection of an iModel.'; + public static description = 'Retrieve details about a specific storage connection of an iModel.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, + description: 'Example 1:' + } + ]; - static flags = { - "connection-id": Flags.string({ - char: 'c', - description: 'The ID of the storage connection to retrieve.', - helpValue: '', - required: true - }), - }; + public static flags = { + "connection-id": Flags.string({ + char: 'c', + description: 'The ID of the storage connection to retrieve.', + helpValue: '', + required: true + }), + }; - async run() { - const { flags } = await this.parse(ConnectionInfo); + public async run() { + const { flags } = await this.parse(ConnectionInfo); - const client = await this.getSynchronizationClient(); + const client = await this.getSynchronizationClient(); - const response = await client.getStorageConnection(flags["connection-id"]); + const response = await client.getStorageConnection(flags["connection-id"]); - return this.logAndReturnResult(response.connection); - } + return this.logAndReturnResult(response.connection); } +} \ No newline at end of file diff --git a/src/commands/imodel/connection/list.ts b/src/commands/imodel/connection/list.ts index f547eaa4..64977f07 100644 --- a/src/commands/imodel/connection/list.ts +++ b/src/commands/imodel/connection/list.ts @@ -7,54 +7,54 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class ListConnections extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/synchronization/operations/get-storage-connections/", - name: "Get Storage Connections", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/synchronization/operations/get-storage-connections/", + name: "Get Storage Connections", + }; - static description = 'List all storage connections of a specific iModel.'; + public static description = 'List all storage connections of a specific iModel.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, - description: 'Example 1: Listing all connections for an iModel' - }, - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --top 5`, - description: 'Example 2: Listing the first 5 connections for an iModel' - }, - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --top 5 --skip 15`, - description: 'Example 3: Listing the 5 connections after the first 15 connections are skipped for an iModel' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, + description: 'Example 1: Listing all connections for an iModel' + }, + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --top 5`, + description: 'Example 2: Listing the first 5 connections for an iModel' + }, + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --top 5 --skip 15`, + description: 'Example 3: Listing the 5 connections after the first 15 connections are skipped for an iModel' + } + ]; - static flags = { - "imodel-id": CustomFlags.iModelIDFlag({ - description: 'The ID of the iModel whose storage connections you want to list.' - }), - skip: Flags.integer({ - description: 'The number of changesets to skip.', - helpValue: '', - required: false - }), - top: Flags.integer({ - description: 'The maximum number of changesets to return.', - helpValue: '', - required: false - }), - }; + public static flags = { + "imodel-id": customFlags.iModelIDFlag({ + description: 'The ID of the iModel whose storage connections you want to list.' + }), + skip: Flags.integer({ + description: 'The number of changesets to skip.', + helpValue: '', + required: false + }), + top: Flags.integer({ + description: 'The maximum number of changesets to return.', + helpValue: '', + required: false + }), + }; - async run() { - const { flags } = await this.parse(ListConnections); + public async run() { + const { flags } = await this.parse(ListConnections); - const client = await this.getSynchronizationClient(); + const client = await this.getSynchronizationClient(); - const response = await client.getStorageConnections(flags["imodel-id"], flags.top, flags.skip); + const response = await client.getStorageConnections(flags["imodel-id"], flags.top, flags.skip); - return this.logAndReturnResult(response); - } + return this.logAndReturnResult(response); } +} diff --git a/src/commands/imodel/connection/run/create.ts b/src/commands/imodel/connection/run/create.ts index 0be1e2c1..24db7b56 100644 --- a/src/commands/imodel/connection/run/create.ts +++ b/src/commands/imodel/connection/run/create.ts @@ -9,37 +9,37 @@ import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; export default class CreateConnectionRun extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/synchronization/operations/run-storage-connection/", - name: "Run Storage Connection", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/synchronization/operations/run-storage-connection/", + name: "Run Storage Connection", + }; - static description = "Run the specified storage connection to synchronize files with an iModel."; + public static description = "Run the specified storage connection to synchronize files with an iModel."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, - description: 'Example 1: Running a storage connection for an iModel' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, + description: 'Example 1: Running a storage connection for an iModel' + } + ]; - static flags = { - "connection-id": Flags.string({ - char: 'c', - description: 'The ID of the storage connection to run.', - helpValue: '', - required: true - }), - }; + public static flags = { + "connection-id": Flags.string({ + char: 'c', + description: 'The ID of the storage connection to run.', + helpValue: '', + required: true + }), + }; - async run() { - const { flags } = await this.parse(CreateConnectionRun); + public async run() { + const { flags } = await this.parse(CreateConnectionRun); - const client = await this.getSynchronizationClient(); + const client = await this.getSynchronizationClient(); - await client.createStorageConnectionRun(flags["connection-id"]); + await client.createStorageConnectionRun(flags["connection-id"]); - return this.logAndReturnResult({ result: 'started' }); - } + return this.logAndReturnResult({ result: 'started' }); + } } \ No newline at end of file diff --git a/src/commands/imodel/connection/run/info.ts b/src/commands/imodel/connection/run/info.ts index fdddb738..24770c6c 100644 --- a/src/commands/imodel/connection/run/info.ts +++ b/src/commands/imodel/connection/run/info.ts @@ -9,40 +9,40 @@ import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; export default class ConnectionRunInfo extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/synchronization/operations/get-storage-connection-run/", - name: "Get Storage Connection Run", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/synchronization/operations/get-storage-connection-run/", + name: "Get Storage Connection Run", + }; - static description = 'Retrieve details about a specific run of a storage connection.'; + public static description = 'Retrieve details about a specific run of a storage connection.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --connection-id abc12345-6789-4321-abcd-9876543210ef --connection-run-id run98765-4321-abcd-1234-567890abcdef`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --connection-id abc12345-6789-4321-abcd-9876543210ef --connection-run-id run98765-4321-abcd-1234-567890abcdef`, + description: 'Example 1:' + } + ]; - static flags = { - "connection-id": Flags.string({ - char: 'c', - description: 'The ID of the storage connection associated with the run.', - helpValue: '', - required: true - }), - "connection-run-id": Flags.string({ - description: 'The ID of the storage connection run.', - helpValue: '', - required: true }), - }; + public static flags = { + "connection-id": Flags.string({ + char: 'c', + description: 'The ID of the storage connection associated with the run.', + helpValue: '', + required: true + }), + "connection-run-id": Flags.string({ + description: 'The ID of the storage connection run.', + helpValue: '', + required: true }), + }; - async run() { - const { flags } = await this.parse(ConnectionRunInfo); + public async run() { + const { flags } = await this.parse(ConnectionRunInfo); - const client = await this.getSynchronizationClient(); + const client = await this.getSynchronizationClient(); - const response = await client.getStorageConnectionRun(flags["connection-id"], flags["connection-run-id"]); + const response = await client.getStorageConnectionRun(flags["connection-id"], flags["connection-run-id"]); - return this.logAndReturnResult(response.run); - } + return this.logAndReturnResult(response.run); } +} diff --git a/src/commands/imodel/connection/run/list.ts b/src/commands/imodel/connection/run/list.ts index 7ca5d08c..4d62b225 100644 --- a/src/commands/imodel/connection/run/list.ts +++ b/src/commands/imodel/connection/run/list.ts @@ -9,51 +9,51 @@ import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; export default class ConnectionRunsListed extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/synchronization/operations/get-storage-connection-runs/", - name: "Get Storage Connection Runs", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/synchronization/operations/get-storage-connection-runs/", + name: "Get Storage Connection Runs", + }; - static description = "List all runs for a specific storage connection."; + public static description = "List all runs for a specific storage connection."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, - description: 'Example 1: List all runs for a specific connection' - }, - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --top 10`, - description: 'Example 2: Limit the results to 10 runs' - }, - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --skip 5`, - description: 'Example 3: Skip the first 5 runs and return the next set' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, + description: 'Example 1: List all runs for a specific connection' + }, + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --top 10`, + description: 'Example 2: Limit the results to 10 runs' + }, + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --skip 5`, + description: 'Example 3: Skip the first 5 runs and return the next set' + } + ]; - static flags = { - "connection-id": Flags.string({ - char: 'c', - description: "The ID of the storage connection.", - helpValue: '', - required: true - }), - skip: Flags.integer({ - description: "Skip a number of runs in the result.", - helpValue: '' - }), - top: Flags.integer({ - description: "Limit the number of runs returned.", - helpValue: '' - }), - }; + public static flags = { + "connection-id": Flags.string({ + char: 'c', + description: "The ID of the storage connection.", + helpValue: '', + required: true + }), + skip: Flags.integer({ + description: "Skip a number of runs in the result.", + helpValue: '' + }), + top: Flags.integer({ + description: "Limit the number of runs returned.", + helpValue: '' + }), + }; - async run() { - const { flags } = await this.parse(ConnectionRunsListed); + public async run() { + const { flags } = await this.parse(ConnectionRunsListed); - const client = await this.getSynchronizationClient(); - const response = await client.getStorageConnectionRuns(flags["connection-id"], flags.top, flags.skip); + const client = await this.getSynchronizationClient(); + const response = await client.getStorageConnectionRuns(flags["connection-id"], flags.top, flags.skip); - return this.logAndReturnResult(response); - } + return this.logAndReturnResult(response); } +} diff --git a/src/commands/imodel/connection/sourcefile/add.ts b/src/commands/imodel/connection/sourcefile/add.ts index 49adbdae..6e5e873b 100644 --- a/src/commands/imodel/connection/sourcefile/add.ts +++ b/src/commands/imodel/connection/sourcefile/add.ts @@ -10,65 +10,65 @@ import BaseCommand from "../../../../extensions/base-command.js"; import { ConnectorType } from "../../../../services/synchronizationClient/models/connector-type.js"; export default class CreateConnectionSourceFile extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/synchronization/operations/add-storage-connection-sourcefile/", - name: "Add Storage Connection SourceFile", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/synchronization/operations/add-storage-connection-sourcefile/", + name: "Add Storage Connection SourceFile", + }; - static description = 'Add a source file to an existing storage connection of an iModel.'; + public static description = 'Add a source file to an existing storage connection of an iModel.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --storage-file-id t5bDFuN4qUa9ojVw1E5FGtldp8BgSbNCiJ2XMdiT-cA --connector-type MSTN`, - description: 'Example 1: Add a source file to a storage connection' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --storage-file-id t5bDFuN4qUa9ojVw1E5FGtldp8BgSbNCiJ2XMdiT-cA --connector-type MSTN`, + description: 'Example 1: Add a source file to a storage connection' + } + ]; - static flags = { - "connection-id": Flags.string({ - char: 'c', - description: 'The ID of the storage connection to which the source file will be added.', - helpValue: '', - required: true, - }), - "connector-type": Flags.string({ - description: 'The connector type for synchronization.', - helpValue: '', - options: [ - 'AUTOPLANT', - 'CIVIL', - 'CIVIL3D', - 'DWG', - 'GEOSPATIAL', - 'IFC', - 'MSTN', - 'NWD', - 'OBD', - 'OPENTOWER', - 'PROSTRUCTURES', - 'REVIT', - 'SPPID', - 'SPXREVIEW' - ], - required: true, - }), - "storage-file-id": Flags.string({ - description: 'The storage file ID.', - helpValue: '', - required: true, - }), - }; + public static flags = { + "connection-id": Flags.string({ + char: 'c', + description: 'The ID of the storage connection to which the source file will be added.', + helpValue: '', + required: true, + }), + "connector-type": Flags.string({ + description: 'The connector type for synchronization.', + helpValue: '', + options: [ + 'AUTOPLANT', + 'CIVIL', + 'CIVIL3D', + 'DWG', + 'GEOSPATIAL', + 'IFC', + 'MSTN', + 'NWD', + 'OBD', + 'OPENTOWER', + 'PROSTRUCTURES', + 'REVIT', + 'SPPID', + 'SPXREVIEW' + ], + required: true, + }), + "storage-file-id": Flags.string({ + description: 'The storage file ID.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(CreateConnectionSourceFile); + public async run() { + const { flags } = await this.parse(CreateConnectionSourceFile); - const client = await this.getSynchronizationClient(); + const client = await this.getSynchronizationClient(); - const response = await client.addSourceFile(flags["connection-id"], { - connectorType: flags["connector-type"] as ConnectorType, - storageFileId: flags["storage-file-id"], - }); + const response = await client.addSourceFile(flags["connection-id"], { + connectorType: flags["connector-type"] as ConnectorType, + storageFileId: flags["storage-file-id"], + }); - return this.logAndReturnResult(response.sourceFile); - } + return this.logAndReturnResult(response.sourceFile); } +} diff --git a/src/commands/imodel/connection/sourcefile/delete.ts b/src/commands/imodel/connection/sourcefile/delete.ts index 07681317..431b5cc9 100644 --- a/src/commands/imodel/connection/sourcefile/delete.ts +++ b/src/commands/imodel/connection/sourcefile/delete.ts @@ -9,41 +9,41 @@ import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; export default class ConnectionSourceFileDelete extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/synchronization/operations/remove-storage-connection-sourcefile/", - name: "Remove Storage Connection SourceFile", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/synchronization/operations/remove-storage-connection-sourcefile/", + name: "Remove Storage Connection SourceFile", + }; - static description = "Remove a source file from a storage connection of an iModel."; + public static description = "Remove a source file from a storage connection of an iModel."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --source-file-id 297c8ab9-53a3-4fe5-adf8-79b4c1a95cbb`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --source-file-id 297c8ab9-53a3-4fe5-adf8-79b4c1a95cbb`, + description: 'Example 1:' + } + ]; - static flags = { - "connection-id": Flags.string({ - char: 'c', - description: 'The ID of the storage connection.', - helpValue: '', - required: true, - }), - "source-file-id": Flags.string({ - description: 'The source file ID to delete.', - helpValue: '', - required: true, - }), - }; + public static flags = { + "connection-id": Flags.string({ + char: 'c', + description: 'The ID of the storage connection.', + helpValue: '', + required: true, + }), + "source-file-id": Flags.string({ + description: 'The source file ID to delete.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(ConnectionSourceFileDelete); + public async run() { + const { flags } = await this.parse(ConnectionSourceFileDelete); - const client = await this.getSynchronizationClient(); + const client = await this.getSynchronizationClient(); - await client.deleteSourceFile(flags["connection-id"], flags["source-file-id"]); + await client.deleteSourceFile(flags["connection-id"], flags["source-file-id"]); - return this.logAndReturnResult({ result: 'deleted' }); - } + return this.logAndReturnResult({ result: 'deleted' }); + } } diff --git a/src/commands/imodel/connection/sourcefile/info.ts b/src/commands/imodel/connection/sourcefile/info.ts index 04882c14..5f33c2ae 100644 --- a/src/commands/imodel/connection/sourcefile/info.ts +++ b/src/commands/imodel/connection/sourcefile/info.ts @@ -9,41 +9,41 @@ import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; export default class ConnectionSourceFileInfo extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/synchronization/operations/get-storage-connection-sourcefile/", - name: "Get Storage Connection SourceFile", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/synchronization/operations/get-storage-connection-sourcefile/", + name: "Get Storage Connection SourceFile", + }; - static description = 'Retrieve details about a specific source file in a storage connection of an iModel.'; + public static description = 'Retrieve details about a specific source file in a storage connection of an iModel.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --source-file-id 297c8ab9-53a3-4fe5-adf8-79b4c1a95cbb`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --source-file-id 297c8ab9-53a3-4fe5-adf8-79b4c1a95cbb`, + description: 'Example 1:' + } + ]; - static flags = { - "connection-id": Flags.string({ - char: 'c', - description: 'The ID of the storage connection.', - helpValue: '', - required: true, - }), - "source-file-id": Flags.string({ - description: 'The ID of the source file to retrieve.', - helpValue: '', - required: true, - }), - }; + public static flags = { + "connection-id": Flags.string({ + char: 'c', + description: 'The ID of the storage connection.', + helpValue: '', + required: true, + }), + "source-file-id": Flags.string({ + description: 'The ID of the source file to retrieve.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(ConnectionSourceFileInfo); + public async run() { + const { flags } = await this.parse(ConnectionSourceFileInfo); - const client = await this.getSynchronizationClient(); + const client = await this.getSynchronizationClient(); - const response = await client.getSourceFile(flags["connection-id"], flags["source-file-id"]); + const response = await client.getSourceFile(flags["connection-id"], flags["source-file-id"]); - return this.logAndReturnResult(response.sourceFile); - } + return this.logAndReturnResult(response.sourceFile); } +} diff --git a/src/commands/imodel/connection/sourcefile/list.ts b/src/commands/imodel/connection/sourcefile/list.ts index a33a6bf0..621e292b 100644 --- a/src/commands/imodel/connection/sourcefile/list.ts +++ b/src/commands/imodel/connection/sourcefile/list.ts @@ -9,51 +9,51 @@ import { ApiReference } from "../../../../extensions/api-reference.js"; import BaseCommand from "../../../../extensions/base-command.js"; export default class ListSourceFiles extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/synchronization/operations/get-storage-connection-sourcefiles/", - name: "Get Storage Connection SourceFiles", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/synchronization/operations/get-storage-connection-sourcefiles/", + name: "Get Storage Connection SourceFiles", + }; - static description = 'List all source files in a specific storage connection.'; + public static description = 'List all source files in a specific storage connection.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, - description: 'Example 1: List all source files in a specific storage connection' - }, - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --top 10`, - description: 'Example 2: Limit the results to 10 source files' - }, - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --skip 5`, - description: 'Example 3: Skip the first 5 source files and return the next set' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, + description: 'Example 1: List all source files in a specific storage connection' + }, + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --top 10`, + description: 'Example 2: Limit the results to 10 source files' + }, + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --skip 5`, + description: 'Example 3: Skip the first 5 source files and return the next set' + } + ]; - static flags = { - "connection-id": Flags.string({ - char: 'c', - description: 'The ID of the storage connection.', - helpValue: '', - required: true - }), - skip: Flags.integer({ - description: 'Skip a number of source files in the result.', - helpValue: '' - }), - top: Flags.integer({ - description: 'Limit the number of source files returned.', - helpValue: '' - }), - }; + public static flags = { + "connection-id": Flags.string({ + char: 'c', + description: 'The ID of the storage connection.', + helpValue: '', + required: true + }), + skip: Flags.integer({ + description: 'Skip a number of source files in the result.', + helpValue: '' + }), + top: Flags.integer({ + description: 'Limit the number of source files returned.', + helpValue: '' + }), + }; - async run() { - const { flags } = await this.parse(ListSourceFiles); + public async run() { + const { flags } = await this.parse(ListSourceFiles); - const client = await this.getSynchronizationClient(); - const response = await client.getSourceFiles(flags["connection-id"], flags.top, flags.skip); + const client = await this.getSynchronizationClient(); + const response = await client.getSourceFiles(flags["connection-id"], flags.top, flags.skip); - return this.logAndReturnResult(response.sourceFiles); - } + return this.logAndReturnResult(response.sourceFiles); } +} diff --git a/src/commands/imodel/connection/sourcefile/update.ts b/src/commands/imodel/connection/sourcefile/update.ts index a0bd8ebe..a553c2e8 100644 --- a/src/commands/imodel/connection/sourcefile/update.ts +++ b/src/commands/imodel/connection/sourcefile/update.ts @@ -10,70 +10,70 @@ import BaseCommand from "../../../../extensions/base-command.js"; import { ConnectorType } from "../../../../services/synchronizationClient/models/connector-type.js"; export default class ConnectionSourceFileUpdate extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/synchronization/operations/update-storage-connection-sourcefile/", - name: "Update Storage Connection SourceFile", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/synchronization/operations/update-storage-connection-sourcefile/", + name: "Update Storage Connection SourceFile", + }; - static description = 'Update an existing source file in a storage connection of an iModel.'; + public static description = 'Update an existing source file in a storage connection of an iModel.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --source-file-id 297c8ab9-53a3-4fe5-adf8-79b4c1a95cbb --connector-type DWG --storage-file-id b67d9839-2663-4465-a425-d1541d32e4c7`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --source-file-id 297c8ab9-53a3-4fe5-adf8-79b4c1a95cbb --connector-type DWG --storage-file-id b67d9839-2663-4465-a425-d1541d32e4c7`, + description: 'Example 1:' + } + ]; - static flags = { - "connection-id": Flags.string({ - char: 'c', - description: 'The ID of the storage connection.', - helpValue: '', - required: true, - }), - "connector-type": Flags.string({ - description: 'The connector type for synchronization.', - helpValue: '', - options: [ - 'AUTOPLANT', - 'CIVIL', - 'CIVIL3D', - 'DWG', - 'GEOSPATIAL', - 'IFC', - 'MSTN', - 'NWD', - 'OBD', - 'OPENTOWER', - 'PROSTRUCTURES', - 'REVIT', - 'SPPID', - 'SPXREVIEW' - ], - required: true, - }), - "source-file-id": Flags.string({ - description: 'The source file ID to update.', - helpValue: '', - required: true, - }), - "storage-file-id": Flags.string({ - description: 'The storage file ID to update to.', - helpValue: '', - required: true - }) - }; + public static flags = { + "connection-id": Flags.string({ + char: 'c', + description: 'The ID of the storage connection.', + helpValue: '', + required: true, + }), + "connector-type": Flags.string({ + description: 'The connector type for synchronization.', + helpValue: '', + options: [ + 'AUTOPLANT', + 'CIVIL', + 'CIVIL3D', + 'DWG', + 'GEOSPATIAL', + 'IFC', + 'MSTN', + 'NWD', + 'OBD', + 'OPENTOWER', + 'PROSTRUCTURES', + 'REVIT', + 'SPPID', + 'SPXREVIEW' + ], + required: true, + }), + "source-file-id": Flags.string({ + description: 'The source file ID to update.', + helpValue: '', + required: true, + }), + "storage-file-id": Flags.string({ + description: 'The storage file ID to update to.', + helpValue: '', + required: true + }) + }; - async run() { - const { flags } = await this.parse(ConnectionSourceFileUpdate); + public async run() { + const { flags } = await this.parse(ConnectionSourceFileUpdate); - const client = await this.getSynchronizationClient(); + const client = await this.getSynchronizationClient(); - const response = await client.updateSourceFile(flags["connection-id"], flags["source-file-id"], { - connectorType: flags["connector-type"] as ConnectorType, - storageFileId: flags["storage-file-id"], - }); + const response = await client.updateSourceFile(flags["connection-id"], flags["source-file-id"], { + connectorType: flags["connector-type"] as ConnectorType, + storageFileId: flags["storage-file-id"], + }); - return this.logAndReturnResult(response.sourceFile); - } + return this.logAndReturnResult(response.sourceFile); } +} diff --git a/src/commands/imodel/connection/update.ts b/src/commands/imodel/connection/update.ts index 298f8df0..18f772b1 100644 --- a/src/commands/imodel/connection/update.ts +++ b/src/commands/imodel/connection/update.ts @@ -10,55 +10,55 @@ import BaseCommand from "../../../extensions/base-command.js"; import { AuthenticationType } from "../../../services/synchronizationClient/models/authentication-type.js"; export default class UpdateStorageConnection extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/synchronization/operations/update-storage-connection/", - name: "Update Storage Connection", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/synchronization/operations/update-storage-connection/", + name: "Update Storage Connection", + }; - static description = 'Update an existing storage connection of an iModel.'; + public static description = 'Update an existing storage connection of an iModel.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --name "Updated Project Files"`, - description: 'Example 1: Updating a connection with a new display name' - }, - { - command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --authentication-type Service`, - description: 'Example 2: Changing authentication type for a connection' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --name "Updated Project Files"`, + description: 'Example 1: Updating a connection with a new display name' + }, + { + command: `<%= config.bin %> <%= command.id %> --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --authentication-type Service`, + description: 'Example 2: Changing authentication type for a connection' + } + ]; - static flags = { - "authentication-type": Flags.string({ - description: 'The authorization workflow type.', - helpValue: '', - options: ['User', 'Service'], - required: false, - }), - "connection-id": Flags.string({ - char: 'c', - description: 'The ID of the storage connection to update.', - helpValue: '', - required: true, - }), - name: Flags.string({ - char: 'n', - description: 'The new display name for the storage connection.', - helpValue: '', - required: false, - }), - }; + public static flags = { + "authentication-type": Flags.string({ + description: 'The authorization workflow type.', + helpValue: '', + options: ['User', 'Service'], + required: false, + }), + "connection-id": Flags.string({ + char: 'c', + description: 'The ID of the storage connection to update.', + helpValue: '', + required: true, + }), + name: Flags.string({ + char: 'n', + description: 'The new display name for the storage connection.', + helpValue: '', + required: false, + }), + }; - async run() { - const { flags } = await this.parse(UpdateStorageConnection); + public async run() { + const { flags } = await this.parse(UpdateStorageConnection); - const client = await this.getSynchronizationClient(); + const client = await this.getSynchronizationClient(); - const response = await client.updateStorageConnection(flags["connection-id"], { - authenticationType: flags["authentication-type"] as AuthenticationType, - displayName: flags.name, - }); + const response = await client.updateStorageConnection(flags["connection-id"], { + authenticationType: flags["authentication-type"] as AuthenticationType, + displayName: flags.name, + }); - return this.logAndReturnResult(response.connection); - } + return this.logAndReturnResult(response.connection); } +} diff --git a/src/commands/imodel/create.ts b/src/commands/imodel/create.ts index f9a91891..f9554334 100644 --- a/src/commands/imodel/create.ts +++ b/src/commands/imodel/create.ts @@ -7,25 +7,25 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; -import { CustomFlags } from "../../extensions/custom-flags.js"; +import { customFlags } from "../../extensions/custom-flags.js"; import { validateFloat } from "../../extensions/validation/validate-float.js"; export default class CreateIModel extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/imodels-v2/operations/create-imodel/", - name: "Create iModel", + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/imodels-v2/operations/create-imodel/", + name: "Create iModel", }; - static customDocs = true; // Set to true to use custom documentation + public static customDocs = true; // Set to true to use custom documentation - static description = `Create an empty iModel within a specified iTwin. + public static description = `Create an empty iModel within a specified iTwin. iModel extent can be provided to this command in multiple ways: 1) Utilizing the \`--extent\` flag, where coordinates are provided in form of serialized JSON. 2) By providing all of the following flags: \`--sw-latitude\`, \`--sw-longitude\`, \`--ne-latitude\`, \`--ne-longitude\` `; - static examples = [ + public static examples = [ { command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --name "Basic iModel"`, description: 'Example 1: Creating an iModel with minimal options' @@ -40,19 +40,19 @@ export default class CreateIModel extends BaseCommand { }, ]; - static flags = { + public static flags = { description: Flags.string({ char: 'd', description: 'A description for the iModel.', helpValue: '', required: false, }), - extent: CustomFlags.extent({ + extent: customFlags.extent({ description: 'The maximum rectangular area on Earth that encloses the iModel, defined by its southwest and northeast corners and provided in serialized JSON format.', helpValue: '', required: false, }), - "itwin-id": CustomFlags.iTwinIDFlag({ + "itwin-id": customFlags.iTwinIDFlag({ description: 'The ID of the iTwin where the iModel should be created.' }), name: Flags.string({ @@ -66,6 +66,7 @@ export default class CreateIModel extends BaseCommand { description: 'Northeast latitude of the extent.', exclusive: ['extent'], helpValue: "", + // eslint-disable-next-line @typescript-eslint/promise-function-async parse: (input) => validateFloat(input), required: false, }), @@ -74,6 +75,7 @@ export default class CreateIModel extends BaseCommand { description: 'Northeast longitude of the extent.', exclusive: ['extent'], helpValue: "", + // eslint-disable-next-line @typescript-eslint/promise-function-async parse: (input) => validateFloat(input), required: false, }), @@ -86,6 +88,7 @@ export default class CreateIModel extends BaseCommand { description: 'Southwest latitude of the extent.', exclusive: ['extent'], helpValue: "", + // eslint-disable-next-line @typescript-eslint/promise-function-async parse: (input) => validateFloat(input), required: false, }), @@ -94,25 +97,26 @@ export default class CreateIModel extends BaseCommand { description: 'Southwest longitude of the extent.', exclusive: ['extent'], helpValue: "", + // eslint-disable-next-line @typescript-eslint/promise-function-async parse: (input) => validateFloat(input), required: false, }), }; - async run() { + public async run() { const { flags } = await this.parse(CreateIModel); - if(flags["ne-latitude"] !== undefined) { + if(flags["ne-latitude"] !== undefined && flags["ne-longitude"] !== undefined && flags["sw-latitude"] !== undefined && flags["sw-longitude"] !== undefined) { flags.extent ??= { northEast: { - latitude: Number.parseFloat(flags["ne-latitude"]!), - longitude: Number.parseFloat(flags["ne-longitude"]!), + latitude: Number.parseFloat(flags["ne-latitude"]), + longitude: Number.parseFloat(flags["ne-longitude"]), }, southWest: { - latitude: Number.parseFloat(flags["sw-latitude"]!), - longitude: Number.parseFloat(flags["sw-longitude"]!) + latitude: Number.parseFloat(flags["sw-latitude"]), + longitude: Number.parseFloat(flags["sw-longitude"]) } - } + }; } const client = this.getIModelClient(); @@ -128,7 +132,7 @@ export default class CreateIModel extends BaseCommand { }, }); - this.setContext(iModel.iTwinId, iModel.id); + await this.setContext(iModel.iTwinId, iModel.id); return this.logAndReturnResult(iModel); } diff --git a/src/commands/imodel/delete.ts b/src/commands/imodel/delete.ts index 29f940d1..7129521d 100644 --- a/src/commands/imodel/delete.ts +++ b/src/commands/imodel/delete.ts @@ -5,30 +5,30 @@ import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; -import { CustomFlags } from "../../extensions/custom-flags.js"; +import { customFlags } from "../../extensions/custom-flags.js"; export default class DeleteIModel extends BaseCommand { - static apiReference : ApiReference = { + public static apiReference: ApiReference = { link: "https://developer.bentley.com/apis/imodels-v2/operations/delete-imodel/", name: "Delete iModel", }; - static description = 'Delete an existing iModel.'; + public static description = 'Delete an existing iModel.'; - static examples = [ + public static examples = [ { command: `<%= config.bin %> <%= command.id %> --imodel-id 5e19bee0-3aea-4355-a9f0-c6df9989ee7d`, description: 'Example 1:' } ]; - static flags = { - "imodel-id": CustomFlags.iModelIDFlag({ + public static flags = { + "imodel-id": customFlags.iModelIDFlag({ description: 'The ID of the iModel to delete.' }), }; - async run() { + public async run() { const { flags } = await this.parse(DeleteIModel); const client = this.getIModelClient(); diff --git a/src/commands/imodel/info.ts b/src/commands/imodel/info.ts index 1a4d03e3..df038960 100644 --- a/src/commands/imodel/info.ts +++ b/src/commands/imodel/info.ts @@ -5,38 +5,38 @@ import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; -import { CustomFlags } from "../../extensions/custom-flags.js"; +import { customFlags } from "../../extensions/custom-flags.js"; export class IModelInfo extends BaseCommand { - static apiReference : ApiReference = { + public static apiReference: ApiReference = { link: "https://developer.bentley.com/apis/imodels-v2/operations/get-imodel-details/", name: "Get iModel Details", }; - static description = 'Retrieve metadata of an iModel.'; + public static description = 'Retrieve metadata of an iModel.'; - static examples = [ + public static examples = [ { command: `<%= config.bin %> <%= command.id %> --imodel-id 5e19bee0-3aea-4355-a9f0-c6df9989ee7d`, description: 'Example 1:' } ]; - static flags = { - "imodel-id": CustomFlags.iModelIDFlag({ + public static flags = { + "imodel-id": customFlags.iModelIDFlag({ description: 'The ID of the iModel to retrieve information for.' }), }; - async run() { + public async run() { const { flags } = await this.parse(IModelInfo); const iModelClient = this.getIModelClient(); const iModel = await iModelClient.iModels.getSingle({ - authorization: await this.getAuthorizationCallback(), - iModelId: flags["imodel-id"] - }) + authorization: await this.getAuthorizationCallback(), + iModelId: flags["imodel-id"] + }); return this.logAndReturnResult(iModel); } diff --git a/src/commands/imodel/list.ts b/src/commands/imodel/list.ts index a4e180e4..1cb77635 100644 --- a/src/commands/imodel/list.ts +++ b/src/commands/imodel/list.ts @@ -8,93 +8,93 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; -import { CustomFlags } from "../../extensions/custom-flags.js"; +import { customFlags } from "../../extensions/custom-flags.js"; export default class ListIModels extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/imodels-v2/operations/get-itwin-imodels/", - name: "List iModels", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/imodels-v2/operations/get-itwin-imodels/", + name: "List iModels", + }; - static description = 'Retrieve a list of iModels belonging to the specified iTwin.'; + public static description = 'Retrieve a list of iModels belonging to the specified iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, - description: 'Example 1: List all iModels for a specific iTwin' - }, - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --top 10 --order-by "name desc"`, - description: 'Example 2: List the first 10 iModels, ordered by name in descending order' - }, - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --search "Sun City"`, - description: 'Example 3: Search for iModels with "Sun City" in their name or description' - }, - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --state initialized`, - description: 'Example 4: List only initialized iModels' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, + description: 'Example 1: List all iModels for a specific iTwin' + }, + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --top 10 --order-by "name desc"`, + description: 'Example 2: List the first 10 iModels, ordered by name in descending order' + }, + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --search "Sun City"`, + description: 'Example 3: Search for iModels with "Sun City" in their name or description' + }, + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --state initialized`, + description: 'Example 4: List only initialized iModels' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin to list iModels for.' - }), - name: Flags.string({ - char: 'n', - description: 'Filter iModels by their exact name.', - helpValue: '', - required: false, - }), - "order-by": Flags.string({ - description: "Order the results by 'name' or 'createdDateTime'. Use 'asc' for ascending or 'desc' for descending order.", - helpValue: '', - required: false, - }), - search: Flags.string({ - description: 'Filter iModels by a string in their name or description.', - helpValue: '', - required: false, - }), - skip: Flags.integer({ - description: 'Skip a number of items in the result.', - helpValue: '', - required: false, - }), - // state: Flags.string({ - // description: 'Filter iModels by their state.', - // helpValue: '', - // options: ['initialized', 'notInitialized'], - // required: false, - // }), - top: Flags.integer({ - description: 'Limit the number of items returned.', - helpValue: '', - required: false, - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin to list iModels for.' + }), + name: Flags.string({ + char: 'n', + description: 'Filter iModels by their exact name.', + helpValue: '', + required: false, + }), + "order-by": Flags.string({ + description: "Order the results by 'name' or 'createdDateTime'. Use 'asc' for ascending or 'desc' for descending order.", + helpValue: '', + required: false, + }), + search: Flags.string({ + description: 'Filter iModels by a string in their name or description.', + helpValue: '', + required: false, + }), + skip: Flags.integer({ + description: 'Skip a number of items in the result.', + helpValue: '', + required: false, + }), + // state: Flags.string({ + // description: 'Filter iModels by their state.', + // helpValue: '', + // options: ['initialized', 'notInitialized'], + // required: false, + // }), + top: Flags.integer({ + description: 'Limit the number of items returned.', + helpValue: '', + required: false, + }), + }; - async run() { - const { flags } = await this.parse(ListIModels); + public async run() { + const { flags } = await this.parse(ListIModels); - const client = this.getIModelClient(); - const authorization = await this.getAuthorizationCallback(); + const client = this.getIModelClient(); + const authorization = await this.getAuthorizationCallback(); - const iModels = client.iModels.getRepresentationList({ - authorization, - urlParams: { - $orderBy: flags["order-by"] as unknown as OrderBy, - $search: flags.search, - $skip: flags.skip, - $top: flags.top, - iTwinId: flags["itwin-id"], - name: flags.name, - }, - }); + const iModels = client.iModels.getRepresentationList({ + authorization, + urlParams: { + $orderBy: flags["order-by"] as unknown as OrderBy, + $search: flags.search, + $skip: flags.skip, + $top: flags.top, + iTwinId: flags["itwin-id"], + name: flags.name, + }, + }); - const result: IModel[] = await (flags.top ? take(iModels, flags.top) : toArray(iModels)); + const result: IModel[] = await (flags.top ? take(iModels, flags.top) : toArray(iModels)); - return this.logAndReturnResult(result); - } + return this.logAndReturnResult(result); } +} diff --git a/src/commands/imodel/named-version/create.ts b/src/commands/imodel/named-version/create.ts index 363ced90..d083deaa 100644 --- a/src/commands/imodel/named-version/create.ts +++ b/src/commands/imodel/named-version/create.ts @@ -7,70 +7,70 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class CreateNamedVersion extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/imodels-v2/operations/create-imodel-named-version/", - name: "Create Named Version", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/imodels-v2/operations/create-imodel-named-version/", + name: "Create Named Version", + }; - static description = 'Create a new named version for iModel.'; + public static description = 'Create a new named version for iModel.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --changeset-id 2f3b4a8c92d747d5c8a8b2f9cde6742e5d74b3b5 --name "Version 1.0" --description "Initial release"`, - description: 'Example 1: Creating a named version with a description' - }, - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --name "Version 2.0"`, - description: 'Example 2: Creating a named version without specifying changesetId (uses the latest changeset)' - }, - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --changeset-id 4b8a5d9e8d534a71b02894f2a2b4e91d --name "Version 3.0"`, - description: 'Example 3: Creating a named version without a description' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --changeset-id 2f3b4a8c92d747d5c8a8b2f9cde6742e5d74b3b5 --name "Version 1.0" --description "Initial release"`, + description: 'Example 1: Creating a named version with a description' + }, + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --name "Version 2.0"`, + description: 'Example 2: Creating a named version without specifying changesetId (uses the latest changeset)' + }, + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --changeset-id 4b8a5d9e8d534a71b02894f2a2b4e91d --name "Version 3.0"`, + description: 'Example 3: Creating a named version without a description' + } + ]; - static flags = { - "changeset-id": Flags.string({ - description: 'The ID of the changeset for the named version. Defaults to the latest changeset if not specified.', - helpValue: '', - required: false, - }), - description: Flags.string({ - char: 'd', - description: 'A description for the named version.', - helpValue: '', - required: false, - }), - "imodel-id": CustomFlags.iModelIDFlag({ - description: 'The ID of the iModel where the named version will be created.' - }), - name: Flags.string({ - char: 'n', - description: 'The name of the new named version.', - helpValue: '', - required: true, - }), - }; + public static flags = { + "changeset-id": Flags.string({ + description: 'The ID of the changeset for the named version. Defaults to the latest changeset if not specified.', + helpValue: '', + required: false, + }), + description: Flags.string({ + char: 'd', + description: 'A description for the named version.', + helpValue: '', + required: false, + }), + "imodel-id": customFlags.iModelIDFlag({ + description: 'The ID of the iModel where the named version will be created.' + }), + name: Flags.string({ + char: 'n', + description: 'The name of the new named version.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(CreateNamedVersion); + public async run() { + const { flags } = await this.parse(CreateNamedVersion); - const client = this.getIModelClient(); - const authorization = await this.getAuthorizationCallback(); + const client = this.getIModelClient(); + const authorization = await this.getAuthorizationCallback(); - const createdNameVersion = await client.namedVersions.create({ - authorization, - iModelId: flags["imodel-id"], - namedVersionProperties: { - changesetId: flags["changeset-id"], - description: flags.description, - name: flags.name, - }, - }); + const createdNameVersion = await client.namedVersions.create({ + authorization, + iModelId: flags["imodel-id"], + namedVersionProperties: { + changesetId: flags["changeset-id"], + description: flags.description, + name: flags.name, + }, + }); - return this.logAndReturnResult(createdNameVersion); - } + return this.logAndReturnResult(createdNameVersion); } +} diff --git a/src/commands/imodel/named-version/info.ts b/src/commands/imodel/named-version/info.ts index c9581093..27006ce1 100644 --- a/src/commands/imodel/named-version/info.ts +++ b/src/commands/imodel/named-version/info.ts @@ -7,46 +7,46 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class NamedVersionInfo extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/imodels-v2/operations/get-imodel-named-version-details/", - name: "Get Named Version Details", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/imodels-v2/operations/get-imodel-named-version-details/", + name: "Get Named Version Details", + }; - static description = 'Retrieve details about a specific named version in an iModel.'; + public static description = 'Retrieve details about a specific named version in an iModel.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --named-version-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --named-version-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, + description: 'Example 1:' + } + ]; - static flags = { - "imodel-id": CustomFlags.iModelIDFlag({ - description: 'The ID of the iModel whose named version you want to retrieve.' - }), - "named-version-id": Flags.string({ - description: 'The ID of the named version.', - helpValue: '', - required: true, - }), - }; + public static flags = { + "imodel-id": customFlags.iModelIDFlag({ + description: 'The ID of the iModel whose named version you want to retrieve.' + }), + "named-version-id": Flags.string({ + description: 'The ID of the named version.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(NamedVersionInfo); + public async run() { + const { flags } = await this.parse(NamedVersionInfo); - const client = this.getIModelClient(); - const authorization = await this.getAuthorizationCallback(); + const client = this.getIModelClient(); + const authorization = await this.getAuthorizationCallback(); - const namedVersionInfo = await client.namedVersions.getSingle({ - authorization, - iModelId: flags["imodel-id"], - namedVersionId: flags["named-version-id"], - }); + const namedVersionInfo = await client.namedVersions.getSingle({ + authorization, + iModelId: flags["imodel-id"], + namedVersionId: flags["named-version-id"], + }); - return this.logAndReturnResult(namedVersionInfo); - } + return this.logAndReturnResult(namedVersionInfo); } +} diff --git a/src/commands/imodel/named-version/list.ts b/src/commands/imodel/named-version/list.ts index b12e3802..00dca6ca 100644 --- a/src/commands/imodel/named-version/list.ts +++ b/src/commands/imodel/named-version/list.ts @@ -8,92 +8,92 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class ListNamedVersions extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/imodels-v2/operations/get-imodel-named-versions/", - name: "Get Named Versions", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/imodels-v2/operations/get-imodel-named-versions/", + name: "Get Named Versions", + }; - static description = 'List all named versions for a specific iModel.'; + public static description = 'List all named versions for a specific iModel.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --top 10`, - description: 'Example 1: List the first 10 named versions for a specific iModel' - }, - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --skip 5 --top 10`, - description: 'Example 2: Skip the first 5 named versions and return the next set' - }, - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --search "Milestone"`, - description: `Example 3: Search for named versions containing 'Milestone'` - }, - { - command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --name "Version 2.0" --order-by "changesetIndex desc"`, - description: 'Example 4: Filter named versions by exact name and sort in descending order by changesetIndex' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --top 10`, + description: 'Example 1: List the first 10 named versions for a specific iModel' + }, + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --skip 5 --top 10`, + description: 'Example 2: Skip the first 5 named versions and return the next set' + }, + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --search "Milestone"`, + description: `Example 3: Search for named versions containing 'Milestone'` + }, + { + command: `<%= config.bin %> <%= command.id %> --imodel-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --name "Version 2.0" --order-by "changesetIndex desc"`, + description: 'Example 4: Filter named versions by exact name and sort in descending order by changesetIndex' + } + ]; - static flags = { - "imodel-id": CustomFlags.iModelIDFlag({ - description: 'The ID of the iModel whose named versions you want to list.' - }), - name: Flags.string({ - char: 'n', - description: 'Filter named versions by exact name.', - helpValue: '', - required: false, - }), - "order-by": Flags.string({ - description: 'Sort by `changesetIndex` or `createdDateTime`, in `asc` or `desc` order.', - helpValue: '', - required: false, - }), - search: Flags.string({ - description: 'Search named versions by name or description.', - helpValue: '', - required: false, - }), - skip: Flags.integer({ - description: 'Skip a number of named versions in the result.', - helpValue: '', - required: false, - }), - top: Flags.integer({ - description: 'Limit the number of named versions returned.', - helpValue: '', - required: false, - }), - }; + public static flags = { + "imodel-id": customFlags.iModelIDFlag({ + description: 'The ID of the iModel whose named versions you want to list.' + }), + name: Flags.string({ + char: 'n', + description: 'Filter named versions by exact name.', + helpValue: '', + required: false, + }), + "order-by": Flags.string({ + description: 'Sort by `changesetIndex` or `createdDateTime`, in `asc` or `desc` order.', + helpValue: '', + required: false, + }), + search: Flags.string({ + description: 'Search named versions by name or description.', + helpValue: '', + required: false, + }), + skip: Flags.integer({ + description: 'Skip a number of named versions in the result.', + helpValue: '', + required: false, + }), + top: Flags.integer({ + description: 'Limit the number of named versions returned.', + helpValue: '', + required: false, + }), + }; - async run() { - const { flags } = await this.parse(ListNamedVersions); + public async run() { + const { flags } = await this.parse(ListNamedVersions); - const client = this.getIModelClient(); - const authorization = await this.getAuthorizationCallback(); + const client = this.getIModelClient(); + const authorization = await this.getAuthorizationCallback(); - const orderBy : OrderBy | undefined = flags["order-by"] ? { - operator: flags["order-by"].split(" ")[1] === "desc" ? OrderByOperator.Descending : OrderByOperator.Ascending, - property: flags["order-by"].split(" ")[0] as NamedVersionOrderByProperty, - } : undefined; + const orderBy : OrderBy | undefined = flags["order-by"] ? { + operator: flags["order-by"].split(" ")[1] === "desc" ? OrderByOperator.Descending : OrderByOperator.Ascending, + property: flags["order-by"].split(" ")[0] as NamedVersionOrderByProperty, + } : undefined; - const namedVersionsList = client.namedVersions.getRepresentationList({ - authorization, - iModelId: flags["imodel-id"], - urlParams: { - $orderBy: orderBy, - $search: flags.search, - $skip: flags.skip, - $top: flags.top, - name: flags.name, - } - }); + const namedVersionsList = client.namedVersions.getRepresentationList({ + authorization, + iModelId: flags["imodel-id"], + urlParams: { + $orderBy: orderBy, + $search: flags.search, + $skip: flags.skip, + $top: flags.top, + name: flags.name, + } + }); - const result: NamedVersion[] = await (flags.top ? take(namedVersionsList, flags.top) : toArray(namedVersionsList)); + const result: NamedVersion[] = await (flags.top ? take(namedVersionsList, flags.top) : toArray(namedVersionsList)); - return this.logAndReturnResult(result); - } + return this.logAndReturnResult(result); } +} diff --git a/src/commands/imodel/populate.ts b/src/commands/imodel/populate.ts index da9baddf..add05069 100644 --- a/src/commands/imodel/populate.ts +++ b/src/commands/imodel/populate.ts @@ -3,36 +3,37 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import { IModel } from "@itwin/imodels-client-management" -import { Flags } from "@oclif/core" -import fs from "node:fs" -import path from "node:path" +import { IModel } from "@itwin/imodels-client-management"; +import { Flags } from "@oclif/core"; +import fs from "node:fs"; +import path from "node:path"; import { ApiReference } from "../../extensions/api-reference.js"; -import BaseCommand from "../../extensions/base-command.js" -import { CustomFlags } from "../../extensions/custom-flags.js" -import { AuthorizationInformation } from "../../services/authorization-client/authorization-type.js" -import { FileUpload } from "../../services/storage-client/models/file-upload.js" -import { ItemsWithFolderLink } from "../../services/storage-client/models/items-with-folder-link.js" -import { AuthInfo } from "../../services/synchronizationClient/models/connection-auth.js" -import { ConnectorType } from "../../services/synchronizationClient/models/connector-type.js" +import BaseCommand from "../../extensions/base-command.js"; +import { customFlags } from "../../extensions/custom-flags.js"; +import { AuthorizationInformation, AuthorizationType } from "../../services/authorization-client/authorization-type.js"; +import { FileUpload } from "../../services/storage-client/models/file-upload.js"; +import { ItemsWithFolderLink } from "../../services/storage-client/models/items-with-folder-link.js"; +import { AuthInfo } from "../../services/synchronizationClient/models/connection-auth.js"; +import { ConnectorType } from "../../services/synchronizationClient/models/connector-type.js"; import { ExecutionResult } from "../../services/synchronizationClient/models/execution-result.js"; -import { ExecutionState } from "../../services/synchronizationClient/models/execution-state.js" -import { SourceFile } from "../../services/synchronizationClient/models/source-file.js" -import { StorageConnection } from "../../services/synchronizationClient/models/storage-connection.js" -import { StorageConnectionListResponse } from "../../services/synchronizationClient/models/storage-connection-response.js" -import { StorageRun } from "../../services/synchronizationClient/models/storage-run.js" +import { ExecutionState } from "../../services/synchronizationClient/models/execution-state.js"; +import { SourceFile } from "../../services/synchronizationClient/models/source-file.js"; +import { StorageConnection } from "../../services/synchronizationClient/models/storage-connection.js"; +import { StorageConnectionListResponse } from "../../services/synchronizationClient/models/storage-connection-response.js"; +import { StorageRun } from "../../services/synchronizationClient/models/storage-run.js"; +import { FolderTypedType } from "../../services/storage-client/models/folder-typed.js"; export default class PopulateIModel extends BaseCommand { - static apiReference: ApiReference = { + public static apiReference: ApiReference = { link: "/docs/command-workflows/imodel-populate", name: "iModel Populate", sectionName: "Workflow Reference" }; - static description = 'Synchronize design files into an iModel.' + public static description = 'Synchronize design files into an iModel.'; - static examples = [ + public static examples = [ { command: `<%= config.bin %> <%= command.id %> --imodel-id b1a2c3d4-5678-90ab-cdef-1234567890ab --file file1.dwg --connector-type DWG --file file2.dwg --connector-type DWG`, description: 'Example 1: Synchronizing DWG Files' @@ -51,52 +52,52 @@ export default class PopulateIModel extends BaseCommand { } ]; - static flags = { + public static flags = { "connector-type": Flags.string({ - char: 'c', - description: `Specify connectors to use for synchronization. This option can be provided multiple times. If no connector-type options are provided, they are selected automatically depending on file extensions of provided files. If only one connector is specified, it will be used for all files. If multiple connectors are specified, each connector will be used for the corresponding file in the files list (first connector for the first file, second connector for the second file, and so on).\n NOTE: .dgn and .dwg file types can be associated with multiple connector types. When no 'connector-type' options are provided, connectors for those file types are assigned as follows: .dgn => MSTN, .dwg => DWG `, - helpValue: '', - multiple: true, - options: [ - 'AUTOPLANT', - 'CIVIL', - 'CIVIL3D', - 'DWG', - 'GEOSPATIAL', - 'IFC', - 'MSTN', - 'NWD', - 'OBD', - 'OPENTOWER', - 'PROSTRUCTURES', - 'REVIT', - 'SPPID', - 'SPXREVIEW' - ], - required: false, - type: "option" - }), + char: 'c', + description: `Specify connectors to use for synchronization. This option can be provided multiple times. If no connector-type options are provided, they are selected automatically depending on file extensions of provided files. If only one connector is specified, it will be used for all files. If multiple connectors are specified, each connector will be used for the corresponding file in the files list (first connector for the first file, second connector for the second file, and so on).\n NOTE: .dgn and .dwg file types can be associated with multiple connector types. When no 'connector-type' options are provided, connectors for those file types are assigned as follows: .dgn => MSTN, .dwg => DWG `, + helpValue: '', + multiple: true, + options: [ + 'AUTOPLANT', + 'CIVIL', + 'CIVIL3D', + 'DWG', + 'GEOSPATIAL', + 'IFC', + 'MSTN', + 'NWD', + 'OBD', + 'OPENTOWER', + 'PROSTRUCTURES', + 'REVIT', + 'SPPID', + 'SPXREVIEW' + ], + required: false, + type: "option" + }), file: Flags.file({ - char: 'f', - description: 'Specify a list of source files to synchronize into the iModel.', - helpValue: '', - multiple: true, - required: true - }), - "imodel-id": CustomFlags.iModelIDFlag({ - description: 'The ID of the iModel to populate.' + char: 'f', + description: 'Specify a list of source files to synchronize into the iModel.', + helpValue: '', + multiple: true, + required: true + }), + "imodel-id": customFlags.iModelIDFlag({ + description: 'The ID of the iModel to populate.' }), "no-wait": Flags.boolean({ - description: 'Do not wait for the synchronization process to complete.', - required: false, + description: 'Do not wait for the synchronization process to complete.', + required: false, }), - } + }; - async run() { + public async run() { const { flags } = await this.parse(PopulateIModel); - if(flags["connector-type"] && flags["connector-type"]!.length !== 1 && flags.file!.length !== flags["connector-type"]!.length) { - this.error("When multiple connector-type options are provided, their amount must match file option amount. Alternatively, you can provide a single connector-type option, which will then be applied to all file options. You can also provide no connector-type options, in which case the command will attempt automatic detection.") + if(flags["connector-type"] && flags["connector-type"].length !== 1 && flags.file.length !== flags["connector-type"].length) { + this.error("When multiple connector-type options are provided, their amount must match file option amount. Alternatively, you can provide a single connector-type option, which will then be applied to all file options. You can also provide no connector-type options, in which case the command will attempt automatic detection."); } const filesAndConnectorToImport = this.checkAndGetFilesWithConnectors(flags.file, flags["connector-type"]); @@ -111,14 +112,14 @@ export default class PopulateIModel extends BaseCommand { } const files = await Promise.all( - filesAndConnectorToImport.map((newFileInfo) => this.processFile(topFolders, rootFolderId, newFileInfo)) + filesAndConnectorToImport.map(async (newFileInfo) => this.processFile(topFolders, rootFolderId, newFileInfo)) ); this.log(`Checking existing connections for iModel ID: ${iModel.id}`); const existingConnections = await this.runCommand('imodel:connection:list', ['--imodel-id', iModel.id]); const authInfo = await this.runCommand('auth:info', []); - const authType = authInfo.authorizationType === 'Service' ? 'Service' : 'User'; + const authType = authInfo.authorizationType === AuthorizationType.Service ? 'Service' : 'User'; if(authType === 'User') { this.log("Authorizing..."); @@ -152,17 +153,17 @@ export default class PopulateIModel extends BaseCommand { iTwinId: iModel.iTwinId, rootFolderId, summary, - } + }; return populateResponse; } private async addFileToConnectionIfItIsNotPresent(connectionId: string, sourceFiles: SourceFile[], file: { connectorType: ConnectorType, fileId: string, fileName: string }) { const fileExist = sourceFiles.find(f => f.storageFileId === file.fileId); - if (!fileExist) { - this.log(`Adding file: ${file.fileId} to default connection: ${connectionId}`); - await this.runCommand('imodel:connection:sourcefile:add', ['--connection-id', connectionId, '--connector-type', file.connectorType, '--storage-file-id', file.fileId]); - } + if (!fileExist) { + this.log(`Adding file: ${file.fileId} to default connection: ${connectionId}`); + await this.runCommand('imodel:connection:sourcefile:add', ['--connection-id', connectionId, '--connector-type', file.connectorType, '--storage-file-id', file.fileId]); + } } private checkAndGetFilesWithConnectors(files: string[], connectorTypes: string[] | undefined) : NewFileInfo[] { @@ -183,7 +184,7 @@ export default class PopulateIModel extends BaseCommand { } else if (!connectorTypes) { const splitedFile = file.split('.'); - + if(splitedFile.length === 1) { this.error(`${file} has no extension`); @@ -193,20 +194,19 @@ export default class PopulateIModel extends BaseCommand { connector = getConnectorTypeFromFileExtension(`${splitedFile.at(-2)}.${splitedFile.at(-1)}`); } - connector ??= getConnectorTypeFromFileExtension(splitedFile.at(-1)!); - - if(!connector) - { - this.error(`Unable to get extension from file name: ${file}`); - } + connector ??= getConnectorTypeFromFileExtension(`${splitedFile.at(-1)}`); } + if(!connector) + { + this.error(`Unable to get extension from file name: ${file}`); + } resultArray.push({ - connectorType: connector!, + connectorType: connector, fileName: path.basename(file), fullFilePath: file - }) + }); } return resultArray; @@ -226,7 +226,7 @@ export default class PopulateIModel extends BaseCommand { let defaultConnection = existingConnections.find(connection => connection.displayName === 'Default iTwinCLI Connection'); if (!defaultConnection) { const authInfo = await this.runCommand('auth:info', []); - const authType = authInfo.authorizationType === 'Service' ? 'Service' : 'User'; + const authType = authInfo.authorizationType === AuthorizationType.Service ? 'Service' : 'User'; this.log(`Creating new default connection`); defaultConnection = await this.runCommand('imodel:connection:create', @@ -238,7 +238,7 @@ export default class PopulateIModel extends BaseCommand { const connectionSourceFiles = await this.runCommand('imodel:connection:sourcefile:list', ['--connection-id', defaultConnection.id]); await Promise.all( - files.map((file) => this.addFileToConnectionIfItIsNotPresent(defaultConnection.id, connectionSourceFiles, file)) + files.map(async (file) => this.addFileToConnectionIfItIsNotPresent(defaultConnection.id, connectionSourceFiles, file)) ); this.log(`Running connection for connection ID: ${defaultConnection.id}`); @@ -248,7 +248,7 @@ export default class PopulateIModel extends BaseCommand { private async processFile(topFolders: ItemsWithFolderLink, rootFolderId: string, fileInfo: NewFileInfo): Promise<{connectorType: ConnectorType, fileId: string, fileName: string}> { this.log(`Processing file: ${fileInfo.fileName}`); - const fileExists = topFolders.items?.find(entry => entry.type === 'file' && entry.displayName === fileInfo.fileName); + const fileExists = topFolders.items?.find(entry => entry.type === FolderTypedType.FOLDER && entry.displayName === fileInfo.fileName); let fileId: string | undefined; if (fileExists?.id) { @@ -274,12 +274,10 @@ export default class PopulateIModel extends BaseCommand { const runId = storageConnection?._links?.lastRun?.href.split("/")[8]; let storageConnectionRun; do { - // eslint-disable-next-line no-await-in-loop storageConnectionRun = await this.runCommand('imodel:connection:run:info', ['--connection-id', connectionId, '--connection-run-id', runId]); - // eslint-disable-next-line no-await-in-loop - await new Promise(resolve => { setTimeout(resolve, 10_000) }); + + await new Promise(resolve => { setTimeout(resolve, 10_000); }); this.log(`Waiting for synchronization to complete for run ID: ${runId} with state: ${storageConnectionRun?.state}`); - // eslint-disable-next-line no-unmodified-loop-condition } while (waitForCompletion && storageConnectionRun?.state !== ExecutionState.COMPLETED); if(waitForCompletion && storageConnectionRun.result !== ExecutionResult.SUCCESS) { @@ -307,9 +305,9 @@ export interface PopulateResponse { summary: { connectionId: string; files: { - connectorType: ConnectorType; - fileId: string; - fileName: string; + connectorType: ConnectorType; + fileId: string; + fileName: string; }[]; runId: string; }[] @@ -321,7 +319,7 @@ interface NewFileInfo { fullFilePath: string; } -const fileExtensionToConnectorType: { [key: string]: ConnectorType[] } = { +const fileExtensionToConnectorType: Record = { "3dm": [ConnectorType.MSTN], "3ds": [ConnectorType.MSTN], dae: [ConnectorType.MSTN], @@ -349,6 +347,7 @@ const fileExtensionToConnectorType: { [key: string]: ConnectorType[] } = { stl: [ConnectorType.MSTN], stp: [ConnectorType.MSTN], vue: [ConnectorType.SPXREVIEW], + // eslint-disable-next-line @typescript-eslint/naming-convention "x_t": [ConnectorType.MSTN], zip: [ConnectorType.SPPID], }; diff --git a/src/commands/imodel/update.ts b/src/commands/imodel/update.ts index cb86965c..9aca1280 100644 --- a/src/commands/imodel/update.ts +++ b/src/commands/imodel/update.ts @@ -7,128 +7,132 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; -import { CustomFlags } from "../../extensions/custom-flags.js"; +import { customFlags } from "../../extensions/custom-flags.js"; import { validateFloat } from "../../extensions/validation/validate-float.js"; export default class UpdateCommand extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/imodels-v2/operations/update-imodel/", - name: "Update iModel", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/imodels-v2/operations/update-imodel/", + name: "Update iModel", + }; - static customDocs = true; + public static customDocs = true; - static description = `Update metadata of an existing iModel. + public static description = `Update metadata of an existing iModel. iModel extent can be provided to this command in multiple ways: 1) Utilizing the \`--extent\` flag, where coordinates are provided in form of serialized JSON. 2) By providing all of the following flags: \`--sw-latitude\`, \`--sw-longitude\`, \`--ne-latitude\`, \`--ne-longitude\` `; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --imodel-id 5e19bee0-3aea-4355-a9f0-c6df9989ee7d --name "Updated Sun City Renewable-energy Plant" --description "Updated overall model of wind and solar farms in Sun City" --extent '{ "southWest": { "latitude": 46.13267702834806, "longitude": 7.672120009938448 }, "northEast": { "latitude": 46.302763954781234, "longitude": 7.835541640797823 }}'`, - description: 'Example 1: Updating an iModel name, description and extent (JSON format)' - }, - { - command: `<%= config.bin %> <%= command.id %> --imodel-id 5e19bee0-3aea-4355-a9f0-c6df9989ee7d --name "Updated Sun City Renewable-energy Plant" --description "Updated overall model of wind and solar farms in Sun City" --sw-latitude 46.13267702834806 --sw-longitude 7.672120009938448 --ne-latitude 46.302763954781234 --ne-longitude 7.835541640797823`, - description: 'Example 2: Updating an iModel name, description and extent (separate flags format)' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --imodel-id 5e19bee0-3aea-4355-a9f0-c6df9989ee7d --name "Updated Sun City Renewable-energy Plant" --description "Updated overall model of wind and solar farms in Sun City" --extent '{ "southWest": { "latitude": 46.13267702834806, "longitude": 7.672120009938448 }, "northEast": { "latitude": 46.302763954781234, "longitude": 7.835541640797823 }}'`, + description: 'Example 1: Updating an iModel name, description and extent (JSON format)' + }, + { + command: `<%= config.bin %> <%= command.id %> --imodel-id 5e19bee0-3aea-4355-a9f0-c6df9989ee7d --name "Updated Sun City Renewable-energy Plant" --description "Updated overall model of wind and solar farms in Sun City" --sw-latitude 46.13267702834806 --sw-longitude 7.672120009938448 --ne-latitude 46.302763954781234 --ne-longitude 7.835541640797823`, + description: 'Example 2: Updating an iModel name, description and extent (separate flags format)' + } + ]; - static flags = { - description: Flags.string({ - char: 'd', - description: 'The new description for the iModel.', - helpValue: '', - required: false, - }), - extent: CustomFlags.extent({ - description: 'The new maximum rectangular area on Earth that encloses the iModel, defined by its southwest and northeast corners and provided in serialized JSON format.', - helpValue: '', - required: false, - }), - "imodel-id": CustomFlags.iModelIDFlag({ - description: 'The ID of the iModel to update.' - }), - name: Flags.string({ - char: 'n', - description: 'The new name of the iModel.', - helpValue: '', - required: false, - }), - "ne-latitude": Flags.string({ - dependsOn: ['ne-longitude', 'sw-latitude', 'sw-longitude'], - description: 'Northeast latitude of the extent.', - exclusive: ['extent'], - helpValue: "", - parse: (input) => validateFloat(input), - required: false, - }), - "ne-longitude": Flags.string({ - dependsOn: ['ne-latitude', 'sw-latitude', 'sw-longitude'], - description: 'Northeast longitude of the extent.', - exclusive: ['extent'], - helpValue: "", - parse: (input) => validateFloat(input), - required: false, - }), - "sw-latitude": Flags.string({ - dependsOn:['ne-latitude', 'ne-longitude', 'sw-longitude'], - description: 'Southwest latitude of the extent.', - exclusive: ['extent'], - helpValue: "", - parse: (input) => validateFloat(input), - required: false, - }), - "sw-longitude": Flags.string({ - dependsOn: ['ne-latitude', 'ne-longitude', 'sw-latitude'], - description: 'Southwest longitude of the extent.', - exclusive: ['extent'], - helpValue: "", - parse: (input) => validateFloat(input), - required: false, - }), - }; + public static flags = { + description: Flags.string({ + char: 'd', + description: 'The new description for the iModel.', + helpValue: '', + required: false, + }), + extent: customFlags.extent({ + description: 'The new maximum rectangular area on Earth that encloses the iModel, defined by its southwest and northeast corners and provided in serialized JSON format.', + helpValue: '', + required: false, + }), + "imodel-id": customFlags.iModelIDFlag({ + description: 'The ID of the iModel to update.' + }), + name: Flags.string({ + char: 'n', + description: 'The new name of the iModel.', + helpValue: '', + required: false, + }), + "ne-latitude": Flags.string({ + dependsOn: ['ne-longitude', 'sw-latitude', 'sw-longitude'], + description: 'Northeast latitude of the extent.', + exclusive: ['extent'], + helpValue: "", + // eslint-disable-next-line @typescript-eslint/promise-function-async + parse: (input) => validateFloat(input), + required: false, + }), + "ne-longitude": Flags.string({ + dependsOn: ['ne-latitude', 'sw-latitude', 'sw-longitude'], + description: 'Northeast longitude of the extent.', + exclusive: ['extent'], + helpValue: "", + // eslint-disable-next-line @typescript-eslint/promise-function-async + parse: (input) => validateFloat(input), + required: false, + }), + "sw-latitude": Flags.string({ + dependsOn:['ne-latitude', 'ne-longitude', 'sw-longitude'], + description: 'Southwest latitude of the extent.', + exclusive: ['extent'], + helpValue: "", + // eslint-disable-next-line @typescript-eslint/promise-function-async + parse: (input) => validateFloat(input), + required: false, + }), + "sw-longitude": Flags.string({ + dependsOn: ['ne-latitude', 'ne-longitude', 'sw-latitude'], + description: 'Southwest longitude of the extent.', + exclusive: ['extent'], + helpValue: "", + // eslint-disable-next-line @typescript-eslint/promise-function-async + parse: (input) => validateFloat(input), + required: false, + }), + }; - async run() { - const { flags } = await this.parse(UpdateCommand); + public async run() { + const { flags } = await this.parse(UpdateCommand); - if(flags["ne-latitude"] !== undefined) { - flags.extent ??= { - northEast: { - latitude: Number.parseFloat(flags["ne-latitude"]!), - longitude: Number.parseFloat(flags["ne-longitude"]!), - }, - southWest: { - latitude: Number.parseFloat(flags["sw-latitude"]!), - longitude: Number.parseFloat(flags["sw-longitude"]!) - } + if(flags["ne-latitude"] !== undefined && flags["ne-longitude"] !== undefined && flags["sw-latitude"] !== undefined && flags["sw-longitude"] !== undefined) { + flags.extent ??= { + northEast: { + latitude: Number.parseFloat(flags["ne-latitude"]), + longitude: Number.parseFloat(flags["ne-longitude"]), + }, + southWest: { + latitude: Number.parseFloat(flags["sw-latitude"]), + longitude: Number.parseFloat(flags["sw-longitude"]) } - } + }; + } - if (flags.description === undefined && flags.name === undefined && flags.extent === undefined) { - this.error("At least one of the update parameters must be provided"); - } + if (flags.description === undefined && flags.name === undefined && flags.extent === undefined) { + this.error("At least one of the update parameters must be provided"); + } - const client = this.getIModelClient(); - const authorization = await this.getAuthorizationCallback(); + const client = this.getIModelClient(); + const authorization = await this.getAuthorizationCallback(); - const iModelInfo = await client.iModels.getSingle({ - authorization, - iModelId: flags["imodel-id"] - }); + const iModelInfo = await client.iModels.getSingle({ + authorization, + iModelId: flags["imodel-id"] + }); - const iModel = await client.iModels.update({ - authorization, - iModelId: flags["imodel-id"], - iModelProperties: { - description: flags.description, - extent: flags.extent, - name: flags.name ?? iModelInfo.name - }, - }); + const iModel = await client.iModels.update({ + authorization, + iModelId: flags["imodel-id"], + iModelProperties: { + description: flags.description, + extent: flags.extent, + name: flags.name ?? iModelInfo.name + }, + }); - return this.logAndReturnResult(iModel); - } + return this.logAndReturnResult(iModel); } +} diff --git a/src/commands/imodel/view/cesium-sandcastle.ts b/src/commands/imodel/view/cesium-sandcastle.ts index 55bcfe9a..76e186ba 100644 --- a/src/commands/imodel/view/cesium-sandcastle.ts +++ b/src/commands/imodel/view/cesium-sandcastle.ts @@ -10,19 +10,19 @@ import { deflate } from "pako"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; import { Link, Links } from "../../../services/general-models/links.js"; export default class CesiumSandcastle extends BaseCommand { - static apiReference: ApiReference = { - link: "/docs/command-workflows/cesium-sandcastle", - name: "Cesium Sandcastle", - sectionName: "Workflow Reference", + public static apiReference: ApiReference = { + link: "/docs/command-workflows/cesium-sandcastle", + name: "Cesium Sandcastle", + sectionName: "Workflow Reference", }; - static description = "> 🔬 This command is currently in Technical Preview.\nSetup iModel and get URL to view it in Cesium Sandcastle."; + public static description = "> 🔬 This command is currently in Technical Preview.\nSetup iModel and get URL to view it in Cesium Sandcastle."; - static examples = [ + public static examples = [ { command: `<%= config.bin %> <%= command.id %> --imodel-id 5e19bee0-3aea-4355-a9f0-c6df9989ee7d`, description: 'Example 1: Get a link to an iModel in Cesium Sandcastle' @@ -41,13 +41,13 @@ export default class CesiumSandcastle extends BaseCommand { } ]; - static flags = { + public static flags = { "changeset-id": Flags.string({ description: "Changeset id to be viewed in Cesium Sandcastle. If not provided, the latest changeset will be used.", helpValue: '', required: false }), - "imodel-id": CustomFlags.iModelIDFlag({ + "imodel-id": customFlags.iModelIDFlag({ description: "iModel id to be viewed in Cesium Sandcastle." }), "open": Flags.boolean({ @@ -65,15 +65,15 @@ export default class CesiumSandcastle extends BaseCommand { }) }; - async createExport(iModelId: string, changesetId: string): Promise { + private async createExport(iModelId: string, changesetId: string): Promise { const args = [ "--method", "POST", "--path", "mesh-export", "--version-header", "application/vnd.bentley.itwin-platform.v1+json", "--body", JSON.stringify({ - changesetId, - exportType: "CESIUM", - iModelId + changesetId, + exportType: "CESIUM", + iModelId }), ]; @@ -81,7 +81,7 @@ export default class CesiumSandcastle extends BaseCommand { return created.export; } - async getExports(iModelId: string) : Promise { + private async getExports(iModelId: string) : Promise { const exportArgs = [ "--method", "GET", "--path", "mesh-export/", @@ -93,7 +93,7 @@ export default class CesiumSandcastle extends BaseCommand { return response.exports; } - async getOrCreateExport(iModelId: string, changesetId: string): Promise { + private async getOrCreateExport(iModelId: string, changesetId: string): Promise { this.log(`Getting existing exports for iModel: ${iModelId} and changeset: ${changesetId}`); let existingExports = await this.getExports(iModelId); const existingExport = existingExports.find((exp) => exp.request.exportType === "CESIUM" && exp.request.changesetId === changesetId); @@ -107,18 +107,23 @@ export default class CesiumSandcastle extends BaseCommand { let newExport = await this.createExport(iModelId, changesetId); while (newExport.status !== "Complete") { this.log(`Export status is ${newExport.status}. Waiting for export to complete...`); - // eslint-disable-next-line no-await-in-loop + existingExports = await this.getExports(iModelId); - newExport = existingExports.find((exp) => exp.id === newExport.id)!; - // eslint-disable-next-line no-await-in-loop - await new Promise((resolve) => {setTimeout(resolve, 5000)}); + + const foundExport = existingExports.find((exp) => exp.id === newExport.id); + if(foundExport === undefined) + this.error("Export creation has failed"); + + newExport = foundExport; + + await new Promise((resolve) => {setTimeout(resolve, 5000);}); } this.log(`Export completed successfully`); return newExport; } - async run() { + public async run() { const { flags } = await this.parse(CesiumSandcastle); let changesetId = flags["changeset-id"] ?? ""; @@ -148,7 +153,7 @@ export default class CesiumSandcastle extends BaseCommand { if (flags.open) { this.log(`Opening URL in browser...`); - open(url); + await open(url); } return this.logAndReturnResult({ url }); @@ -156,16 +161,18 @@ export default class CesiumSandcastle extends BaseCommand { } -type ExportResponse = { +interface ExportResponse { + // eslint-disable-next-line @typescript-eslint/naming-convention _links: Links exports: ExportInfo[], } -type ExportCreateResponse = { +interface ExportCreateResponse { export: ExportInfo } -type ExportInfo = { +interface ExportInfo { + // eslint-disable-next-line @typescript-eslint/naming-convention _links: { mesh: Link }, @@ -177,7 +184,7 @@ type ExportInfo = { status: "Complete" | "InProgress" | "Invalid" | "NotStarted", } -type ExportRequest = { +interface ExportRequest { changesetId: string, exportType: "3DFT" | "3DTiles" | "CESIUM" | "IMODEL", iModelId: string, @@ -189,14 +196,14 @@ function extractTileSetUrl(exportInfo: ExportInfo): string { } const urlParts = exportInfo._links.mesh.href.split("?"); - return urlParts[0] + "/tileset.json?" + urlParts[1]; + return `${urlParts[0] }/tileset.json?${ urlParts[1]}`; } function makeCompressedBase64String(data: string[]) : string { let jsonString = JSON.stringify(data); jsonString = jsonString.slice(2, 2 + jsonString.length - 4); let base64String = Buffer.from( - deflate(jsonString, { raw: true }) + deflate(jsonString, { raw: true }) ).toString('base64'); base64String = base64String.replace(/=+$/, ''); // remove padding @@ -214,9 +221,9 @@ function htmlData() : string { } function jsData(tilesetUrl: string, terrain?: string) : string { - let viewerParams = "" + let viewerParams = ""; if(terrain === 'cesiumWorldTerrain') { - viewerParams += "terrain: Cesium.Terrain.fromWorldTerrain()," + viewerParams += "terrain: Cesium.Terrain.fromWorldTerrain(),"; } return ` diff --git a/src/commands/itwin/create.ts b/src/commands/itwin/create.ts index 46c15c15..b3d501b1 100644 --- a/src/commands/itwin/create.ts +++ b/src/commands/itwin/create.ts @@ -10,126 +10,128 @@ import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; export default class CreateITwin extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/itwins/operations/create-itwin/", - name: "Create iTwin", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/itwins/operations/create-itwin/", + name: "Create iTwin", + }; - static customDocs = true; + public static customDocs = true; - static description = 'Create a new iTwin with specified properties.'; + public static description = 'Create a new iTwin with specified properties.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --class Thing --sub-class Asset --name "Golden Gate Revamp"`, - description: `Example 1: Creating an iTwin with the 'Thing' class and 'Asset' subclass` - }, - { - command: `<%= config.bin %> <%= command.id %> --class Endeavor --sub-class Project --name "Bridge Construction" --geographic-location "San Francisco, CA" --iana-time-zone America/Los_Angeles`, - description: `Example 2: Creating an iTwin with the 'Endeavor' class and 'Project' subclass` - }, - { - command: `<%= config.bin %> <%= command.id %> --class Endeavor --sub-class Program --name "Rail Network" --data-center-location "UK South" --status Trial`, - description: `Example 3: Creating an iTwin with data center location and status set to 'Trial'` - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --class Thing --sub-class Asset --name "Golden Gate Revamp"`, + description: `Example 1: Creating an iTwin with the 'Thing' class and 'Asset' subclass` + }, + { + command: `<%= config.bin %> <%= command.id %> --class Endeavor --sub-class Project --name "Bridge Construction" --geographic-location "San Francisco, CA" --iana-time-zone America/Los_Angeles`, + description: `Example 2: Creating an iTwin with the 'Endeavor' class and 'Project' subclass` + }, + { + command: `<%= config.bin %> <%= command.id %> --class Endeavor --sub-class Program --name "Rail Network" --data-center-location "UK South" --status Trial`, + description: `Example 3: Creating an iTwin with data center location and status set to 'Trial'` + } + ]; - static flags = { - class: Flags.string({ - description: 'The Class of your iTwin.', - helpValue: '', - options: ["Account", "Thing", "Endeavor"], - required: true, - }), - "data-center-location": Flags.string({ - description: 'Data center for iTwin data. Defaults to East US.', - helpValue: '', - options: ['East US', 'North Europe', 'West Europe', 'Southeast Asia', 'Australia East', 'UK South', 'Canada Central', 'Central India', 'Japan East'], - required: false, - }), - "geographic-location": Flags.string({ - description: 'Optional location, typically an address or city.', - helpValue: '', - required: false - }), - "iana-time-zone": Flags.string({ - description: 'Optional IANA time zone ID.', - helpValue: '', - required: false, - }), - name: Flags.string({ - char: 'n', - description: "The iTwin's display name.", - helpValue: '', - required: true, - }), - number: Flags.string({ - description: 'Unique identifier for the iTwin. Defaults to iTwin Id if unspecified.', - helpValue: '', - required: false, - }), - "parent-id": Flags.string({ - description: "Optional parent iTwin Id. Defaults to user's Account iTwin.", - helpValue: '', - required: false, - }), - save: Flags.boolean({ - description: 'Save the iTwin id to the context.', - required: false, - }), - status: Flags.string({ - description: 'Status of the iTwin. Defaults to Active.', - helpValue: '', - options: ['Active', 'Inactive', 'Trial'], - required: false, - }), - "sub-class": Flags.string({ - description: 'The subClass of your iTwin.', - helpValue: '', - options: ["Account", "Portfolio", "Asset", "Program", "Project", "WorkPackage"], - required: true, - }), - type: Flags.string({ - description: "An open ended property to better define your iTwin's Type.", - helpValue: '', - required: false, - }), - }; + public static flags = { + class: Flags.string({ + description: 'The Class of your iTwin.', + helpValue: '', + options: ["Account", "Thing", "Endeavor"], + required: true, + }), + "data-center-location": Flags.string({ + description: 'Data center for iTwin data. Defaults to East US.', + helpValue: '', + options: ['East US', 'North Europe', 'West Europe', 'Southeast Asia', 'Australia East', 'UK South', 'Canada Central', 'Central India', 'Japan East'], + required: false, + }), + "geographic-location": Flags.string({ + description: 'Optional location, typically an address or city.', + helpValue: '', + required: false + }), + "iana-time-zone": Flags.string({ + description: 'Optional IANA time zone ID.', + helpValue: '', + required: false, + }), + name: Flags.string({ + char: 'n', + description: "The iTwin's display name.", + helpValue: '', + required: true, + }), + // eslint-disable-next-line id-denylist + number: Flags.string({ + description: 'Unique identifier for the iTwin. Defaults to iTwin Id if unspecified.', + helpValue: '', + required: false, + }), + "parent-id": Flags.string({ + description: "Optional parent iTwin Id. Defaults to user's Account iTwin.", + helpValue: '', + required: false, + }), + save: Flags.boolean({ + description: 'Save the iTwin id to the context.', + required: false, + }), + status: Flags.string({ + description: 'Status of the iTwin. Defaults to Active.', + helpValue: '', + options: ['Active', 'Inactive', 'Trial'], + required: false, + }), + "sub-class": Flags.string({ + description: 'The subClass of your iTwin.', + helpValue: '', + options: ["Account", "Portfolio", "Asset", "Program", "Project", "WorkPackage"], + required: true, + }), + type: Flags.string({ + description: "An open ended property to better define your iTwin's Type.", + helpValue: '', + required: false, + }), + }; - async run() { - const { flags } = await this.parse(CreateITwin); + public async run() { + const { flags } = await this.parse(CreateITwin); - const iTwin : ITwin = { - class: flags.class as ITwinClass, - dataCenterLocation: flags["data-center-location"], - displayName: flags.name, - geographicLocation: flags["geographic-location"], - ianaTimeZone: flags["iana-time-zone"], - number: flags.number, - parentId: flags["parent-id"], - status: flags.status, - subClass: flags["sub-class"] as ITwinSubClass, - type: flags.type - }; + const iTwin : ITwin = { + class: flags.class as ITwinClass, + dataCenterLocation: flags["data-center-location"], + displayName: flags.name, + geographicLocation: flags["geographic-location"], + ianaTimeZone: flags["iana-time-zone"], + // eslint-disable-next-line id-denylist + number: flags.number, + parentId: flags["parent-id"], + status: flags.status, + subClass: flags["sub-class"] as ITwinSubClass, + type: flags.type + }; - const accessToken = await this.getAccessToken(); - const client = this.getITwinAccessClient(); + const accessToken = await this.getAccessToken(); + const client = this.getITwinAccessClient(); - const creatediTwin = await client.createiTwin(accessToken, iTwin); - if(creatediTwin.error) - { - this.error(JSON.stringify(creatediTwin.error, null, 2)); - } + const creatediTwin = await client.createiTwin(accessToken, iTwin); + if(creatediTwin.error) + { + this.error(JSON.stringify(creatediTwin.error, null, 2)); + } - if (flags.save) { - if(creatediTwin.data?.id === undefined){ - this.log("iTwin Id not found in response. Cannot save to context."); - } - else { - this.setContext(creatediTwin.data.id); - } + if (flags.save) { + if(creatediTwin.data?.id === undefined){ + this.log("iTwin Id not found in response. Cannot save to context."); + } + else { + await this.setContext(creatediTwin.data.id); } - - return this.logAndReturnResult(creatediTwin.data); } + + return this.logAndReturnResult(creatediTwin.data); } +} diff --git a/src/commands/itwin/delete.ts b/src/commands/itwin/delete.ts index dcf58889..93db27fd 100644 --- a/src/commands/itwin/delete.ts +++ b/src/commands/itwin/delete.ts @@ -5,41 +5,41 @@ import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; -import { CustomFlags } from "../../extensions/custom-flags.js"; +import { customFlags } from "../../extensions/custom-flags.js"; export default class DeleteITwin extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/itwins/operations/delete-itwin/", - name: "Delete iTwin", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/itwins/operations/delete-itwin/", + name: "Delete iTwin", + }; - static description = 'Delete the specified iTwin.'; + public static description = 'Delete the specified iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id b1a2c3d4-5678-90ab-cdef-1234567890ab`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id b1a2c3d4-5678-90ab-cdef-1234567890ab`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin to be deleted.' - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin to be deleted.' + }), + }; - async run() { - const { flags } = await this.parse(DeleteITwin); + public async run() { + const { flags } = await this.parse(DeleteITwin); - const accessToken = await this.getAccessToken(); - const client = this.getITwinAccessClient(); - - const response = await client.deleteiTwin(accessToken, flags["itwin-id"]) - if(response.error) - { - this.error(JSON.stringify(response.error, null, 2)); - } + const accessToken = await this.getAccessToken(); + const client = this.getITwinAccessClient(); - return this.logAndReturnResult({ result: 'deleted' }); + const response = await client.deleteiTwin(accessToken, flags["itwin-id"]); + if(response.error) + { + this.error(JSON.stringify(response.error, null, 2)); } + + return this.logAndReturnResult({ result: 'deleted' }); } +} diff --git a/src/commands/itwin/info.ts b/src/commands/itwin/info.ts index 0097ba03..e7a52afd 100644 --- a/src/commands/itwin/info.ts +++ b/src/commands/itwin/info.ts @@ -5,42 +5,42 @@ import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; -import { CustomFlags } from "../../extensions/custom-flags.js"; +import { customFlags } from "../../extensions/custom-flags.js"; export default class ITwinInfo extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/iTwins/operations/get-itwin/", - name: "Get iTwin Details", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/iTwins/operations/get-itwin/", + name: "Get iTwin Details", + }; - static description = 'Retrieve metadata for the specified iTwin.'; + public static description = 'Retrieve metadata for the specified iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id b1a2c3d4-5678-90ab-cdef-1234567890ab`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id b1a2c3d4-5678-90ab-cdef-1234567890ab`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin to retrieve information about.' - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin to retrieve information about.' + }), + }; - async run() { - const { flags } = await this.parse(ITwinInfo); + public async run() { + const { flags } = await this.parse(ITwinInfo); - const accessToken = await this.getAccessToken(); - const client = this.getITwinAccessClient(); + const accessToken = await this.getAccessToken(); + const client = this.getITwinAccessClient(); - const response = await client.getAsync(accessToken, flags["itwin-id"], 'representation'); + const response = await client.getAsync(accessToken, flags["itwin-id"], 'representation'); - if(response.error) - { - this.error(JSON.stringify(response.error, null, 2)); - } - - return this.logAndReturnResult(response.data); + if(response.error) + { + this.error(JSON.stringify(response.error, null, 2)); } + + return this.logAndReturnResult(response.data); } +} diff --git a/src/commands/itwin/list.ts b/src/commands/itwin/list.ts index 5580f31f..024db1f3 100644 --- a/src/commands/itwin/list.ts +++ b/src/commands/itwin/list.ts @@ -10,122 +10,124 @@ import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; export default class ListITwins extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/itwins/operations/get-my-itwins/", - name: "List iTwins", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/itwins/operations/get-my-itwins/", + name: "List iTwins", + }; - static description = 'List all iTwins the calling user is a member of.'; + public static description = 'List all iTwins the calling user is a member of.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %>`, - description: 'Example 1: Getting all itwins' - }, - { - command: `<%= config.bin %> <%= command.id %> --sub-class Project --status Active`, - description: 'Example 2: Filtering by subClass and status' - }, - { - command: `<%= config.bin %> <%= command.id %> --sub-class Program --type Luxury --top 10`, - description: 'Example 3: Limiting the number of returned results and filtering by type' - }, - { - command: `<%= config.bin %> <%= command.id %> --sub-class Asset --name "Solar Farm" --include-inactive`, - description: 'Example 4: Searching by display name and including inactive iTwins' - }, - { - command: `<%= config.bin %> <%= command.id %> --sub-class WorkPackage --parent-id b1a2c3d4-5678-90ab-cdef-1234567890ab --skip 5`, - description: 'Example 5: Filtering by parent iTwin ID and skipping the first 5 results' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %>`, + description: 'Example 1: Getting all itwins' + }, + { + command: `<%= config.bin %> <%= command.id %> --sub-class Project --status Active`, + description: 'Example 2: Filtering by subClass and status' + }, + { + command: `<%= config.bin %> <%= command.id %> --sub-class Program --type Luxury --top 10`, + description: 'Example 3: Limiting the number of returned results and filtering by type' + }, + { + command: `<%= config.bin %> <%= command.id %> --sub-class Asset --name "Solar Farm" --include-inactive`, + description: 'Example 4: Searching by display name and including inactive iTwins' + }, + { + command: `<%= config.bin %> <%= command.id %> --sub-class WorkPackage --parent-id b1a2c3d4-5678-90ab-cdef-1234567890ab --skip 5`, + description: 'Example 5: Filtering by parent iTwin ID and skipping the first 5 results' + } + ]; - static flags = { - "include-inactive": Flags.boolean({ - description: 'Include Inactive iTwins in the result.', - required: false - }), - "itwin-account-id": Flags.string({ - description: 'Filter by the iTwin Account ID.', - helpValue: '', - required: false - }), - name: Flags.string({ - char: 'n', - description: 'Find iTwins with the exact display name specified.', - helpValue: '', - required: false, - }), - number: Flags.string({ - description: 'Find iTwins with the exact number specified.', - helpValue: '', - required: false, - }), - "parent-id": Flags.string({ - description: 'Filter by the parent iTwin ID.', - helpValue: '', - required: false - }), - search: Flags.string({ - description: 'Search iTwins by a string in the number or display name.', - helpValue: '', - required: false, - }), - skip: Flags.integer({ - description: 'Skip a number of items in the result.', - helpValue: '', - required: false, - }), - status: Flags.string({ - description: 'Filter by the status of the iTwin.', - helpValue: '', - options: ['Active', 'Inactive', 'Trial'], - required: false - }), - "sub-class": Flags.string({ - description: 'Filter by a specific iTwin subClass.', - helpValue: '', - options: Object.values(ITwinSubClass), - required: false - }), - top: Flags.integer({ - description: 'Limit the number of items returned.', - helpValue: '', - required: false, - }), - type: Flags.string({ - description: "Filter by the iTwin's Type.", - helpValue: '', - required: false, - }), - }; + public static flags = { + "include-inactive": Flags.boolean({ + description: 'Include Inactive iTwins in the result.', + required: false + }), + "itwin-account-id": Flags.string({ + description: 'Filter by the iTwin Account ID.', + helpValue: '', + required: false + }), + name: Flags.string({ + char: 'n', + description: 'Find iTwins with the exact display name specified.', + helpValue: '', + required: false, + }), + // eslint-disable-next-line id-denylist + number: Flags.string({ + description: 'Find iTwins with the exact number specified.', + helpValue: '', + required: false, + }), + "parent-id": Flags.string({ + description: 'Filter by the parent iTwin ID.', + helpValue: '', + required: false + }), + search: Flags.string({ + description: 'Search iTwins by a string in the number or display name.', + helpValue: '', + required: false, + }), + skip: Flags.integer({ + description: 'Skip a number of items in the result.', + helpValue: '', + required: false, + }), + status: Flags.string({ + description: 'Filter by the status of the iTwin.', + helpValue: '', + options: ['Active', 'Inactive', 'Trial'], + required: false + }), + "sub-class": Flags.string({ + description: 'Filter by a specific iTwin subClass.', + helpValue: '', + options: Object.values(ITwinSubClass), + required: false + }), + top: Flags.integer({ + description: 'Limit the number of items returned.', + helpValue: '', + required: false, + }), + type: Flags.string({ + description: "Filter by the iTwin's Type.", + helpValue: '', + required: false, + }), + }; - async run() { - const { flags } = await this.parse(ListITwins); + public async run() { + const { flags } = await this.parse(ListITwins); - const accessToken = await this.getAccessToken(); - const client = this.getITwinAccessClient(); + const accessToken = await this.getAccessToken(); + const client = this.getITwinAccessClient(); - const response = await client.queryAsync(accessToken, undefined, { - displayName: flags.name, - iTwinAccountId: flags["itwin-account-id"], - includeInactive: flags["include-inactive"], - number: flags.number, - parentId: flags["parent-id"], - resultMode: 'representation', - search: flags.search, - skip: flags.skip, - status: flags.status, - subClass: flags["sub-class"] as ITwinSubClass, - top: flags.top, - type: flags.type - }) + const response = await client.queryAsync(accessToken, undefined, { + displayName: flags.name, + iTwinAccountId: flags["itwin-account-id"], + includeInactive: flags["include-inactive"], + // eslint-disable-next-line id-denylist + number: flags.number, + parentId: flags["parent-id"], + resultMode: 'representation', + search: flags.search, + skip: flags.skip, + status: flags.status, + subClass: flags["sub-class"] as ITwinSubClass, + top: flags.top, + type: flags.type + }); - if(response.error) - { - this.error(JSON.stringify(response.error, null, 2)); - } - - return this.logAndReturnResult(response.data); + if(response.error) + { + this.error(JSON.stringify(response.error, null, 2)); } + + return this.logAndReturnResult(response.data); } +} diff --git a/src/commands/itwin/repository/create.ts b/src/commands/itwin/repository/create.ts index fe6f2b30..364d8ab9 100644 --- a/src/commands/itwin/repository/create.ts +++ b/src/commands/itwin/repository/create.ts @@ -8,70 +8,70 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class CreateRepository extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/iTwins/operations/create-repository/", - name: "Create Repository", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/iTwins/operations/create-repository/", + name: "Create Repository", + }; - static description = 'Create a new repository URI for iTwin data.'; + public static description = 'Create a new repository URI for iTwin data.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --class GeographicInformationSystem --sub-class WebMapTileService --uri https://example.com/repository1`, - description: 'Example 1: Creating a repository with Geographic Information System class' - }, - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --class Construction --sub-class Performance --uri https://example.com/repository2`, - description: 'Example 2: Creating a repository for Construction class with MapServer subclass' - }, - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --class Subsurface --sub-class EvoWorkspace --uri https://example.com/repository3`, - description: 'Example 3: Creating a repository for Subsurface class without specifying a subclass' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --class GeographicInformationSystem --sub-class WebMapTileService --uri https://example.com/repository1`, + description: 'Example 1: Creating a repository with Geographic Information System class' + }, + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --class Construction --sub-class Performance --uri https://example.com/repository2`, + description: 'Example 2: Creating a repository for Construction class with MapServer subclass' + }, + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --class Subsurface --sub-class EvoWorkspace --uri https://example.com/repository3`, + description: 'Example 3: Creating a repository for Subsurface class without specifying a subclass' + } + ]; - static flags = { - class: Flags.string({ - description: 'The class of your iTwin repository.', - helpValue: '', - options: ['GeographicInformationSystem', 'Construction', 'Subsurface'], - required: true, - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin to which the repository belongs.' - }), - "sub-class": Flags.string({ - description: 'The subClass of your repository.', - helpValue: '', - options: ['WebMapService', 'WebMapTileService', 'MapServer', 'Performance', 'EvoWorkspace'], - }), - uri: Flags.string({ - description: 'The URI to the custom repository.', - helpValue: '', - required: true, - }), - }; + public static flags = { + class: Flags.string({ + description: 'The class of your iTwin repository.', + helpValue: '', + options: ['GeographicInformationSystem', 'Construction', 'Subsurface'], + required: true, + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin to which the repository belongs.' + }), + "sub-class": Flags.string({ + description: 'The subClass of your repository.', + helpValue: '', + options: ['WebMapService', 'WebMapTileService', 'MapServer', 'Performance', 'EvoWorkspace'], + }), + uri: Flags.string({ + description: 'The URI to the custom repository.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(CreateRepository); + public async run() { + const { flags } = await this.parse(CreateRepository); - const accessToken = await this.getAccessToken(); - const client = this.getITwinAccessClient(); + const accessToken = await this.getAccessToken(); + const client = this.getITwinAccessClient(); - const response = await client.createRepository(accessToken, flags["itwin-id"], { - class: flags.class as RepositoryClass, - subClass: flags["sub-class"] as RepositorySubClass, - uri: flags.uri - }); + const response = await client.createRepository(accessToken, flags["itwin-id"], { + class: flags.class as RepositoryClass, + subClass: flags["sub-class"] as RepositorySubClass, + uri: flags.uri + }); - if(response.error) - { - this.error(JSON.stringify(response.error, null, 2)); - } - - return this.logAndReturnResult(response.data); + if(response.error) + { + this.error(JSON.stringify(response.error, null, 2)); } + + return this.logAndReturnResult(response.data); } +} diff --git a/src/commands/itwin/repository/delete.ts b/src/commands/itwin/repository/delete.ts index 5d923550..19e3a670 100644 --- a/src/commands/itwin/repository/delete.ts +++ b/src/commands/itwin/repository/delete.ts @@ -7,46 +7,46 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class DeleteRepository extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/iTwins/operations/delete-repository/", - name: "Delete Repository", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/iTwins/operations/delete-repository/", + name: "Delete Repository", + }; - static description = 'Delete a specified repository from an iTwin.'; + public static description = 'Delete a specified repository from an iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --repository-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --repository-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, + description: 'Example 1:' + } + ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin that the repository belongs to.' - }), - "repository-id": Flags.string({ - description: 'The ID of the repository to delete.', - helpValue: '', - required: true, - }), - }; + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin that the repository belongs to.' + }), + "repository-id": Flags.string({ + description: 'The ID of the repository to delete.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(DeleteRepository); + public async run() { + const { flags } = await this.parse(DeleteRepository); - const client = this.getITwinAccessClient(); - const accessToken = await this.getAccessToken(); + const client = this.getITwinAccessClient(); + const accessToken = await this.getAccessToken(); - const response = await client.deleteRepository(accessToken, flags["itwin-id"], flags["repository-id"]); - if(response.error) - { - this.error(JSON.stringify(response.error, null, 2)); - } - - return this.logAndReturnResult({ result: 'deleted' }); + const response = await client.deleteRepository(accessToken, flags["itwin-id"], flags["repository-id"]); + if(response.error) + { + this.error(JSON.stringify(response.error, null, 2)); } + + return this.logAndReturnResult({ result: 'deleted' }); } +} diff --git a/src/commands/itwin/repository/list.ts b/src/commands/itwin/repository/list.ts index 7f948aa5..88709530 100644 --- a/src/commands/itwin/repository/list.ts +++ b/src/commands/itwin/repository/list.ts @@ -7,65 +7,65 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; -import { CustomFlags } from "../../../extensions/custom-flags.js"; +import { customFlags } from "../../../extensions/custom-flags.js"; export default class ListRepositories extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/itwins/operations/get-repositories-by-itwin-id/", - name: "List Repositories", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/itwins/operations/get-repositories-by-itwin-id/", + name: "List Repositories", + }; - static description = 'Retrieve a list of repositories for a specified iTwin.'; + public static description = 'Retrieve a list of repositories for a specified iTwin.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, - description: 'Example 1: Listing all repositories for an iTwin' - }, - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --class iModels`, - description: 'Example 2: Filtering repositories by class' - }, - { - command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --class GeographicInformationSystem --sub-class WebMapTileService`, - description: 'Example 3: Filtering repositories by class and subClass' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, + description: 'Example 1: Listing all repositories for an iTwin' + }, + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --class iModels`, + description: 'Example 2: Filtering repositories by class' + }, + { + command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51 --class GeographicInformationSystem --sub-class WebMapTileService`, + description: 'Example 3: Filtering repositories by class and subClass' + } + ]; - static flags = { - class: Flags.string({ - description: 'Specify a particular class of repositories to retrieve.', - helpValue: '', - options: ["iModels", "RealityData", "Storage", "Forms", "Issues", "SensorData", "GeographicInformationSystem", "Construction", "Subsurface"], - required: false - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin whose repositories should be retrieved.' - }), - "sub-class": Flags.string({ - description: 'Specify a subClass of repositories. Only applicable for **`GeographicInformationSystem`** class. ', - helpValue: '', - options: ["WebMapService", "WebMapTileService", "MapServer"], - required: false - }), - }; + public static flags = { + class: Flags.string({ + description: 'Specify a particular class of repositories to retrieve.', + helpValue: '', + options: ["iModels", "RealityData", "Storage", "Forms", "Issues", "SensorData", "GeographicInformationSystem", "Construction", "Subsurface"], + required: false + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin whose repositories should be retrieved.' + }), + "sub-class": Flags.string({ + description: 'Specify a subClass of repositories. Only applicable for **`GeographicInformationSystem`** class. ', + helpValue: '', + options: ["WebMapService", "WebMapTileService", "MapServer"], + required: false + }), + }; - async run() { - const { flags } = await this.parse(ListRepositories); + public async run() { + const { flags } = await this.parse(ListRepositories); - const client = this.getITwinAccessClient(); - const accessToken = await this.getAccessToken(); + const client = this.getITwinAccessClient(); + const accessToken = await this.getAccessToken(); - const response = await client.queryRepositoriesAsync(accessToken, flags["itwin-id"], { - class: flags.class, - subClass: flags["sub-class"] - }); + const response = await client.queryRepositoriesAsync(accessToken, flags["itwin-id"], { + class: flags.class, + subClass: flags["sub-class"] + }); - if(response.error) - { - this.error(JSON.stringify(response.error, null, 2)); - } - - return this.logAndReturnResult(response.data); + if(response.error) + { + this.error(JSON.stringify(response.error, null, 2)); } + + return this.logAndReturnResult(response.data); } +} diff --git a/src/commands/itwin/update.ts b/src/commands/itwin/update.ts index 8c4d09dc..726ed475 100644 --- a/src/commands/itwin/update.ts +++ b/src/commands/itwin/update.ts @@ -8,91 +8,93 @@ import { Flags } from "@oclif/core"; import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; -import { CustomFlags } from "../../extensions/custom-flags.js"; +import { customFlags } from "../../extensions/custom-flags.js"; export default class UpdateCommand extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/itwins/operations/update-itwin/", - name: "Update iTwin", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/itwins/operations/update-itwin/", + name: "Update iTwin", + }; - static description = 'Update the specified iTwin. Only include properties you want to update.'; + public static description = 'Update the specified iTwin. Only include properties you want to update.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --itwin-id b1a2c3d4-5678-90ab-cdef-1234567890ab --name "Updated Portfolio"`, - description: `Example 1: Updating iTwin's display name` - }, - { - command: `<%= config.bin %> <%= command.id %> --itwin-id b1a2c3d4-5678-90ab-cdef-1234567890ab --geographic-location "New York, NY" --iana-time-zone America/New_York`, - description: 'Example 2: Changing geographic location and time zone' - }, - { - command: `<%= config.bin %> <%= command.id %> --itwin-id b1a2c3d4-5678-90ab-cdef-1234567890ab --status Inactive`, - description: `Example 3: Setting the iTwin's status to 'Inactive'` - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --itwin-id b1a2c3d4-5678-90ab-cdef-1234567890ab --name "Updated Portfolio"`, + description: `Example 1: Updating iTwin's display name` + }, + { + command: `<%= config.bin %> <%= command.id %> --itwin-id b1a2c3d4-5678-90ab-cdef-1234567890ab --geographic-location "New York, NY" --iana-time-zone America/New_York`, + description: 'Example 2: Changing geographic location and time zone' + }, + { + command: `<%= config.bin %> <%= command.id %> --itwin-id b1a2c3d4-5678-90ab-cdef-1234567890ab --status Inactive`, + description: `Example 3: Setting the iTwin's status to 'Inactive'` + } + ]; - static flags = { - "geographic-location": Flags.string({ - description: 'Optional location, typically an address or city.', - helpValue: '', - required: false - }), - "iana-time-zone": Flags.string({ - description: 'Optional IANA time zone ID.', - helpValue: '', - required: false, - }), - "itwin-id": CustomFlags.iTwinIDFlag({ - description: 'The ID of the iTwin to be updated.' - }), - name: Flags.string({ - char: 'n', - description: "The iTwin's display name.", - helpValue: '', - required: false, - }), - number: Flags.string({ - description: 'Unique identifier for the iTwin.', - helpValue: '', - required: false, - }), - status: Flags.string({ - description: 'Status of the iTwin. Defaults to Active.', - helpValue: '', - options: ['Active', 'Inactive', 'Trial'], - required: false, - }), - type: Flags.string({ - description: "Open ended property to define your iTwin's type. ", - helpValue: '', - required: false, - }), - }; + public static flags = { + "geographic-location": Flags.string({ + description: 'Optional location, typically an address or city.', + helpValue: '', + required: false + }), + "iana-time-zone": Flags.string({ + description: 'Optional IANA time zone ID.', + helpValue: '', + required: false, + }), + "itwin-id": customFlags.iTwinIDFlag({ + description: 'The ID of the iTwin to be updated.' + }), + name: Flags.string({ + char: 'n', + description: "The iTwin's display name.", + helpValue: '', + required: false, + }), + // eslint-disable-next-line id-denylist + number: Flags.string({ + description: 'Unique identifier for the iTwin.', + helpValue: '', + required: false, + }), + status: Flags.string({ + description: 'Status of the iTwin. Defaults to Active.', + helpValue: '', + options: ['Active', 'Inactive', 'Trial'], + required: false, + }), + type: Flags.string({ + description: "Open ended property to define your iTwin's type. ", + helpValue: '', + required: false, + }), + }; - async run() { - const { flags } = await this.parse(UpdateCommand); + public async run() { + const { flags } = await this.parse(UpdateCommand); - const iTwinUpdate : ITwin = { - displayName: flags.name, - geographicLocation: flags["geographic-location"], - ianaTimeZone: flags["iana-time-zone"], - number: flags.number, - status: flags.status, - type: flags.type, - }; + const iTwinUpdate : ITwin = { + displayName: flags.name, + geographicLocation: flags["geographic-location"], + ianaTimeZone: flags["iana-time-zone"], + // eslint-disable-next-line id-denylist + number: flags.number, + status: flags.status, + type: flags.type, + }; - const accessToken = await this.getAccessToken(); - const client = this.getITwinAccessClient(); + const accessToken = await this.getAccessToken(); + const client = this.getITwinAccessClient(); - const response = await client.updateiTwin(accessToken, flags["itwin-id"], iTwinUpdate); + const response = await client.updateiTwin(accessToken, flags["itwin-id"], iTwinUpdate); - if(response.error) - { - this.error(JSON.stringify(response.error, null, 2)); - } - - return this.logAndReturnResult(response.data); + if(response.error) + { + this.error(JSON.stringify(response.error, null, 2)); } + + return this.logAndReturnResult(response.data); } +} diff --git a/src/commands/storage/file/create.ts b/src/commands/storage/file/create.ts index 4c45380c..38c3209f 100644 --- a/src/commands/storage/file/create.ts +++ b/src/commands/storage/file/create.ts @@ -9,52 +9,52 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class FileCreate extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/storage/operations/create-file/", - name: "Create File", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/storage/operations/create-file/", + name: "Create File", + }; - static description = 'Create a new file in a specified folder in iTwin\'s storage.'; + public static description = 'Create a new file in a specified folder in iTwin\'s storage.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --folder-id abc12345-6789-4321-abcd-9876543210ef --name design.dwg`, - description: 'Example 1: Creating a file with display name only' - }, - { - command: `<%= config.bin %> <%= command.id %> --folder-id abc12345-6789-4321-abcd-9876543210ef --name model.ifc --description "Model file for the building design"`, - description: 'Example 2: Creating a file with display name and description' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --folder-id abc12345-6789-4321-abcd-9876543210ef --name design.dwg`, + description: 'Example 1: Creating a file with display name only' + }, + { + command: `<%= config.bin %> <%= command.id %> --folder-id abc12345-6789-4321-abcd-9876543210ef --name model.ifc --description "Model file for the building design"`, + description: 'Example 2: Creating a file with display name and description' + } + ]; - static flags = { - description: Flags.string({ - char: 'd', - description: 'A description for the file.', - helpValue: '', - required: false - }), - "folder-id": Flags.string({ - char: 'f', - description: 'The ID of the folder where the file will be created.', - helpValue: '', - required: true - }), - name: Flags.string({ - char: 'n', - description: 'The display name of the file.', - helpValue: '', - required: true - }), - }; + public static flags = { + description: Flags.string({ + char: 'd', + description: 'A description for the file.', + helpValue: '', + required: false + }), + "folder-id": Flags.string({ + char: 'f', + description: 'The ID of the folder where the file will be created.', + helpValue: '', + required: true + }), + name: Flags.string({ + char: 'n', + description: 'The display name of the file.', + helpValue: '', + required: true + }), + }; - async run() { - const { flags } = await this.parse(FileCreate); + public async run() { + const { flags } = await this.parse(FileCreate); - const client = await this.getStorageApiClient(); + const client = await this.getStorageApiClient(); - const response = await client.createFile(flags["folder-id"], flags.name, flags.description); + const response = await client.createFile(flags["folder-id"], flags.name, flags.description); - return this.logAndReturnResult(response); - } + return this.logAndReturnResult(response); } +} diff --git a/src/commands/storage/file/delete.ts b/src/commands/storage/file/delete.ts index 6b2fa736..e9ab99d9 100644 --- a/src/commands/storage/file/delete.ts +++ b/src/commands/storage/file/delete.ts @@ -9,36 +9,36 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class DeleteFile extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/storage/operations/delete-file/", - name: "Delete File", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/storage/operations/delete-file/", + name: "Delete File", + }; - static description = "Delete a file from an iTwin's storage."; + public static description = "Delete a file from an iTwin's storage."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --file-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --file-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, + description: 'Example 1:' + } + ]; - static flags = { - "file-id": Flags.string({ - char: 'f', - description: 'The ID of the file to be deleted.', - helpValue: '', - required: true, - }), - }; + public static flags = { + "file-id": Flags.string({ + char: 'f', + description: 'The ID of the file to be deleted.', + helpValue: '', + required: true, + }), + }; - async run() { - const { flags } = await this.parse(DeleteFile); + public async run() { + const { flags } = await this.parse(DeleteFile); - const client = await this.getStorageApiClient(); + const client = await this.getStorageApiClient(); - await client.deleteFile(flags["file-id"]); + await client.deleteFile(flags["file-id"]); - return this.logAndReturnResult({ result: 'deleted' }); - } + return this.logAndReturnResult({ result: 'deleted' }); } +} diff --git a/src/commands/storage/file/info.ts b/src/commands/storage/file/info.ts index 95dfd46c..51263d7f 100644 --- a/src/commands/storage/file/info.ts +++ b/src/commands/storage/file/info.ts @@ -9,35 +9,35 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class FileInfo extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/storage/operations/get-file/", - name: "Get File", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/storage/operations/get-file/", + name: "Get File", + }; - static description = "Retrieve metadata for a specific file in an iTwin's storage."; + public static description = "Retrieve metadata for a specific file in an iTwin's storage."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --file-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --file-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, + description: 'Example 1:' + } + ]; - static flags = { - "file-id": Flags.string({ - char: 'f', - description: "The ID of the file to retrieve information about.", - helpValue: '', - required: true - }), - }; + public static flags = { + "file-id": Flags.string({ + char: 'f', + description: "The ID of the file to retrieve information about.", + helpValue: '', + required: true + }), + }; - async run() { - const { flags } = await this.parse(FileInfo); + public async run() { + const { flags } = await this.parse(FileInfo); - const client = await this.getStorageApiClient(); - const result = await client.getFile(flags["file-id"]); + const client = await this.getStorageApiClient(); + const result = await client.getFile(flags["file-id"]); - return this.logAndReturnResult(result.file); - } + return this.logAndReturnResult(result.file); } +} diff --git a/src/commands/storage/file/list.ts b/src/commands/storage/file/list.ts index ebf3378a..59e6695c 100644 --- a/src/commands/storage/file/list.ts +++ b/src/commands/storage/file/list.ts @@ -9,54 +9,53 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class ListFiles extends BaseCommand { - static apiReference: ApiReference[] = [ - { - link: "https://developer.bentley.com/apis/storage/operations/get-files-in-folder/", - name: "List Files in Folder", - }, - { - link: "https://developer.bentley.com/apis/storage/operations/get-folders-and-files-in-folder/", - name: "List Files and Folders in Folder", - } - ]; + public static apiReference: ApiReference[] = [ + { + link: "https://developer.bentley.com/apis/storage/operations/get-files-in-folder/", + name: "List Files in Folder", + }, + { + link: "https://developer.bentley.com/apis/storage/operations/get-folders-and-files-in-folder/", + name: "List Files and Folders in Folder", + } + ]; - static description = "List files in a folder of an iTwin's storage. Optionally, include subfolders in the result."; + public static description = "List files in a folder of an iTwin's storage. Optionally, include subfolders in the result."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --folder-id b1a2c3d4-5678-90ab-cdef-1234567890ab`, - description: 'Example 1: List files in a specific folder' - }, - { - command: `<%= config.bin %> <%= command.id %> --folder-id b1a2c3d4-5678-90ab-cdef-1234567890ab --include-folders`, - description: 'Example 2: List files and include subfolders in the result' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --folder-id b1a2c3d4-5678-90ab-cdef-1234567890ab`, + description: 'Example 1: List files in a specific folder' + }, + { + command: `<%= config.bin %> <%= command.id %> --folder-id b1a2c3d4-5678-90ab-cdef-1234567890ab --include-folders`, + description: 'Example 2: List files and include subfolders in the result' + } + ]; - static flags = { - "folder-id": Flags.string({ - char: 'f', - description: "The ID of the folder whose files you want to list.", - helpValue: '', - required: true - }), - "include-folders": Flags.boolean({ - description: "Whether to include subfolders in the result." - }), - }; + public static flags = { + "folder-id": Flags.string({ + char: 'f', + description: "The ID of the folder whose files you want to list.", + helpValue: '', + required: true + }), + "include-folders": Flags.boolean({ + description: "Whether to include subfolders in the result." + }), + }; - async run() { - const { flags } = await this.parse(ListFiles); + public async run() { + const { flags } = await this.parse(ListFiles); - const client = await this.getStorageApiClient(); + const client = await this.getStorageApiClient(); - if (flags["include-folders"]) { - const result = await client.getFilesAndFolders(flags["folder-id"]); - return this.logAndReturnResult(result.items); - } - - const result = await client.getFiles(flags["folder-id"]); - return this.logAndReturnResult(result.files); - + if (flags["include-folders"]) { + const filesAndFoldersResult = await client.getFilesAndFolders(flags["folder-id"]); + return this.logAndReturnResult(filesAndFoldersResult.items); } + + const filesResult = await client.getFiles(flags["folder-id"]); + return this.logAndReturnResult(filesResult.files); } +} diff --git a/src/commands/storage/file/update-complete.ts b/src/commands/storage/file/update-complete.ts index dca0b932..8e0ca932 100644 --- a/src/commands/storage/file/update-complete.ts +++ b/src/commands/storage/file/update-complete.ts @@ -9,36 +9,36 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class FileUpdateComplete extends BaseCommand { - static apiReference : ApiReference = { - link: 'https://developer.bentley.com/apis/storage/operations/complete-file-creation/', - name: 'Complete File Creation', - }; + public static apiReference: ApiReference = { + link: 'https://developer.bentley.com/apis/storage/operations/complete-file-creation/', + name: 'Complete File Creation', + }; - static description = 'Complete the file creation or content update process by marking the operation as done.'; + public static description = 'Complete the file creation or content update process by marking the operation as done.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --file-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, - description: 'Example 1: Complete the file creation or update process' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --file-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, + description: 'Example 1: Complete the file creation or update process' + } + ]; - static flags = { - "file-id": Flags.string({ - char: 'f', - description: 'The ID of the file for which the creation or update is being completed. ', - helpValue: '', - required: true - }), - }; + public static flags = { + "file-id": Flags.string({ + char: 'f', + description: 'The ID of the file for which the creation or update is being completed. ', + helpValue: '', + required: true + }), + }; - async run() { - const { flags } = await this.parse(FileUpdateComplete); + public async run() { + const { flags } = await this.parse(FileUpdateComplete); - const client = await this.getStorageApiClient(); - const response = await client.completeFileUpload(flags["file-id"]); + const client = await this.getStorageApiClient(); + const response = await client.completeFileUpload(flags["file-id"]); - return this.logAndReturnResult(response.file); - } + return this.logAndReturnResult(response.file); } +} \ No newline at end of file diff --git a/src/commands/storage/file/update-content.ts b/src/commands/storage/file/update-content.ts index 3b3bf932..bb84bd39 100644 --- a/src/commands/storage/file/update-content.ts +++ b/src/commands/storage/file/update-content.ts @@ -9,35 +9,35 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class UpdateContent extends BaseCommand { - static apiReference : ApiReference = { - link: 'https://developer.bentley.com/apis/storage/operations/update-file-content/', - name: 'Update File Content', - } + public static apiReference: ApiReference = { + link: 'https://developer.bentley.com/apis/storage/operations/update-file-content/', + name: 'Update File Content', + }; - static description = 'Update the content of an existing file. A URL is returned to upload the file content.'; + public static description = 'Update the content of an existing file. A URL is returned to upload the file content.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --file-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, - description: 'Example 1: Get URL to update file content' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --file-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42`, + description: 'Example 1: Get URL to update file content' + } + ]; - static flags = { - "file-id": Flags.string({ - char: 'f', - description: 'The ID of the file to update the content for.', - helpValue: '', - required: true - }), - }; + public static flags = { + "file-id": Flags.string({ + char: 'f', + description: 'The ID of the file to update the content for.', + helpValue: '', + required: true + }), + }; - async run() { - const { flags } = await this.parse(UpdateContent); + public async run() { + const { flags } = await this.parse(UpdateContent); - const storageApiClient = await this.getStorageApiClient(); - const response = await storageApiClient.updateFileContent(flags["file-id"]); + const storageApiClient = await this.getStorageApiClient(); + const response = await storageApiClient.updateFileContent(flags["file-id"]); - return this.logAndReturnResult(response); - } - } \ No newline at end of file + return this.logAndReturnResult(response); + } +} \ No newline at end of file diff --git a/src/commands/storage/file/update.ts b/src/commands/storage/file/update.ts index 404bbb99..f1e5156f 100644 --- a/src/commands/storage/file/update.ts +++ b/src/commands/storage/file/update.ts @@ -9,49 +9,49 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class UpdateCommand extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/storage/operations/update-file/", - name: "Update File", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/storage/operations/update-file/", + name: "Update File", + }; - static description = "Update the metadata of a file in an iTwin's storage, such as display name or description."; + public static description = "Update the metadata of a file in an iTwin's storage, such as display name or description."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --file-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --name "Updated Design File"`, - description: 'Example 1: Update file display name' - }, - { - command: `<%= config.bin %> <%= command.id %> --file-id c9f2b8a5-345d-4cfa-b3e5-123456789abc --name "New Model File" --description "Updated model with new specifications"`, - description: 'Example 2: Update file description and display name' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --file-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --name "Updated Design File"`, + description: 'Example 1: Update file display name' + }, + { + command: `<%= config.bin %> <%= command.id %> --file-id c9f2b8a5-345d-4cfa-b3e5-123456789abc --name "New Model File" --description "Updated model with new specifications"`, + description: 'Example 2: Update file description and display name' + } + ]; - static flags = { - description: Flags.string({ - char: 'd', - description: "A description for the file." , - helpValue: '', - }), - "file-id": Flags.string({ - char: 'f', - description: "The ID of the file to be updated.", - helpValue: '', - required: true - }), - name: Flags.string({ - char: 'n', - description: "The new display name for the file.", - helpValue: '', - }), - }; + public static flags = { + description: Flags.string({ + char: 'd', + description: "A description for the file." , + helpValue: '', + }), + "file-id": Flags.string({ + char: 'f', + description: "The ID of the file to be updated.", + helpValue: '', + required: true + }), + name: Flags.string({ + char: 'n', + description: "The new display name for the file.", + helpValue: '', + }), + }; - async run() { - const { flags } = await this.parse(UpdateCommand); + public async run() { + const { flags } = await this.parse(UpdateCommand); - const client = await this.getStorageApiClient(); - const response = await client.updateFile(flags["file-id"], flags.name, flags.description); + const client = await this.getStorageApiClient(); + const response = await client.updateFile(flags["file-id"], flags.name, flags.description); - return this.logAndReturnResult(response.file); - } + return this.logAndReturnResult(response.file); } +} diff --git a/src/commands/storage/file/upload.ts b/src/commands/storage/file/upload.ts index c8941aac..4fb269e2 100644 --- a/src/commands/storage/file/upload.ts +++ b/src/commands/storage/file/upload.ts @@ -4,69 +4,70 @@ *--------------------------------------------------------------------------------------------*/ import { Flags } from "@oclif/core"; -import fs from "node:fs" +import fs from "node:fs"; import BaseCommand from "../../../extensions/base-command.js"; +import { ApiReference } from "../../../extensions/api-reference.js"; export default class FileUpload extends BaseCommand { - static apiReference = { - link: 'https://developer.bentley.com/apis/storage/operations/upload-file/', - name: 'Upload File', - }; + public static apiReference: ApiReference = { + link: 'https://developer.bentley.com/apis/storage/operations/upload-file/', + name: 'Upload File', + }; - static description = 'Upload a new file to a specified URL within iTwin storage.'; + public static description = 'Upload a new file to a specified URL within iTwin storage.'; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --upload-url https://example.com/upload-url --file-path /path/to/your/file.pdf`, - description: 'Example 1: Upload a PDF file to the storage' - }, - { - command: `<%= config.bin %> <%= command.id %> --upload-url https://example.com/image-upload-url --file-path /path/to/your/image.jpg`, - description: 'Example 2: Upload an image file to the storage' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --upload-url https://example.com/upload-url --file-path /path/to/your/file.pdf`, + description: 'Example 1: Upload a PDF file to the storage' + }, + { + command: `<%= config.bin %> <%= command.id %> --upload-url https://example.com/image-upload-url --file-path /path/to/your/image.jpg`, + description: 'Example 2: Upload an image file to the storage' + } + ]; - static flags = { - "file-path": Flags.string({ - char: 'f', - description: 'The path to the file you want to upload.', - helpValue: '', - required: true - }), - "upload-url": Flags.string({ - char: 'u', - description: 'The URL where the file should be uploaded.', - helpValue: '', - required: true - }), - }; - - async run() { - const { flags } = await this.parse(FileUpload); + public static flags = { + "file-path": Flags.string({ + char: 'f', + description: 'The path to the file you want to upload.', + helpValue: '', + required: true + }), + "upload-url": Flags.string({ + char: 'u', + description: 'The URL where the file should be uploaded.', + helpValue: '', + required: true + }), + }; - const client = await this.getStorageApiClient(); + public async run() { + const { flags } = await this.parse(FileUpload); - const fileBuffer = fs.readFileSync(flags["file-path"]); - const fileArrayBuffer = this.toArrayBuffer(fileBuffer); + const client = await this.getStorageApiClient(); - const response = await client.uploadFile(flags["upload-url"], fileArrayBuffer); - if (response.status < 200 || response.status >= 300) { - this.error(`Encountered a problem when placing information to blob storage: ${response.statusText}`); - } + const fileBuffer = fs.readFileSync(flags["file-path"]); + const fileArrayBuffer = this.toArrayBuffer(fileBuffer); - const returnObject = { result: 'uploaded' }; - return this.logAndReturnResult(returnObject); + const response = await client.uploadFile(flags["upload-url"], fileArrayBuffer); + if (response.status < 200 || response.status >= 300) { + this.error(`Encountered a problem when placing information to blob storage: ${response.statusText}`); } - toArrayBuffer(buffer: Buffer) { - const arrayBuffer = new ArrayBuffer(buffer.length); - const view = new Uint8Array(arrayBuffer); - for (const [i, element] of buffer.entries()) { - view[i] = element; - } - - return arrayBuffer; + const returnObject = { result: 'uploaded' }; + return this.logAndReturnResult(returnObject); + } + + private toArrayBuffer(buffer: Buffer) { + const arrayBuffer = new ArrayBuffer(buffer.length); + const view = new Uint8Array(arrayBuffer); + for (const [i, element] of buffer.entries()) { + view[i] = element; } + + return arrayBuffer; } +} \ No newline at end of file diff --git a/src/commands/storage/folder/create.ts b/src/commands/storage/folder/create.ts index d95ae9df..2c748a9d 100644 --- a/src/commands/storage/folder/create.ts +++ b/src/commands/storage/folder/create.ts @@ -9,52 +9,52 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class CreateFolder extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/storage/operations/create-folder/", - name: "Create Folder", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/storage/operations/create-folder/", + name: "Create Folder", + }; - static description = "Create a new folder in a specified parent folder in iTwin's storage."; + public static description = "Create a new folder in a specified parent folder in iTwin's storage."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --parent-folder-id ROOT_FOLDER_ID_HERE --name "Project Documents" --description "Folder for all project-related documents"`, - description: `Example 1: Create a folder inside the root folder with a description\n#Note: You can retrieve the root folder ID using the 'itp storage root-folder' command.` - }, - { - command: `<%= config.bin %> <%= command.id %> --parent-folder-id b2c3d4e5-6789-01ab-cdef-2345678901bc --name "Design Files"`, - description: 'Example 2: Create a subfolder inside an existing folder' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --parent-folder-id ROOT_FOLDER_ID_HERE --name "Project Documents" --description "Folder for all project-related documents"`, + description: `Example 1: Create a folder inside the root folder with a description\n#Note: You can retrieve the root folder ID using the 'itp storage root-folder' command.` + }, + { + command: `<%= config.bin %> <%= command.id %> --parent-folder-id b2c3d4e5-6789-01ab-cdef-2345678901bc --name "Design Files"`, + description: 'Example 2: Create a subfolder inside an existing folder' + } + ]; - static flags = { - description: Flags.string({ - char: 'd', - description: "A description of the folder.", - helpValue: '' - }), - name: Flags.string({ - char: 'n', - description: "The display name of the folder to be created.", - helpValue: '', - required: true - }), - "parent-folder-id": Flags.string({ - description: "The ID of the parent folder where the new folder will be created.", - helpValue: '', - required: true - }), - }; + public static flags = { + description: Flags.string({ + char: 'd', + description: "A description of the folder.", + helpValue: '' + }), + name: Flags.string({ + char: 'n', + description: "The display name of the folder to be created.", + helpValue: '', + required: true + }), + "parent-folder-id": Flags.string({ + description: "The ID of the parent folder where the new folder will be created.", + helpValue: '', + required: true + }), + }; - async run() { - const { flags } = await this.parse(CreateFolder); + public async run() { + const { flags } = await this.parse(CreateFolder); - const client = await this.getStorageApiClient(); - const response = await client.createFolder(flags["parent-folder-id"], { - description: flags.description, - displayName: flags.name, - }); + const client = await this.getStorageApiClient(); + const response = await client.createFolder(flags["parent-folder-id"], { + description: flags.description, + displayName: flags.name, + }); - return this.logAndReturnResult(response.folder); - } + return this.logAndReturnResult(response.folder); } +} diff --git a/src/commands/storage/folder/delete.ts b/src/commands/storage/folder/delete.ts index 49a50400..79d59c9d 100644 --- a/src/commands/storage/folder/delete.ts +++ b/src/commands/storage/folder/delete.ts @@ -9,35 +9,35 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class DeleteFolder extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/storage/operations/delete-folder/", - name: "Delete Folder", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/storage/operations/delete-folder/", + name: "Delete Folder", + }; - static description = "Delete a folder from an iTwin's storage."; + public static description = "Delete a folder from an iTwin's storage."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --folder-id a1b2c3d4-5678-90ab-cdef-1234567890ab`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --folder-id a1b2c3d4-5678-90ab-cdef-1234567890ab`, + description: 'Example 1:' + } + ]; - static flags = { - "folder-id": Flags.string({ - char: 'f', - description: "The ID of the folder to be deleted.", - helpValue: '', - required: true - }), - }; + public static flags = { + "folder-id": Flags.string({ + char: 'f', + description: "The ID of the folder to be deleted.", + helpValue: '', + required: true + }), + }; - async run() { - const { flags } = await this.parse(DeleteFolder); + public async run() { + const { flags } = await this.parse(DeleteFolder); - const client = await this.getStorageApiClient(); - await client.deleteFolder(flags["folder-id"]); + const client = await this.getStorageApiClient(); + await client.deleteFolder(flags["folder-id"]); - return this.logAndReturnResult({ result: 'deleted' }); - } + return this.logAndReturnResult({ result: 'deleted' }); } +} diff --git a/src/commands/storage/folder/info.ts b/src/commands/storage/folder/info.ts index 6699bde1..eff6055f 100644 --- a/src/commands/storage/folder/info.ts +++ b/src/commands/storage/folder/info.ts @@ -9,35 +9,35 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class FolderInfo extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/storage/operations/get-folder/", - name: "Get Folder Info", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/storage/operations/get-folder/", + name: "Get Folder Info", + }; - static description = "Retrieve metadata for a specific folder in an iTwin's storage."; + public static description = "Retrieve metadata for a specific folder in an iTwin's storage."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --folder-id a1b2c3d4-5678-90ab-cdef-1234567890ab`, - description: 'Example 1:' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --folder-id a1b2c3d4-5678-90ab-cdef-1234567890ab`, + description: 'Example 1:' + } + ]; - static flags = { - "folder-id": Flags.string({ - char: 'f', - description: "The ID of the folder to retrieve information about.", - helpValue: '', - required: true - }), - }; + public static flags = { + "folder-id": Flags.string({ + char: 'f', + description: "The ID of the folder to retrieve information about.", + helpValue: '', + required: true + }), + }; - async run() { - const { flags } = await this.parse(FolderInfo); + public async run() { + const { flags } = await this.parse(FolderInfo); - const client = await this.getStorageApiClient(); - const response = await client.getFolder(flags["folder-id"]); + const client = await this.getStorageApiClient(); + const response = await client.getFolder(flags["folder-id"]); - return this.logAndReturnResult(response.folder); - } + return this.logAndReturnResult(response.folder); } +} diff --git a/src/commands/storage/folder/list.ts b/src/commands/storage/folder/list.ts index 2ff5a003..6d5458d1 100644 --- a/src/commands/storage/folder/list.ts +++ b/src/commands/storage/folder/list.ts @@ -9,54 +9,54 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class ListFolders extends BaseCommand { - static apiReference: ApiReference[] = [ - { - link: "https://developer.bentley.com/apis/storage/operations/get-folders-in-folder/", - name: "List Folders in Folder", - }, - { - link: "https://developer.bentley.com/apis/storage/operations/get-folders-and-files-in-folder/", - name: "List Folders and Files in Folder", - } - ]; + public static apiReference: ApiReference[] = [ + { + link: "https://developer.bentley.com/apis/storage/operations/get-folders-in-folder/", + name: "List Folders in Folder", + }, + { + link: "https://developer.bentley.com/apis/storage/operations/get-folders-and-files-in-folder/", + name: "List Folders and Files in Folder", + } + ]; - static description = "List folders in a parent folder of an iTwin's storage. Optionally, include files in the result."; + public static description = "List folders in a parent folder of an iTwin's storage. Optionally, include files in the result."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --folder-id a1b2c3d4-5678-90ab-cdef-1234567890ab`, - description: 'Example 1: List all folders in a parent folder' - }, - { - command: `<%= config.bin %> <%= command.id %> --folder-id a1b2c3d4-5678-90ab-cdef-1234567890ab --include-files`, - description: 'Example 2: List all folders and files in a parent folder' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --folder-id a1b2c3d4-5678-90ab-cdef-1234567890ab`, + description: 'Example 1: List all folders in a parent folder' + }, + { + command: `<%= config.bin %> <%= command.id %> --folder-id a1b2c3d4-5678-90ab-cdef-1234567890ab --include-files`, + description: 'Example 2: List all folders and files in a parent folder' + } + ]; - static flags = { - "folder-id": Flags.string({ - char: 'f', - description: "The ID of the parent folder whose contents you want to list.", - helpValue: '', - required: true - }), - "include-files": Flags.boolean({ - description: "Whether to include files in the result.", - }), - }; + public static flags = { + "folder-id": Flags.string({ + char: 'f', + description: "The ID of the parent folder whose contents you want to list.", + helpValue: '', + required: true + }), + "include-files": Flags.boolean({ + description: "Whether to include files in the result.", + }), + }; - async run() { - const { flags } = await this.parse(ListFolders); + public async run() { + const { flags } = await this.parse(ListFolders); - const client = await this.getStorageApiClient(); + const client = await this.getStorageApiClient(); - if (flags["include-files"]) { - const result = await client.getFilesAndFolders(flags["folder-id"]); - return this.logAndReturnResult(result.items); - } + if (flags["include-files"]) { + const result = await client.getFilesAndFolders(flags["folder-id"]); + return this.logAndReturnResult(result.items); + } - const response = await client.getFolders(flags["folder-id"]); - return this.logAndReturnResult(response.folders); + const response = await client.getFolders(flags["folder-id"]); + return this.logAndReturnResult(response.folders); - } } +} diff --git a/src/commands/storage/folder/update.ts b/src/commands/storage/folder/update.ts index ca693ade..c68c2d47 100644 --- a/src/commands/storage/folder/update.ts +++ b/src/commands/storage/folder/update.ts @@ -9,52 +9,52 @@ import { ApiReference } from "../../../extensions/api-reference.js"; import BaseCommand from "../../../extensions/base-command.js"; export default class UpdateFolder extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/storage/operations/update-folder/", - name: "Update Folder", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/storage/operations/update-folder/", + name: "Update Folder", + }; - static description = "Update the metadata of a folder in an iTwin's storage, such as its display name or description."; + public static description = "Update the metadata of a folder in an iTwin's storage, such as its display name or description."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --folder-id a1b2c3d4-5678-90ab-cdef-1234567890ab --name "Updated Project Documents"`, - description: 'Example 1: Update folder display name' - }, - { - command: `<%= config.bin %> <%= command.id %> --folder-id b2c3d4e5-6789-01ab-cdef-2345678901bc --name "Updated Design Files" --description "Folder containing updated design documents"`, - description: 'Example 2: Update folder display name and description' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --folder-id a1b2c3d4-5678-90ab-cdef-1234567890ab --name "Updated Project Documents"`, + description: 'Example 1: Update folder display name' + }, + { + command: `<%= config.bin %> <%= command.id %> --folder-id b2c3d4e5-6789-01ab-cdef-2345678901bc --name "Updated Design Files" --description "Folder containing updated design documents"`, + description: 'Example 2: Update folder display name and description' + } + ]; - static flags = { - description: Flags.string({ - char: 'd', - description: "A description for the folder.", - helpValue: '', - }), - "folder-id": Flags.string({ - char: 'f', - description: "The ID of the folder to be updated.", - helpValue: '', - required: true - }), - name: Flags.string({ - char: 'n', - description: "The new display name for the folder.", - helpValue: '', - }), - }; + public static flags = { + description: Flags.string({ + char: 'd', + description: "A description for the folder.", + helpValue: '', + }), + "folder-id": Flags.string({ + char: 'f', + description: "The ID of the folder to be updated.", + helpValue: '', + required: true + }), + name: Flags.string({ + char: 'n', + description: "The new display name for the folder.", + helpValue: '', + }), + }; - async run() { - const { flags } = await this.parse(UpdateFolder); + public async run() { + const { flags } = await this.parse(UpdateFolder); - const client = await this.getStorageApiClient(); - const response = await client.updateFolder(flags["folder-id"], { - description: flags.description, - displayName: flags.name, - }); + const client = await this.getStorageApiClient(); + const response = await client.updateFolder(flags["folder-id"], { + description: flags.description, + displayName: flags.name, + }); - return this.logAndReturnResult(response.folder); - } + return this.logAndReturnResult(response.folder); + } } diff --git a/src/commands/storage/root-folder.ts b/src/commands/storage/root-folder.ts index 0bbac5e7..934d6c14 100644 --- a/src/commands/storage/root-folder.ts +++ b/src/commands/storage/root-folder.ts @@ -6,25 +6,26 @@ import { Flags } from '@oclif/core'; import BaseCommand from '../../extensions/base-command.js'; -import { CustomFlags } from '../../extensions/custom-flags.js'; +import { customFlags } from '../../extensions/custom-flags.js'; +import { ApiReference } from '../../extensions/api-reference.js'; export default class GetRootFolder extends BaseCommand { - static apiReference = { + public static apiReference: ApiReference = { link: 'https://developer.bentley.com/apis/storage/operations/get-top-level-folders-and-files-by-project/', name: 'Get Top-Level Folders and Files', }; - static description = 'Retrieve the top-level folders and files in an iTwin\'s storage.'; + public static description = 'Retrieve the top-level folders and files in an iTwin\'s storage.'; - static examples = [ + public static examples = [ { command: `<%= config.bin %> <%= command.id %> --itwin-id ad0ba809-9241-48ad-9eb0-c8038c1a1d51`, description: 'Example 1:' } ]; - static flags = { - "itwin-id": CustomFlags.iTwinIDFlag({ + public static flags = { + "itwin-id": customFlags.iTwinIDFlag({ description: 'The ID of the iTwin whose top-level folders and files you want to retrieve.' }), skip: Flags.integer({ @@ -39,7 +40,7 @@ export default class GetRootFolder extends BaseCommand { }), }; - async run() { + public async run() { const { flags } = await this.parse(GetRootFolder); const client = await this.getStorageApiClient(); diff --git a/src/commands/user/info.ts b/src/commands/user/info.ts index 312a960f..98ffa0c8 100644 --- a/src/commands/user/info.ts +++ b/src/commands/user/info.ts @@ -9,39 +9,39 @@ import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; export default class UserInfo extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/users/operations/get-users-by-id-list/", - name: "Get Users by ID List", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/users/operations/get-users-by-id-list/", + name: "Get Users by ID List", + }; - static description = "Retrieve information about specific users based on their user IDs."; + public static description = "Retrieve information about specific users based on their user IDs."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --user-id user1-id --user-id user2-id --user-id user3-id`, - description: 'Example 1: Retrieve information about specific users by their user IDs' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --user-id user1-id --user-id user2-id --user-id user3-id`, + description: 'Example 1: Retrieve information about specific users by their user IDs' + } + ]; - static flags = { - "user-id": Flags.string({ - description: "User IDs to retrieve information for. Max amount of 1000.", - helpValue: '', - multiple: true, - required: true - }), - }; + public static flags = { + "user-id": Flags.string({ + description: "User IDs to retrieve information for. Max amount of 1000.", + helpValue: '', + multiple: true, + required: true + }), + }; - async run() { - const { flags } = await this.parse(UserInfo); + public async run() { + const { flags } = await this.parse(UserInfo); - if(flags["user-id"] !== undefined && flags["user-id"]!.length > 1000) { - this.error("A maximum of 1000 user IDs can be provided."); - } + if(flags["user-id"] !== undefined && flags["user-id"].length > 1000) { + this.error("A maximum of 1000 user IDs can be provided."); + } - const client = await this.getUserApiClient(); - const response = await client.getUsers(flags["user-id"]); + const client = await this.getUserApiClient(); + const response = await client.getUsers(flags["user-id"]); - return this.logAndReturnResult(response.users); - } + return this.logAndReturnResult(response.users); } +} diff --git a/src/commands/user/me.ts b/src/commands/user/me.ts index a3e4520f..1ca4246f 100644 --- a/src/commands/user/me.ts +++ b/src/commands/user/me.ts @@ -7,26 +7,26 @@ import { ApiReference } from "../../extensions/api-reference.js"; // Added impor import BaseCommand from "../../extensions/base-command.js"; export default class Me extends BaseCommand { - static apiReference: ApiReference = { + public static apiReference: ApiReference = { link: "https://developer.bentley.com/apis/users/operations/me/", name: "User Me", }; - static args = {} + public static args = {}; - static description = 'Retrieve information about the currently authenticated user.' + public static description = 'Retrieve information about the currently authenticated user.'; - static examples = [ + public static examples = [ { command: `<%= config.bin %> <%= command.id %>`, description: 'Example 1:' } ]; - static flags = {} + public static flags = {}; - async run() { - const userApiClient = await this.getUserApiClient() + public async run() { + const userApiClient = await this.getUserApiClient(); const userInfo = await userApiClient.getMe(); return this.logAndReturnResult(userInfo.user); diff --git a/src/commands/user/search.ts b/src/commands/user/search.ts index f78b0421..ea582bf7 100644 --- a/src/commands/user/search.ts +++ b/src/commands/user/search.ts @@ -9,38 +9,38 @@ import { ApiReference } from "../../extensions/api-reference.js"; import BaseCommand from "../../extensions/base-command.js"; export default class UserSearch extends BaseCommand { - static apiReference: ApiReference = { - link: "https://developer.bentley.com/apis/users/operations/get-users/", - name: "Search Users", - }; + public static apiReference: ApiReference = { + link: "https://developer.bentley.com/apis/users/operations/get-users/", + name: "Search Users", + }; - static description = "Search for users based on filter criteria.\nNOTE: Only users in the same organization are returned by this command. Because of this, no results will be returned when this command is called by a service client. This is because service clients are not a part of service client owner's organization."; + public static description = "Search for users based on filter criteria.\nNOTE: Only users in the same organization are returned by this command. Because of this, no results will be returned when this command is called by a service client. This is because service clients are not a part of service client owner's organization."; - static examples = [ - { - command: `<%= config.bin %> <%= command.id %> --search "John Doe"`, - description: 'Example 1: Search for users by a name string' - }, - { - command: `<%= config.bin %> <%= command.id %> --search john.doe@example.com`, - description: 'Example 2: Search for users by email' - } - ]; + public static examples = [ + { + command: `<%= config.bin %> <%= command.id %> --search "John Doe"`, + description: 'Example 1: Search for users by a name string' + }, + { + command: `<%= config.bin %> <%= command.id %> --search john.doe@example.com`, + description: 'Example 2: Search for users by email' + } + ]; - static flags = { - search: Flags.string({ - description: "A string to search for users by name, email, or other attributes.", - helpValue: '', - required: true - }), - }; + public static flags = { + search: Flags.string({ + description: "A string to search for users by name, email, or other attributes.", + helpValue: '', + required: true + }), + }; - async run() { - const { flags } = await this.parse(UserSearch); + public async run() { + const { flags } = await this.parse(UserSearch); - const client = await this.getUserApiClient(); - const response = await client.searchUsers(flags.search); + const client = await this.getUserApiClient(); + const response = await client.searchUsers(flags.search); - return this.logAndReturnResult(response.users); - } + return this.logAndReturnResult(response.users); } +} diff --git a/src/extensions/api-reference.ts b/src/extensions/api-reference.ts index d4290dd9..81d422a0 100644 --- a/src/extensions/api-reference.ts +++ b/src/extensions/api-reference.ts @@ -3,8 +3,8 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -export type ApiReference = { - link: string; - name: string; - sectionName?: string; -}; \ No newline at end of file +export interface ApiReference { + link: string; + name: string; + sectionName?: string; +} \ No newline at end of file diff --git a/src/extensions/base-command.ts b/src/extensions/base-command.ts index 76621bcb..da5668ca 100644 --- a/src/extensions/base-command.ts +++ b/src/extensions/base-command.ts @@ -25,7 +25,7 @@ import { UserApiClient } from '../services/user-client/user-api-client.js'; import { Configuration } from './configuration.js'; export default abstract class BaseCommand extends Command { - static baseFlags = { + public static baseFlags = { json: Flags.boolean({ char: 'j', description: 'Pretty format the JSON command response and suppress all logging.', @@ -44,12 +44,12 @@ export default abstract class BaseCommand extends Command { helpGroup: 'GLOBAL', required: false }), - } + }; - static enableJsonFlag = true; + public static enableJsonFlag = true; protected async clearContext() { - const contextPath = this.config.cacheDir + '/context.json'; + const contextPath = `${this.config.cacheDir }/context.json`; if (fs.existsSync(contextPath)) { fs.rmSync(contextPath, { force: true }); } @@ -84,7 +84,7 @@ export default abstract class BaseCommand extends Command { protected async getAuthorizationCallback(accessToken?: string) : Promise { const parts = (accessToken ?? await this.getAccessToken()).split(" "); - return () => Promise.resolve({ + return async () => Promise.resolve({ scheme: parts[0], token: parts[1] }); @@ -139,7 +139,7 @@ export default abstract class BaseCommand extends Command { } protected getContext() : UserContext | undefined { - const contextPath = this.config.cacheDir + '/context.json'; + const contextPath = `${this.config.cacheDir }/context.json`; if (!fs.existsSync(contextPath)) { return; } @@ -220,21 +220,21 @@ export default abstract class BaseCommand extends Command { protected logTable(data: T) { if(Array.isArray(data)) - { - const table = new Table(); - table.addRows(data) + { + const table = new Table(); + table.addRows(data); - for (const column of table.table.columns) column.alignment = "left"; - this.log(table.render()); - } - else - { - const table = new Table(); - table.addRows([data]) + for (const column of table.table.columns) column.alignment = "left"; + this.log(table.render()); + } + else + { + const table = new Table(); + table.addRows([data]); - for (const column of table.table.columns) column.alignment = "left"; - this.log(table.render()); - } + for (const column of table.table.columns) column.alignment = "left"; + this.log(table.render()); + } } protected override async parse( @@ -271,7 +271,7 @@ export default abstract class BaseCommand extends Command { } protected async setContext(iTwinId: string, iModelId?: string) { - const contextPath = this.config.cacheDir + '/context.json'; + const contextPath = `${this.config.cacheDir }/context.json`; const context: UserContext = { iModelId, diff --git a/src/extensions/configuration.ts b/src/extensions/configuration.ts index f04928ad..a733ddd1 100644 --- a/src/extensions/configuration.ts +++ b/src/extensions/configuration.ts @@ -3,9 +3,9 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -export type Configuration = { - apiUrl: string - clientId: string - clientSecret: string | undefined - issuerUrl: string +export interface Configuration { + apiUrl: string + clientId: string + clientSecret: string | undefined + issuerUrl: string } \ No newline at end of file diff --git a/src/extensions/custom-flags.ts b/src/extensions/custom-flags.ts index 07a02c37..ddf57533 100644 --- a/src/extensions/custom-flags.ts +++ b/src/extensions/custom-flags.ts @@ -7,30 +7,30 @@ import { Flags } from "@oclif/core"; import extent from "./custom-flags/extent.js"; import groupMembers from "./custom-flags/group-member-array.js"; -import noSchemaJson from "./custom-flags/no-schema-json.js" +import noSchemaJson from "./custom-flags/no-schema-json.js"; import userMembers from "./custom-flags/user-member-array.js"; -export const CustomFlags = { - extent, - groupMembers, - iModelIDFlag: (config : CustomFlagConfig) => Flags.string({ - char: 'm', - description: config.description, - env: 'ITP_IMODEL_ID', - helpValue: '', - required: true, - }), - iTwinIDFlag: (config : CustomFlagConfig) => Flags.string({ - char: 'i', - description: config.description, - env: 'ITP_ITWIN_ID', - helpValue: '', - required: true, - }), - noSchemaJson, - userMembers -} +export const customFlags = { + extent, + groupMembers, + iModelIDFlag: (config : CustomFlagConfig) => Flags.string({ + char: 'm', + description: config.description, + env: 'ITP_IMODEL_ID', + helpValue: '', + required: true, + }), + iTwinIDFlag: (config : CustomFlagConfig) => Flags.string({ + char: 'i', + description: config.description, + env: 'ITP_ITWIN_ID', + helpValue: '', + required: true, + }), + noSchemaJson, + userMembers +}; -export type CustomFlagConfig = { - description: string; -}; \ No newline at end of file +export interface CustomFlagConfig { + description: string; +} \ No newline at end of file diff --git a/src/extensions/custom-flags/extent.ts b/src/extensions/custom-flags/extent.ts index 8022a6b8..eb292f74 100644 --- a/src/extensions/custom-flags/extent.ts +++ b/src/extensions/custom-flags/extent.ts @@ -11,26 +11,27 @@ import { validateJson } from "../validation/validate-json.js"; import zodErrorToMessage from "../validation/zod-error-to-message.js"; export default Flags.custom({ - parse: (input) => Promise.resolve( - validateJson(input, validationFunction), - ) + // eslint-disable-next-line @typescript-eslint/promise-function-async + parse: (input) => Promise.resolve( + validateJson(input, validationFunction), + ) }); const validationFunction = (input: Extent): string => { - const result = ExtentSchema.safeParse(input); - if(result.error === undefined) - return ''; + const result = extentSchema.safeParse(input); + if(result.error === undefined) + return ''; - return zodErrorToMessage(result.error); -} + return zodErrorToMessage(result.error); +}; -const ExtentSchema = zod.object({ - northEast: zod.object({ - latitude: zod.number(), - longitude: zod.number(), - }), - southWest: zod.object({ - latitude: zod.number(), - longitude: zod.number(), - }), -}) satisfies zod.ZodType \ No newline at end of file +const extentSchema = zod.object({ + northEast: zod.object({ + latitude: zod.number(), + longitude: zod.number(), + }), + southWest: zod.object({ + latitude: zod.number(), + longitude: zod.number(), + }), +}) satisfies zod.ZodType; \ No newline at end of file diff --git a/src/extensions/custom-flags/group-member-array.ts b/src/extensions/custom-flags/group-member-array.ts index 51e8711e..b0eae3ca 100644 --- a/src/extensions/custom-flags/group-member-array.ts +++ b/src/extensions/custom-flags/group-member-array.ts @@ -11,20 +11,21 @@ import { validateJson } from "../validation/validate-json.js"; import zodErrorToMessage from "../validation/zod-error-to-message.js"; export default Flags.custom({ - parse: (input) => Promise.resolve( - validateJson(input, validationFunction) - ), + // eslint-disable-next-line @typescript-eslint/promise-function-async + parse: (input) => Promise.resolve( + validateJson(input, validationFunction) + ), }); const validationFunction = (input: GroupMember[]): string => { - const result = zod.array(GroupMemberSchema).safeParse(input); - if(result.error === undefined) - return ''; + const result = zod.array(groupMemberSchema).safeParse(input); + if(result.error === undefined) + return ''; - return zodErrorToMessage(result.error); -} + return zodErrorToMessage(result.error); +}; -const GroupMemberSchema = zod.object({ - groupId: zod.string().uuid(), - roleIds: zod.array(zod.string().uuid()), -}) satisfies zod.ZodType \ No newline at end of file +const groupMemberSchema = zod.object({ + groupId: zod.string().uuid(), + roleIds: zod.array(zod.string().uuid()), +}) satisfies zod.ZodType; \ No newline at end of file diff --git a/src/extensions/custom-flags/no-schema-json.ts b/src/extensions/custom-flags/no-schema-json.ts index ba5d0c10..dc9d697a 100644 --- a/src/extensions/custom-flags/no-schema-json.ts +++ b/src/extensions/custom-flags/no-schema-json.ts @@ -8,7 +8,8 @@ import { Flags } from "@oclif/core"; import { validateJson } from "../validation/validate-json.js"; export default Flags.custom({ - parse: (input) => Promise.resolve( - validateJson(input) - ), + // eslint-disable-next-line @typescript-eslint/promise-function-async + parse: (input) => Promise.resolve( + validateJson(input) + ), }); \ No newline at end of file diff --git a/src/extensions/custom-flags/user-member-array.ts b/src/extensions/custom-flags/user-member-array.ts index efd84c2d..44d658f9 100644 --- a/src/extensions/custom-flags/user-member-array.ts +++ b/src/extensions/custom-flags/user-member-array.ts @@ -11,20 +11,21 @@ import { validateJson } from "../validation/validate-json.js"; import zodErrorToMessage from "../validation/zod-error-to-message.js"; export default Flags.custom({ - parse: (input) => Promise.resolve( - validateJson(input, validationFunction) - ), + // eslint-disable-next-line @typescript-eslint/promise-function-async + parse: (input) => Promise.resolve( + validateJson(input, validationFunction) + ), }); const validationFunction = (input: UserMember[]): string => { - const result = zod.array(UserMemberSchema).safeParse(input); - if(result.error === undefined) - return ''; + const result = zod.array(userMemberSchema).safeParse(input); + if(result.error === undefined) + return ''; - return zodErrorToMessage(result.error); -} + return zodErrorToMessage(result.error); +}; -const UserMemberSchema = zod.object({ - email: zod.string().email(), - roleIds: zod.array(zod.string().uuid()) -}) satisfies zod.ZodType \ No newline at end of file +const userMemberSchema = zod.object({ + email: zod.string().email(), + roleIds: zod.array(zod.string().uuid()) +}) satisfies zod.ZodType; \ No newline at end of file diff --git a/src/extensions/validation/validate-float.ts b/src/extensions/validation/validate-float.ts index ba83711e..ccbc8d18 100644 --- a/src/extensions/validation/validate-float.ts +++ b/src/extensions/validation/validate-float.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ export const validateFloat = async (floatString: string): Promise => { - if(!/^-?\d*(\.\d+)?$/.test(floatString)){ - throw new TypeError(`${floatString} is not a valid number.`) - } + if(!/^-?\d*(\.\d+)?$/.test(floatString)){ + throw new TypeError(`${floatString} is not a valid number.`); + } - return floatString; + return floatString; }; \ No newline at end of file diff --git a/src/extensions/validation/validate-json.ts b/src/extensions/validation/validate-json.ts index f42f7597..92a0dbb3 100644 --- a/src/extensions/validation/validate-json.ts +++ b/src/extensions/validation/validate-json.ts @@ -4,21 +4,21 @@ *--------------------------------------------------------------------------------------------*/ export const validateJson = (jsonString: string, validationFunc?: (input: T) => string): T => { - let parsed: T; - try { - parsed = JSON.parse(jsonString) as T; - } - catch { - throw new Error(`'${jsonString}' is not valid serialized JSON.`); - } + let parsed: T; + try { + parsed = JSON.parse(jsonString) as T; + } + catch { + throw new Error(`'${jsonString}' is not valid serialized JSON.`); + } - if(validationFunc === undefined) - return parsed; + if(validationFunc === undefined) + return parsed; - const validationError = validationFunc(parsed) - if (validationError) { - throw new Error(validationError); - } + const validationError = validationFunc(parsed); + if (validationError) { + throw new Error(validationError); + } - return parsed; -} \ No newline at end of file + return parsed; +}; \ No newline at end of file diff --git a/src/extensions/validation/validate-uuid-csv.ts b/src/extensions/validation/validate-uuid-csv.ts index 6c69a73d..92825e88 100644 --- a/src/extensions/validation/validate-uuid-csv.ts +++ b/src/extensions/validation/validate-uuid-csv.ts @@ -4,11 +4,11 @@ *--------------------------------------------------------------------------------------------*/ export const validateUuidCSV = async (csvUuidString: string): Promise => { - const UUIDs = csvUuidString.split(','); - const areAllUUIDs = UUIDs.every((uuid) => uuid.match(/^[\da-f]{8}-[\da-f]{4}-[1-5][\da-f]{3}-[89ab][\da-f]{3}-[\da-f]{12}$/i)) - if(!areAllUUIDs) { - throw new Error(`There are invalid UUIDs in '${csvUuidString}'.`) - } + const uuidList = csvUuidString.split(','); + const areAllUUIDs = uuidList.every((uuid) => uuid.match(/^[\da-f]{8}-[\da-f]{4}-[1-5][\da-f]{3}-[89ab][\da-f]{3}-[\da-f]{12}$/i)); + if(!areAllUUIDs) { + throw new Error(`There are invalid UUIDs in '${csvUuidString}'.`); + } - return csvUuidString; -} \ No newline at end of file + return csvUuidString; +}; \ No newline at end of file diff --git a/src/extensions/validation/zod-error-to-message.ts b/src/extensions/validation/zod-error-to-message.ts index 941fca5d..4cd29670 100644 --- a/src/extensions/validation/zod-error-to-message.ts +++ b/src/extensions/validation/zod-error-to-message.ts @@ -3,47 +3,47 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import { ZodError, ZodIssue } from "zod" +import { ZodError, ZodIssue } from "zod"; const zodErrorToMessage = (error: ZodError): string => { - let message = "Following issues were found during schema validation:\n"; - for(const issue of error.issues) { - message += zodIssueToErrorMessage(issue); - } + let message = "Following issues were found during schema validation:\n"; + for(const issue of error.issues) { + message += zodIssueToErrorMessage(issue); + } - return message; -} + return message; +}; const zodIssueToErrorMessage = (issue: ZodIssue): string => { - const path = joinPath(issue.path); - switch(issue.code) { - case "invalid_type": { - return issue.received === 'undefined' - ? `\t- missing required property '${path}' of type '${issue.expected}'\n` - : `\t- ${path}: expected type '${issue.expected}', received '${issue.received}'\n`; - } - - case "invalid_string": { - return `\t- ${path} is not a valid ${issue.validation}\n` - } - - default: { - return `\t- ${path}: value is not valid\n` - } + const path = joinPath(issue.path); + switch(issue.code) { + case "invalid_type": { + return issue.received === 'undefined' + ? `\t- missing required property '${path}' of type '${issue.expected}'\n` + : `\t- ${path}: expected type '${issue.expected}', received '${issue.received}'\n`; + } + + case "invalid_string": { + return `\t- ${path} is not a valid ${issue.validation as string}\n`; } -} + + default: { + return `\t- ${path}: value is not valid\n`; + } + } +}; const joinPath = (path: (number|string)[]): string => { - let builtPath = ""; - for (const token of path) { - if(typeof token === 'number') { - builtPath = builtPath.slice(0,-1); - } - - builtPath += typeof token === 'number' || /^\d+$/.test(token) ? `[${token}].` : `${token}.`; + let builtPath = ""; + for (const token of path) { + if(typeof token === 'number') { + builtPath = builtPath.slice(0,-1); } + + builtPath += typeof token === 'number' || /^\d+$/.test(token) ? `[${token}].` : `${token}.`; + } - return builtPath.slice(0, -1); -} + return builtPath.slice(0, -1); +}; export default zodErrorToMessage; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 7b1ecb0e..17277a8e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,4 +3,4 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -export {run} from '@oclif/core' +export {run} from '@oclif/core'; diff --git a/src/services/access-control-client/access-control-client.ts b/src/services/access-control-client/access-control-client.ts index d7bf39d5..83c5840d 100644 --- a/src/services/access-control-client/access-control-client.ts +++ b/src/services/access-control-client/access-control-client.ts @@ -4,103 +4,103 @@ *--------------------------------------------------------------------------------------------*/ import { ITwinPlatformApiClient } from "../iTwin-api-client.js"; -import { Group, GroupResponse, GroupUpdate, GroupsResponse } from "./models/group.js"; +import { Group, GroupResponse, GroupsResponse, GroupUpdate } from "./models/group.js"; import { Permissions } from "./models/permissions.js"; import { Role, RoleResponse, RolesResponse } from "./models/role.js"; export class AccessControlClient { - apiVersionHeader = 'application/vnd.bentley.itwin-platform.v2+json'; - iTwinPlatformApiClient: ITwinPlatformApiClient; + private _apiVersionHeader = 'application/vnd.bentley.itwin-platform.v2+json'; + private _iTwinPlatformApiClient: ITwinPlatformApiClient; - constructor(apiUrl: string, authToken: string) { - this.iTwinPlatformApiClient = new ITwinPlatformApiClient(apiUrl, authToken, this.apiVersionHeader); - } + constructor(apiUrl: string, authToken: string) { + this._iTwinPlatformApiClient = new ITwinPlatformApiClient(apiUrl, authToken, this._apiVersionHeader); + } - createGroup(iTwinId: string, group: Group): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/groups`, - body: group, - method: 'POST' - }); - } + public async createGroup(iTwinId: string, group: Group): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/groups`, + body: group, + method: 'POST' + }); + } - createiTwinRole(iTwinId: string, role: Role): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/roles`, - body: role, - method: 'POST' - }); - } + public async createiTwinRole(iTwinId: string, role: Role): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/roles`, + body: role, + method: 'POST' + }); + } - async deleteGroup(iTwinId: string, groupId: string): Promise { - await this.iTwinPlatformApiClient.sendRequestNoResponse({ - apiPath: `accesscontrol/itwins/${iTwinId}/groups/${groupId}`, - method: 'DELETE' - }); - } + public async deleteGroup(iTwinId: string, groupId: string): Promise { + await this._iTwinPlatformApiClient.sendRequestNoResponse({ + apiPath: `accesscontrol/itwins/${iTwinId}/groups/${groupId}`, + method: 'DELETE' + }); + } - async deleteiTwinRole(iTwinId: string, roleId: string): Promise { - await this.iTwinPlatformApiClient.sendRequestNoResponse({ - apiPath: `accesscontrol/itwins/${iTwinId}/roles/${roleId}`, - method: 'DELETE' - }); - } + public async deleteiTwinRole(iTwinId: string, roleId: string): Promise { + await this._iTwinPlatformApiClient.sendRequestNoResponse({ + apiPath: `accesscontrol/itwins/${iTwinId}/roles/${roleId}`, + method: 'DELETE' + }); + } - getAllAvailableiTwinPermissions(): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/permissions`, - method: 'GET' - }); - } + public async getAllAvailableiTwinPermissions(): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/permissions`, + method: 'GET' + }); + } - getAlliTwinPermissions(iTwinId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/permissions`, - method: 'GET' - }); - } + public async getAlliTwinPermissions(iTwinId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/permissions`, + method: 'GET' + }); + } - getGroup(iTwinId: string, groupId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/groups/${groupId}`, - method: 'GET' - }); - } + public async getGroup(iTwinId: string, groupId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/groups/${groupId}`, + method: 'GET' + }); + } - getGroups(iTwinId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/groups`, - method: 'GET' - }); - } + public async getGroups(iTwinId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/groups`, + method: 'GET' + }); + } - getiTwinRole(iTwinId: string, roleId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/roles/${roleId}`, - method: 'GET' - }); - } + public async getiTwinRole(iTwinId: string, roleId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/roles/${roleId}`, + method: 'GET' + }); + } - getiTwinRoles(iTwinId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/roles`, - method: 'GET' - }); - } + public async getiTwinRoles(iTwinId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/roles`, + method: 'GET' + }); + } - updateGroup(iTwinId: string, groupId: string, group: GroupUpdate): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/groups/${groupId}`, - body: group, - method: 'PATCH' - }); - } + public async updateGroup(iTwinId: string, groupId: string, group: GroupUpdate): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/groups/${groupId}`, + body: group, + method: 'PATCH' + }); + } - updateiTwinRole(iTwinId: string, roleId: string, role: Role): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/roles/${roleId}`, - body: role, - method: 'PATCH' - }); - } + public async updateiTwinRole(iTwinId: string, roleId: string, role: Role): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/roles/${roleId}`, + body: role, + method: 'PATCH' + }); + } } diff --git a/src/services/access-control-client/access-control-member-client.ts b/src/services/access-control-client/access-control-member-client.ts index 41ff9f0c..40c7760d 100644 --- a/src/services/access-control-client/access-control-member-client.ts +++ b/src/services/access-control-client/access-control-member-client.ts @@ -10,131 +10,131 @@ import { ListOfMembers, MemberResponse, MembersListResponse, MembersResponse } f import { OwnerListResponse, OwnerResponse } from "./models/owner.js"; export class AccessControlMemberClient { - apiVersionHeader = 'application/vnd.bentley.itwin-platform.v2+json'; - iTwinPlatformApiClient: ITwinPlatformApiClient; - - constructor(apiUrl: string, accessToken: string) { - this.iTwinPlatformApiClient = new ITwinPlatformApiClient(apiUrl, accessToken, this.apiVersionHeader); - } - - async addGroupMember(iTwinId: string, groups: GroupMembersRequest): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/members/groups`, - body: groups, - method: 'POST' - }); - } - - async addOwner(iTwinId: string, email: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/members/owners`, - body: { - email - }, - method: 'POST' - }); - } - - async addUserMembers(iTwinId: string, members: ListOfMembers): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/members/users`, - body: members, - method: 'POST' - }); - } - - async deleteGroupMember(iTwinId: string, groupId: string): Promise { - await this.iTwinPlatformApiClient.sendRequestNoResponse({ - apiPath: `accesscontrol/itwins/${iTwinId}/members/groups/${groupId}`, - method: 'DELETE' - }); - } - - async deleteOwner(iTwinId: string, memberId: string): Promise { - await this.iTwinPlatformApiClient.sendRequestNoResponse({ - apiPath: `accesscontrol/itwins/${iTwinId}/members/owners/${memberId}`, - method: 'DELETE' - }); - } - - async deleteUserMember(iTwinId: string, memberId: string): Promise { - await this.iTwinPlatformApiClient.sendRequestNoResponse({ - apiPath: `accesscontrol/itwins/${iTwinId}/members/users/${memberId}`, - method: 'DELETE' - }); - } - - async getGroupMember(iTwinId: string, groupId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/members/groups/${groupId}`, - method: 'GET' - }); - } - - async getGroupMembers(iTwinId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/members/groups`, - method: 'GET' - }); - } - - async getMemberInvitations(iTwinId: string, skip?: number, top?: number): Promise { - const query: Query[] = [ - { - key: "$skip", - value: skip - }, - { - key: "$top", - value: top - } - ]; - - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/members/invitations`, - method: 'GET', - query - }); - } - - async getOwnerList(iTwinId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/members/owners`, - method: 'GET' - }); - } - - async getUserMember(iTwinId: string, memberId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/members/users/${memberId}`, - method: 'GET' - }); - } - - async getUserMembers(iTwinId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/members/users`, - method: 'GET' - }); - } - - async updateGroupMember(iTwinId: string, groupId: string, roleIds: string[]): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/members/groups/${groupId}`, - body: { - roleIds - }, - method: 'PATCH' - }); - } - - async updateUserMember(iTwinId: string, memberId: string, roleIds: string[]): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `accesscontrol/itwins/${iTwinId}/members/users/${memberId}`, - body: { - roleIds - }, - method: 'PATCH' - }); - } + private _apiVersionHeader = 'application/vnd.bentley.itwin-platform.v2+json'; + private _iTwinPlatformApiClient: ITwinPlatformApiClient; + + constructor(apiUrl: string, accessToken: string) { + this._iTwinPlatformApiClient = new ITwinPlatformApiClient(apiUrl, accessToken, this._apiVersionHeader); + } + + public async addGroupMember(iTwinId: string, groups: GroupMembersRequest): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/members/groups`, + body: groups, + method: 'POST' + }); + } + + public async addOwner(iTwinId: string, email: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/members/owners`, + body: { + email + }, + method: 'POST' + }); + } + + public async addUserMembers(iTwinId: string, members: ListOfMembers): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/members/users`, + body: members, + method: 'POST' + }); + } + + public async deleteGroupMember(iTwinId: string, groupId: string): Promise { + await this._iTwinPlatformApiClient.sendRequestNoResponse({ + apiPath: `accesscontrol/itwins/${iTwinId}/members/groups/${groupId}`, + method: 'DELETE' + }); + } + + public async deleteOwner(iTwinId: string, memberId: string): Promise { + await this._iTwinPlatformApiClient.sendRequestNoResponse({ + apiPath: `accesscontrol/itwins/${iTwinId}/members/owners/${memberId}`, + method: 'DELETE' + }); + } + + public async deleteUserMember(iTwinId: string, memberId: string): Promise { + await this._iTwinPlatformApiClient.sendRequestNoResponse({ + apiPath: `accesscontrol/itwins/${iTwinId}/members/users/${memberId}`, + method: 'DELETE' + }); + } + + public async getGroupMember(iTwinId: string, groupId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/members/groups/${groupId}`, + method: 'GET' + }); + } + + public async getGroupMembers(iTwinId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/members/groups`, + method: 'GET' + }); + } + + public async getMemberInvitations(iTwinId: string, skip?: number, top?: number): Promise { + const query: Query[] = [ + { + key: "$skip", + value: skip + }, + { + key: "$top", + value: top + } + ]; + + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/members/invitations`, + method: 'GET', + query + }); + } + + public async getOwnerList(iTwinId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/members/owners`, + method: 'GET' + }); + } + + public async getUserMember(iTwinId: string, memberId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/members/users/${memberId}`, + method: 'GET' + }); + } + + public async getUserMembers(iTwinId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/members/users`, + method: 'GET' + }); + } + + public async updateGroupMember(iTwinId: string, groupId: string, roleIds: string[]): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/members/groups/${groupId}`, + body: { + roleIds + }, + method: 'PATCH' + }); + } + + public async updateUserMember(iTwinId: string, memberId: string, roleIds: string[]): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `accesscontrol/itwins/${iTwinId}/members/users/${memberId}`, + body: { + roleIds + }, + method: 'PATCH' + }); + } } diff --git a/src/services/access-control-client/models/group-members.ts b/src/services/access-control-client/models/group-members.ts index 2884248a..5145f8fc 100644 --- a/src/services/access-control-client/models/group-members.ts +++ b/src/services/access-control-client/models/group-members.ts @@ -3,10 +3,10 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -export type GroupMember = { - email: string; - givenName: string; - id: string; - organization: string; - surname: string; -}; +export interface GroupMember { + email: string; + givenName: string; + id: string; + organization: string; + surname: string; +} diff --git a/src/services/access-control-client/models/group.ts b/src/services/access-control-client/models/group.ts index 908df352..f51b0270 100644 --- a/src/services/access-control-client/models/group.ts +++ b/src/services/access-control-client/models/group.ts @@ -3,62 +3,63 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import { Links } from "../../general-models/links.js" -import { Role } from "./role.js" +import { Links } from "../../general-models/links.js"; +import { Role } from "./role.js"; -export type Group = { - description?: string, - id?: string, - imsGroups?: string[] - members?: GroupUser[], - name?: string, +export interface Group { + description?: string, + id?: string, + imsGroups?: string[] + members?: GroupUser[], + name?: string, } -export type GroupUser = { - email: string, - givenName: string, - organization: string - surname: string, - userId: string, +export interface GroupUser { + email: string, + givenName: string, + organization: string + surname: string, + userId: string, } -export type GroupUpdate = { - description?: string, - imsGroups?: string[] - members?: string[], - name?: string, +export interface GroupUpdate { + description?: string, + imsGroups?: string[] + members?: string[], + name?: string, } -export type GroupResponse = { - group: Group +export interface GroupResponse { + group: Group } -export type GroupsResponse = { - groups: Group[] +export interface GroupsResponse { + groups: Group[] } -export type GroupMember = { - groupId: string, - roleIds: string[] +export interface GroupMember { + groupId: string, + roleIds: string[] } -export type GroupMembersRequest = { - members: GroupMember[] +export interface GroupMembersRequest { + members: GroupMember[] } -export type GroupMembersResponse = { - _links: Links - members: GroupMemberInfo[] +export interface GroupMembersResponse { + // eslint-disable-next-line @typescript-eslint/naming-convention + _links: Links + members: GroupMemberInfo[] } -export type GroupMemberResponse = { - member: GroupMemberInfo +export interface GroupMemberResponse { + member: GroupMemberInfo } -export type GroupMemberInfo = { - groupDescription: string, - groupName: string, - id: string, - roles: Role[] +export interface GroupMemberInfo { + groupDescription: string, + groupName: string, + id: string, + roles: Role[] } diff --git a/src/services/access-control-client/models/invitations.ts b/src/services/access-control-client/models/invitations.ts index 5c9a5c00..6a7662b3 100644 --- a/src/services/access-control-client/models/invitations.ts +++ b/src/services/access-control-client/models/invitations.ts @@ -3,18 +3,18 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import { Role } from "./role.js" +import { Role } from "./role.js"; -export type Invitation = { - createdDate: Date, - email: string, - expirationDate: Date, - id: string, - invitedByEmail: string, - roles: Role[] - status: string, +export interface Invitation { + createdDate: Date, + email: string, + expirationDate: Date, + id: string, + invitedByEmail: string, + roles: Role[] + status: string, } -export type InvitationsResponse = { - invitations: Invitation[] +export interface InvitationsResponse { + invitations: Invitation[] } \ No newline at end of file diff --git a/src/services/access-control-client/models/members.ts b/src/services/access-control-client/models/members.ts index cae84f6c..e4a2ec7d 100644 --- a/src/services/access-control-client/models/members.ts +++ b/src/services/access-control-client/models/members.ts @@ -3,38 +3,39 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import { Links } from "../../general-models/links.js" -import { Invitation } from "./invitations.js" -import { Role } from "./role.js" +import { Links } from "../../general-models/links.js"; +import { Invitation } from "./invitations.js"; +import { Role } from "./role.js"; -export type ListOfMembers = { - members: UserMember[] +export interface ListOfMembers { + members: UserMember[] } -export type UserMember = { - email: string - roleIds: string[] +export interface UserMember { + email: string + roleIds: string[] } -export type Member = { - email: string - givenName: string - id: string - organization: string - roles: Role[] - surname: string +export interface Member { + email: string + givenName: string + id: string + organization: string + roles: Role[] + surname: string } -export type MembersResponse = { - invitations: Invitation[] - members: Member[], +export interface MembersResponse { + invitations: Invitation[] + members: Member[], } -export type MembersListResponse = { - _links: Links - members: Member[], +export interface MembersListResponse { + // eslint-disable-next-line @typescript-eslint/naming-convention + _links: Links + members: Member[], } -export type MemberResponse = { - member: Member +export interface MemberResponse { + member: Member } \ No newline at end of file diff --git a/src/services/access-control-client/models/owner.ts b/src/services/access-control-client/models/owner.ts index 5909fb09..d88b9b30 100644 --- a/src/services/access-control-client/models/owner.ts +++ b/src/services/access-control-client/models/owner.ts @@ -3,16 +3,17 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import { Links } from "../../general-models/links.js" -import { GroupMember } from "./group-members.js" -import { Invitation } from "./invitations.js" +import { Links } from "../../general-models/links.js"; +import { GroupMember } from "./group-members.js"; +import { Invitation } from "./invitations.js"; -export type OwnerResponse = { - invitation: Invitation - member: GroupMember, +export interface OwnerResponse { + invitation: Invitation + member: GroupMember, } -export type OwnerListResponse = { - _links: Links - members: GroupMember[], +export interface OwnerListResponse { + // eslint-disable-next-line @typescript-eslint/naming-convention + _links: Links + members: GroupMember[], } \ No newline at end of file diff --git a/src/services/access-control-client/models/permissions.ts b/src/services/access-control-client/models/permissions.ts index eec2f8a9..8a1c58b6 100644 --- a/src/services/access-control-client/models/permissions.ts +++ b/src/services/access-control-client/models/permissions.ts @@ -3,6 +3,6 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -export type Permissions = { - permissions: string[] +export interface Permissions { + permissions: string[] } \ No newline at end of file diff --git a/src/services/access-control-client/models/role.ts b/src/services/access-control-client/models/role.ts index 25499a04..181cfdb9 100644 --- a/src/services/access-control-client/models/role.ts +++ b/src/services/access-control-client/models/role.ts @@ -3,18 +3,18 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -export type Role = { - description?: string, - displayName?: string, - id?: string, - permissions?: string[] +export interface Role { + description?: string, + displayName?: string, + id?: string, + permissions?: string[] } -export type RoleResponse = { - role: Role +export interface RoleResponse { + role: Role } -export type RolesResponse = { - roles: Role[] +export interface RolesResponse { + roles: Role[] } \ No newline at end of file diff --git a/src/services/authorization-client/auth-token-info.ts b/src/services/authorization-client/auth-token-info.ts index 034c79df..06be43d9 100644 --- a/src/services/authorization-client/auth-token-info.ts +++ b/src/services/authorization-client/auth-token-info.ts @@ -3,10 +3,10 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import { AuthorizationType } from "./authorization-type.js" +import { AuthorizationType } from "./authorization-type.js"; -export type AuthTokenInfo = { - authToken?: string, - authenticationType?: AuthorizationType, - expirationDate?: Date +export interface AuthTokenInfo { + authToken?: string, + authenticationType?: AuthorizationType, + expirationDate?: Date } \ No newline at end of file diff --git a/src/services/authorization-client/authorization-client.ts b/src/services/authorization-client/authorization-client.ts index ad6c7f73..cc46d76a 100644 --- a/src/services/authorization-client/authorization-client.ts +++ b/src/services/authorization-client/authorization-client.ts @@ -16,154 +16,156 @@ import { AuthorizationInformation, AuthorizationType } from "./authorization-typ export class AuthorizationClient { private readonly _cliConfiguration: Config; - private readonly environmentConfiguration: Configuration; - + private readonly _environmentConfiguration: Configuration; + constructor(envConfig: Configuration, cliConfig: Config) { - this.environmentConfiguration = envConfig; - this._cliConfiguration = cliConfig; + this._environmentConfiguration = envConfig; + this._cliConfiguration = cliConfig; + } + + public async getTokenAsync() : Promise { + const tokenInfo = this.getExistingAuthTokenInfo(); + if(tokenInfo?.authToken && this.isExpirationDateValid(tokenInfo.expirationDate)) { + return tokenInfo.authToken; } - - async getTokenAsync() : Promise { - const tokenInfo = this.getExistingAuthTokenInfo(); - if(tokenInfo?.authToken && this.isExpirationDateValid(tokenInfo.expirationDate)) { - return tokenInfo.authToken; - } - - const newTokenInfo = await this.login(); - - return newTokenInfo.authToken; + + const newTokenInfo = await this.login(); + + return newTokenInfo.authToken; + } + + public info() : AuthorizationInformation { + const existingTokenInfo = this.getExistingAuthTokenInfo(); + + return { + apiUrl : this._environmentConfiguration.apiUrl, + authorizationType: existingTokenInfo?.authenticationType ?? AuthorizationType.Interactive, + clientId: this._environmentConfiguration.clientId, + expirationDate: existingTokenInfo?.expirationDate, + issuerUrl: this._environmentConfiguration.issuerUrl + }; + } + + public async login(clientId?: string, clientSecret?: string) : Promise { + let authType: AuthorizationType; + let usedToken : string; + + const usedClientId = clientId ?? this._environmentConfiguration.clientId; + const usedClientSecret = clientSecret ?? this._environmentConfiguration.clientSecret; + + if(usedClientId && usedClientSecret) { + usedToken = await this.getAccessTokenFromService(usedClientId, usedClientSecret, this._environmentConfiguration.issuerUrl); + authType = AuthorizationType.Service; } - - info() : AuthorizationInformation { - const existingTokenInfo = this.getExistingAuthTokenInfo(); - - return { - apiUrl : this.environmentConfiguration.apiUrl, - authorizationType: existingTokenInfo?.authenticationType ?? AuthorizationType.Interactive, - clientId: this.environmentConfiguration.clientId, - expirationDate: existingTokenInfo?.expirationDate, - issuerUrl: this.environmentConfiguration.issuerUrl - } + else { + usedToken = await this.getAccessTokenFromWebsiteLogin(usedClientId, this._environmentConfiguration.issuerUrl); + authType = AuthorizationType.Interactive; } - async login(clientId?: string, clientSecret?: string) : Promise { - let authType: AuthorizationType; - let usedToken : string; - - const usedClientId = clientId ?? this.environmentConfiguration.clientId; - const usedClientSecret = clientSecret ?? this.environmentConfiguration.clientSecret; - - if(usedClientId && usedClientSecret) { - usedToken = await this.getAccessTokenFromService(usedClientId, usedClientSecret, this.environmentConfiguration.issuerUrl); - authType = AuthorizationType.Service; - } - else { - usedToken = await this.getAccessTokenFromWebsiteLogin(usedClientId, this.environmentConfiguration.issuerUrl); - authType = AuthorizationType.Interactive; - } - - return this.saveAccessToken(usedToken, authType); + return this.saveAccessToken(usedToken, authType); + } + + public async logout() { + const existingTokenInfo = this.getExistingAuthTokenInfo(); + + // Login from IMS + if(existingTokenInfo?.authenticationType === AuthorizationType.Interactive) { + const {clientId, issuerUrl} = this._environmentConfiguration; + + const client = new NodeCliAuthorizationClient({ + clientId, + expiryBuffer: 10 * 60, + issuerUrl, + redirectUri: "http://localhost:3301/signin-callback", + scope: "itwin-platform", + tokenStorePath: this._cliConfiguration.cacheDir, + }); + + await client.signOut(); } - async logout() { - const existingTokenInfo = this.getExistingAuthTokenInfo(); - - // Login from IMS - if(existingTokenInfo?.authenticationType === AuthorizationType.Interactive) { - const {clientId, issuerUrl} = this.environmentConfiguration - - const client = new NodeCliAuthorizationClient({ - clientId, - expiryBuffer: 10 * 60, - issuerUrl, - redirectUri: "http://localhost:3301/signin-callback", - scope: "itwin-platform" - }); - - await client.signOut(); - } - - if (!fs.existsSync(this._cliConfiguration.cacheDir)) { - fs.mkdirSync(this._cliConfiguration.cacheDir, { recursive: true }); - } - - // Remove token from cache - const tokenPath = path.join(this._cliConfiguration.cacheDir, 'token.json'); - if(fs.existsSync(tokenPath)) - { - fs.unlinkSync(tokenPath); - } + if (!fs.existsSync(this._cliConfiguration.cacheDir)) { + fs.mkdirSync(this._cliConfiguration.cacheDir, { recursive: true }); } - private async getAccessTokenFromService(clientId: string, clientSecret: string, issuerUrl: string) { - const client = new ServiceAuthorizationClient({ - authority: issuerUrl, - clientId, - clientSecret, - scope: 'itwin-platform' - }) - - return client.getAccessToken(); - } - - private async getAccessTokenFromWebsiteLogin(clientId: string, issuerUrl: string) { - const client = new NodeCliAuthorizationClient({ - clientId, - expiryBuffer: 10 * 60, - issuerUrl, - redirectUri: "http://localhost:3301/signin-callback", - scope: "itwin-platform", - tokenStorePath: this._cliConfiguration.cacheDir, - }); - - await client.signIn(); - return client.getAccessToken(); + // Remove token from cache + const tokenPath = path.join(this._cliConfiguration.cacheDir, 'token.json'); + if(fs.existsSync(tokenPath)) + { + fs.unlinkSync(tokenPath); + } + } + + private async getAccessTokenFromService(clientId: string, clientSecret: string, issuerUrl: string) { + const client = new ServiceAuthorizationClient({ + authority: issuerUrl, + clientId, + clientSecret, + scope: 'itwin-platform' + }); + + return client.getAccessToken(); + } + + private async getAccessTokenFromWebsiteLogin(clientId: string, issuerUrl: string) { + const client = new NodeCliAuthorizationClient({ + clientId, + expiryBuffer: 10 * 60, + issuerUrl, + redirectUri: "http://localhost:3301/signin-callback", + scope: "itwin-platform", + tokenStorePath: this._cliConfiguration.cacheDir, + }); + + await client.signIn(); + return client.getAccessToken(); + } + + private getExistingAuthTokenInfo() { + const tokenPath = path.join(this._cliConfiguration.cacheDir, 'token.json'); + + if (!fs.existsSync(tokenPath)) { + return; } - private getExistingAuthTokenInfo() { - const tokenPath = path.join(this._cliConfiguration.cacheDir, 'token.json'); + return JSON.parse(fs.readFileSync(tokenPath, 'utf8')) as AuthTokenInfo; + } - if (!fs.existsSync(tokenPath)) { - return; - } - - return JSON.parse(fs.readFileSync(tokenPath, 'utf8')) as AuthTokenInfo; + private isExpirationDateValid(expirationDate: Date | undefined) { + if(!expirationDate) { + return false; } - private isExpirationDateValid(expirationDate: Date | undefined) { - if(!expirationDate) { - return false; - } - - // This is required because the expirationDate is not instanciated - // because it is cast from a string in json - const expirationDateFixed = new Date(expirationDate); - - const currentDate = new Date(); - return expirationDateFixed > currentDate; - } + // This is required because the expirationDate is not instanciated + // because it is cast from a string in json + const expirationDateFixed = new Date(expirationDate); + + const currentDate = new Date(); + return expirationDateFixed > currentDate; + } - private saveAccessToken(accessToken: string, authenticationType: AuthorizationType) { - // Ensure the directory exists - if (!fs.existsSync(this._cliConfiguration.cacheDir)) { - fs.mkdirSync(this._cliConfiguration.cacheDir, { recursive: true }); - } + private saveAccessToken(accessToken: string, authenticationType: AuthorizationType) { + // Ensure the directory exists + if (!fs.existsSync(this._cliConfiguration.cacheDir)) { + fs.mkdirSync(this._cliConfiguration.cacheDir, { recursive: true }); + } - const fixedAccessToken = accessToken.startsWith('Bearer ') ? accessToken : `Bearer ${accessToken}`; + const fixedAccessToken = accessToken.startsWith('Bearer ') ? accessToken : `Bearer ${accessToken}`; - const parsedToken = jwtDecode(fixedAccessToken); + const parsedToken = jwtDecode(fixedAccessToken); - const expiration = new Date(parsedToken.exp! * 1000); - const tokenInfo : AuthTokenInfo = { - authToken: fixedAccessToken, - authenticationType, - expirationDate: expiration - } + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const expiration = new Date(parsedToken.exp! * 1000); + const tokenInfo : AuthTokenInfo = { + authToken: fixedAccessToken, + authenticationType, + expirationDate: expiration + }; - const tokenPath = path.join(this._cliConfiguration.cacheDir, 'token.json'); - fs.writeFileSync(tokenPath, JSON.stringify(tokenInfo)); + const tokenPath = path.join(this._cliConfiguration.cacheDir, 'token.json'); + fs.writeFileSync(tokenPath, JSON.stringify(tokenInfo)); - return tokenInfo; - } + return tokenInfo; + } } \ No newline at end of file diff --git a/src/services/authorization-client/authorization-type.ts b/src/services/authorization-client/authorization-type.ts index 0d88c6e7..150d69b5 100644 --- a/src/services/authorization-client/authorization-type.ts +++ b/src/services/authorization-client/authorization-type.ts @@ -4,14 +4,14 @@ *--------------------------------------------------------------------------------------------*/ export enum AuthorizationType { - Interactive = "Interactive", - Service = "Service" + Interactive = "Interactive", + Service = "Service" } -export type AuthorizationInformation = { - apiUrl: string; - authorizationType: AuthorizationType; - clientId: string; - expirationDate?: Date; - issuerUrl: string; +export interface AuthorizationInformation { + apiUrl: string; + authorizationType: AuthorizationType; + clientId: string; + expirationDate?: Date; + issuerUrl: string; } \ No newline at end of file diff --git a/src/services/changed-elements-client/changed-elements-api-client.ts b/src/services/changed-elements-client/changed-elements-api-client.ts index 23763d77..b5d88ec9 100644 --- a/src/services/changed-elements-client/changed-elements-api-client.ts +++ b/src/services/changed-elements-client/changed-elements-api-client.ts @@ -4,87 +4,87 @@ *--------------------------------------------------------------------------------------------*/ import { ITwinPlatformApiClient } from "../iTwin-api-client.js"; -import { ChangeTrackingRequest, ChangesetComparisonResponse, ChangesetsResponse, TrackingResponse } from "./tracking.js"; +import { ChangesetComparisonResponse, ChangesetsResponse, ChangeTrackingRequest, TrackingResponse } from "./tracking.js"; export class ChangedElementsApiClient { - iTwinPlatformApiClient: ITwinPlatformApiClient; + private _iTwinPlatformApiClient: ITwinPlatformApiClient; - constructor(client : ITwinPlatformApiClient) { - this.iTwinPlatformApiClient = client; - } + constructor(client : ITwinPlatformApiClient) { + this._iTwinPlatformApiClient = client; + } - async changeTracking(request: ChangeTrackingRequest) : Promise { - await this.iTwinPlatformApiClient.sendRequestNoResponse({ - apiPath: 'changedelements/tracking', - body: request, - method: 'PUT' - }); - } + public async changeTracking(request: ChangeTrackingRequest) : Promise { + await this._iTwinPlatformApiClient.sendRequestNoResponse({ + apiPath: 'changedelements/tracking', + body: request, + method: 'PUT' + }); + } - async getComparison(iTwinId: string, iModelId: string, startChangesetId: string, endChangesetId: string) : Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: 'changedelements/comparison', - method: 'GET', - query: [ - { - key: 'iTwinId', - value: iTwinId - }, - { - key: 'iModelId', - value: iModelId - }, - { - key: 'startChangesetId', - value: startChangesetId - }, - { - key: 'endChangesetId', - value: endChangesetId - } - ] - }); - } + public async getComparison(iTwinId: string, iModelId: string, startChangesetId: string, endChangesetId: string) : Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: 'changedelements/comparison', + method: 'GET', + query: [ + { + key: 'iTwinId', + value: iTwinId + }, + { + key: 'iModelId', + value: iModelId + }, + { + key: 'startChangesetId', + value: startChangesetId + }, + { + key: 'endChangesetId', + value: endChangesetId + } + ] + }); + } - getTracking(iModelId: string, iTwinId: string) : Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: 'changedelements/tracking', - method: 'GET', - query: [ - { - key:'iModelId', - value: iModelId - }, - { - key: 'iTwinId', - value: iTwinId - } - ] - }); - } + public async getTracking(iModelId: string, iTwinId: string) : Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: 'changedelements/tracking', + method: 'GET', + query: [ + { + key:'iModelId', + value: iModelId + }, + { + key: 'iTwinId', + value: iTwinId + } + ] + }); + } - listChangesets(iModelId: string, iTwinId: string, top?: number, skip?: number) : Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: 'changedelements/changesets', - method: 'GET', - query: [ - { - key:'iModelId', - value: iModelId - }, - { - key: 'iTwinId', - value: iTwinId - }, - { - key: '$top', - value: top - }, - { - key: '$skip', - value: skip - } - ] - }); - } + public async listChangesets(iModelId: string, iTwinId: string, top?: number, skip?: number) : Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: 'changedelements/changesets', + method: 'GET', + query: [ + { + key:'iModelId', + value: iModelId + }, + { + key: 'iTwinId', + value: iTwinId + }, + { + key: '$top', + value: top + }, + { + key: '$skip', + value: skip + } + ] + }); + } } \ No newline at end of file diff --git a/src/services/changed-elements-client/tracking.ts b/src/services/changed-elements-client/tracking.ts index 533afbee..001bc91b 100644 --- a/src/services/changed-elements-client/tracking.ts +++ b/src/services/changed-elements-client/tracking.ts @@ -3,42 +3,43 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import { Links } from "../general-models/links.js" +import { Links } from "../general-models/links.js"; -export type ChangeTrackingRequest = { - enable: boolean, - iModelId: string, - iTwinId: string +export interface ChangeTrackingRequest { + enable: boolean, + iModelId: string, + iTwinId: string } -export type TrackingResponse = { - enabled : boolean +export interface TrackingResponse { + enabled : boolean } -export type ChangesetsResponse = { - _links: Links - changesetStatus: Changeset[] +export interface ChangesetsResponse { + // eslint-disable-next-line @typescript-eslint/naming-convention + _links: Links + changesetStatus: Changeset[] } -export type Changeset = { - id: string, - index: number, - ready: boolean +export interface Changeset { + id: string, + index: number, + ready: boolean } -export type ChangesetComparisonResponse = { - changedElements: ChangesetComparison +export interface ChangesetComparisonResponse { + changedElements: ChangesetComparison } -export type ChangesetComparison = { - classIds: string[], - elements: string[], - modelIds: string[], - newChecksums: string[][], - oldCheckSsms: string[][], - opcodes: number[], - parentClassIds: string[] - parentIds: string[], - properties: string[][], - type: number[], +export interface ChangesetComparison { + classIds: string[], + elements: string[], + modelIds: string[], + newChecksums: string[][], + oldCheckSsms: string[][], + opcodes: number[], + parentClassIds: string[] + parentIds: string[], + properties: string[][], + type: number[], } \ No newline at end of file diff --git a/src/services/general-models/links.ts b/src/services/general-models/links.ts index a34ddc05..aab507e6 100644 --- a/src/services/general-models/links.ts +++ b/src/services/general-models/links.ts @@ -3,15 +3,15 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -export type Links = { - next: Link - prev: Link, - self: Link, +export interface Links { + next: Link + prev: Link, + self: Link, } -export type Link = { - /** +export interface Link { + /** * Hyperlink to the specific entity. */ - href?: string; -}; \ No newline at end of file + href?: string; +} \ No newline at end of file diff --git a/src/services/general-models/user-context.ts b/src/services/general-models/user-context.ts index a4935aec..1416e7e5 100644 --- a/src/services/general-models/user-context.ts +++ b/src/services/general-models/user-context.ts @@ -1,4 +1,9 @@ -export type UserContext = { - iModelId?: string; - iTwinId?: string; +/*--------------------------------------------------------------------------------------------- +* Copyright (c) Bentley Systems, Incorporated. All rights reserved. +* See LICENSE.md in the project root for license terms and full copyright notice. +*--------------------------------------------------------------------------------------------*/ + +export interface UserContext { + iModelId?: string; + iTwinId?: string; } \ No newline at end of file diff --git a/src/services/iTwin-api-client.ts b/src/services/iTwin-api-client.ts index d8408ef5..2e611ef7 100644 --- a/src/services/iTwin-api-client.ts +++ b/src/services/iTwin-api-client.ts @@ -1,5 +1,3 @@ -/* eslint-disable unicorn/filename-case */ - /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. @@ -20,18 +18,18 @@ export interface Query { } export class ITwinPlatformApiClient { - private readonly apiVersionHeader: string | undefined; - private readonly authToken: string; - private readonly iTwinPlatformApiBasePath: string; + private readonly _apiVersionHeader: string | undefined; + private readonly _authToken: string; + private readonly _iTwinPlatformApiBasePath: string; constructor(url: string, token: string, apiVersionHeader?: string | undefined) { - this.iTwinPlatformApiBasePath = url; - this.authToken = token; - this.apiVersionHeader = apiVersionHeader; + this._iTwinPlatformApiBasePath = url; + this._authToken = token; + this._apiVersionHeader = apiVersionHeader; } - async sendRequest(options: RequestOption): Promise { + public async sendRequest(options: RequestOption): Promise { const result = await this.request(options); if(!result) { @@ -41,13 +39,14 @@ export class ITwinPlatformApiClient { return result; } - async sendRequestNoResponse(options: RequestOption): Promise { + public async sendRequestNoResponse(options: RequestOption): Promise { await this.request(options); } private getHeadersList(headers: Record | undefined, apiVersionHeader: string | undefined) { const headersList: Record = { - 'Authorization': this.authToken, + // eslint-disable-next-line @typescript-eslint/naming-convention + Authorization: this._authToken, 'Content-Type': 'application/json', ...headers }; @@ -55,8 +54,8 @@ export class ITwinPlatformApiClient { if (apiVersionHeader) { headersList.Accept = apiVersionHeader; } - else if (this.apiVersionHeader) { - headersList.Accept = this.apiVersionHeader; + else if (this._apiVersionHeader) { + headersList.Accept = this._apiVersionHeader; } return headersList; @@ -67,6 +66,7 @@ export class ITwinPlatformApiClient { return ''; } + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const queryString = query.filter(entry => Boolean(entry.value)).map(entry => `${encodeURIComponent(entry.key)}=${encodeURIComponent(entry.value!)}`).join('&'); if(queryString.length === 0) { @@ -90,18 +90,18 @@ export class ITwinPlatformApiClient { method }; - const response = await fetch(`${this.iTwinPlatformApiBasePath}/${apiPath}${queryString}`, fetchOptions); + const response = await fetch(`${this._iTwinPlatformApiBasePath}/${apiPath}${queryString}`, fetchOptions); if(!response.ok) { - const responseData = await response.json(); + const errorResponseData = await response.json(); try { - const typedError = responseData as ErrorResponse; + const typedError = errorResponseData as ErrorResponse; const stringifiedError = JSON.stringify(typedError.error, Object.getOwnPropertyNames(typedError.error)); throw new Error(`HTTP error! status: ${response.status}. Response data: ${stringifiedError}`); } catch { - throw new Error(`HTTP error! ${JSON.stringify(responseData)}`); + throw new Error(`HTTP error! ${JSON.stringify(errorResponseData)}`); } } @@ -114,17 +114,17 @@ export class ITwinPlatformApiClient { } } -type ErrorResponse = { +interface ErrorResponse { error: Error } -type Error = { +interface Error { code: string, details: ErrorDetails[] message: string, } -type ErrorDetails = { +interface ErrorDetails { code: string message: string, target: string diff --git a/src/services/storage-client/models/file-base.ts b/src/services/storage-client/models/file-base.ts index a3df21a9..2ca6a9bc 100644 --- a/src/services/storage-client/models/file-base.ts +++ b/src/services/storage-client/models/file-base.ts @@ -3,15 +3,15 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -export type FileBase = { - /** +export interface FileBase { + /** * Description of the file. */ - description?: string; - /** + description?: string; + /** * Display name of the file. */ - displayName?: string; -}; + displayName?: string; +} diff --git a/src/services/storage-client/models/file-response.ts b/src/services/storage-client/models/file-response.ts index 1325058d..31f662ac 100644 --- a/src/services/storage-client/models/file-response.ts +++ b/src/services/storage-client/models/file-response.ts @@ -6,15 +6,16 @@ import { Links } from "../../general-models/links.js"; import { FileTyped } from "./file-typed.js"; -export type FileResponse = { - file?: FileTyped; -}; +export interface FileResponse { + file?: FileTyped; +} -export type FilesResponse = { - files: FileTyped[]; +export interface FilesResponse { + files: FileTyped[]; } -export type ItemsResponse = { - _links: Links - items: FileTyped[]; +export interface ItemsResponse { + // eslint-disable-next-line @typescript-eslint/naming-convention + _links: Links + items: FileTyped[]; } diff --git a/src/services/storage-client/models/file-typed-type.ts b/src/services/storage-client/models/file-typed-type.ts index 89cba52b..4656f1be 100644 --- a/src/services/storage-client/models/file-typed-type.ts +++ b/src/services/storage-client/models/file-typed-type.ts @@ -4,6 +4,6 @@ *--------------------------------------------------------------------------------------------*/ export enum FileTypedType { - FILE = 'file', - FOLDER = 'folder' + FILE = 'file', + FOLDER = 'folder' } diff --git a/src/services/storage-client/models/file-typed.ts b/src/services/storage-client/models/file-typed.ts index 7641aa40..56c33f0e 100644 --- a/src/services/storage-client/models/file-typed.ts +++ b/src/services/storage-client/models/file-typed.ts @@ -7,47 +7,48 @@ import { FileTypedType } from "./file-typed-type.js"; import { LinksItem } from "./links-item.js"; -export type FileTyped = { - _links?: LinksItem; - /** +export interface FileTyped { + // eslint-disable-next-line @typescript-eslint/naming-convention + _links?: LinksItem; + /** * Date when the file was created. */ - createdDateTime?: string; - /** + createdDateTime?: string; + /** * Description of the file. */ - description?: string; - /** + description?: string; + /** * Display name of the file. */ - displayName?: string; - /** + displayName?: string; + /** * Unique Identifier of the file. */ - id?: string; - /** + id?: string; + /** * Display name of the user who modified file last. */ - lastModifiedByDisplayName?: string; - /** + lastModifiedByDisplayName?: string; + /** * Date when the file was last time modified. */ - lastModifiedDateTime?: string; - /** + lastModifiedDateTime?: string; + /** * Unique Identifier of the parent folder. */ - parentFolderId?: string; - /** + parentFolderId?: string; + /** * Absolute path to the file. */ - path?: string; - /** + path?: string; + /** * Size to the file in bytes. */ - size?: number; - /** + size?: number; + /** * Identification of the file entity. */ - type?: FileTypedType; -}; + type?: FileTypedType; +} diff --git a/src/services/storage-client/models/file-upload.ts b/src/services/storage-client/models/file-upload.ts index 2275e62d..a8b135f8 100644 --- a/src/services/storage-client/models/file-upload.ts +++ b/src/services/storage-client/models/file-upload.ts @@ -6,6 +6,7 @@ import { LinksUpload } from "./links-upload.js"; -export type FileUpload = { - _links?: LinksUpload; -}; +export interface FileUpload { + // eslint-disable-next-line @typescript-eslint/naming-convention + _links?: LinksUpload; +} diff --git a/src/services/storage-client/models/folder-typed.ts b/src/services/storage-client/models/folder-typed.ts index 227ade1e..d2dea26f 100644 --- a/src/services/storage-client/models/folder-typed.ts +++ b/src/services/storage-client/models/folder-typed.ts @@ -5,60 +5,61 @@ import { LinksItem } from "./links-item.js"; -export type FolderTyped = { - _links?: LinksItem; - /** +export interface FolderTyped { + // eslint-disable-next-line @typescript-eslint/naming-convention + _links?: LinksItem; + /** * Date when the folder was created. */ - createdDateTime?: string; - /** + createdDateTime?: string; + /** * Description of the folder. */ - description?: string; - /** + description?: string; + /** * Display name of the folder. */ - displayName?: string; - /** + displayName?: string; + /** * Unique Identifier of the folder. */ - id?: string; - /** + id?: string; + /** * Display name of the user who modified folder last. */ - lastModifiedByDisplayName?: string; - /** + lastModifiedByDisplayName?: string; + /** * Date when the folder was last time modified. */ - lastModifiedDateTime?: string; - /** + lastModifiedDateTime?: string; + /** * Unique Identifier of the parent folder. */ - parentFolderId?: string; - /** + parentFolderId?: string; + /** * Absolute path to the folder. */ - path?: string; - /** + path?: string; + /** * Identification of the folder entity. */ - type?: FolderTypedType; + type?: FolderTypedType; -}; +} export enum FolderTypedType { - FOLDER = 'folder' + FOLDER = 'folder' } -export type FolderInfo = { - description?: string - displayName?: string +export interface FolderInfo { + description?: string + displayName?: string } -export type FolderResponse = { - folder: FolderTyped; +export interface FolderResponse { + folder: FolderTyped; } -export type FoldersResponse = { - folders: FolderTyped[]; +export interface FoldersResponse { + folders: FolderTyped[]; } \ No newline at end of file diff --git a/src/services/storage-client/models/items-with-folder-link.ts b/src/services/storage-client/models/items-with-folder-link.ts index 77c24562..787bd106 100644 --- a/src/services/storage-client/models/items-with-folder-link.ts +++ b/src/services/storage-client/models/items-with-folder-link.ts @@ -7,7 +7,8 @@ import { FileTyped } from "./file-typed.js"; import { FolderTyped } from "./folder-typed.js"; import { LinksPagingWithFolderLink } from "./links-paging-with-folder-link.js"; -export type ItemsWithFolderLink = { - _links?: LinksPagingWithFolderLink - items?: Array; -}; +export interface ItemsWithFolderLink { + // eslint-disable-next-line @typescript-eslint/naming-convention + _links?: LinksPagingWithFolderLink + items?: Array; +} diff --git a/src/services/storage-client/models/links-item.ts b/src/services/storage-client/models/links-item.ts index 2265386c..dc6cb127 100644 --- a/src/services/storage-client/models/links-item.ts +++ b/src/services/storage-client/models/links-item.ts @@ -5,8 +5,8 @@ import { Link } from "../../general-models/links.js"; -export type LinksItem = { - createdBy?: Link; - lastModifiedBy?: Link; - parentFolder?: Link; -}; +export interface LinksItem { + createdBy?: Link; + lastModifiedBy?: Link; + parentFolder?: Link; +} diff --git a/src/services/storage-client/models/links-paging-with-folder-link.ts b/src/services/storage-client/models/links-paging-with-folder-link.ts index caeb94c1..9f618300 100644 --- a/src/services/storage-client/models/links-paging-with-folder-link.ts +++ b/src/services/storage-client/models/links-paging-with-folder-link.ts @@ -5,10 +5,10 @@ import { Link } from "../../general-models/links.js"; -export type LinksPagingWithFolderLink = { - folder?: Link; - next?: Link; - prev?: Link; - self?: Link; -}; +export interface LinksPagingWithFolderLink { + folder?: Link; + next?: Link; + prev?: Link; + self?: Link; +} diff --git a/src/services/storage-client/models/links-upload.ts b/src/services/storage-client/models/links-upload.ts index 0fd066ea..50e31066 100644 --- a/src/services/storage-client/models/links-upload.ts +++ b/src/services/storage-client/models/links-upload.ts @@ -5,7 +5,7 @@ import { Link } from "../../general-models/links.js"; -export type LinksUpload = { - completeUrl?: Link; - uploadUrl?: Link; -}; +export interface LinksUpload { + completeUrl?: Link; + uploadUrl?: Link; +} diff --git a/src/services/storage-client/storage-api-client.ts b/src/services/storage-client/storage-api-client.ts index d955f767..83c3a53d 100644 --- a/src/services/storage-client/storage-api-client.ts +++ b/src/services/storage-client/storage-api-client.ts @@ -10,140 +10,140 @@ import { FolderInfo, FolderResponse, FoldersResponse } from "./models/folder-typ import { ItemsWithFolderLink } from "./models/items-with-folder-link.js"; export class StorageApiClient { - iTwinPlatformApiClient: ITwinPlatformApiClient; - - constructor(client: ITwinPlatformApiClient) { - this.iTwinPlatformApiClient = client; - } - - completeFileUpload(fileId: string) : Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `storage/files/${fileId}/complete`, - method: "POST" - }); - } - - createFile(folderId: string, displayName: string, description?: string) : Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `storage/folders/${folderId}/files`, - body: { - description, - displayName - }, - method: "POST", - }); - } - - createFolder(folderId: string, folder: FolderInfo): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `storage/folders/${folderId}/folders`, - body: folder, - method: 'POST' - }); - } - - async deleteFile(fileId: string): Promise { - await this.iTwinPlatformApiClient.sendRequestNoResponse({ - apiPath: `storage/files/${fileId}`, - method: "DELETE", - }); - } - - async deleteFolder(folderId: string): Promise { - await this.iTwinPlatformApiClient.sendRequestNoResponse({ - apiPath: `storage/folders/${folderId}`, - method: 'DELETE' - }); - } - - getFile(fileId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `storage/files/${fileId}`, - method: "GET", - }); - } - - getFiles(folderId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `storage/folders/${folderId}/files`, - method: "GET", - }); - } - - getFilesAndFolders(folderId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `storage/folders/${folderId}/list`, - method: "GET", - }); - } - - getFolder(folderId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `storage/folders/${folderId}`, - method: 'GET' - }); - } - - getFolders(folderId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `storage/folders/${folderId}/folders`, - method: 'GET' - }); - } - - getTopLevelFoldersAndFiles(iTwinId: string, top?: number, skip?: number) : Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `storage/`, - headers: { accept: "application/vnd.bentley.itwin-platform.v1+json" }, - method: 'GET', - query: [ - { - key: 'iTwinId', - value: iTwinId - }, - { - key: '$top', - value: top - }, - { - key: '$skip', - value: skip - } - ] - }); - } - - updateFile(fileId: string, displayName?: string, description?: string) : Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `storage/files/${fileId}`, - body: { - description, - displayName - }, - method: "PATCH", - }); - } - - updateFileContent(fileId: string) : Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `storage/files/${fileId}/updatecontent`, - method: "POST" - }); - } - - updateFolder(folderId: string, folderInfo: FolderInfo): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `storage/folders/${folderId}`, - body: folderInfo, - method: 'PATCH' - }); - } - - uploadFile(url: string, file: ArrayBuffer) { - return fetch(url, { - body: file, - headers: { 'x-ms-blob-type': 'BlockBlob' }, - method: 'PUT', - }); - } + private _iTwinPlatformApiClient: ITwinPlatformApiClient; + + constructor(client: ITwinPlatformApiClient) { + this._iTwinPlatformApiClient = client; + } + + public async completeFileUpload(fileId: string) : Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `storage/files/${fileId}/complete`, + method: "POST" + }); + } + + public async createFile(folderId: string, displayName: string, description?: string) : Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `storage/folders/${folderId}/files`, + body: { + description, + displayName + }, + method: "POST", + }); + } + + public async createFolder(folderId: string, folder: FolderInfo): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `storage/folders/${folderId}/folders`, + body: folder, + method: 'POST' + }); + } + + public async deleteFile(fileId: string): Promise { + await this._iTwinPlatformApiClient.sendRequestNoResponse({ + apiPath: `storage/files/${fileId}`, + method: "DELETE", + }); + } + + public async deleteFolder(folderId: string): Promise { + await this._iTwinPlatformApiClient.sendRequestNoResponse({ + apiPath: `storage/folders/${folderId}`, + method: 'DELETE' + }); + } + + public async getFile(fileId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `storage/files/${fileId}`, + method: "GET", + }); + } + + public async getFiles(folderId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `storage/folders/${folderId}/files`, + method: "GET", + }); + } + + public async getFilesAndFolders(folderId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `storage/folders/${folderId}/list`, + method: "GET", + }); + } + + public async getFolder(folderId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `storage/folders/${folderId}`, + method: 'GET' + }); + } + + public async getFolders(folderId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `storage/folders/${folderId}/folders`, + method: 'GET' + }); + } + + public async getTopLevelFoldersAndFiles(iTwinId: string, top?: number, skip?: number) : Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `storage/`, + headers: { accept: "application/vnd.bentley.itwin-platform.v1+json" }, + method: 'GET', + query: [ + { + key: 'iTwinId', + value: iTwinId + }, + { + key: '$top', + value: top + }, + { + key: '$skip', + value: skip + } + ] + }); + } + + public async updateFile(fileId: string, displayName?: string, description?: string) : Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `storage/files/${fileId}`, + body: { + description, + displayName + }, + method: "PATCH", + }); + } + + public async updateFileContent(fileId: string) : Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `storage/files/${fileId}/updatecontent`, + method: "POST" + }); + } + + public async updateFolder(folderId: string, folderInfo: FolderInfo): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `storage/folders/${folderId}`, + body: folderInfo, + method: 'PATCH' + }); + } + + public async uploadFile(url: string, file: ArrayBuffer) { + return fetch(url, { + body: file, + headers: { 'x-ms-blob-type': 'BlockBlob' }, + method: 'PUT', + }); + } } diff --git a/src/services/synchronizationClient/models/authentication-type.ts b/src/services/synchronizationClient/models/authentication-type.ts index 6ac48c34..37f0ace5 100644 --- a/src/services/synchronizationClient/models/authentication-type.ts +++ b/src/services/synchronizationClient/models/authentication-type.ts @@ -4,6 +4,6 @@ *--------------------------------------------------------------------------------------------*/ export enum AuthenticationType { - SERVICE = 'Service', - USER = 'User' + SERVICE = 'Service', + USER = 'User' } diff --git a/src/services/synchronizationClient/models/connection-auth.ts b/src/services/synchronizationClient/models/connection-auth.ts index bda8a53f..ff95bd2c 100644 --- a/src/services/synchronizationClient/models/connection-auth.ts +++ b/src/services/synchronizationClient/models/connection-auth.ts @@ -3,15 +3,16 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import { Link } from "../../general-models/links.js" +import { Link } from "../../general-models/links.js"; -export type AuthInfo = { - _links: { - authorizationUrl : Link - } - isUserAuthorized: boolean +export interface AuthInfo { + // eslint-disable-next-line @typescript-eslint/naming-convention + _links: { + authorizationUrl : Link + } + isUserAuthorized: boolean } -export type ConnectionAuth = { - authorizationInformation: AuthInfo +export interface ConnectionAuth { + authorizationInformation: AuthInfo } \ No newline at end of file diff --git a/src/services/synchronizationClient/models/connection-links.ts b/src/services/synchronizationClient/models/connection-links.ts index d93e34d3..dcbfa25d 100644 --- a/src/services/synchronizationClient/models/connection-links.ts +++ b/src/services/synchronizationClient/models/connection-links.ts @@ -5,8 +5,8 @@ import { Link } from "../../general-models/links.js"; -export type ConnectionLinks = { - iModel?: Link; - lastRun?: Link; - project?: Link; -}; +export interface ConnectionLinks { + iModel?: Link; + lastRun?: Link; + project?: Link; +} diff --git a/src/services/synchronizationClient/models/connector-type.ts b/src/services/synchronizationClient/models/connector-type.ts index eaee6ae0..d848ede6 100644 --- a/src/services/synchronizationClient/models/connector-type.ts +++ b/src/services/synchronizationClient/models/connector-type.ts @@ -4,18 +4,18 @@ *--------------------------------------------------------------------------------------------*/ export enum ConnectorType { - AUTOPLANT = 'AUTOPLANT', - CIVIL = 'CIVIL', - CIVIL3D = 'CIVIL3D', - DWG = 'DWG', - GEOSPATIAL = 'GEOSPATIAL', - IFC = 'IFC', - MSTN = 'MSTN', - NWD = 'NWD', - OBD = 'OBD', - OPENTOWER = 'OPENTOWER', - PROSTRUCTURES = "PROSTRUCTURES", - REVIT = 'REVIT', - SPPID = 'SPPID', - SPXREVIEW = 'SPXREVIEW' + AUTOPLANT = 'AUTOPLANT', + CIVIL = 'CIVIL', + CIVIL3D = 'CIVIL3D', + DWG = 'DWG', + GEOSPATIAL = 'GEOSPATIAL', + IFC = 'IFC', + MSTN = 'MSTN', + NWD = 'NWD', + OBD = 'OBD', + OPENTOWER = 'OPENTOWER', + PROSTRUCTURES = "PROSTRUCTURES", + REVIT = 'REVIT', + SPPID = 'SPPID', + SPXREVIEW = 'SPXREVIEW' } diff --git a/src/services/synchronizationClient/models/execution-result.ts b/src/services/synchronizationClient/models/execution-result.ts index 5e96e3de..026f7e01 100644 --- a/src/services/synchronizationClient/models/execution-result.ts +++ b/src/services/synchronizationClient/models/execution-result.ts @@ -4,11 +4,11 @@ *--------------------------------------------------------------------------------------------*/ export enum ExecutionResult { - CANCELLED = "Cancelled", - ERROR = "Error", - PARTIAL_SUCCESS = "PartialSuccess", - SKIPPED = "Skipped", - SUCCESS = "Success", - TIMED_OUT = "TimedOut", - UNDETERMINED = "Undetermined" + CANCELLED = "Cancelled", + ERROR = "Error", + PARTIAL_SUCCESS = "PartialSuccess", + SKIPPED = "Skipped", + SUCCESS = "Success", + TIMED_OUT = "TimedOut", + UNDETERMINED = "Undetermined" } diff --git a/src/services/synchronizationClient/models/execution-state.ts b/src/services/synchronizationClient/models/execution-state.ts index 3360a6e0..90597344 100644 --- a/src/services/synchronizationClient/models/execution-state.ts +++ b/src/services/synchronizationClient/models/execution-state.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ export enum ExecutionState { - COMPLETED = "Completed", - EXECUTING = "Executing", - FINALIZING = "Finalizing", - IDLE = "Idle", - NOT_STARTED = "NotStarted", - QUEUED = "Queued", - WAITING_TO_EXECUTE = "WaitingToExecute", - WAITING_TO_RETRY = "WaitingToRetry" + COMPLETED = "Completed", + EXECUTING = "Executing", + FINALIZING = "Finalizing", + IDLE = "Idle", + NOT_STARTED = "NotStarted", + QUEUED = "Queued", + WAITING_TO_EXECUTE = "WaitingToExecute", + WAITING_TO_RETRY = "WaitingToRetry" } diff --git a/src/services/synchronizationClient/models/job-phase.ts b/src/services/synchronizationClient/models/job-phase.ts index 8d3e28c6..41ba567c 100644 --- a/src/services/synchronizationClient/models/job-phase.ts +++ b/src/services/synchronizationClient/models/job-phase.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ export enum JobPhase { - MASTER_FILE = "MasterFile", - PREPROCESSOR = "Preprocessor", - REFERENCE_FILE = "ReferenceFile" + MASTER_FILE = "MasterFile", + PREPROCESSOR = "Preprocessor", + REFERENCE_FILE = "ReferenceFile" } diff --git a/src/services/synchronizationClient/models/source-file.ts b/src/services/synchronizationClient/models/source-file.ts index 8f354b79..347b0ff1 100644 --- a/src/services/synchronizationClient/models/source-file.ts +++ b/src/services/synchronizationClient/models/source-file.ts @@ -3,27 +3,29 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -import { Link, Links } from "../../general-models/links.js" -import { ConnectorType } from "./connector-type.js" +import { Link, Links } from "../../general-models/links.js"; +import { ConnectorType } from "./connector-type.js"; export type SourceFile = { - _links: { - file: Link - } - id: string, - lastKnownFileName: string, -} & SourceFileInfo + // eslint-disable-next-line @typescript-eslint/naming-convention + _links: { + file: Link + } + id: string, + lastKnownFileName: string, +} & SourceFileInfo; -export type SourceFileInfo = { - connectorType: ConnectorType - storageFileId: string, +export interface SourceFileInfo { + connectorType: ConnectorType + storageFileId: string, } -export type SourceFileResponse = { - sourceFile: SourceFile; +export interface SourceFileResponse { + sourceFile: SourceFile; } -export type SourceFilesResponse = { - _links: Links - sourceFiles: SourceFile[]; +export interface SourceFilesResponse { + // eslint-disable-next-line @typescript-eslint/naming-convention + _links: Links + sourceFiles: SourceFile[]; } \ No newline at end of file diff --git a/src/services/synchronizationClient/models/storage-connection-create.ts b/src/services/synchronizationClient/models/storage-connection-create.ts index 1db51a98..3344c793 100644 --- a/src/services/synchronizationClient/models/storage-connection-create.ts +++ b/src/services/synchronizationClient/models/storage-connection-create.ts @@ -6,11 +6,11 @@ import { AuthenticationType } from "./authentication-type.js"; import { StorageFileCreate } from "./storage-file-create.js"; -export type StorageConnectionCreate = { - authenticationType?: AuthenticationType; - displayName?: string; - iModelId: string; - sourceFiles: Array; -}; +export interface StorageConnectionCreate { + authenticationType?: AuthenticationType; + displayName?: string; + iModelId: string; + sourceFiles: Array; +} diff --git a/src/services/synchronizationClient/models/storage-connection-response.ts b/src/services/synchronizationClient/models/storage-connection-response.ts index d47244a9..ca340f14 100644 --- a/src/services/synchronizationClient/models/storage-connection-response.ts +++ b/src/services/synchronizationClient/models/storage-connection-response.ts @@ -6,16 +6,17 @@ import { Links } from "../../general-models/links.js"; import { StorageConnection } from "./storage-connection.js"; -export type StorageConnectionResponse = { - connection?: StorageConnection; -}; +export interface StorageConnectionResponse { + connection?: StorageConnection; +} -export type StorageConnectionListResponse = { - _links: Links; - connections: StorageConnection[]; +export interface StorageConnectionListResponse { + // eslint-disable-next-line @typescript-eslint/naming-convention + _links: Links; + connections: StorageConnection[]; } -export type StorageConnectionUpdate = { - authenticationType?: 'Service' | 'User'; - displayName?: string; +export interface StorageConnectionUpdate { + authenticationType?: 'Service' | 'User'; + displayName?: string; } diff --git a/src/services/synchronizationClient/models/storage-connection.ts b/src/services/synchronizationClient/models/storage-connection.ts index d53b07d5..e1eff6c9 100644 --- a/src/services/synchronizationClient/models/storage-connection.ts +++ b/src/services/synchronizationClient/models/storage-connection.ts @@ -6,17 +6,18 @@ import { AuthenticationType } from "./authentication-type.js"; import { ConnectionLinks } from "./connection-links.js"; -export type StorageConnection = { - _links: ConnectionLinks; - authenticationType: AuthenticationType; - displayName: string; - error: StorageConnectionError - iModelId: string; - iTwinId: string; - id: string; -}; +export interface StorageConnection { + // eslint-disable-next-line @typescript-eslint/naming-convention + _links: ConnectionLinks; + authenticationType: AuthenticationType; + displayName: string; + error: StorageConnectionError + iModelId: string; + iTwinId: string; + id: string; +} -export type StorageConnectionError = { - description: string; - errorKey: string; +export interface StorageConnectionError { + description: string; + errorKey: string; } diff --git a/src/services/synchronizationClient/models/storage-file-create.ts b/src/services/synchronizationClient/models/storage-file-create.ts index e8b71334..2aa58b3a 100644 --- a/src/services/synchronizationClient/models/storage-file-create.ts +++ b/src/services/synchronizationClient/models/storage-file-create.ts @@ -5,7 +5,7 @@ import { ConnectorType } from "./connector-type.js"; -export type StorageFileCreate = { - connectorType: ConnectorType; - storageFileId: string; -}; +export interface StorageFileCreate { + connectorType: ConnectorType; + storageFileId: string; +} diff --git a/src/services/synchronizationClient/models/storage-job.ts b/src/services/synchronizationClient/models/storage-job.ts index c94d5219..69da48b8 100644 --- a/src/services/synchronizationClient/models/storage-job.ts +++ b/src/services/synchronizationClient/models/storage-job.ts @@ -6,12 +6,12 @@ import { ConnectorType } from "./connector-type.js"; import { StorageTask } from "./storage-task.js"; -export type StorageJob = { - connectorType?: ConnectorType; - endDateTime?: string; - id?: string; - result?: string; - startDateTime?: string; - state?: string; - tasks?: Array; -}; +export interface StorageJob { + connectorType?: ConnectorType; + endDateTime?: string; + id?: string; + result?: string; + startDateTime?: string; + state?: string; + tasks?: Array; +} diff --git a/src/services/synchronizationClient/models/storage-run-response.ts b/src/services/synchronizationClient/models/storage-run-response.ts index 129d18d1..c2fe9365 100644 --- a/src/services/synchronizationClient/models/storage-run-response.ts +++ b/src/services/synchronizationClient/models/storage-run-response.ts @@ -6,11 +6,12 @@ import { Links } from "../../general-models/links.js"; import { StorageRun } from "./storage-run.js"; -export type StorageRunResponse = { - run?: StorageRun; -}; +export interface StorageRunResponse { + run?: StorageRun; +} -export type StorageRunsResponse = { - _links: Links - runs: StorageRun[]; +export interface StorageRunsResponse { + // eslint-disable-next-line @typescript-eslint/naming-convention + _links: Links + runs: StorageRun[]; } diff --git a/src/services/synchronizationClient/models/storage-run.ts b/src/services/synchronizationClient/models/storage-run.ts index 36f5689f..35d5a6dd 100644 --- a/src/services/synchronizationClient/models/storage-run.ts +++ b/src/services/synchronizationClient/models/storage-run.ts @@ -8,13 +8,13 @@ import { ExecutionState } from "./execution-state.js"; import { JobPhase } from "./job-phase.js"; import { StorageJob } from "./storage-job.js"; -export type StorageRun = { - connectionId?: string; - endDateTime?: string; - id?: string; - jobs?: Array; - phase?: JobPhase; - result?: ExecutionResult; - startDateTime?: string; - state?: ExecutionState; -}; +export interface StorageRun { + connectionId?: string; + endDateTime?: string; + id?: string; + jobs?: Array; + phase?: JobPhase; + result?: ExecutionResult; + startDateTime?: string; + state?: ExecutionState; +} diff --git a/src/services/synchronizationClient/models/storage-task.ts b/src/services/synchronizationClient/models/storage-task.ts index fe0e7308..d93b45a4 100644 --- a/src/services/synchronizationClient/models/storage-task.ts +++ b/src/services/synchronizationClient/models/storage-task.ts @@ -5,13 +5,13 @@ import { TaskError } from "./task-error.js"; -export type StorageTask = { - endDateTime?: string; - error?: TaskError; - id?: string; - result?: string; - retryAttempts?: number; - startDateTime?: string; - state?: string; - storageFileId?: string; -}; +export interface StorageTask { + endDateTime?: string; + error?: TaskError; + id?: string; + result?: string; + retryAttempts?: number; + startDateTime?: string; + state?: string; + storageFileId?: string; +} diff --git a/src/services/synchronizationClient/models/task-error.ts b/src/services/synchronizationClient/models/task-error.ts index 363e9426..4d2a3728 100644 --- a/src/services/synchronizationClient/models/task-error.ts +++ b/src/services/synchronizationClient/models/task-error.ts @@ -3,16 +3,16 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -export type TaskError = { - bridgeExitCode?: number; - canUserFix?: boolean; - category?: string; - description?: string; - descriptionKey?: string; - details?: string; - errorCode?: string; - kbArticleLink?: string; - message?: string; - phase?: string; - system?: string; -}; +export interface TaskError { + bridgeExitCode?: number; + canUserFix?: boolean; + category?: string; + description?: string; + descriptionKey?: string; + details?: string; + errorCode?: string; + kbArticleLink?: string; + message?: string; + phase?: string; + system?: string; +} diff --git a/src/services/synchronizationClient/synchronization-api-client.ts b/src/services/synchronizationClient/synchronization-api-client.ts index 7d80a42f..5182d7f1 100644 --- a/src/services/synchronizationClient/synchronization-api-client.ts +++ b/src/services/synchronizationClient/synchronization-api-client.ts @@ -11,155 +11,156 @@ import { StorageConnectionListResponse, StorageConnectionResponse, StorageConnec import { StorageRunResponse, StorageRunsResponse } from "./models/storage-run-response.js"; export class SynchronizationApiClient { - iTwinPlatformApiClient: ITwinPlatformApiClient; - - constructor(client: ITwinPlatformApiClient) { - this.iTwinPlatformApiClient = client; - } - - addSourceFile(connectionId: string, sourceFile: SourceFileInfo): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `synchronization/imodels/storageconnections/${connectionId}/sourcefiles`, - body: sourceFile, - method: "POST" - }); - } - - authorizeUserForConnection(): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: 'synchronization/imodels/connections/authorizationinformation', - method: 'GET', - query: [ - { - key: 'redirectUrl', - value: 'http://localhost:3301/callback' - } - ] - }); - } - - createStorageConnection(connection: StorageConnectionCreate): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: 'synchronization/imodels/storageconnections', - body: connection, - method: 'POST' - }); - } - - async createStorageConnectionRun(connectionId: string) { - await this.iTwinPlatformApiClient.sendRequestNoResponse({ - apiPath: `synchronization/imodels/storageconnections/${connectionId}/run`, - method: "POST" - }); - } - - async deleteSourceFile(connectionId: string, sourceFileId: string): Promise { - await this.iTwinPlatformApiClient.sendRequestNoResponse({ - apiPath: `synchronization/imodels/storageconnections/${connectionId}/sourcefiles/${sourceFileId}`, - method: "DELETE", - }); - } - - async deleteStorageConnection(connectionId: string): Promise { - await this.iTwinPlatformApiClient.sendRequestNoResponse({ - apiPath: `synchronization/imodels/storageconnections/${connectionId}`, - method: "DELETE", - }); - } - - getSourceFile(connectionId: string, sourceFileId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `synchronization/imodels/storageconnections/${connectionId}/sourcefiles/${sourceFileId}`, - method: "GET" - }); - } - - getSourceFiles(connectionId: string, top?: number, skip?: number): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `synchronization/imodels/storageconnections/${connectionId}/sourcefiles`, - headers: { - "Prefer": "return=representation" - }, - method: "GET", - query: [ - { - key: '$top', - value: top - }, - { - key: '$skip', - value: skip - } - ] - }); - } - - getStorageConnection(connectionId: string): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `synchronization/imodels/storageconnections/${connectionId}`, - method: 'GET' - }); - } - - getStorageConnectionRun(connectionId: string, runId: string) : Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `synchronization/imodels/storageconnections/${connectionId}/runs/${runId}`, - method: "GET" - }); - } - - getStorageConnectionRuns(connectionId: string, top?: number, skip?: number): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `synchronization/imodels/storageconnections/${connectionId}/runs`, - method: "GET", - query: [ - { - key: '$top', - value: top - }, - { - key: '$skip', - value: skip - } - ] - }); - } - - getStorageConnections(iModelId: string, top?: number, skip?: number): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `synchronization/imodels/storageconnections`, - method: 'GET', - query: [ - { - key: 'imodelId', - value: iModelId - }, - { - key: '$top', - value: top - }, - { - key: '$skip', - value: skip - } - - ] - }); - } - - updateSourceFile(connectionId: string, sourceFileId: string, update: SourceFileInfo): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `synchronization/imodels/storageconnections/${connectionId}/sourcefiles/${sourceFileId}`, - body: update, - method: "PUT" - }); - } - - updateStorageConnection(connectionId: string, update: StorageConnectionUpdate): Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: `synchronization/imodels/storageconnections/${connectionId}`, - body: update, - method: "PUT" - }); - } + private _iTwinPlatformApiClient: ITwinPlatformApiClient; + + constructor(client: ITwinPlatformApiClient) { + this._iTwinPlatformApiClient = client; + } + + public async addSourceFile(connectionId: string, sourceFile: SourceFileInfo): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `synchronization/imodels/storageconnections/${connectionId}/sourcefiles`, + body: sourceFile, + method: "POST" + }); + } + + public async authorizeUserForConnection(): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: 'synchronization/imodels/connections/authorizationinformation', + method: 'GET', + query: [ + { + key: 'redirectUrl', + value: 'http://localhost:3301/callback' + } + ] + }); + } + + public async createStorageConnection(connection: StorageConnectionCreate): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: 'synchronization/imodels/storageconnections', + body: connection, + method: 'POST' + }); + } + + public async createStorageConnectionRun(connectionId: string) { + await this._iTwinPlatformApiClient.sendRequestNoResponse({ + apiPath: `synchronization/imodels/storageconnections/${connectionId}/run`, + method: "POST" + }); + } + + public async deleteSourceFile(connectionId: string, sourceFileId: string): Promise { + await this._iTwinPlatformApiClient.sendRequestNoResponse({ + apiPath: `synchronization/imodels/storageconnections/${connectionId}/sourcefiles/${sourceFileId}`, + method: "DELETE", + }); + } + + public async deleteStorageConnection(connectionId: string): Promise { + await this._iTwinPlatformApiClient.sendRequestNoResponse({ + apiPath: `synchronization/imodels/storageconnections/${connectionId}`, + method: "DELETE", + }); + } + + public async getSourceFile(connectionId: string, sourceFileId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `synchronization/imodels/storageconnections/${connectionId}/sourcefiles/${sourceFileId}`, + method: "GET" + }); + } + + public async getSourceFiles(connectionId: string, top?: number, skip?: number): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `synchronization/imodels/storageconnections/${connectionId}/sourcefiles`, + headers: { + // eslint-disable-next-line @typescript-eslint/naming-convention + Prefer: "return=representation" + }, + method: "GET", + query: [ + { + key: '$top', + value: top + }, + { + key: '$skip', + value: skip + } + ] + }); + } + + public async getStorageConnection(connectionId: string): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `synchronization/imodels/storageconnections/${connectionId}`, + method: 'GET' + }); + } + + public async getStorageConnectionRun(connectionId: string, runId: string) : Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `synchronization/imodels/storageconnections/${connectionId}/runs/${runId}`, + method: "GET" + }); + } + + public async getStorageConnectionRuns(connectionId: string, top?: number, skip?: number): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `synchronization/imodels/storageconnections/${connectionId}/runs`, + method: "GET", + query: [ + { + key: '$top', + value: top + }, + { + key: '$skip', + value: skip + } + ] + }); + } + + public async getStorageConnections(iModelId: string, top?: number, skip?: number): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `synchronization/imodels/storageconnections`, + method: 'GET', + query: [ + { + key: 'imodelId', + value: iModelId + }, + { + key: '$top', + value: top + }, + { + key: '$skip', + value: skip + } + + ] + }); + } + + public async updateSourceFile(connectionId: string, sourceFileId: string, update: SourceFileInfo): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `synchronization/imodels/storageconnections/${connectionId}/sourcefiles/${sourceFileId}`, + body: update, + method: "PUT" + }); + } + + public async updateStorageConnection(connectionId: string, update: StorageConnectionUpdate): Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: `synchronization/imodels/storageconnections/${connectionId}`, + body: update, + method: "PUT" + }); + } } diff --git a/src/services/user-client/models/user.ts b/src/services/user-client/models/user.ts index 3834ae00..4e953aa6 100644 --- a/src/services/user-client/models/user.ts +++ b/src/services/user-client/models/user.ts @@ -3,24 +3,24 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ -export type UserResponse = { - user: User +export interface UserResponse { + user: User } -export type UsersResponse = { - users: User[] +export interface UsersResponse { + users: User[] } -export type User = { - alternateEmail: string, - city?: string, - country: string, - createdDateTime: Date - displayName: string, - email: string, - givenName: string, - id: string, - language: string, - organizationName: string, - phone?: string, +export interface User { + alternateEmail: string, + city?: string, + country: string, + createdDateTime: Date + displayName: string, + email: string, + givenName: string, + id: string, + language: string, + organizationName: string, + phone?: string, } \ No newline at end of file diff --git a/src/services/user-client/user-api-client.ts b/src/services/user-client/user-api-client.ts index 37b8138a..5eeed0a2 100644 --- a/src/services/user-client/user-api-client.ts +++ b/src/services/user-client/user-api-client.ts @@ -7,38 +7,38 @@ import { ITwinPlatformApiClient, Query } from "../iTwin-api-client.js"; import { UserResponse, UsersResponse } from "./models/user.js"; export class UserApiClient { - iTwinPlatformApiClient: ITwinPlatformApiClient; + private _iTwinPlatformApiClient: ITwinPlatformApiClient; - constructor(client: ITwinPlatformApiClient) { - this.iTwinPlatformApiClient = client; - } + constructor(client: ITwinPlatformApiClient) { + this._iTwinPlatformApiClient = client; + } - async getMe() : Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: 'users/me', - method: 'GET' - }) - } + public async getMe() : Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: 'users/me', + method: 'GET' + }); + } - async getUsers(userIDs: string[]) : Promise { - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: 'users/getbyidlist', - body: userIDs, - method: 'POST' - }) - } + public async getUsers(userIDs: string[]) : Promise { + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: 'users/getbyidlist', + body: userIDs, + method: 'POST' + }); + } - async searchUsers(search: string) : Promise { - const query : Query[] = []; - query.push({ - key: "$search", - value: search - }); + public async searchUsers(search: string) : Promise { + const query : Query[] = []; + query.push({ + key: "$search", + value: search + }); - return this.iTwinPlatformApiClient.sendRequest({ - apiPath: 'users/', - method: 'GET', - query - }) - } + return this._iTwinPlatformApiClient.sendRequest({ + apiPath: 'users/', + method: 'GET', + query + }); + } } \ No newline at end of file diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json new file mode 100644 index 00000000..fd977405 --- /dev/null +++ b/tsconfig.eslint.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", + "include": ["./src/**/*", "./integration-tests/**/*", "./bin/*", "./eslint.config.mjs"], + "exclude": ["dist", "tmp"], +} diff --git a/tsconfig.json b/tsconfig.json index 6e3ab70e..05e9002d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,9 +8,11 @@ "target": "es2022", "moduleResolution": "node16", "composite": true, - "sourceMap": true + "sourceMap": true, + "allowJs": true, }, "include": ["./src/**/*"], + "exclude": ["dist", "./tmp/**","./bin/**", "./eslint.config.mjs"], "ts-node": { "esm": true }