From aa5e94d640fa23df80f21c65611f89306415434c Mon Sep 17 00:00:00 2001 From: Fabians Date: Tue, 29 Mar 2022 17:12:31 +0300 Subject: [PATCH] chore: reformatting everything with prettier --- .github/ISSUE_TEMPLATE/bug_report.md | 20 +- .github/ISSUE_TEMPLATE/feature_request.md | 1 - .github/workflows/close-issue.yml | 9 +- .github/workflows/open-issue.yml | 4 +- SECURITY.md | 2 +- docker-compose-speckle.yml | 59 +- lerna.json | 4 +- packages/fileimport-service/ifc/api.js | 155 ++-- .../fileimport-service/ifc/import_file.js | 64 +- packages/fileimport-service/ifc/parser.js | 335 +++++---- packages/fileimport-service/knex.js | 4 +- packages/fileimport-service/src/daemon.js | 162 +++-- packages/frontend/.vscode/launch.json | 2 +- packages/frontend/README.md | 1 + packages/frontend/babel.config.js | 4 +- .../frontend/src/graphql/objectSingle.gql | 2 +- .../src/graphql/objectSingleNoData.gql | 2 +- .../frontend/src/graphql/streamCommits.gql | 2 +- .../components/comments/CommentListItem.vue | 52 +- .../comments/CommentThreadViewer.vue | 99 +-- .../comments/CommentsViewerNavbar.vue | 4 +- .../components/common/CommitPreviewCard.vue | 17 +- .../components/common/StreamPreviewCard.vue | 12 +- .../main/components/feed/ListItemActivity.vue | 8 +- .../components/feed/ListItemActivity2.vue | 8 +- .../src/main/components/feed/Timeline.vue | 2 +- .../onboarding/GettingStartedSteps.vue | 3 +- .../stream/globals/GlobalsBuilder.vue | 2 +- .../stream/globals/GlobalsEntry.vue | 8 +- .../main/components/user/ListItemUserApp.vue | 4 +- .../components/user/UserAuthorisedApps.vue | 2 +- .../main/components/user/UserDeleteCard.vue | 2 +- .../src/main/components/viewer/Bubbles.vue | 24 +- .../components/viewer/CommentAddOverlay.vue | 2 +- .../components/viewer/CommentsOverlay.vue | 50 +- .../main/components/viewer/ResourceGroup.vue | 8 +- .../components/viewer/dialogs/AllCommits.vue | 2 +- .../src/main/dialogs/BranchEditDialog.vue | 4 +- .../frontend/src/main/dialogs/NewBranch.vue | 2 +- .../src/main/dialogs/ServerInvites.vue | 4 +- .../src/main/dialogs/StreamInviteDialog.vue | 4 +- .../src/main/pages/auth/AuthorizeApp.vue | 4 +- .../frontend/src/main/pages/auth/Login.vue | 2 +- .../frontend/src/main/pages/stream/Branch.vue | 22 +- .../src/main/pages/stream/Comments.vue | 28 +- .../main/pages/stream/CommitObjectViewer.vue | 2 +- .../src/main/pages/stream/Globals.vue | 2 +- .../src/main/pages/stream/Settings.vue | 4 +- .../src/main/pages/stream/StreamHome.vue | 13 +- packages/frontend/src/plugins/helpers.js | 1 - packages/frontend/src/sass/variables.scss | 35 +- .../objectloader/examples/browser/index.html | 28 +- .../objectloader/examples/browser/script.js | 18 +- packages/objectloader/examples/node/script.js | 14 +- packages/objectloader/readme.md | 12 +- packages/preview-service/app.js | 66 +- packages/preview-service/bg_service/index.js | 87 ++- packages/preview-service/knex.js | 4 +- packages/preview-service/readme.md | 1 + .../render_page/src/example.html | 28 +- packages/preview-service/routes/api.js | 42 +- packages/preview-service/routes/index.js | 8 +- packages/preview-service/routes/objects.js | 70 +- packages/preview-service/routes/preview.js | 122 ++-- .../routes/services/objects_utils.js | 63 +- .../routes/speckleObjectsStream.js | 32 +- packages/server/.vscode/launch.json | 10 +- packages/server/CHANGELOG.md | 676 +++++++++--------- packages/server/logging/apolloPlugin.js | 74 +- packages/server/logging/index.js | 26 +- packages/server/logging/matomoHelper.js | 36 +- packages/server/logging/sentryHelper.js | 14 +- .../graph/resolvers/activity.js | 112 ++- .../graph/schemas/activity.graphql | 47 +- .../20210616173000_stream_activity.js | 34 +- .../modules/activitystream/services/index.js | 190 ++--- .../activitystream/tests/activity.spec.js | 245 ++++--- packages/server/modules/apiexplorer/index.js | 16 +- packages/server/modules/auth/defaultApps.js | 80 +-- .../modules/auth/graph/resolvers/apps.js | 74 +- .../modules/auth/graph/resolvers/auth.js | 4 +- .../modules/auth/graph/schemas/apps.graphql | 15 +- .../modules/auth/graph/schemas/auth.graphql | 8 +- packages/server/modules/auth/index.js | 22 +- .../auth/migrations/2020-05-29-apps.js | 120 ++-- packages/server/modules/auth/rest/index.js | 124 ++-- packages/server/modules/auth/services/apps.js | 283 ++++---- packages/server/modules/auth/strategies.js | 111 +-- .../modules/auth/strategies/azure-ad.js | 106 +-- .../server/modules/auth/strategies/github.js | 135 ++-- .../server/modules/auth/strategies/google.js | 132 ++-- .../server/modules/auth/tests/apps.spec.js | 323 ++++++--- .../modules/auth/tests/appsGrapql.spec.js | 263 ++++--- .../comments/graph/resolvers/comments.js | 183 +++-- .../comments/graph/schemas/comments.gql | 51 +- packages/server/modules/comments/index.js | 8 +- .../migrations/20220222173000_comments.js | 16 +- .../server/modules/comments/services/index.js | 140 ++-- .../comments/tests/comments.graph.spec.js | 6 +- .../modules/comments/tests/comments.spec.js | 448 ++++++++---- .../modules/core/graph/directives/hasRole.js | 17 +- .../modules/core/graph/directives/hasScope.js | 29 +- .../modules/core/graph/resolvers/apitoken.js | 38 +- .../modules/core/graph/resolvers/branches.js | 154 ++-- .../modules/core/graph/resolvers/objects.js | 62 +- .../modules/core/graph/resolvers/server.js | 47 +- packages/server/modules/core/graph/scalars.js | 10 +- .../core/graph/schemas/apitoken.graphql | 14 +- .../core/graph/schemas/objects.graphql | 17 +- .../modules/core/graph/schemas/user.graphql | 2 +- packages/server/modules/core/index.js | 32 +- .../modules/core/migrations/000-core.js | 320 +++++---- ...20201222100048_add_sourceapp_to_commits.js | 16 +- ...01522_add_totalchildrencount_to_commits.js | 16 +- ...20532_add_commit_parents_simplification.js | 22 +- .../20201230111428_add_scopes_public_field.js | 20 +- .../20210225130308_add_roles_public_field.js | 20 +- ...314101154_add_invitefield_to_serverinfo.js | 20 +- .../20210322190000_add_streamid_to_objects.js | 174 +++-- ...20210603160000_optional_user_references.js | 32 +- .../20211119105730_de_duplicate_users.js | 149 ++-- .../server/modules/core/rest/authUtils.js | 53 +- .../server/modules/core/rest/diffDownload.js | 110 +-- .../server/modules/core/rest/diffUpload.js | 56 +- packages/server/modules/core/rest/download.js | 154 ++-- .../modules/core/rest/speckleObjectsStream.js | 32 +- packages/server/modules/core/rest/upload.js | 231 +++--- .../server/modules/core/services/branches.js | 85 ++- .../server/modules/core/services/generic.js | 55 +- .../server/modules/core/services/tokens.js | 114 +-- .../server/modules/core/services/users.js | 3 +- .../modules/core/tests/branches.spec.js | 188 +++-- .../server/modules/core/tests/commits.spec.js | 296 +++++--- .../server/modules/core/tests/init.spec.js | 78 +- .../server/modules/core/tests/objects.spec.js | 525 ++++++++------ .../server/modules/core/tests/rest.spec.js | 426 ++++++----- .../server/modules/core/tests/streams.spec.js | 288 ++++---- packages/server/modules/emails/index.js | 85 ++- .../20220118181256-email-verifications.js | 20 +- packages/server/modules/emails/rest/index.js | 98 ++- .../emails/tests/verifications.spec.js | 209 +++--- .../graph/resolvers/fileUploads.js | 13 +- .../graph/schemas/fileuploads.graphql | 69 +- packages/server/modules/fileuploads/index.js | 178 ++--- .../migrations/20210915130000-fileuploads.js | 38 +- .../fileuploads/services/fileuploads.js | 76 +- packages/server/modules/previews/index.js | 288 +++++--- .../migrations/20210426200000-previews.js | 36 +- packages/server/modules/previews/ogImage.js | 43 +- .../modules/previews/services/previews.js | 25 +- packages/server/modules/pwdreset/index.js | 14 +- .../migrations/20210304111614_pwdreset.js | 16 +- .../server/modules/pwdreset/rest/index.js | 107 +-- .../server/modules/pwdreset/services/index.js | 6 +- .../modules/pwdreset/tests/pwdrest.spec.js | 91 ++- .../graph/resolvers/serverInvites.js | 24 +- .../graph/schemas/serverInvites.graphql | 7 +- .../server/modules/serverinvites/index.js | 20 +- .../migrations/20210303185834_invites.js | 28 +- .../modules/serverinvites/services/index.js | 126 ++-- .../serverinvites/tests/serverInvites.spec.js | 324 +++++---- .../modules/stats/graph/resolvers/stats.js | 23 +- packages/server/modules/stats/index.js | 10 +- .../server/modules/stats/services/index.js | 41 +- .../webhooks/graph/schemas/webhooks.graphql | 2 +- .../migrations/20210701180000-webhooks.js | 50 +- .../modules/webhooks/services/webhooks.js | 148 ++-- .../modules/webhooks/tests/webhooks.spec.js | 331 +++++---- .../server/scripts/duplicateUserMigration.js | 157 ++-- packages/server/scripts/seedUsers.js | 27 +- packages/server/test/helpers.js | 67 +- packages/viewer/.babelrc | 2 +- packages/viewer/example/example.html | 149 ++-- packages/viewer/readme.md | 38 +- packages/viewer/src/app.js | 67 +- packages/viewer/src/assets/example.html | 148 ++-- packages/viewer/src/modules/EventEmitter.js | 24 +- .../viewer/src/modules/FilteringManager.js | 210 +++--- .../viewer/src/modules/InteractionHandler.js | 368 +++++----- .../viewer/src/modules/SceneObjectManager.js | 268 +++---- packages/viewer/src/modules/SceneObjects.js | 301 ++++---- packages/viewer/src/modules/SectionBox.js | 5 +- .../viewer/src/modules/SelectionHelper.js | 115 +-- packages/viewer/src/modules/Viewer.js | 183 ++--- .../viewer/src/modules/ViewerObjectLoader.js | 72 +- .../src/modules/context/CameraHanlder.js | 185 +++-- .../viewer/src/modules/converter/Converter.js | 580 ++++++++------- .../converter/MeshTriangulationHelper.js | 140 ++-- .../src/modules/converter/ObjectWrapper.js | 2 +- packages/webhook-service/src/knex.js | 4 +- packages/webhook-service/src/main.js | 94 ++- .../template-docker-compose.yml | 105 ++- utils/helm/speckle-server/values.yaml | 32 +- utils/helm/test-init.yml | 6 +- utils/helm/test-values.yml | 10 +- 195 files changed, 8784 insertions(+), 7021 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 0c29a1198..1be1b4829 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -4,7 +4,6 @@ about: Help improve Speckle! title: '' labels: bug assignees: '' - --- **What package are you referring to?** @@ -15,6 +14,7 @@ A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' @@ -27,18 +27,20 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **System Info** -If applicable, please fill in the below details - they help a lot! +If applicable, please fill in the below details - they help a lot! **Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] + +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- Version [e.g. 22] **Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] + +- Device: [e.g. iPhone6] +- OS: [e.g. iOS8.1] +- Browser [e.g. stock browser, safari] +- Version [e.g. 22] **Additional context** Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 31aed1557..d23811f2c 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -4,7 +4,6 @@ about: Suggest an idea for Speckle! title: '' labels: enhancement, question assignees: '' - --- **What package are you referring to?** diff --git a/.github/workflows/close-issue.yml b/.github/workflows/close-issue.yml index 094d6dff2..21a1d7a96 100644 --- a/.github/workflows/close-issue.yml +++ b/.github/workflows/close-issue.yml @@ -32,10 +32,10 @@ jobs: echo 'PROJECT_ID='$(jq '.data.organization.projectNext.id' project_data.json) >> $GITHUB_ENV echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV - + echo "$PROJECT_ID" echo "$STATUS_FIELD_ID" - + echo 'DONE_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .settings | fromjson | .options[] | select(.name== "Done") | .id' project_data.json) >> $GITHUB_ENV echo "$DONE_ID" @@ -52,9 +52,9 @@ jobs: } } }' -f project=$PROJECT_ID -f id=$ISSUE_ID --jq '.data.addProjectNextItem.projectNextItem.id')" - + echo 'ITEM_ID='$item_id >> $GITHUB_ENV - + - name: Update Status env: GITHUB_TOKEN: ${{secrets.GHPROJECT_TOKEN}} @@ -75,4 +75,3 @@ jobs: } } }' -f project=$PROJECT_ID -f status=$STATUS_FIELD_ID -f id=$ITEM_ID -f value=${{ env.DONE_ID }} - diff --git a/.github/workflows/open-issue.yml b/.github/workflows/open-issue.yml index 831d2b0e5..0c0943c66 100644 --- a/.github/workflows/open-issue.yml +++ b/.github/workflows/open-issue.yml @@ -32,7 +32,7 @@ jobs: echo 'PROJECT_ID='$(jq '.data.organization.projectNext.id' project_data.json) >> $GITHUB_ENV echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV - + - name: Add Issue to project env: GITHUB_TOKEN: ${{secrets.GHPROJECT_TOKEN}} @@ -46,5 +46,5 @@ jobs: } } }' -f project=$PROJECT_ID -f id=$ISSUE_ID --jq '.data.addProjectNextItem.projectNextItem.id')" - + echo 'ITEM_ID='$item_id >> $GITHUB_ENV diff --git a/SECURITY.md b/SECURITY.md index eef98c031..6485c32c8 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -9,4 +9,4 @@ ## Reporting a Vulnerability -Hi! If you've found something off, we'd be more than happy if you would report it via security@speckle.systems. We will work together with you to correctly identify the cause and implement a fix. Thanks for helping make Speckle safer! +Hi! If you've found something off, we'd be more than happy if you would report it via security@speckle.systems. We will work together with you to correctly identify the cause and implement a fix. Thanks for helping make Speckle safer! diff --git a/docker-compose-speckle.yml b/docker-compose-speckle.yml index cc3268352..757559624 100644 --- a/docker-compose-speckle.yml +++ b/docker-compose-speckle.yml @@ -1,6 +1,5 @@ -version: "2" +version: '2' services: - speckle-frontend: build: context: . @@ -8,7 +7,7 @@ services: image: speckle/speckle-frontend:local restart: always ports: - - "0.0.0.0:80:80" + - '0.0.0.0:80:80' speckle-server: build: @@ -18,26 +17,26 @@ services: restart: always environment: # TODO: Change this to the URL of the speckle server, as accessed from the network - CANONICAL_URL: "http://localhost" + CANONICAL_URL: 'http://localhost' # TODO: Change this to a unique secret for this server - SESSION_SECRET: "TODO:Replace" + SESSION_SECRET: 'TODO:Replace' - STRATEGY_LOCAL: "true" - DEBUG: "speckle:*" + STRATEGY_LOCAL: 'true' + DEBUG: 'speckle:*' - POSTGRES_URL: "postgres" - POSTGRES_USER: "speckle" - POSTGRES_PASSWORD: "speckle" - POSTGRES_DB: "speckle" + POSTGRES_URL: 'postgres' + POSTGRES_USER: 'speckle' + POSTGRES_PASSWORD: 'speckle' + POSTGRES_DB: 'speckle' - REDIS_URL: "redis://redis" + REDIS_URL: 'redis://redis' - S3_ENDPOINT: "http://minio:9000" - S3_ACCESS_KEY: "minioadmin" - S3_SECRET_KEY: "minioadmin" - S3_BUCKET: "speckle-server" - S3_CREATE_BUCKET: "true" + S3_ENDPOINT: 'http://minio:9000' + S3_ACCESS_KEY: 'minioadmin' + S3_SECRET_KEY: 'minioadmin' + S3_BUCKET: 'speckle-server' + S3_CREATE_BUCKET: 'true' preview-service: build: @@ -45,11 +44,11 @@ services: dockerfile: packages/preview-service/Dockerfile image: speckle/speckle-preview-service:local restart: always - mem_limit: "3000m" - memswap_limit: "3000m" + mem_limit: '3000m' + memswap_limit: '3000m' environment: - DEBUG: "preview-service:*" - PG_CONNECTION_STRING: "postgres://speckle:speckle@postgres/speckle" + DEBUG: 'preview-service:*' + PG_CONNECTION_STRING: 'postgres://speckle:speckle@postgres/speckle' webhook-service: build: @@ -58,8 +57,8 @@ services: image: speckle/speckle-webhook-service:local restart: always environment: - DEBUG: "webhook-service:*" - PG_CONNECTION_STRING: "postgres://speckle:speckle@postgres/speckle" + DEBUG: 'webhook-service:*' + PG_CONNECTION_STRING: 'postgres://speckle:speckle@postgres/speckle' fileimport-service: build: @@ -68,12 +67,12 @@ services: image: speckle/speckle-fileimport-service:local restart: always environment: - DEBUG: "fileimport-service:*" - PG_CONNECTION_STRING: "postgres://speckle:speckle@postgres/speckle" + DEBUG: 'fileimport-service:*' + PG_CONNECTION_STRING: 'postgres://speckle:speckle@postgres/speckle' - S3_ENDPOINT: "http://minio:9000" - S3_ACCESS_KEY: "minioadmin" - S3_SECRET_KEY: "minioadmin" - S3_BUCKET: "speckle-server" + S3_ENDPOINT: 'http://minio:9000' + S3_ACCESS_KEY: 'minioadmin' + S3_SECRET_KEY: 'minioadmin' + S3_BUCKET: 'speckle-server' - SPECKLE_SERVER_URL: "http://speckle-server:3000" + SPECKLE_SERVER_URL: 'http://speckle-server:3000' diff --git a/lerna.json b/lerna.json index a2bb50ba7..7926728a6 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,4 @@ { - "packages": [ - "packages/*" - ], + "packages": ["packages/*"], "version": "independent" } diff --git a/packages/fileimport-service/ifc/api.js b/packages/fileimport-service/ifc/api.js index bb9c430b4..075a66dc3 100644 --- a/packages/fileimport-service/ifc/api.js +++ b/packages/fileimport-service/ifc/api.js @@ -1,49 +1,52 @@ 'use strict' -const crypto = require( 'crypto' ) -const crs = require( 'crypto-random-string' ) -const bcrypt = require( 'bcrypt' ) +const crypto = require('crypto') +const crs = require('crypto-random-string') +const bcrypt = require('bcrypt') -const knex = require( '../knex' ) -const Streams = ( ) => knex( 'streams' ) -const Branches = ( ) => knex( 'branches' ) -const Objects = ( ) => knex( 'objects' ) -const Closures = ( ) => knex( 'object_children_closure' ) -const ApiTokens = ( ) => knex( 'api_tokens' ) -const TokenScopes = ( ) => knex( 'token_scopes' ) +const knex = require('../knex') +const Streams = () => knex('streams') +const Branches = () => knex('branches') +const Objects = () => knex('objects') +const Closures = () => knex('object_children_closure') +const ApiTokens = () => knex('api_tokens') +const TokenScopes = () => knex('token_scopes') module.exports = class ServerAPI { - - constructor( { streamId } ) { + constructor({ streamId }) { this.streamId = streamId this.isSending = false this.buffer = [] } - async saveObject( obj ) { - if( !obj ) throw new Error( 'Null object' ) - - if( !obj.id ) { - obj.id = crypto.createHash( 'md5' ).update( JSON.stringify( obj ) ).digest( 'hex' ) + async saveObject(obj) { + if (!obj) throw new Error('Null object') + + if (!obj.id) { + obj.id = crypto.createHash('md5').update(JSON.stringify(obj)).digest('hex') } - - await this.createObject( this.streamId, obj ) + + await this.createObject(this.streamId, obj) return obj.id - } + } - async createObject( streamId, object ) { - let insertionObject = this.prepInsertionObject( streamId, object ) + async createObject(streamId, object) { + let insertionObject = this.prepInsertionObject(streamId, object) - let closures = [ ] + let closures = [] let totalChildrenCountByDepth = {} - if ( object.__closure !== null ) { - for ( const prop in object.__closure ) { - closures.push( { streamId: streamId, parent: insertionObject.id, child: prop, minDepth: object.__closure[ prop ] } ) + if (object.__closure !== null) { + for (const prop in object.__closure) { + closures.push({ + streamId: streamId, + parent: insertionObject.id, + child: prop, + minDepth: object.__closure[prop] + }) - if ( totalChildrenCountByDepth[ object.__closure[ prop ].toString( ) ] ) - totalChildrenCountByDepth[ object.__closure[ prop ].toString( ) ]++ - else - totalChildrenCountByDepth[ object.__closure[ prop ].toString( ) ] = 1 + if (totalChildrenCountByDepth[object.__closure[prop].toString()]) + totalChildrenCountByDepth[object.__closure[prop].toString()]++ + else totalChildrenCountByDepth[object.__closure[prop].toString()] = 1 } } @@ -51,30 +54,28 @@ module.exports = class ServerAPI { delete insertionObject.__closure insertionObject.totalChildrenCount = closures.length - insertionObject.totalChildrenCountByDepth = JSON.stringify( totalChildrenCountByDepth ) + insertionObject.totalChildrenCountByDepth = JSON.stringify(totalChildrenCountByDepth) - let q1 = Objects( ).insert( insertionObject ).toString( ) + ' on conflict do nothing' - await knex.raw( q1 ) + let q1 = Objects().insert(insertionObject).toString() + ' on conflict do nothing' + await knex.raw(q1) - if ( closures.length > 0 ) { - let q2 = `${ Closures().insert( closures ).toString() } on conflict do nothing` - await knex.raw( q2 ) + if (closures.length > 0) { + let q2 = `${Closures().insert(closures).toString()} on conflict do nothing` + await knex.raw(q2) } return insertionObject.id } - prepInsertionObject( streamId, obj ) { + prepInsertionObject(streamId, obj) { const MAX_OBJECT_SIZE = 10 * 1024 * 1024 - if ( obj.hash ) - obj.id = obj.hash - else - obj.id = obj.id || crypto.createHash( 'md5' ).update( JSON.stringify( obj ) ).digest( 'hex' ) // generate a hash if none is present + if (obj.hash) obj.id = obj.hash + else obj.id = obj.id || crypto.createHash('md5').update(JSON.stringify(obj)).digest('hex') // generate a hash if none is present - let stringifiedObj = JSON.stringify( obj ) - if ( stringifiedObj.length > MAX_OBJECT_SIZE ) { - throw new Error( `Object too large (${stringifiedObj.length} > ${MAX_OBJECT_SIZE})` ) + let stringifiedObj = JSON.stringify(obj) + if (stringifiedObj.length > MAX_OBJECT_SIZE) { + throw new Error(`Object too large (${stringifiedObj.length} > ${MAX_OBJECT_SIZE})`) } return { @@ -85,41 +86,44 @@ module.exports = class ServerAPI { } } - - async getBranchByNameAndStreamId( { streamId, name } ) { - let query = Branches( ).select( '*' ).where( { streamId: streamId } ).andWhere( knex.raw( 'LOWER(name) = ?', [ name ] ) ).first( ) + async getBranchByNameAndStreamId({ streamId, name }) { + let query = Branches() + .select('*') + .where({ streamId: streamId }) + .andWhere(knex.raw('LOWER(name) = ?', [name])) + .first() return await query } - async createBranch( { name, description, streamId, authorId } ) { - let branch = {} - branch.id = crs( { length: 10 } ) - branch.streamId = streamId - branch.authorId = authorId - branch.name = name.toLowerCase( ) - branch.description = description + async createBranch({ name, description, streamId, authorId }) { + let branch = {} + branch.id = crs({ length: 10 }) + branch.streamId = streamId + branch.authorId = authorId + branch.name = name.toLowerCase() + branch.description = description - await Branches( ).returning( 'id' ).insert( branch ) + await Branches().returning('id').insert(branch) - // update stream updated at - await Streams().where( { id: streamId } ).update( { updatedAt: knex.fn.now() } ) + // update stream updated at + await Streams().where({ id: streamId }).update({ updatedAt: knex.fn.now() }) - return branch.id + return branch.id } - async createBareToken( ) { - let tokenId = crs( { length: 10 } ) - let tokenString = crs( { length: 32 } ) - let tokenHash = await bcrypt.hash( tokenString, 10 ) - let lastChars = tokenString.slice( tokenString.length - 6, tokenString.length ) + async createBareToken() { + let tokenId = crs({ length: 10 }) + let tokenString = crs({ length: 32 }) + let tokenHash = await bcrypt.hash(tokenString, 10) + let lastChars = tokenString.slice(tokenString.length - 6, tokenString.length) return { tokenId, tokenString, tokenHash, lastChars } } - async createToken( { userId, name, scopes, lifespan } ) { - let { tokenId, tokenString, tokenHash, lastChars } = await this.createBareToken( ) + async createToken({ userId, name, scopes, lifespan }) { + let { tokenId, tokenString, tokenHash, lastChars } = await this.createBareToken() - if ( scopes.length === 0 ) throw new Error( 'No scopes provided' ) + if (scopes.length === 0) throw new Error('No scopes provided') let token = { id: tokenId, @@ -129,21 +133,20 @@ module.exports = class ServerAPI { name: name, lifespan: lifespan } - let tokenScopes = scopes.map( scope => ( { tokenId: tokenId, scopeName: scope } ) ) + let tokenScopes = scopes.map((scope) => ({ tokenId: tokenId, scopeName: scope })) - await ApiTokens( ).insert( token ) - await TokenScopes( ).insert( tokenScopes ) + await ApiTokens().insert(token) + await TokenScopes().insert(tokenScopes) return { id: tokenId, token: tokenId + tokenString } } - async revokeTokenById( tokenId ) { - let delCount = await ApiTokens( ).where( { id: tokenId.slice( 0, 10 ) } ).del( ) + async revokeTokenById(tokenId) { + let delCount = await ApiTokens() + .where({ id: tokenId.slice(0, 10) }) + .del() - if ( delCount === 0 ) - throw new Error( 'Token revokation failed' ) + if (delCount === 0) throw new Error('Token revokation failed') return true } - - -} \ No newline at end of file +} diff --git a/packages/fileimport-service/ifc/import_file.js b/packages/fileimport-service/ifc/import_file.js index c789de66f..2c923d715 100644 --- a/packages/fileimport-service/ifc/import_file.js +++ b/packages/fileimport-service/ifc/import_file.js @@ -1,47 +1,47 @@ -const fs = require( 'fs' ) +const fs = require('fs') const TMP_RESULTS_PATH = '/tmp/import_result.json' -const { parseAndCreateCommit } = require( './index' ) +const { parseAndCreateCommit } = require('./index') async function main() { - let cmdArgs = process.argv.slice( 2 ) + let cmdArgs = process.argv.slice(2) - let [ filePath, userId, streamId, branchName, commitMessage ] = cmdArgs + let [filePath, userId, streamId, branchName, commitMessage] = cmdArgs - console.log( 'ARGV: ', filePath, userId, streamId, branchName, commitMessage ) + console.log('ARGV: ', filePath, userId, streamId, branchName, commitMessage) - const data = fs.readFileSync( filePath ) + const data = fs.readFileSync(filePath) - let ifcInput = { - data, - streamId: streamId, - userId: userId, - message: commitMessage || 'Imported file' + let ifcInput = { + data, + streamId: streamId, + userId: userId, + message: commitMessage || 'Imported file' + } + if (branchName) ifcInput.branchName = branchName + + let output = { + success: false, + error: 'Unknown error' + } + + try { + let commitId = await parseAndCreateCommit(ifcInput) + output = { + success: true, + commitId } - if ( branchName ) ifcInput.branchName = branchName - - let output = { - success: false, - error: 'Unknown error' + } catch (err) { + output = { + success: false, + error: err.toString() } + } - try { - let commitId = await parseAndCreateCommit( ifcInput ) - output = { - success: true, - commitId - } - } catch ( err ) { - output = { - success: false, - error: err.toString() - } - } - - fs.writeFileSync( TMP_RESULTS_PATH, JSON.stringify( output ) ) - - process.exit( 0 ) + fs.writeFileSync(TMP_RESULTS_PATH, JSON.stringify(output)) + + process.exit(0) } main() diff --git a/packages/fileimport-service/ifc/parser.js b/packages/fileimport-service/ifc/parser.js index 55cb71974..7e702599b 100644 --- a/packages/fileimport-service/ifc/parser.js +++ b/packages/fileimport-service/ifc/parser.js @@ -1,118 +1,129 @@ -const WebIFC = require( 'web-ifc/web-ifc-api-node' ) -const ServerAPI = require( './api.js' ) +const WebIFC = require('web-ifc/web-ifc-api-node') +const ServerAPI = require('./api.js') module.exports = class IFCParser { - - constructor( { serverApi } ) { + constructor({ serverApi }) { this.api = new WebIFC.IfcAPI() this.serverApi = serverApi || new ServerAPI() } - async parse( data ) { - if ( this.api.wasmModule === undefined ) await this.api.Init() + async parse(data) { + if (this.api.wasmModule === undefined) await this.api.Init() - this.modelId = this.api.OpenModel( data, { COORDINATE_TO_ORIGIN: true, USE_FAST_BOOLS: true } ) + this.modelId = this.api.OpenModel(data, { COORDINATE_TO_ORIGIN: true, USE_FAST_BOOLS: true }) - this.projectId = this.api.GetLineIDsWithType( this.modelId, WebIFC.IFCPROJECT ).get( 0 ) + this.projectId = this.api.GetLineIDsWithType(this.modelId, WebIFC.IFCPROJECT).get(0) - this.project = this.api.GetLine( this.modelId, this.projectId, true ) + this.project = this.api.GetLine(this.modelId, this.projectId, true) this.project.__closure = {} - + this.cache = {} this.closureCache = {} - // Steps: create and store in speckle all the geometries (meshes) from this project and store them + // Steps: create and store in speckle all the geometries (meshes) from this project and store them // as reference objects in this.productGeo this.productGeo = {} - await this.createGeometries() - console.log( `Geometries created: ${Object.keys( this.productGeo ).length} meshes.` ) - - // Lastly, traverse the ifc project object and parse it into something friendly; as well as + await this.createGeometries() + console.log(`Geometries created: ${Object.keys(this.productGeo).length} meshes.`) + + // Lastly, traverse the ifc project object and parse it into something friendly; as well as // replace all its geometries with actual references to speckle meshes from the productGeo map - - await this.traverse( this.project, true, 0 ) - - let id = await this.serverApi.saveObject( this.project ) - return { id, tCount: Object.keys( this.project.__closure ).length } + + await this.traverse(this.project, true, 0) + + let id = await this.serverApi.saveObject(this.project) + return { id, tCount: Object.keys(this.project.__closure).length } } async createGeometries() { - this.rawGeo = this.api.LoadAllGeometry( this.modelId ) - - for( let i = 0; i < this.rawGeo.size(); i++ ) { - const mesh = this.rawGeo.get( i ) - const prodId = mesh.expressID - this.productGeo[prodId ] = [] - - for( let j = 0; j < mesh.geometries.size(); j++ ) { - let placedGeom = mesh.geometries.get( j ) - let geom = this.api.GetGeometry( this.modelId, placedGeom.geometryExpressID ) + this.rawGeo = this.api.LoadAllGeometry(this.modelId) - let matrix = placedGeom.flatTransformation + for (let i = 0; i < this.rawGeo.size(); i++) { + const mesh = this.rawGeo.get(i) + const prodId = mesh.expressID + this.productGeo[prodId] = [] + + for (let j = 0; j < mesh.geometries.size(); j++) { + let placedGeom = mesh.geometries.get(j) + let geom = this.api.GetGeometry(this.modelId, placedGeom.geometryExpressID) + + let matrix = placedGeom.flatTransformation let raw = { color: geom.color, // NOTE: material: x, y, z = rgb, w = opacity - vertices: this.api.GetVertexArray( geom.GetVertexData(), geom.GetVertexDataSize() ), - indices: this.api.GetIndexArray( geom.GetIndexData(), geom.GetIndexDataSize() ) + vertices: this.api.GetVertexArray(geom.GetVertexData(), geom.GetVertexDataSize()), + indices: this.api.GetIndexArray(geom.GetIndexData(), geom.GetIndexDataSize()) } - - const { vertices } = this.extractVertexData( raw.vertices ) - for( let k = 0; k < vertices.length; k += 3 ) { - let x = vertices[k], y = vertices[k + 1], z = vertices[k + 2] - vertices[k] = matrix[0] * x + matrix[4] * y + matrix[8] * z + matrix[12] - vertices[k + 1] = ( matrix[2] * x + matrix[6] * y + matrix[10] * z + matrix[14] ) * -1 + const { vertices } = this.extractVertexData(raw.vertices) + + for (let k = 0; k < vertices.length; k += 3) { + let x = vertices[k], + y = vertices[k + 1], + z = vertices[k + 2] + vertices[k] = matrix[0] * x + matrix[4] * y + matrix[8] * z + matrix[12] + vertices[k + 1] = (matrix[2] * x + matrix[6] * y + matrix[10] * z + matrix[14]) * -1 vertices[k + 2] = matrix[1] * x + matrix[5] * y + matrix[9] * z + matrix[13] } // Since all faces are triangles, we must add a `0` before each group of 3. - let spcklFaces = [ ] - for ( let i = 0; i < raw.indices.length; i++ ) { - if( i % 3 === 0 ) - spcklFaces.push( 0 ) - spcklFaces.push( raw.indices[i] ) + let spcklFaces = [] + for (let i = 0; i < raw.indices.length; i++) { + if (i % 3 === 0) spcklFaces.push(0) + spcklFaces.push(raw.indices[i]) } // Create a propper Speckle Mesh - let spcklMesh = { + let spcklMesh = { speckle_type: 'Objects.Geometry.Mesh', units: 'm', volume: 0, area: 0, faces: spcklFaces, - vertices: Array.from( vertices ), - renderMaterial: placedGeom.color ? this.colorToMaterial( placedGeom.color ) : null + vertices: Array.from(vertices), + renderMaterial: placedGeom.color ? this.colorToMaterial(placedGeom.color) : null } - - let id = await this.serverApi.saveObject( spcklMesh ) + + let id = await this.serverApi.saveObject(spcklMesh) let ref = { speckle_type: 'reference', referencedId: id } - this.productGeo[prodId].push( ref ) + this.productGeo[prodId].push(ref) } } } - async traverse( element, recursive = true, depth = 0, specialTypes = [ { type: 'IfcProject', key: 'Name' }, { type: 'IfcBuilding', key: 'Name' }, { type: 'IfcSite', key: 'Name' } ] ) { - + async traverse( + element, + recursive = true, + depth = 0, + specialTypes = [ + { type: 'IfcProject', key: 'Name' }, + { type: 'IfcBuilding', key: 'Name' }, + { type: 'IfcSite', key: 'Name' } + ] + ) { // Fast exit if null/undefined - if ( !element ) return + if (!element) return - // If array, traverse all items in it. - if( Array.isArray( element ) ) { - return await Promise.all( element.map( async el => await this.traverse( el,recursive, depth + 1 , specialTypes ) ) ) + if (Array.isArray(element)) { + return await Promise.all( + element.map(async (el) => await this.traverse(el, recursive, depth + 1, specialTypes)) + ) } - // If it has no expressID, its either a simple type or a { type, value } object. - if( !element.expressID ) { - return await Promise.resolve( element.value !== null && element.value !== undefined ? element.value : element ) + // If it has no expressID, its either a simple type or a { type, value } object. + if (!element.expressID) { + return await Promise.resolve( + element.value !== null && element.value !== undefined ? element.value : element + ) } - if( this.cache[element.expressID.toString()] ) return this.cache[element.expressID.toString()] + if (this.cache[element.expressID.toString()]) return this.cache[element.expressID.toString()] // If you got here -> It's an IFC Element: create base object, upload and return ref. // console.log( `Traversing element ${element.expressID}; Recurse: ${recursive}; Stack ${depth}` ) // Traverse all key/value pairs first. - for( let key of Object.keys( element ) ) { - element[key] = await this.traverse( element[key], recursive, depth + 1, specialTypes ) + for (let key of Object.keys(element)) { + element[key] = await this.traverse(element[key], recursive, depth + 1, specialTypes) } // Assign speckle_type and empty closure table. @@ -120,50 +131,124 @@ module.exports = class IFCParser { element.__closure = {} // Find spatial children and assign to element - const spatialChildrenIds = this.getAllRelatedItemsOfType( element.expressID, WebIFC.IFCRELAGGREGATES, 'RelatingObject', 'RelatedObjects' ) - if( spatialChildrenIds.length > 0 ) element.rawSpatialChildren = spatialChildrenIds.map( ( childId ) => this.api.GetLine( this.modelId, childId, true ) ) + const spatialChildrenIds = this.getAllRelatedItemsOfType( + element.expressID, + WebIFC.IFCRELAGGREGATES, + 'RelatingObject', + 'RelatedObjects' + ) + if (spatialChildrenIds.length > 0) + element.rawSpatialChildren = spatialChildrenIds.map((childId) => + this.api.GetLine(this.modelId, childId, true) + ) // Find children and populate element - const childrenIds = this.getAllRelatedItemsOfType( element.expressID, WebIFC.IFCRELCONTAINEDINSPATIALSTRUCTURE, 'RelatingStructure', 'RelatedElements' ) - if( childrenIds.length > 0 ) element.rawChildren = childrenIds.map( ( childId ) => this.api.GetLine( this.modelId, childId, true ) ) - + const childrenIds = this.getAllRelatedItemsOfType( + element.expressID, + WebIFC.IFCRELCONTAINEDINSPATIALSTRUCTURE, + 'RelatingStructure', + 'RelatedElements' + ) + if (childrenIds.length > 0) + element.rawChildren = childrenIds.map((childId) => + this.api.GetLine(this.modelId, childId, true) + ) + // Find related property sets - const psetsIds = this.getAllRelatedItemsOfType( element.expressID, WebIFC.IFCRELDEFINESBYPROPERTIES, 'RelatingPropertyDefinition', 'RelatedObjects' ) - if( psetsIds.length > 0 ) element.rawPsets = psetsIds.map( ( childId ) => this.api.GetLine( this.modelId, childId, true ) ) + const psetsIds = this.getAllRelatedItemsOfType( + element.expressID, + WebIFC.IFCRELDEFINESBYPROPERTIES, + 'RelatingPropertyDefinition', + 'RelatedObjects' + ) + if (psetsIds.length > 0) + element.rawPsets = psetsIds.map((childId) => this.api.GetLine(this.modelId, childId, true)) // Find related type properties - const typePropsId = this.getAllRelatedItemsOfType( element.expressID, WebIFC.IFCRELDEFINESBYTYPE, 'RelatingType', 'RelatedObjects' ) - if( typePropsId.length > 0 ) element.rawTypeProps = typePropsId.map( ( childId ) => this.api.GetLine( this.modelId, childId, true ) ) + const typePropsId = this.getAllRelatedItemsOfType( + element.expressID, + WebIFC.IFCRELDEFINESBYTYPE, + 'RelatingType', + 'RelatedObjects' + ) + if (typePropsId.length > 0) + element.rawTypeProps = typePropsId.map((childId) => + this.api.GetLine(this.modelId, childId, true) + ) // Lookup geometry in generated geometries object - if( this.productGeo[element.expressID] ) { + if (this.productGeo[element.expressID]) { element['@displayValue'] = this.productGeo[element.expressID] - this.productGeo[element.expressID].forEach( ref => { - this.project.__closure[ref.referencedId.toString()] = depth + this.productGeo[element.expressID].forEach((ref) => { + this.project.__closure[ref.referencedId.toString()] = depth element.__closure[ref.referencedId.toString()] = 1 - } ) + }) } - const isSpecial = specialTypes.find( t => t.type === element.speckle_type ) + const isSpecial = specialTypes.find((t) => t.type === element.speckle_type) // Recurse all children - if ( recursive ) { - await this.processSubElements( element, 'rawSpatialChildren', 'spatialChildren', isSpecial, recursive, depth, specialTypes ) - await this.processSubElements( element, 'rawChildren', 'children', isSpecial, recursive, depth, specialTypes ) - await this.processSubElements( element, 'rawPsets', 'propertySets', false, recursive, depth, specialTypes ) - await this.processSubElements( element, 'rawTypeProps', 'typeProps', false, recursive, depth, specialTypes ) + if (recursive) { + await this.processSubElements( + element, + 'rawSpatialChildren', + 'spatialChildren', + isSpecial, + recursive, + depth, + specialTypes + ) + await this.processSubElements( + element, + 'rawChildren', + 'children', + isSpecial, + recursive, + depth, + specialTypes + ) + await this.processSubElements( + element, + 'rawPsets', + 'propertySets', + false, + recursive, + depth, + specialTypes + ) + await this.processSubElements( + element, + 'rawTypeProps', + 'typeProps', + false, + recursive, + depth, + specialTypes + ) - if( element.children || element.spatialChildren || element.propertySets || element.typeProps ) { - console.log( `${element.constructor.name} ${element.GlobalId}:\n\tchildren count: ${ element.children ? element.children.length : '0'};\n\tspatial children count: ${element.spatialChildren ? element.spatialChildren.length : '0'};\n\tproperty sets count: ${element.propertySets ? element.propertySets.length : 0};\n\ttype properties: ${element.typeProps ? element.typeProps.length : 0}` ) + if ( + element.children || + element.spatialChildren || + element.propertySets || + element.typeProps + ) { + console.log( + `${element.constructor.name} ${element.GlobalId}:\n\tchildren count: ${ + element.children ? element.children.length : '0' + };\n\tspatial children count: ${ + element.spatialChildren ? element.spatialChildren.length : '0' + };\n\tproperty sets count: ${ + element.propertySets ? element.propertySets.length : 0 + };\n\ttype properties: ${element.typeProps ? element.typeProps.length : 0}` + ) } - } - if( this.productGeo[element.expressID] || element.spatialChildren || element.children ) { - let id = await this.serverApi.saveObject( element ) + if (this.productGeo[element.expressID] || element.spatialChildren || element.children) { + let id = await this.serverApi.saveObject(element) let ref = { speckle_type: 'reference', referencedId: id } this.cache[element.expressID.toString()] = ref this.closureCache[element.expressID.toString()] = element.__closure - return ref + return ref } else { this.cache[element.expressID.toString()] = element this.closureCache[element.expressID.toString()] = element.__closure @@ -171,33 +256,26 @@ module.exports = class IFCParser { } } - - async processSubElements( element, key, newKey, isSpecial, recursive, depth, specialTypes ) { - if ( element[key] ) { - if ( !isSpecial ) - element[newKey] = [] + async processSubElements(element, key, newKey, isSpecial, recursive, depth, specialTypes) { + if (element[key]) { + if (!isSpecial) element[newKey] = [] let childCount = {} - for ( let child of element[key] ) { - let res = await this.traverse( child, recursive, depth + 1, specialTypes ) - if ( res.referencedId ) { - if ( isSpecial ) { + for (let child of element[key]) { + let res = await this.traverse(child, recursive, depth + 1, specialTypes) + if (res.referencedId) { + if (isSpecial) { let name = child[isSpecial.key] - if ( !name || name.length === 0 ) - name = 'Undefined' - if ( !childCount[name] ) - childCount[name] = 0 - if ( childCount[name] > 0 ) - name += '-' + childCount[name]++ + if (!name || name.length === 0) name = 'Undefined' + if (!childCount[name]) childCount[name] = 0 + if (childCount[name] > 0) name += '-' + childCount[name]++ element[name] = res - } - else - element[newKey].push( res ) + } else element[newKey].push(res) this.project.__closure[res.referencedId.toString()] = depth element.__closure[res.referencedId.toString()] = 1 // adds to parent (this element) the child's closure tree. - if ( this.closureCache[child.expressID.toString()] ) { - for ( let key of Object.keys( this.closureCache[child.expressID.toString()] ) ) { + if (this.closureCache[child.expressID.toString()]) { + for (let key of Object.keys(this.closureCache[child.expressID.toString()])) { element.__closure[key] = this.closureCache[child.expressID.toString()][key] + 1 } } @@ -208,46 +286,47 @@ module.exports = class IFCParser { } // (c) https://github.com/agviegas/web-ifc-three - extractVertexData( vertexData ) { + extractVertexData(vertexData) { const vertices = [] const normals = [] let isNormalData = false - for ( let i = 0; i < vertexData.length; i++ ) { - isNormalData ? normals.push( vertexData[i] ) : vertices.push( vertexData[i] ) - if ( ( i + 1 ) % 3 === 0 ) isNormalData = !isNormalData + for (let i = 0; i < vertexData.length; i++) { + isNormalData ? normals.push(vertexData[i]) : vertices.push(vertexData[i]) + if ((i + 1) % 3 === 0) isNormalData = !isNormalData } return { vertices, normals } } // (c) https://github.com/agviegas/web-ifc-three/blob/907e08b5673d5e1c18261a4fceade7189d6b2db7/src/IFC/PropertyManager.ts#L110 - getAllRelatedItemsOfType( elementID, type, relation, relatedProperty ) { - const lines = this.api.GetLineIDsWithType( this.modelId, type ) + getAllRelatedItemsOfType(elementID, type, relation, relatedProperty) { + const lines = this.api.GetLineIDsWithType(this.modelId, type) const IDs = [] - for ( let i = 0; i < lines.size(); i++ ) { - const relID = lines.get( i ) - const rel = this.api.GetLine( this.modelId, relID ) + for (let i = 0; i < lines.size(); i++) { + const relID = lines.get(i) + const rel = this.api.GetLine(this.modelId, relID) const relatedItems = rel[relation] let foundElement = false - if ( Array.isArray( relatedItems ) ) { - const values = relatedItems.map( ( item ) => item.value ) - foundElement = values.includes( elementID ) - } else foundElement = ( relatedItems.value === elementID ) + if (Array.isArray(relatedItems)) { + const values = relatedItems.map((item) => item.value) + foundElement = values.includes(elementID) + } else foundElement = relatedItems.value === elementID - if ( foundElement ) { + if (foundElement) { const element = rel[relatedProperty] - if ( !Array.isArray( element ) ) IDs.push( element.value ) - else element.forEach( ( ele ) => IDs.push( ele.value ) ) + if (!Array.isArray(element)) IDs.push(element.value) + else element.forEach((ele) => IDs.push(ele.value)) } } return IDs } - - colorToMaterial( color ) { - let intColor = ( color.w << 24 ) + ( ( color.x * 255 ) << 16 ) + ( ( color.y * 255 ) << 8 ) + ( ( color.z * 255 ) ) - + + colorToMaterial(color) { + let intColor = + (color.w << 24) + ((color.x * 255) << 16) + ((color.y * 255) << 8) + color.z * 255 + return { diffuse: intColor, opacity: color.w, @@ -256,4 +335,4 @@ module.exports = class IFCParser { speckle_type: 'Objects.Other.RenderMaterial' } } -} \ No newline at end of file +} diff --git a/packages/fileimport-service/knex.js b/packages/fileimport-service/knex.js index ff2e57488..8b0c1fefe 100644 --- a/packages/fileimport-service/knex.js +++ b/packages/fileimport-service/knex.js @@ -1,8 +1,8 @@ 'use strict' -module.exports = require( 'knex' )( { +module.exports = require('knex')({ client: 'pg', connection: process.env.PG_CONNECTION_STRING || 'postgres://speckle:speckle@localhost/speckle', pool: { min: 1, max: 1 } // migrations are in managed in the server package -} ) +}) diff --git a/packages/fileimport-service/src/daemon.js b/packages/fileimport-service/src/daemon.js index b48e63cd4..4b5e471a6 100644 --- a/packages/fileimport-service/src/daemon.js +++ b/packages/fileimport-service/src/daemon.js @@ -1,12 +1,12 @@ 'use strict' -const knex = require( '../knex' ) +const knex = require('../knex') -const { getFileStream } = require( './filesApi' ) -const fs = require( 'fs' ) -const { spawn } = require( 'child_process' ) +const { getFileStream } = require('./filesApi') +const fs = require('fs') +const { spawn } = require('child_process') -const ServerAPI = require( '../ifc/api' ) +const ServerAPI = require('../ifc/api') const HEALTHCHECK_FILE_PATH = '/tmp/last_successful_query' @@ -16,7 +16,7 @@ const TMP_RESULTS_PATH = '/tmp/import_result.json' let shouldExit = false async function startTask() { - let { rows } = await knex.raw( ` + let { rows } = await knex.raw(` UPDATE file_uploads SET "convertedStatus" = 1, @@ -29,37 +29,45 @@ async function startTask() { ) as task WHERE file_uploads."id" = task."id" RETURNING file_uploads."id" - ` ) + `) return rows[0] } -async function doTask( task ) { +async function doTask(task) { let tempUserToken = null let serverApi = null try { - console.log( 'Doing task ', task ) - let { rows } = await knex.raw( ` + console.log('Doing task ', task) + let { rows } = await knex.raw( + ` SELECT id as "fileId", "streamId", "branchName", "userId", "fileName", "fileType" FROM file_uploads WHERE id = ? LIMIT 1 - `, [ task.id ] ) + `, + [task.id] + ) let info = rows[0] - if ( !info ) { - throw new Error( 'Internal error: DB inconsistent' ) + if (!info) { + throw new Error('Internal error: DB inconsistent') } - let upstreamFileStream = await getFileStream( { fileId: info.fileId } ) - let diskFileStream = fs.createWriteStream( TMP_FILE_PATH ) - - upstreamFileStream.pipe( diskFileStream ) + let upstreamFileStream = await getFileStream({ fileId: info.fileId }) + let diskFileStream = fs.createWriteStream(TMP_FILE_PATH) - await new Promise( fulfill => diskFileStream.on( 'finish' , fulfill ) ) - - serverApi = new ServerAPI( { streamId: info.streamId } ) - let { token } = await serverApi.createToken( { userId: info.userId, name: 'temp upload token', scopes: [ 'streams:write', 'streams:read' ], lifespan: 1000000 } ) + upstreamFileStream.pipe(diskFileStream) + + await new Promise((fulfill) => diskFileStream.on('finish', fulfill)) + + serverApi = new ServerAPI({ streamId: info.streamId }) + let { token } = await serverApi.createToken({ + userId: info.userId, + name: 'temp upload token', + scopes: ['streams:write', 'streams:read'], + lifespan: 1000000 + }) tempUserToken = token await runProcessWithTimeout( @@ -78,14 +86,14 @@ async function doTask( task ) { 10 * 60 * 1000 ) - let output = JSON.parse( fs.readFileSync( TMP_RESULTS_PATH ) ) + let output = JSON.parse(fs.readFileSync(TMP_RESULTS_PATH)) - if ( !output.success ) - throw new Error( output.error ) + if (!output.success) throw new Error(output.error) let commitId = output.commitId - await knex.raw( ` + await knex.raw( + ` UPDATE file_uploads SET "convertedStatus" = 2, @@ -93,103 +101,103 @@ async function doTask( task ) { "convertedMessage" = 'File converted successfully', "convertedCommitId" = ? WHERE "id" = ? - `, [ commitId, task.id ] ) - } catch ( err ) { - console.log( 'Error: ', err ) - await knex.raw( ` + `, + [commitId, task.id] + ) + } catch (err) { + console.log('Error: ', err) + await knex.raw( + ` UPDATE file_uploads SET "convertedStatus" = 3, "convertedLastUpdate" = NOW(), "convertedMessage" = ? WHERE "id" = ? - `, [ err.toString(), task.id ] ) + `, + [err.toString(), task.id] + ) } - if ( fs.existsSync( TMP_FILE_PATH ) ) fs.unlinkSync( TMP_FILE_PATH ) - if ( fs.existsSync( TMP_RESULTS_PATH ) ) fs.unlinkSync( TMP_RESULTS_PATH ) + if (fs.existsSync(TMP_FILE_PATH)) fs.unlinkSync(TMP_FILE_PATH) + if (fs.existsSync(TMP_RESULTS_PATH)) fs.unlinkSync(TMP_RESULTS_PATH) - if ( tempUserToken ) { - await serverApi.revokeTokenById( tempUserToken ) + if (tempUserToken) { + await serverApi.revokeTokenById(tempUserToken) } - } -function runProcessWithTimeout( cmd, cmdArgs, extraEnv, timeoutMs ) { - - return new Promise( ( resolve, reject ) => { - console.log( `Starting process: ${cmd} ${cmdArgs}` ) - const childProc = spawn( cmd, cmdArgs, { env: { ...process.env, ...extraEnv } } ) +function runProcessWithTimeout(cmd, cmdArgs, extraEnv, timeoutMs) { + return new Promise((resolve, reject) => { + console.log(`Starting process: ${cmd} ${cmdArgs}`) + const childProc = spawn(cmd, cmdArgs, { env: { ...process.env, ...extraEnv } }) - childProc.stdout.on( 'data', ( data ) => { - console.log( 'Parser: ', data.toString() ) - } ) + childProc.stdout.on('data', (data) => { + console.log('Parser: ', data.toString()) + }) - childProc.stderr.on( 'data', ( data ) => { - console.error( 'Parser: ', data.toString() ) - } ) + childProc.stderr.on('data', (data) => { + console.error('Parser: ', data.toString()) + }) let timedOut = false - let timeout = setTimeout( () => { - console.log( 'Process timeout. Killing process...' ) + let timeout = setTimeout(() => { + console.log('Process timeout. Killing process...') timedOut = true - childProc.kill( 9 ) - reject( `Timeout: Process took longer than ${timeoutMs} ms to execute` ) - }, timeoutMs ) + childProc.kill(9) + reject(`Timeout: Process took longer than ${timeoutMs} ms to execute`) + }, timeoutMs) - childProc.on( 'close', ( code ) => { - console.log( `Process exited with code ${code}` ) + childProc.on('close', (code) => { + console.log(`Process exited with code ${code}`) - if ( timedOut ) return // ignore `close` calls after killing (the promise was already rejected) + if (timedOut) return // ignore `close` calls after killing (the promise was already rejected) - clearTimeout( timeout ) + clearTimeout(timeout) - if ( code === 0 ) { + if (code === 0) { resolve() } else { - reject( `Parser exited with code ${code}` ) + reject(`Parser exited with code ${code}`) } - } ) - - } ) - + }) + }) } async function tick() { - if ( shouldExit ) { - process.exit( 0 ) + if (shouldExit) { + process.exit(0) } try { let task = await startTask() - fs.writeFile( HEALTHCHECK_FILE_PATH, '' + Date.now(), () => {} ) + fs.writeFile(HEALTHCHECK_FILE_PATH, '' + Date.now(), () => {}) - if ( !task ) { - setTimeout( tick, 1000 ) + if (!task) { + setTimeout(tick, 1000) return } - await doTask( task ) + await doTask(task) // Check for another task very soon - setTimeout( tick, 10 ) - } catch ( err ) { - console.log( 'Error executing task: ', err ) - setTimeout( tick, 5000 ) + setTimeout(tick, 10) + } catch (err) { + console.log('Error executing task: ', err) + setTimeout(tick, 5000) } } - async function main() { - console.log( 'Starting FileUploads Service...' ) - - process.on( 'SIGTERM', () => { + console.log('Starting FileUploads Service...') + + process.on('SIGTERM', () => { shouldExit = true - console.log( 'Shutting down...' ) - } ) + console.log('Shutting down...') + }) tick() } diff --git a/packages/frontend/.vscode/launch.json b/packages/frontend/.vscode/launch.json index 511204d3b..ed8b45d76 100644 --- a/packages/frontend/.vscode/launch.json +++ b/packages/frontend/.vscode/launch.json @@ -36,4 +36,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/packages/frontend/README.md b/packages/frontend/README.md index dd92b19d2..eb75bddd3 100644 --- a/packages/frontend/README.md +++ b/packages/frontend/README.md @@ -37,6 +37,7 @@ npm run serve ``` ### Packaging for production + If you plan to package the frontend to use in a production setting, see our [Server deployment instructions](https://speckle.guide/dev/server-setup.html) (chapter `Run your speckle-server fork`) ## Community diff --git a/packages/frontend/babel.config.js b/packages/frontend/babel.config.js index a00288472..1f4ca007e 100644 --- a/packages/frontend/babel.config.js +++ b/packages/frontend/babel.config.js @@ -1,6 +1,4 @@ module.exports = { presets: ['@vue/cli-plugin-babel/preset'], - exclude: [ - /(Speckle.js\.). / - ] + exclude: [/(Speckle.js\.). /] } diff --git a/packages/frontend/src/graphql/objectSingle.gql b/packages/frontend/src/graphql/objectSingle.gql index 83d6164c8..6fdac01a1 100644 --- a/packages/frontend/src/graphql/objectSingle.gql +++ b/packages/frontend/src/graphql/objectSingle.gql @@ -1,4 +1,4 @@ -query Object($streamId: String!, $id: String!){ +query Object($streamId: String!, $id: String!) { stream(id: $streamId) { id object(id: $id) { diff --git a/packages/frontend/src/graphql/objectSingleNoData.gql b/packages/frontend/src/graphql/objectSingleNoData.gql index fb1a3820d..ef910c5f4 100644 --- a/packages/frontend/src/graphql/objectSingleNoData.gql +++ b/packages/frontend/src/graphql/objectSingleNoData.gql @@ -1,4 +1,4 @@ -query Object($streamId: String!, $id: String!){ +query Object($streamId: String!, $id: String!) { stream(id: $streamId) { id name diff --git a/packages/frontend/src/graphql/streamCommits.gql b/packages/frontend/src/graphql/streamCommits.gql index 3c68fe617..84228afdc 100644 --- a/packages/frontend/src/graphql/streamCommits.gql +++ b/packages/frontend/src/graphql/streamCommits.gql @@ -4,7 +4,7 @@ query StreamCommits($id: String!) { role commits { totalCount - items{ + items { id authorId authorName diff --git a/packages/frontend/src/main/components/comments/CommentListItem.vue b/packages/frontend/src/main/components/comments/CommentListItem.vue index d40e21396..6cfd6e8f3 100644 --- a/packages/frontend/src/main/components/comments/CommentListItem.vue +++ b/packages/frontend/src/main/components/comments/CommentListItem.vue @@ -23,15 +23,25 @@ - Last reply + Last reply + +
Created on {{ new Date(commentDetails.createdAt).toLocaleString() }} -
- Archive - +
+ + Archive + + @@ -51,7 +61,15 @@ - Mark as read + + Mark as read +
@@ -69,7 +87,7 @@ > mdi-cube-outline - + mdi-comment-outline {{ commentDetails.replies.totalCount }} @@ -103,12 +121,17 @@ export default { }, props: { comment: { type: Object, default: () => null }, - stream: { type: Object, default: () => { return { role: null } } } + stream: { + type: Object, + default: () => { + return { role: null } + } + } }, apollo: { commentDetails: { query: gql` - query($streamId: String!, $id: String!) { + query ($streamId: String!, $id: String!) { comment(streamId: $streamId, id: $id) { id text @@ -146,7 +169,7 @@ export default { $subscribe: { commentThreadActivity: { query: gql` - subscription($streamId: String!, $commentId: String!) { + subscription ($streamId: String!, $commentId: String!) { commentThreadActivity(streamId: $streamId, commentId: $commentId) } `, @@ -160,7 +183,7 @@ export default { return !this.$loggedIn() }, result({ data }) { - if(!data || !data.commentThreadActivity) return + if (!data || !data.commentThreadActivity) return if (data.commentThreadActivity.eventType === 'reply-added') { this.commentDetails.replies.totalCount++ this.commentDetails.updatedAt = Date.now() @@ -181,9 +204,10 @@ export default { }, computed: { canArchiveThread() { - if(!this.comment || !this.stream ) return false - if(!this.stream.role) return false - if(this.comment.authorId === this.$userId() || this.stream.role ==='stream:owner') return true + if (!this.comment || !this.stream) return false + if (!this.stream.role) return false + if (this.comment.authorId === this.$userId() || this.stream.role === 'stream:owner') + return true }, link() { if (!this.commentDetails) return @@ -200,7 +224,7 @@ export default { return new Date(this.commentDetails.updatedAt) - new Date(this.commentDetails.viewedAt) > 0 } }, - methods:{ + methods: { async markAsRead() { this.commentDetails.viewedAt = Date.now() await this.$apollo.mutate({ diff --git a/packages/frontend/src/main/components/comments/CommentThreadViewer.vue b/packages/frontend/src/main/components/comments/CommentThreadViewer.vue index e4c14f710..c81ad7d0b 100644 --- a/packages/frontend/src/main/components/comments/CommentThreadViewer.vue +++ b/packages/frontend/src/main/components/comments/CommentThreadViewer.vue @@ -1,7 +1,9 @@