├── .gitattributes ├── .github └── workflows │ └── publish-on-checkin.yml ├── .gitignore ├── LICENSE ├── README.md ├── api-specs ├── bookstore.openapi.json ├── httpbin.org.openapi.json └── petstore.openapi.json ├── catalog ├── data │ ├── block-snippets.json │ ├── content.json │ ├── grid-snippets.json │ ├── icon-fonts.json │ └── style-snippets.json ├── package-lock.json ├── package.json ├── postcss.config.js ├── src │ ├── authentication │ │ ├── IAuthenticator.ts │ │ ├── accessToken.ts │ │ ├── defaultSessionManager.ts │ │ ├── index.ts │ │ └── sessionManager.ts │ ├── bindingHandlers │ │ ├── acceptChange.ts │ │ ├── copyToClipboard.ts │ │ ├── markdown.ts │ │ ├── scrollintoview.ts │ │ ├── syntaxHighlight.ts │ │ └── tab.ts │ ├── components │ │ ├── apis │ │ │ ├── details-of-api │ │ │ │ ├── detailsOfApiContract.ts │ │ │ │ ├── detailsOfApiHandlers.ts │ │ │ │ ├── detailsOfApiModel.ts │ │ │ │ ├── detailsOfApiModelBinder.ts │ │ │ │ └── ko │ │ │ │ │ ├── detailsOfApi.html │ │ │ │ │ ├── detailsOfApi.module.ts │ │ │ │ │ ├── detailsOfApiEditor.html │ │ │ │ │ ├── detailsOfApiEditor.module.ts │ │ │ │ │ ├── detailsOfApiEditor.ts │ │ │ │ │ ├── detailsOfApiViewModel.ts │ │ │ │ │ ├── detailsOfApiViewModelBinder.ts │ │ │ │ │ └── runtime │ │ │ │ │ ├── api-details.html │ │ │ │ │ └── api-details.ts │ │ │ └── list-of-apis │ │ │ │ ├── ko │ │ │ │ ├── listOfApis.html │ │ │ │ ├── listOfApis.module.ts │ │ │ │ ├── listOfApisEditor.html │ │ │ │ ├── listOfApisEditor.module.ts │ │ │ │ ├── listOfApisEditor.ts │ │ │ │ ├── listOfApisViewModel.ts │ │ │ │ ├── listOfApisViewModelBinder.ts │ │ │ │ └── runtime │ │ │ │ │ ├── api-list-dropdown.html │ │ │ │ │ ├── api-list-dropdown.ts │ │ │ │ │ ├── api-list-tiles.html │ │ │ │ │ ├── api-list-tiles.ts │ │ │ │ │ ├── api-list.html │ │ │ │ │ ├── api-list.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── tagGroupViewModel.ts │ │ │ │ │ └── treeviewNode.ts │ │ │ │ ├── listOfApisContract.ts │ │ │ │ ├── listOfApisHandlers.ts │ │ │ │ ├── listOfApisModel.ts │ │ │ │ └── listOfApisModelBinder.ts │ │ ├── app │ │ │ ├── app.html │ │ │ └── app.ts │ │ ├── code-editor │ │ │ ├── code-editor.html │ │ │ └── code-editor.ts │ │ ├── custom-html │ │ │ ├── constants.ts │ │ │ ├── customHtml.design.module.ts │ │ │ ├── customHtml.publish.module.ts │ │ │ ├── customHtmlContract.ts │ │ │ ├── customHtmlHandlers.ts │ │ │ ├── customHtmlModel.ts │ │ │ ├── customHtmlModelBinder.ts │ │ │ ├── index.ts │ │ │ └── ko │ │ │ │ ├── constants.ts │ │ │ │ ├── customHtmlEditorView.html │ │ │ │ ├── customHtmlEditorViewModel.ts │ │ │ │ ├── customHtmlView.html │ │ │ │ ├── customHtmlViewModel.ts │ │ │ │ ├── customHtmlViewModelBinder.ts │ │ │ │ └── index.ts │ │ ├── defaultAuthenticator.ts │ │ ├── file-input │ │ │ ├── file-input.html │ │ │ └── file-input.ts │ │ ├── fileSystemBlobStorage.ts │ │ ├── operations │ │ │ ├── operation-details │ │ │ │ ├── ko │ │ │ │ │ ├── operationDetails.html │ │ │ │ │ ├── operationDetailsEditor.html │ │ │ │ │ ├── operationDetailsEditor.ts │ │ │ │ │ ├── operationDetailsViewModel.ts │ │ │ │ │ ├── operationDetailsViewModelBinder.ts │ │ │ │ │ └── runtime │ │ │ │ │ │ ├── authorization.html │ │ │ │ │ │ ├── authorization.ts │ │ │ │ │ │ ├── code-sample.html │ │ │ │ │ │ ├── code-sample.ts │ │ │ │ │ │ ├── code-snippet.html │ │ │ │ │ │ ├── code-snippet.ts │ │ │ │ │ │ ├── oauth-server-configuration.html │ │ │ │ │ │ ├── oauth-server-configuration.ts │ │ │ │ │ │ ├── oauthSession.ts │ │ │ │ │ │ ├── operation-console.html │ │ │ │ │ │ ├── operation-console.ts │ │ │ │ │ │ ├── operation-details.html │ │ │ │ │ │ ├── operation-details.ts │ │ │ │ │ │ ├── responsePackage.ts │ │ │ │ │ │ ├── templates │ │ │ │ │ │ ├── csharp.liquid │ │ │ │ │ │ ├── curl.liquid │ │ │ │ │ │ ├── http.liquid │ │ │ │ │ │ ├── java.liquid │ │ │ │ │ │ ├── javascript.liquid │ │ │ │ │ │ ├── objc.liquid │ │ │ │ │ │ ├── php.liquid │ │ │ │ │ │ ├── python.liquid │ │ │ │ │ │ ├── ruby.liquid │ │ │ │ │ │ ├── swift.liquid │ │ │ │ │ │ ├── templates.ts │ │ │ │ │ │ ├── ws_csharp.liquid │ │ │ │ │ │ ├── ws_javascript.liquid │ │ │ │ │ │ └── ws_wscat.liquid │ │ │ │ │ │ ├── type-definition-combination.html │ │ │ │ │ │ ├── type-definition-enum.html │ │ │ │ │ │ ├── type-definition-indexer.html │ │ │ │ │ │ ├── type-definition-object.html │ │ │ │ │ │ ├── type-definition.html │ │ │ │ │ │ ├── type-definition.ts │ │ │ │ │ │ └── websocketClient.ts │ │ │ │ ├── operationDetails.design.module.ts │ │ │ │ ├── operationDetails.publish.module.ts │ │ │ │ ├── operationDetailsContract.ts │ │ │ │ ├── operationDetailsHandlers.ts │ │ │ │ ├── operationDetailsModel.ts │ │ │ │ └── operationDetailsModelBinder.ts │ │ │ └── operation-list │ │ │ │ ├── ko │ │ │ │ ├── operationList.html │ │ │ │ ├── operationList.module.ts │ │ │ │ ├── operationListEditor.html │ │ │ │ ├── operationListEditor.module.ts │ │ │ │ ├── operationListEditor.ts │ │ │ │ ├── operationListViewModel.ts │ │ │ │ ├── operationListViewModelBinder.ts │ │ │ │ └── runtime │ │ │ │ │ ├── operation-list.html │ │ │ │ │ └── operation-list.ts │ │ │ │ ├── operationListContract.ts │ │ │ │ ├── operationListHandlers.ts │ │ │ │ ├── operationListModel.ts │ │ │ │ └── operationListModelBinder.ts │ │ ├── pagination │ │ │ ├── pagination.html │ │ │ └── pagination.ts │ │ ├── spinner │ │ │ ├── spinner.html │ │ │ └── spinner.ts │ │ ├── staticAuthenticator.ts │ │ ├── staticRouter.ts │ │ ├── staticSettingsProvider.ts │ │ ├── tag-input │ │ │ ├── tag-input.html │ │ │ ├── tag-input.ts │ │ │ └── tag-list.html │ │ └── users │ │ │ └── validation-summary │ │ │ ├── ko │ │ │ ├── runtime │ │ │ │ ├── validation-summary.html │ │ │ │ └── validation-summary.ts │ │ │ ├── validationSummary.html │ │ │ ├── validationSummaryEditor.html │ │ │ ├── validationSummaryEditor.ts │ │ │ ├── validationSummaryViewModel.ts │ │ │ └── validationSummaryViewModelBinder.ts │ │ │ ├── validationSummary.design.module.ts │ │ │ ├── validationSummary.module.ts │ │ │ ├── validationSummaryContract.ts │ │ │ ├── validationSummaryHandlers.ts │ │ │ ├── validationSummaryModel.ts │ │ │ └── validationSummaryModelBinder.ts │ ├── config.design.json │ ├── config.host.json │ ├── config.publish.json │ ├── config.runtime.json │ ├── constants.ts │ ├── contracts │ │ ├── aadB2CClientConfig.ts │ │ ├── aadClientConfig.ts │ │ ├── api.ts │ │ ├── apiChangeLog.ts │ │ ├── apiTagDescription.ts │ │ ├── apiVersionSet.ts │ │ ├── armResource.ts │ │ ├── authenticationSettings.ts │ │ ├── authorizationServer.ts │ │ ├── captchaParams.ts │ │ ├── example.ts │ │ ├── hostname.ts │ │ ├── identity.ts │ │ ├── identityProvider.ts │ │ ├── identitySettings.ts │ │ ├── jwtToken.ts │ │ ├── nameValuePair.ts │ │ ├── oauthSession.ts │ │ ├── openIdConnectMetadata.ts │ │ ├── openIdConnectProvider.ts │ │ ├── openapi │ │ │ ├── index.ts │ │ │ ├── openApi.ts │ │ │ ├── openApiComponents.ts │ │ │ ├── openApiExample.ts │ │ │ ├── openApiExternalDoc.ts │ │ │ ├── openApiMediaType.ts │ │ │ ├── openApiObjectInfo.ts │ │ │ ├── openApiOperation.ts │ │ │ ├── openApiParameter.ts │ │ │ ├── openApiPath.ts │ │ │ ├── openApiPaths.ts │ │ │ ├── openApiReference.ts │ │ │ ├── openApiRequestBody.ts │ │ │ ├── openApiResponse.ts │ │ │ ├── openApiResponses.ts │ │ │ ├── openApiSchema.ts │ │ │ ├── openApiServer.ts │ │ │ └── openApiTag.ts │ │ ├── operation.ts │ │ ├── page.ts │ │ ├── parameter.ts │ │ ├── product.ts │ │ ├── reportRecord.ts │ │ ├── reportRecordByApi.ts │ │ ├── reportRecordByGeo.ts │ │ ├── reportRecordByOperation.ts │ │ ├── reportRecordByProduct.ts │ │ ├── reportRecordBySubscription.ts │ │ ├── reportRecordByTime.ts │ │ ├── representation.ts │ │ ├── request.ts │ │ ├── resetRequest.ts │ │ ├── response.ts │ │ ├── revision.ts │ │ ├── schema.ts │ │ ├── searchQuery.ts │ │ ├── service.ts │ │ ├── signupRequest.ts │ │ ├── subscription.ts │ │ ├── subscriptionSecrets.ts │ │ ├── swaggerObject.ts │ │ ├── tag.ts │ │ ├── tagResource.ts │ │ ├── tenantSettings.ts │ │ ├── trace.ts │ │ ├── url.ts │ │ ├── user.ts │ │ └── validationReport.ts │ ├── controller │ │ └── contentController.ts │ ├── errors │ │ ├── appError.ts │ │ ├── index.ts │ │ ├── mapiError.ts │ │ ├── sessionExpirationErrorHandler.ts │ │ ├── unauthorizedError.ts │ │ └── unhandledErrorHandler.ts │ ├── injection │ │ └── inversifyAdapter.ts │ ├── libraries │ │ ├── block-snippets.json │ │ ├── grid-snippets.json │ │ └── icon-fonts.json │ ├── logging │ │ └── appInsightsLogger.ts │ ├── main.design.module.ts │ ├── main.host.module.ts │ ├── main.publish.module.ts │ ├── main.runtime.module.ts │ ├── middlewares │ │ ├── index.ts │ │ ├── staticContentMiddleware.ts │ │ └── unhandledErrorMiddleware.ts │ ├── models │ │ ├── api.ts │ │ ├── authorizationServer.ts │ │ ├── console │ │ │ ├── consoleHeader.ts │ │ │ ├── consoleHost.ts │ │ │ ├── consoleOperation.ts │ │ │ ├── consoleParameter.ts │ │ │ ├── consoleRepresentation.ts │ │ │ ├── consoleRequest.ts │ │ │ ├── consoleResponse.ts │ │ │ ├── consoleTrace.ts │ │ │ └── formDataItem.ts │ │ ├── identityProvider.ts │ │ ├── jObject.ts │ │ ├── knownHttpHeaders.ts │ │ ├── knownMimeTypes.ts │ │ ├── knownStatusCodes.ts │ │ ├── openIdConnectProvider.ts │ │ ├── operation.ts │ │ ├── page.ts │ │ ├── parameter.ts │ │ ├── parameterExample.ts │ │ ├── product.ts │ │ ├── representation.ts │ │ ├── representationExample.ts │ │ ├── request.ts │ │ ├── response.ts │ │ ├── revision.ts │ │ ├── schema.ts │ │ ├── service.ts │ │ ├── statusCode.ts │ │ ├── subscription.ts │ │ ├── tag.ts │ │ ├── tagGroup.ts │ │ ├── typeDefinition.ts │ │ ├── user.ts │ │ ├── versionSet.ts │ │ ├── xsdSchemaConverter.spec.ts │ │ └── xsdSchemaConverter.ts │ ├── modules.d.ts │ ├── persistence │ │ ├── cachedObjectStorage.ts │ │ ├── dataProvider.ts │ │ ├── fileSystemDataProvider.ts │ │ ├── fileSystemObjectStorage.ts │ │ ├── httpDataProvider.ts │ │ ├── memoryBlobStorage.ts │ │ ├── memoryObjectStorage.ts │ │ ├── publishingCacheModule.ts │ │ ├── remoteBlobStorage.ts │ │ └── remoteObjectStorage.ts │ ├── polyfills.ts │ ├── publishing │ │ ├── openApiPublisher.ts │ │ ├── runtimeConfigBuilder.ts │ │ └── runtimeConfigPublisher.ts │ ├── routing │ │ ├── oldContentRouteGuard.ts │ │ ├── relativePathRouter.ts │ │ ├── routeHelper.ts │ │ └── unsavedChangesRouteGuard.ts │ ├── services │ │ ├── apiService.ts │ │ ├── index.ts │ │ ├── markdownService.ts │ │ ├── openApiConverter.ts │ │ ├── openApiIndexBuilder.ts │ │ ├── reportQuery.ts │ │ ├── roleService.ts │ │ ├── tagService.ts │ │ ├── templatingService.ts │ │ ├── ttlCache.ts │ │ └── userService.ts │ ├── startup.design.ts │ ├── startup.host.ts │ ├── startup.publish.ts │ ├── startup.runtime.ts │ ├── themes │ │ ├── designer │ │ │ ├── assets │ │ │ │ └── index.html │ │ │ └── styles │ │ │ │ ├── animation.scss │ │ │ │ ├── arrows.scss │ │ │ │ ├── balloons.scss │ │ │ │ ├── buttons.scss │ │ │ │ ├── codeEditor.scss │ │ │ │ ├── confirmation.scss │ │ │ │ ├── cropper.scss │ │ │ │ ├── draggables.scss │ │ │ │ ├── dropbucket.scss │ │ │ │ ├── dropdowns.scss │ │ │ │ ├── dropzones.scss │ │ │ │ ├── editors │ │ │ │ ├── boxEditor.scss │ │ │ │ ├── colorPicker.scss │ │ │ │ ├── colorSelector.scss │ │ │ │ ├── fontEditor.scss │ │ │ │ ├── fontSelector.scss │ │ │ │ ├── rowLayoutSelector.scss │ │ │ │ └── videoEditor.scss │ │ │ │ ├── flex.scss │ │ │ │ ├── fonts │ │ │ │ ├── OpenSans-Bold.ttf │ │ │ │ ├── OpenSans-BoldItalic.ttf │ │ │ │ ├── OpenSans-Italic.ttf │ │ │ │ ├── OpenSans-Light.ttf │ │ │ │ ├── OpenSans-LightItalic.ttf │ │ │ │ ├── OpenSans-Regular.ttf │ │ │ │ ├── paperbits.eot │ │ │ │ ├── paperbits.svg │ │ │ │ ├── paperbits.ttf │ │ │ │ ├── paperbits.woff │ │ │ │ └── paperbits.woff2 │ │ │ │ ├── forms.scss │ │ │ │ ├── grid.scss │ │ │ │ ├── host.scss │ │ │ │ ├── icons-toolboxes.scss │ │ │ │ ├── icons-widgets.scss │ │ │ │ ├── icons.scss │ │ │ │ ├── icons │ │ │ │ ├── icon-accordion.svg │ │ │ │ ├── icon-api-management.svg │ │ │ │ ├── icon-button.svg │ │ │ │ ├── icon-card.svg │ │ │ │ ├── icon-carousel.svg │ │ │ │ ├── icon-checkbox.svg │ │ │ │ ├── icon-collapsible-panel.svg │ │ │ │ ├── icon-component.svg │ │ │ │ ├── icon-date-input.svg │ │ │ │ ├── icon-email-input.svg │ │ │ │ ├── icon-form.svg │ │ │ │ ├── icon-map.svg │ │ │ │ ├── icon-menu.svg │ │ │ │ ├── icon-multi-line-input.svg │ │ │ │ ├── icon-number-input.svg │ │ │ │ ├── icon-password-input.svg │ │ │ │ ├── icon-picture-gallery.svg │ │ │ │ ├── icon-picture.svg │ │ │ │ ├── icon-range-input.svg │ │ │ │ ├── icon-search-box.svg │ │ │ │ ├── icon-select-input.svg │ │ │ │ ├── icon-splitter.svg │ │ │ │ ├── icon-submit-form-button.svg │ │ │ │ ├── icon-tab-panel.svg │ │ │ │ ├── icon-table.svg │ │ │ │ ├── icon-testimonials.svg │ │ │ │ ├── icon-text-block.svg │ │ │ │ ├── icon-text-input.svg │ │ │ │ ├── icon-time-input.svg │ │ │ │ ├── icon-url-input.svg │ │ │ │ ├── icon-video-player.svg │ │ │ │ └── icon-youtube-player.svg │ │ │ │ ├── layouts.scss │ │ │ │ ├── lightbox.scss │ │ │ │ ├── lists.scss │ │ │ │ ├── mixins.scss │ │ │ │ ├── scaffolding.scss │ │ │ │ ├── scrollbars.scss │ │ │ │ ├── slider.scss │ │ │ │ ├── spinners.scss │ │ │ │ ├── styles.scss │ │ │ │ ├── tabs.scss │ │ │ │ ├── thumbnails.scss │ │ │ │ ├── toasts.scss │ │ │ │ ├── toolbox.paragraph.scss │ │ │ │ ├── toolboxes.scss │ │ │ │ ├── tooltips.scss │ │ │ │ ├── typography.scss │ │ │ │ ├── utils.scss │ │ │ │ ├── variables.scss │ │ │ │ ├── widgets.scss │ │ │ │ ├── widgets │ │ │ │ ├── map.scss │ │ │ │ ├── textblock.scss │ │ │ │ ├── video.scss │ │ │ │ └── youtube.scss │ │ │ │ └── workshops.scss │ │ └── website │ │ │ ├── assets │ │ │ └── page.html │ │ │ └── styles │ │ │ ├── alerts.scss │ │ │ ├── animations.scss │ │ │ ├── badges.scss │ │ │ ├── balloons.scss │ │ │ ├── breadcrumbs.scss │ │ │ ├── buttons.scss │ │ │ ├── charts.scss │ │ │ ├── docs.scss │ │ │ ├── flex.scss │ │ │ ├── fonts │ │ │ ├── icons.eot │ │ │ ├── icons.svg │ │ │ ├── icons.ttf │ │ │ └── icons.woff │ │ │ ├── forms.scss │ │ │ ├── icons.scss │ │ │ ├── icons │ │ │ ├── icon-aad.svg │ │ │ ├── icon-magnifier.svg │ │ │ ├── icon-wadl.svg │ │ │ └── icon-wsdl.svg │ │ │ ├── layouts.scss │ │ │ ├── lists.scss │ │ │ ├── mixins.scss │ │ │ ├── monaco.editor.scss │ │ │ ├── navs.scss │ │ │ ├── pagination.scss │ │ │ ├── panels.scss │ │ │ ├── pills.scss │ │ │ ├── prism.scss │ │ │ ├── reboot.scss │ │ │ ├── resizables.scss │ │ │ ├── spinners.scss │ │ │ ├── styles.design.scss │ │ │ ├── styles.scss │ │ │ ├── svgs │ │ │ ├── download.svg │ │ │ ├── openapi.svg │ │ │ ├── wadl.svg │ │ │ └── wsdl.svg │ │ │ ├── tables.scss │ │ │ ├── tabs.scss │ │ │ ├── tags.scss │ │ │ ├── text.scss │ │ │ ├── utils.scss │ │ │ ├── variables.scss │ │ │ └── widgets │ │ │ ├── button.scss │ │ │ ├── card.scss │ │ │ ├── carousel.scss │ │ │ ├── collapsibles.scss │ │ │ ├── map.scss │ │ │ ├── picture.scss │ │ │ ├── popups.scss │ │ │ ├── slider.scss │ │ │ ├── table-of-contents.scss │ │ │ ├── tabs.scss │ │ │ ├── textblock.scss │ │ │ ├── video.scss │ │ │ ├── widgets.scss │ │ │ └── youtube.scss │ ├── types │ │ └── index.d.ts │ └── utils.ts ├── tsconfig.json ├── tslint.json ├── webpack.build.js ├── webpack.designer.js ├── webpack.develop.js ├── webpack.host.js ├── webpack.publisher.js └── webpack.runtime.js ├── package-lock.json └── readme.gif /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pfx binary 2 | *.ico binary 3 | *.svg binary 4 | *.jpg binary 5 | *.png binary 6 | *.exe binary 7 | *.eot binary 8 | *.woff binary 9 | *.woff2 binary 10 | *.ttf binary 11 | *.otf binary 12 | *.cdr binary -------------------------------------------------------------------------------- /.github/workflows/publish-on-checkin.yml: -------------------------------------------------------------------------------- 1 | name: Publish and deploy to GitHub Pages 2 | 3 | defaults: 4 | run: 5 | working-directory: ./catalog 6 | 7 | on: 8 | push: 9 | branches: 10 | - main 11 | 12 | jobs: 13 | build_and_publish_job: 14 | if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') 15 | runs-on: ubuntu-latest 16 | name: Build and Publish Job 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Use Node.js ${{ matrix.node-version }} 20 | uses: actions/setup-node@v1 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | - run: npm install 24 | - run: npm run publish 25 | 26 | - name: Deploy 27 | uses: peaceiris/actions-gh-pages@v3 28 | with: 29 | github_token: ${{ secrets.GITHUB_TOKEN }} 30 | publish_dir: ./catalog/dist/website 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .history/ 2 | .vs/ 3 | .vscode/ 4 | catalog/dist/ 5 | catalog/node_modules/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /catalog/data/icon-fonts.json: -------------------------------------------------------------------------------- 1 | { 2 | "fonts": [ 3 | { 4 | "displayName": "Font Awesome icons", 5 | "key": "fonts/default", 6 | "variants": [ 7 | { 8 | "file": "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/webfonts/fa-regular-400.ttf", 9 | "style": "normal", 10 | "weight": "400" 11 | } 12 | ] 13 | }, 14 | { 15 | "displayName": "Material Design icons", 16 | "variants": [ 17 | { 18 | "file": "https://cdnjs.cloudflare.com/ajax/libs/material-design-icons/3.0.2/iconfont/MaterialIcons-Regular.ttf", 19 | "style": "normal", 20 | "weight": "400" 21 | } 22 | ] 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /catalog/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require("autoprefixer") 4 | ], 5 | sourceMap: true, 6 | minimize: true 7 | } -------------------------------------------------------------------------------- /catalog/src/authentication/IAuthenticator.ts: -------------------------------------------------------------------------------- 1 | import { AccessToken } from "./accessToken"; 2 | 3 | export interface IAuthenticator { 4 | /** 5 | * Returns access token as a string. 6 | */ 7 | getAccessTokenAsString(): Promise; 8 | 9 | /** 10 | * Returns access token for current session. 11 | */ 12 | getAccessToken(): Promise; 13 | 14 | /** 15 | * Sets new token for the session. 16 | * @param accessToken {string} Access token in SharedAccessSignature or Bearer token format. 17 | */ 18 | setAccessToken(accessToken: AccessToken): Promise; 19 | 20 | /** 21 | * Clears access token from current session. 22 | */ 23 | clearAccessToken(): void; 24 | 25 | /** 26 | * Checks if current user is signed in. 27 | */ 28 | isAuthenticated(): Promise; 29 | } -------------------------------------------------------------------------------- /catalog/src/authentication/defaultSessionManager.ts: -------------------------------------------------------------------------------- 1 | import { SessionManager } from "./sessionManager"; 2 | 3 | export class DefaultSessionManager implements SessionManager { 4 | public async getItem(key: string): Promise { 5 | const value = sessionStorage.getItem(key); 6 | 7 | if (!value) { 8 | return null; 9 | } 10 | 11 | return JSON.parse(value); 12 | } 13 | 14 | public async setItem(key: string, value: T): Promise { 15 | sessionStorage.setItem(key, JSON.stringify(value)); 16 | } 17 | 18 | public async removeItem(key: string): Promise { 19 | sessionStorage.removeItem(key); 20 | } 21 | } -------------------------------------------------------------------------------- /catalog/src/authentication/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./IAuthenticator"; 2 | export * from "./accessToken"; -------------------------------------------------------------------------------- /catalog/src/authentication/sessionManager.ts: -------------------------------------------------------------------------------- 1 | export interface SessionManager { 2 | /** 3 | * Returns stored value. 4 | * @param key 5 | */ 6 | getItem(key: string): Promise; 7 | 8 | /** 9 | * Stores value with specified key. 10 | * @param key {string} Stored value key. 11 | * @param value {T} Stored value. 12 | */ 13 | setItem(key: string, value: T): Promise; 14 | 15 | /** 16 | * Removes value with specified key. 17 | * @param key {string} Stored value key. 18 | */ 19 | removeItem(key: string): Promise; 20 | } -------------------------------------------------------------------------------- /catalog/src/bindingHandlers/acceptChange.ts: -------------------------------------------------------------------------------- 1 | import * as ko from "knockout"; 2 | 3 | ko.extenders.acceptChange = (target, condition) => { 4 | const result = ko.pureComputed({ 5 | read: target, 6 | write: (newValue) => { 7 | if (!ko.unwrap(condition)) { 8 | return; 9 | } 10 | target(newValue); 11 | } 12 | }); 13 | 14 | result(target()); 15 | 16 | return result; 17 | }; -------------------------------------------------------------------------------- /catalog/src/bindingHandlers/copyToClipboard.ts: -------------------------------------------------------------------------------- 1 | import * as ko from "knockout"; 2 | 3 | ko.bindingHandlers["copyToClipboard"] = { 4 | init: (element: HTMLElement, valueAccessor: () => string): void => { 5 | const copyToClipboard = () => { 6 | const placeholder = document.createElement("textarea"); 7 | placeholder.innerText = ko.unwrap(valueAccessor()); 8 | document.body.appendChild(placeholder); 9 | 10 | const range = document.createRange(); 11 | range.selectNode(placeholder); 12 | 13 | const selection = window.getSelection(); 14 | selection.removeAllRanges(); 15 | selection.addRange(range); 16 | 17 | document.execCommand("copy"); 18 | 19 | selection.removeAllRanges(); 20 | document.body.removeChild(placeholder); 21 | }; 22 | 23 | ko.applyBindingsToNode(element, { click: copyToClipboard }, null); 24 | } 25 | }; -------------------------------------------------------------------------------- /catalog/src/bindingHandlers/markdown.ts: -------------------------------------------------------------------------------- 1 | import * as ko from "knockout"; 2 | import { MarkdownService } from "../services/markdownService"; 3 | 4 | interface MarkdownConfig { 5 | /** 6 | * Markdown source. 7 | */ 8 | source: string; 9 | 10 | /** 11 | * Maximum length of text before truncation. 12 | */ 13 | truncateAt: number; 14 | } 15 | 16 | 17 | ko.bindingHandlers["markdown"] = { 18 | update: (element: HTMLElement, valueAccessor: () => string | MarkdownConfig): void => { 19 | const config = ko.unwrap(valueAccessor()); 20 | const htmlObservable = ko.observable(); 21 | const markdownService = new MarkdownService(); 22 | 23 | let markdown: string; 24 | let length: number; 25 | 26 | if (!config) { 27 | return; 28 | } 29 | 30 | if (typeof config === "string") { 31 | markdown = config; 32 | } 33 | else { 34 | markdown = config.source; 35 | length = config.truncateAt; 36 | } 37 | 38 | ko.applyBindingsToNode(element, { html: htmlObservable }, null); 39 | 40 | const html = markdownService.processMarkdown(markdown); 41 | htmlObservable(html); 42 | } 43 | }; -------------------------------------------------------------------------------- /catalog/src/bindingHandlers/scrollintoview.ts: -------------------------------------------------------------------------------- 1 | import * as ko from "knockout"; 2 | 3 | ko.bindingHandlers["scrollintoview"] = { 4 | init: (element: HTMLElement): void => { 5 | element.scrollIntoView({ behavior: "smooth", block: "end" }); 6 | } 7 | }; -------------------------------------------------------------------------------- /catalog/src/bindingHandlers/tab.ts: -------------------------------------------------------------------------------- 1 | import * as ko from "knockout"; 2 | 3 | interface TabConfig { 4 | isSelected: ko.Observable; 5 | } 6 | 7 | ko.bindingHandlers["tab"] = { 8 | update: (element: HTMLElement, valueAccessor: () => TabConfig): void => { 9 | const config = valueAccessor(); 10 | const isSelected = ko.unwrap(config.isSelected); 11 | 12 | ko.applyBindingsToNode(element, { 13 | css: { 14 | "nav-link-active": isSelected 15 | }, 16 | attr: { 17 | "aria-selected": isSelected ? "true" : "false" 18 | } 19 | }, null); 20 | } 21 | }; -------------------------------------------------------------------------------- /catalog/src/components/apis/details-of-api/detailsOfApiContract.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from "@paperbits/common"; 2 | import { HyperlinkContract } from "@paperbits/common/editing"; 3 | 4 | export interface DetailsOfApiContract extends Contract { 5 | /** 6 | * Link to a page that contains API changlog. 7 | */ 8 | changeLogPageHyperlink?: HyperlinkContract; 9 | } 10 | -------------------------------------------------------------------------------- /catalog/src/components/apis/details-of-api/detailsOfApiHandlers.ts: -------------------------------------------------------------------------------- 1 | import { IWidgetOrder, IWidgetHandler } from "@paperbits/common/editing"; 2 | import { DetailsOfApiModel } from "./detailsOfApiModel"; 3 | 4 | export class DetailsOfApiHandlers implements IWidgetHandler { 5 | public async getWidgetOrder(): Promise { 6 | const widgetOrder: IWidgetOrder = { 7 | name: "apiDetails", 8 | category: "APIs", 9 | displayName: "API: Details", 10 | iconClass: "widget-icon widget-icon-api-management", 11 | requires: ["html"], 12 | createModel: async () => new DetailsOfApiModel() 13 | }; 14 | 15 | return widgetOrder; 16 | } 17 | } -------------------------------------------------------------------------------- /catalog/src/components/apis/details-of-api/detailsOfApiModel.ts: -------------------------------------------------------------------------------- 1 | import { HyperlinkModel } from "@paperbits/common/permalinks"; 2 | 3 | export class DetailsOfApiModel { 4 | /** 5 | * Link to a page that contains API changelog. 6 | */ 7 | public changeLogPageHyperlink: HyperlinkModel; 8 | } 9 | -------------------------------------------------------------------------------- /catalog/src/components/apis/details-of-api/ko/detailsOfApi.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /catalog/src/components/apis/details-of-api/ko/detailsOfApi.module.ts: -------------------------------------------------------------------------------- 1 | import { IInjectorModule, IInjector } from "@paperbits/common/injection"; 2 | import { DetailsOfApiModelBinder } from "../detailsOfApiModelBinder"; 3 | import { DetailsOfApiViewModelBinder } from "./detailsOfApiViewModelBinder"; 4 | 5 | 6 | export class DetailsOfApiModule implements IInjectorModule { 7 | public register(injector: IInjector): void { 8 | injector.bindToCollection("modelBinders", DetailsOfApiModelBinder); 9 | injector.bindToCollection("viewModelBinders", DetailsOfApiViewModelBinder); 10 | } 11 | } -------------------------------------------------------------------------------- /catalog/src/components/apis/details-of-api/ko/detailsOfApiEditor.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 7 | 9 |
10 |
11 | 12 | 16 |
17 |
18 |
-------------------------------------------------------------------------------- /catalog/src/components/apis/details-of-api/ko/detailsOfApiEditor.module.ts: -------------------------------------------------------------------------------- 1 | import { IInjectorModule, IInjector } from "@paperbits/common/injection"; 2 | import { DetailsOfApiHandlers } from "../detailsOfApiHandlers"; 3 | import { DetailsOfApiEditor } from "./detailsOfApiEditor"; 4 | 5 | export class DetailsOfApiEditorModule implements IInjectorModule { 6 | public register(injector: IInjector): void { 7 | injector.bind("detailsOfApiEditor", DetailsOfApiEditor); 8 | injector.bindToCollection("widgetHandlers", DetailsOfApiHandlers, "detailsOfApiHandlers"); 9 | } 10 | } -------------------------------------------------------------------------------- /catalog/src/components/apis/details-of-api/ko/detailsOfApiViewModel.ts: -------------------------------------------------------------------------------- 1 | import * as ko from "knockout"; 2 | import template from "./detailsOfApi.html"; 3 | import { Component } from "@paperbits/common/ko/decorators"; 4 | 5 | @Component({ 6 | selector: "detailsOfApi", 7 | template: template 8 | }) 9 | export class DetailsOfApiViewModel { 10 | public readonly runtimeConfig: ko.Observable; 11 | 12 | constructor() { 13 | this.runtimeConfig = ko.observable(); 14 | } 15 | } -------------------------------------------------------------------------------- /catalog/src/components/apis/list-of-apis/ko/listOfApis.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /catalog/src/components/apis/list-of-apis/ko/listOfApis.module.ts: -------------------------------------------------------------------------------- 1 | import { IInjectorModule, IInjector } from "@paperbits/common/injection"; 2 | import { ListOfApisModelBinder } from "../listOfApisModelBinder"; 3 | import { ListOfApisViewModelBinder } from "./listOfApisViewModelBinder"; 4 | 5 | 6 | export class ListOfApisModule implements IInjectorModule { 7 | public register(injector: IInjector): void { 8 | injector.bindToCollection("modelBinders", ListOfApisModelBinder); 9 | injector.bindToCollection("viewModelBinders", ListOfApisViewModelBinder); 10 | } 11 | } -------------------------------------------------------------------------------- /catalog/src/components/apis/list-of-apis/ko/listOfApisEditor.module.ts: -------------------------------------------------------------------------------- 1 | import { ListOfApisEditor } from "./listOfApisEditor"; 2 | import { IInjectorModule, IInjector } from "@paperbits/common/injection"; 3 | import { ListOfApisHandlers, ListOfApisTilesHandlers, ListOfApisDropdownHandlers } from "../listOfApisHandlers"; 4 | 5 | export class ListOfApisEditorModule implements IInjectorModule { 6 | public register(injector: IInjector): void { 7 | injector.bind("listOfApisEditor", ListOfApisEditor); 8 | injector.bindToCollection("widgetHandlers", ListOfApisHandlers, "listOfApisHandlers"); 9 | injector.bindToCollection("widgetHandlers", ListOfApisTilesHandlers, "listOfApisTilesHandlers"); 10 | injector.bindToCollection("widgetHandlers", ListOfApisDropdownHandlers, "listOfApisDropdownHandlers"); 11 | } 12 | } -------------------------------------------------------------------------------- /catalog/src/components/apis/list-of-apis/ko/listOfApisViewModel.ts: -------------------------------------------------------------------------------- 1 | import * as ko from "knockout"; 2 | import template from "./listOfApis.html"; 3 | import { Component } from "@paperbits/common/ko/decorators"; 4 | 5 | @Component({ 6 | selector: "listOfApis", 7 | template: template 8 | }) 9 | export class ListOfApisViewModel { 10 | public readonly layout: ko.Observable; 11 | public readonly runtimeConfig: ko.Observable; 12 | 13 | constructor() { 14 | this.layout = ko.observable(); 15 | this.runtimeConfig = ko.observable(); 16 | } 17 | } -------------------------------------------------------------------------------- /catalog/src/components/apis/list-of-apis/ko/runtime/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./api-list"; 2 | export * from "./api-list-dropdown"; 3 | export * from "./api-list-tiles"; -------------------------------------------------------------------------------- /catalog/src/components/apis/list-of-apis/ko/runtime/tagGroupViewModel.ts: -------------------------------------------------------------------------------- 1 | import * as ko from "knockout"; 2 | 3 | export class TagGroupViewModel { 4 | public expanded: ko.Observable; 5 | } -------------------------------------------------------------------------------- /catalog/src/components/apis/list-of-apis/listOfApisContract.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from "@paperbits/common"; 2 | import { HyperlinkContract } from "@paperbits/common/editing"; 3 | 4 | 5 | /** 6 | * API list widget contract. 7 | */ 8 | export interface ListOfApisContract extends Contract { 9 | /** 10 | * API list layout. 11 | */ 12 | itemStyleView?: string; 13 | 14 | /** 15 | * Indicated that an APIs can be selected. 16 | */ 17 | allowSelection: boolean; 18 | 19 | /** 20 | * Show API type. 21 | */ 22 | showApiType: boolean; 23 | 24 | /** 25 | * Default GroupByTag to enabled. 26 | */ 27 | defaultGroupByTagToEnabled?: boolean; 28 | 29 | /** 30 | * Link to a page that contains API details. 31 | */ 32 | detailsPageHyperlink?: HyperlinkContract; 33 | } 34 | -------------------------------------------------------------------------------- /catalog/src/components/apis/list-of-apis/listOfApisModel.ts: -------------------------------------------------------------------------------- 1 | import { HyperlinkModel } from "@paperbits/common/permalinks"; 2 | 3 | export class ListOfApisModel { 4 | /** 5 | * List layout. 6 | */ 7 | public layout?: string; 8 | 9 | /** 10 | * Indicated that an operations can be selected. 11 | */ 12 | public allowSelection: boolean; 13 | 14 | /** 15 | * Show API type. 16 | */ 17 | public showApiType: boolean; 18 | 19 | /** 20 | * Default GroupByTag to enabled. 21 | */ 22 | public defaultGroupByTagToEnabled: boolean; 23 | 24 | /** 25 | * Link to a page that contains operation details. 26 | */ 27 | public detailsPageHyperlink: HyperlinkModel; 28 | 29 | constructor(layout?: string) { 30 | this.layout = layout; 31 | } 32 | } -------------------------------------------------------------------------------- /catalog/src/components/app/app.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /catalog/src/components/code-editor/code-editor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
-------------------------------------------------------------------------------- /catalog/src/components/code-editor/code-editor.ts: -------------------------------------------------------------------------------- 1 | import * as ko from "knockout"; 2 | import template from "./code-editor.html"; 3 | import { Component, Event, OnMounted, Param } from "@paperbits/common/ko/decorators"; 4 | 5 | @Component({ 6 | selector: "code-editor", 7 | template: template 8 | }) 9 | export class CodeEditor { 10 | public readonly editorContent: ko.Observable; 11 | public readonly editorLoading: ko.Observable; 12 | 13 | @Param() 14 | public code: string; 15 | 16 | @Event() 17 | public onChange: (content: string) => void; 18 | 19 | constructor() { 20 | this.editorContent = ko.observable(); 21 | this.editorLoading = ko.observable(true); 22 | } 23 | 24 | @OnMounted() 25 | public async init(): Promise { 26 | this.editorContent(this.code); 27 | } 28 | } -------------------------------------------------------------------------------- /catalog/src/components/custom-html/constants.ts: -------------------------------------------------------------------------------- 1 | export const widgetName = "custom-html-code"; 2 | export const widgetDisplayName = "Custom HTML code"; 3 | export const widgetCategory = "Advanced"; 4 | export const widgetSelector = "custom-html"; 5 | export const widgetRuntimeSelector = "custom-html-runtime"; 6 | export const widgetEditorSelector = "custom-html-editor"; 7 | export const widgetIconClass = "widget-icon widget-icon-api-management"; -------------------------------------------------------------------------------- /catalog/src/components/custom-html/customHtml.design.module.ts: -------------------------------------------------------------------------------- 1 | import { IInjectorModule, IInjector } from "@paperbits/common/injection"; 2 | import { CustomHtmlEditorViewModel } from "./ko/customHtmlEditorViewModel"; 3 | import { HTMLInjectionHandlers } from "./customHtmlHandlers"; 4 | import { CustomHtmlViewModel, CustomHtmlViewModelBinder } from "./ko"; 5 | import { HTMLInjectionModelBinder } from "."; 6 | 7 | export class CustomHtmlDesignModule implements IInjectorModule { 8 | public register(injector: IInjector): void { 9 | injector.bind("customHtmlViewModel", CustomHtmlViewModel); 10 | injector.bind("customHtmlViewEditorModel", CustomHtmlEditorViewModel); 11 | injector.bindToCollection("modelBinders", HTMLInjectionModelBinder); 12 | injector.bindToCollection("viewModelBinders", CustomHtmlViewModelBinder); 13 | injector.bindToCollection("widgetHandlers", HTMLInjectionHandlers); 14 | } 15 | } -------------------------------------------------------------------------------- /catalog/src/components/custom-html/customHtml.publish.module.ts: -------------------------------------------------------------------------------- 1 | import { IInjectorModule, IInjector } from "@paperbits/common/injection"; 2 | import { CustomHtmlViewModel } from "./ko/customHtmlViewModel"; 3 | import { HTMLInjectionModelBinder } from "./customHtmlModelBinder"; 4 | import { CustomHtmlViewModelBinder } from "./ko/customHtmlViewModelBinder"; 5 | 6 | 7 | export class CustomHtmlPublishModule implements IInjectorModule { 8 | public register(injector: IInjector): void { 9 | injector.bind("customHtmlViewModel", CustomHtmlViewModel); 10 | injector.bindToCollection("modelBinders", HTMLInjectionModelBinder); 11 | injector.bindToCollection("viewModelBinders", CustomHtmlViewModelBinder); 12 | } 13 | } -------------------------------------------------------------------------------- /catalog/src/components/custom-html/customHtmlContract.ts: -------------------------------------------------------------------------------- 1 | import { LocalStyles } from "@paperbits/common/styles"; 2 | import { Contract } from "@paperbits/common"; 3 | 4 | export interface HTMLInjectionContract extends Contract { 5 | htmlCode: string; 6 | inheritStyling: boolean; 7 | styles: LocalStyles; 8 | } -------------------------------------------------------------------------------- /catalog/src/components/custom-html/customHtmlHandlers.ts: -------------------------------------------------------------------------------- 1 | import { widgetName, widgetDisplayName, widgetCategory, widgetIconClass } from "./constants"; 2 | import { IWidgetOrder, IWidgetHandler } from "@paperbits/common/editing"; 3 | import { HTMLInjectionModel } from "./customHtmlModel"; 4 | import { htmlCodeInitial, htmlCodeSizeStylesInitial } from "./ko/constants"; 5 | import { StyleHelper } from "@paperbits/styles"; 6 | 7 | export class HTMLInjectionHandlers implements IWidgetHandler { 8 | public async getWidgetOrder(): Promise { 9 | const widgetOrder: IWidgetOrder = { 10 | name: widgetName, 11 | category: widgetCategory, 12 | requires: [], 13 | displayName: widgetDisplayName, 14 | iconClass: widgetIconClass, 15 | 16 | createModel: async () => { 17 | const model = new HTMLInjectionModel(); 18 | model.htmlCode = htmlCodeInitial; 19 | model.inheritStyling = true; 20 | StyleHelper.setPluginConfigForLocalStyles(model.styles, "size", htmlCodeSizeStylesInitial); 21 | return model; 22 | } 23 | }; 24 | 25 | return widgetOrder; 26 | } 27 | } -------------------------------------------------------------------------------- /catalog/src/components/custom-html/customHtmlModel.ts: -------------------------------------------------------------------------------- 1 | import { LocalStyles } from "@paperbits/common/styles"; 2 | 3 | export class HTMLInjectionModel { 4 | public htmlCode: string; 5 | public inheritStyling: boolean; 6 | 7 | /** 8 | * Local styles. 9 | */ 10 | public styles: LocalStyles; 11 | 12 | constructor() { 13 | this.styles = {}; 14 | } 15 | } -------------------------------------------------------------------------------- /catalog/src/components/custom-html/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./constants"; 2 | export * from "./customHtmlHandlers"; 3 | export * from "./customHtmlModel"; 4 | export * from "./customHtmlModelBinder"; -------------------------------------------------------------------------------- /catalog/src/components/custom-html/ko/constants.ts: -------------------------------------------------------------------------------- 1 | import { SizeStylePluginConfig } from "@paperbits/styles/plugins"; 2 | 3 | export const htmlCodeInitial = 4 | ` 5 | 6 | 12 | 13 | 14 |
15 |

Custom HTML code example

16 |

Replace this content with custom HTML code. It will be rendered in an iframe in the developer portal.

17 | 20 |
21 | 22 | `; 23 | 24 | export const htmlCodeSizeStylesInitial: SizeStylePluginConfig = { 25 | height: "300px", 26 | width: "100%", 27 | }; -------------------------------------------------------------------------------- /catalog/src/components/custom-html/ko/customHtmlEditorView.html: -------------------------------------------------------------------------------- 1 |
2 | 4 | 5 | 6 | 12 | 13 | 17 | 18 |
-------------------------------------------------------------------------------- /catalog/src/components/custom-html/ko/customHtmlView.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /catalog/src/components/custom-html/ko/customHtmlViewModel.ts: -------------------------------------------------------------------------------- 1 | import * as ko from "knockout"; 2 | import template from "./customHtmlView.html"; 3 | import { widgetSelector } from "../constants"; 4 | import { Component } from "@paperbits/common/ko/decorators"; 5 | import { StyleModel } from "@paperbits/common/styles"; 6 | 7 | @Component({ 8 | selector: widgetSelector, 9 | template: template 10 | }) 11 | export class CustomHtmlViewModel { 12 | public readonly styles: ko.Observable; 13 | public readonly htmlCode: ko.Observable; 14 | 15 | constructor() { 16 | this.htmlCode = ko.observable(); 17 | this.styles = ko.observable(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /catalog/src/components/custom-html/ko/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./customHtmlEditorViewModel"; 2 | export * from "./customHtmlViewModel"; 3 | export * from "./customHtmlViewModelBinder"; 4 | -------------------------------------------------------------------------------- /catalog/src/components/file-input/file-input.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
6 |
-------------------------------------------------------------------------------- /catalog/src/components/operations/operation-details/ko/operationDetails.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /catalog/src/components/operations/operation-details/ko/operationDetailsViewModel.ts: -------------------------------------------------------------------------------- 1 | import * as ko from "knockout"; 2 | import template from "./operationDetails.html"; 3 | import { Component } from "@paperbits/common/ko/decorators"; 4 | 5 | @Component({ 6 | selector: "operationDetails", 7 | template: template 8 | }) 9 | export class OperationDetailsViewModel { 10 | public readonly config?: ko.Observable; 11 | 12 | constructor() { 13 | this.config = ko.observable(); 14 | } 15 | } -------------------------------------------------------------------------------- /catalog/src/components/operations/operation-details/ko/runtime/code-sample.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 9 |
10 |
11 |



--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/code-sample.ts:
--------------------------------------------------------------------------------
 1 | import * as ko from "knockout";
 2 | import template from "./code-sample.html";
 3 | import { Component, Param } from "@paperbits/common/ko/decorators";
 4 | 
 5 | 
 6 | @Component({
 7 |     selector: "code-sample",
 8 |     template: template
 9 | })
10 | export class CodeSampleViewModel {
11 |     public readonly label: ko.Computed;
12 | 
13 |     constructor() {
14 |         this.title = ko.observable();
15 |         this.content = ko.observable();
16 |         this.language = ko.observable();
17 |         this.label = ko.pureComputed(() => this.joinStringParts(this.title(), this.language()));
18 |     }
19 | 
20 |     @Param()
21 |     public readonly title: ko.Observable;
22 | 
23 |     @Param()
24 |     public readonly content: ko.Observable;
25 | 
26 |     @Param()
27 |     public readonly language: ko.Observable;
28 | 
29 |     private joinStringParts(...parts: string[]): string {
30 |         return parts.filter(x => !!x).join(" - ");
31 |     }
32 | }


--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/code-snippet.html:
--------------------------------------------------------------------------------
 1 | 
2 |
3 | 4 | 9 |
10 |
11 |



--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/code-snippet.ts:
--------------------------------------------------------------------------------
 1 | import * as ko from "knockout";
 2 | import template from "./code-snippet.html";
 3 | import { Component, Param } from "@paperbits/common/ko/decorators";
 4 | 
 5 | 
 6 | @Component({
 7 |     selector: "code-snippet",
 8 |     template: template
 9 | })
10 | export class CodeSnippet {
11 |     public readonly label: ko.Computed;
12 | 
13 |     constructor() {
14 |         this.title = ko.observable();
15 |         this.content = ko.observable();
16 |         this.language = ko.observable();
17 |         this.label = ko.pureComputed(() => this.joinStringParts(this.title(), this.language()));
18 |     }
19 | 
20 |     @Param()
21 |     public readonly title: ko.Observable;
22 | 
23 |     @Param()
24 |     public readonly content: ko.Observable;
25 | 
26 |     @Param()
27 |     public readonly language: ko.Observable;
28 | 
29 |     private joinStringParts(...parts: string[]): string {
30 |         return parts.filter(x => !!x).join(" - ");
31 |     }
32 | }


--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/oauth-server-configuration.ts:
--------------------------------------------------------------------------------
 1 | import * as ko from "knockout";
 2 | import template from "./oauth-server-configuration.html";
 3 | import { Component, OnMounted, Param } from "@paperbits/common/ko/decorators";
 4 | import { AuthorizationServer } from "../../../../../models/authorizationServer";
 5 | 
 6 | @Component({
 7 |     selector: "oauth-server-configuration",
 8 |     template: template,
 9 | })
10 | 
11 | export class OauthServerConfiguration {
12 | 
13 |     public displayedGrantFlows: ko.Observable;
14 |     public displayedScopes: ko.Observable;
15 | 
16 |     constructor() {
17 |         this.authorizationServer = ko.observable();
18 |         this.displayedGrantFlows = ko.observable();
19 |         this.displayedScopes = ko.observable();
20 |     }
21 | 
22 |     @Param()
23 |     public authorizationServer: ko.Observable;
24 | 
25 |     @OnMounted()
26 |     public async initialize(): Promise {
27 |         this.displayedGrantFlows(this.authorizationServer().grantTypes.join(', ').toString());
28 |         this.displayedScopes(this.authorizationServer().scopes.join(', ').toString());
29 |     }
30 | }


--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/oauthSession.ts:
--------------------------------------------------------------------------------
1 | export interface StoredCredentials {
2 |     grantType: string;
3 |     accessToken: string;
4 | }
5 | 
6 | export interface OAuthSession {
7 |     [apiName: string]: StoredCredentials;
8 | }


--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/responsePackage.ts:
--------------------------------------------------------------------------------
1 | import { NameValuePair } from "../../../../../contracts/nameValuePair";
2 | 
3 | export interface ResponsePackage {
4 |     statusCode: number;
5 |     statusMessage: string;
6 |     headers: NameValuePair[];
7 |     body: any;
8 | }


--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/templates/curl.liquid:
--------------------------------------------------------------------------------
 1 | curl -v -X {{method}} "{{requestUrl}}"
 2 | {% for header in request.meaningfulHeaders -%}
 3 | -H "{{ header.name }}: {{ header.displayedValue }}"
 4 | {% endfor -%}
 5 | {% if request.body != blank -%}
 6 | {%- if request.bodyFormat == "raw" -%}
 7 | --data-raw "{{ request.body | replace: '"','\\"'  }}"
 8 | {%- elsif request.bodyFormat == "binary" %}
 9 | --data-binary "@ < path/to/{{request.binary.name}} >"
10 | {% endif -%}
11 | {% endif -%}


--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/templates/http.liquid:
--------------------------------------------------------------------------------
 1 | {{method}} {{requestUrl}} HTTP/1.1
 2 | 
 3 | {% for header in request.meaningfulHeaders -%}
 4 | {{ header.name }}: {{ header.displayedValue }}
 5 | {% endfor %}
 6 | {% if request.body != blank and request.bodyFormat == "raw" -%}
 7 | {{ request.body }}
 8 | {% endif -%}
 9 | {% if request.binary != blank and request.bodyFormat == "binary" -%}
10 | [ {{ request.binary.name }} ]
11 | {% endif -%}


--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/templates/javascript.liquid:
--------------------------------------------------------------------------------
 1 | 
 2 | {%- if request.body != blank and request.bodyFormat == "raw" -%}
 3 | // Request body
 4 | const body = {{request.body}};
 5 | {%- endif %}
 6 | 
 7 | fetch('{{requestUrl}}', {
 8 |         method: '{{method | upcase}}',
 9 |         {%- if request.body != blank %}
10 |         body: JSON.stringify(body),
11 |         {%- endif -%}
12 |         {% if request.meaningfulHeaders.size > 0 %}
13 |         // Request headers
14 |         headers: {
15 |         {%- for header in request.meaningfulHeaders %}
16 |             '{{header.name}}': '{{header.displayedValue}}',
17 |         {%- endfor -%}
18 |         {%- endif -%}
19 |         }
20 |     })
21 |     .then(response => {
22 |         console.log(response.status);
23 |         console.log(response.text());
24 |     })
25 |     .catch(err => console.error(err));


--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/templates/php.liquid:
--------------------------------------------------------------------------------
 1 |  0 -%}
11 | # Request headers
12 | $headers = array(
13 | {%- for header in request.meaningfulHeaders %}
14 |     '{{header.name}}: {{header.displayedValue}}',
15 | {%- endfor -%});
16 | curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
17 | {%- endif %}
18 | {% if request.body != blank %}
19 | # Request body
20 | {% if request.bodyFormat == "raw" -%}
21 | $request_body = '{{request.body}}';
22 | {%- elsif  request.bodyFormat == "binary" %}
23 | $file = fopen("< path\\to\\{{request.binary.name}} >", "r");
24 | $request_body = fread($file,filesize("< path\\to\\{{request.binary.name}} >"));
25 | fclose($file);
26 | {% endif %}
27 | curl_setopt($curl, CURLOPT_POSTFIELDS, $request_body);
28 | {% endif %}
29 | $resp = curl_exec($curl);
30 | curl_close($curl);
31 | var_dump($resp);
32 | ?>


--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/templates/python.liquid:
--------------------------------------------------------------------------------
 1 | ########### Python 3.2 #############
 2 | import urllib.request, json
 3 | 
 4 | try:
 5 |     url = "{{requestUrl}}"
 6 | 
 7 |     hdr ={
 8 |     # Request headers
 9 | {%- for header in request.meaningfulHeaders %}
10 |     '{{header.name}}': '{{header.displayedValue}}',
11 | {%- endfor %}
12 |     }
13 | {% if request.body != blank %}
14 |     # Request body
15 | {%- if request.bodyFormat == "raw" %}
16 |     data =  {{request.body}}
17 |     data = json.dumps(data)
18 |     req = urllib.request.Request(url, headers=hdr, data = bytes(data.encode("utf-8")))
19 | {%- elsif  request.bodyFormat == "binary" %}
20 |     with open('< path/to/{{request.binary.name}} >', 'rb') as f:
21 |         data = f.read()
22 |     req = urllib.request.Request(url, headers=hdr, data = bytes(data))
23 | {%- endif %}
24 | {% else %}
25 |     req = urllib.request.Request(url, headers=hdr)
26 | {% endif %}
27 |     req.get_method = lambda: '{{method}}'
28 |     response = urllib.request.urlopen(req)
29 |     print(response.getcode())
30 |     print(response.read())
31 | except Exception as e:
32 |     print(e)
33 | ####################################


--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/templates/ruby.liquid:
--------------------------------------------------------------------------------
 1 | require 'net/http'
 2 | 
 3 | uri = URI('{{requestUrl}}')
 4 | 
 5 | 
 6 | request = Net::HTTP::{{ method | downcase | capitalize }}.new(uri.request_uri)
 7 | 
 8 | # Request headers
 9 | {% for header in request.meaningfulHeaders -%}
10 | request['{{header.name}}'] = '{{header.displayedValue}}'
11 | {% endfor %}
12 | {% if request.body != blank -%}
13 | # Request body
14 | {% if request.bodyFormat == "raw" -%}
15 | request.body = '{{ request.body }}'
16 | {%- elsif  request.bodyFormat == "binary" -%}
17 | request.body = File.read("< path/to/{{request.binary.name}} >")
18 | {% endif %}
19 | {% endif %}
20 | response = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
21 |     http.request(request)
22 | end
23 | 
24 | puts response.code
25 | puts response.body
26 | 


--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/templates/templates.ts:
--------------------------------------------------------------------------------
 1 | import * as curl from "./curl.liquid";
 2 | import * as csharp from "./csharp.liquid";
 3 | import * as http from "./http.liquid";
 4 | import * as java from "./java.liquid";
 5 | import * as javascript from "./javascript.liquid";
 6 | import * as php from "./php.liquid";
 7 | import * as python from "./python.liquid";
 8 | import * as ruby from "./ruby.liquid";
 9 | import * as swift from "./swift.liquid"
10 | import * as ws_wscat from "./ws_wscat.liquid";
11 | import * as ws_csharp from "./ws_csharp.liquid";
12 | import * as ws_javascript from "./ws_javascript.liquid";
13 | 
14 | export const templates = {
15 |     curl: curl.default,
16 |     csharp: csharp.default,
17 |     http: http.default,
18 |     java: java.default,
19 |     javascript: javascript.default,
20 |     php: php.default,
21 |     python: python.default,
22 |     ruby: ruby.default,
23 |     swift: swift.default,
24 |     ws_wscat: ws_wscat.default,
25 |     ws_csharp: ws_csharp.default,
26 |     ws_javascript: ws_javascript.default,
27 | 
28 | };


--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/templates/ws_javascript.liquid:
--------------------------------------------------------------------------------
 1 | let socket = new WebSocket("{{displayedWsUrl}}");
 2 | 
 3 | socket.onopen = function(e) {
 4 |   alert("[open] Connection established");
 5 |   alert("Sending to server");
 6 |   socket.send("My name is John");
 7 | };
 8 | 
 9 | socket.onmessage = function(event) {
10 |   alert(`[message] Data received from server: ${event.data}`);
11 | };
12 | 
13 | socket.onclose = function(event) {
14 |   if (event.wasClean) {
15 |     alert(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
16 |   } else {
17 |     // e.g. server process killed or network down
18 |     // event.code is usually 1006 in this case
19 |     alert('[close] Connection died');
20 |   }
21 | };
22 | 
23 | socket.onerror = function(error) {
24 |   alert(`[error] ${error.message}`);
25 | };


--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/templates/ws_wscat.liquid:
--------------------------------------------------------------------------------
1 | wscat -c {{displayedWsUrl}}


--------------------------------------------------------------------------------
/catalog/src/components/operations/operation-details/ko/runtime/type-definition-enum.html:
--------------------------------------------------------------------------------
 1 | 
2 |
3 |
4 |
Type
5 |
Values
6 |
7 |
8 |
9 |
10 |
12 | 13 |
14 | 15 | , 16 | 17 | 18 |
19 |
20 |
21 |
-------------------------------------------------------------------------------- /catalog/src/components/operations/operation-details/operationDetails.design.module.ts: -------------------------------------------------------------------------------- 1 | import { IInjectorModule, IInjector } from "@paperbits/common/injection"; 2 | import { OperationDetailsHandlers } from "./operationDetailsHandlers"; 3 | import { OperationDetailsEditor } from "./ko/operationDetailsEditor"; 4 | import { OperationDetailsModelBinder } from "./operationDetailsModelBinder"; 5 | import { OperationDetailsViewModelBinder } from "./ko/operationDetailsViewModelBinder"; 6 | 7 | 8 | export class OperationDetailsDesignModule implements IInjectorModule { 9 | public register(injector: IInjector): void { 10 | injector.bind("operationDetailsEditor", OperationDetailsEditor); 11 | injector.bindToCollection("widgetHandlers", OperationDetailsHandlers, "operationDetailsHandlers"); 12 | injector.bindToCollection("modelBinders", OperationDetailsModelBinder); 13 | injector.bindToCollection("viewModelBinders", OperationDetailsViewModelBinder); 14 | } 15 | } -------------------------------------------------------------------------------- /catalog/src/components/operations/operation-details/operationDetails.publish.module.ts: -------------------------------------------------------------------------------- 1 | import { IInjectorModule, IInjector } from "@paperbits/common/injection"; 2 | import { OperationDetailsModelBinder } from "./operationDetailsModelBinder"; 3 | import { OperationDetailsViewModelBinder } from "./ko/operationDetailsViewModelBinder"; 4 | 5 | 6 | export class OperationDetailsPublishModule implements IInjectorModule { 7 | public register(injector: IInjector): void { 8 | injector.bindToCollection("modelBinders", OperationDetailsModelBinder); 9 | injector.bindToCollection("viewModelBinders", OperationDetailsViewModelBinder); 10 | } 11 | } -------------------------------------------------------------------------------- /catalog/src/components/operations/operation-details/operationDetailsContract.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from "@paperbits/common"; 2 | 3 | export interface OperationDetailsContract extends Contract { 4 | /** 5 | * Indicates whether "Try" button should appear on the operation details widget. 6 | */ 7 | enableConsole?: boolean; 8 | 9 | /** 10 | * Defines how schema gets presented in operation details by default, e.g. "table" or "raw". 11 | */ 12 | defaultSchemaView?: string; 13 | 14 | /** 15 | * Indicates whether operation details should appear in the visible area (for example if API details is too long). 16 | */ 17 | enableScrollTo?: boolean; 18 | 19 | /** 20 | * Indicates whether the Test console should use CORS proxy vs direct calls from the browser. 21 | */ 22 | useCorsProxy?: boolean; 23 | } 24 | -------------------------------------------------------------------------------- /catalog/src/components/operations/operation-details/operationDetailsModel.ts: -------------------------------------------------------------------------------- 1 | export class OperationDetailsModel { 2 | /** 3 | * Indicates whether "Try" button should appear on the operation details widget. 4 | */ 5 | public enableConsole?: boolean; 6 | 7 | /** 8 | * Defines how schema gets presented in operation details by default, e.g. "table" or "raw". 9 | */ 10 | public defaultSchemaView?: string; 11 | 12 | /** 13 | * Indicates whether operation details should appear in the visible area (for example if API details is too long). 14 | */ 15 | public enableScrollTo?: boolean; 16 | 17 | /** 18 | * Indicates whether the Test console should use CORS proxy vs direct calls from the browser. 19 | */ 20 | public useCorsProxy?: boolean; 21 | 22 | constructor() { 23 | this.enableConsole = true; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /catalog/src/components/operations/operation-list/ko/operationList.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /catalog/src/components/operations/operation-list/ko/operationList.module.ts: -------------------------------------------------------------------------------- 1 | import { IInjectorModule, IInjector } from "@paperbits/common/injection"; 2 | import { OperationListModelBinder } from "../operationListModelBinder"; 3 | import { OperationListViewModelBinder } from "./operationListViewModelBinder"; 4 | 5 | 6 | export class OperationListModule implements IInjectorModule { 7 | public register(injector: IInjector): void { 8 | injector.bindToCollection("modelBinders", OperationListModelBinder); 9 | injector.bindToCollection("viewModelBinders", OperationListViewModelBinder); 10 | } 11 | } -------------------------------------------------------------------------------- /catalog/src/components/operations/operation-list/ko/operationListEditor.module.ts: -------------------------------------------------------------------------------- 1 | import { IInjectorModule, IInjector } from "@paperbits/common/injection"; 2 | import { OperationListHandlers } from "../operationListHandlers"; 3 | import { OperationListEditor } from "./operationListEditor"; 4 | 5 | export class OperationListEditorModule implements IInjectorModule { 6 | public register(injector: IInjector): void { 7 | injector.bind("operationListEditor", OperationListEditor); 8 | injector.bindToCollection("widgetHandlers", OperationListHandlers, "operationListHandlers"); 9 | } 10 | } -------------------------------------------------------------------------------- /catalog/src/components/operations/operation-list/ko/operationListViewModel.ts: -------------------------------------------------------------------------------- 1 | import * as ko from "knockout"; 2 | import template from "./operationList.html"; 3 | import { Component } from "@paperbits/common/ko/decorators"; 4 | 5 | @Component({ 6 | selector: "operationList", 7 | template: template 8 | }) 9 | export class OperationListViewModel { 10 | public readonly runtimeConfig: ko.Observable; 11 | 12 | constructor() { 13 | this.runtimeConfig = ko.observable(); 14 | } 15 | } -------------------------------------------------------------------------------- /catalog/src/components/operations/operation-list/operationListContract.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from "@paperbits/common"; 2 | import { HyperlinkContract } from "@paperbits/common/editing"; 3 | 4 | /** 5 | * Operation list widget configuration. 6 | */ 7 | export interface OperationListContract extends Contract { 8 | /** 9 | * Indicated that an operation can be selected. 10 | */ 11 | allowSelection: boolean; 12 | 13 | /** 14 | * Indicated that an operations name should wraps to new line if it's too long. 15 | */ 16 | wrapText: boolean; 17 | 18 | /** 19 | * Allow switching between URL paths and operation names 20 | */ 21 | showToggleUrlPath: boolean; 22 | 23 | /** 24 | * Show URL paths instead of operation names by default. 25 | */ 26 | defaultShowUrlPath: boolean; 27 | 28 | /** 29 | * Default GroupByTag to enabled. 30 | */ 31 | defaultGroupByTagToEnabled?: boolean; 32 | 33 | /** 34 | * Link to a page that contains operation details. 35 | */ 36 | detailsPageHyperlink?: HyperlinkContract; 37 | } 38 | -------------------------------------------------------------------------------- /catalog/src/components/operations/operation-list/operationListHandlers.ts: -------------------------------------------------------------------------------- 1 | import { IWidgetOrder, IWidgetHandler } from "@paperbits/common/editing"; 2 | import { OperationListModel } from "./operationListModel"; 3 | 4 | export class OperationListHandlers implements IWidgetHandler { 5 | public async getWidgetOrder(): Promise { 6 | const widgetOrder: IWidgetOrder = { 7 | name: "operationList", 8 | category: "Operations", 9 | displayName: "List of operations", 10 | iconClass: "widget-icon widget-icon-api-management", 11 | requires: ["html"], 12 | createModel: async () => new OperationListModel() 13 | }; 14 | 15 | return widgetOrder; 16 | } 17 | } -------------------------------------------------------------------------------- /catalog/src/components/operations/operation-list/operationListModel.ts: -------------------------------------------------------------------------------- 1 | import { HyperlinkModel } from "@paperbits/common/permalinks"; 2 | 3 | export class OperationListModel { 4 | /** 5 | * Indicated that an operations can be selected. 6 | */ 7 | public allowSelection: boolean; 8 | 9 | /** 10 | * Indicated that an operations name should wraps to new line if it's too long. 11 | */ 12 | public wrapText: boolean; 13 | 14 | /** 15 | * Allow switching between URL paths and operation names 16 | */ 17 | public showToggleUrlPath: boolean; 18 | 19 | /** 20 | * Show URL paths instead of operation names by default. 21 | */ 22 | public defaultShowUrlPath: boolean; 23 | 24 | /** 25 | * Default GroupByTag to enabled. 26 | */ 27 | public defaultGroupByTagToEnabled: boolean; 28 | 29 | /** 30 | * Link to a page that contains operation details. 31 | */ 32 | public detailsPageHyperlink: HyperlinkModel; 33 | } 34 | -------------------------------------------------------------------------------- /catalog/src/components/spinner/spinner.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
-------------------------------------------------------------------------------- /catalog/src/components/spinner/spinner.ts: -------------------------------------------------------------------------------- 1 | import template from "./spinner.html"; 2 | import { Component } from "@paperbits/common/ko/decorators"; 3 | 4 | @Component({ 5 | selector: "spinner", 6 | template: template 7 | }) 8 | export class Spinner { } -------------------------------------------------------------------------------- /catalog/src/components/staticAuthenticator.ts: -------------------------------------------------------------------------------- 1 | import { IAuthenticator, AccessToken } from "../authentication"; 2 | 3 | export class StaticAuthenticator implements IAuthenticator { 4 | private accessToken: AccessToken; 5 | 6 | public async getAccessToken(): Promise { 7 | return this.accessToken; 8 | } 9 | 10 | public async getAccessTokenAsString(): Promise { 11 | return this.accessToken.toString(); 12 | } 13 | 14 | public async setAccessToken(accessToken: AccessToken): Promise { 15 | this.accessToken = accessToken; 16 | } 17 | 18 | public clearAccessToken(): void { 19 | this.accessToken = undefined; 20 | } 21 | 22 | public async isAuthenticated(): Promise { 23 | const accessToken = await this.getAccessTokenAsString(); 24 | return !!accessToken; 25 | } 26 | } -------------------------------------------------------------------------------- /catalog/src/components/staticSettingsProvider.ts: -------------------------------------------------------------------------------- 1 | import { ISettingsProvider } from "@paperbits/common/configuration"; 2 | 3 | export class StaticSettingsProvider implements ISettingsProvider { 4 | constructor(private readonly configuration: Object) { } 5 | 6 | public getSetting(name: string): Promise { 7 | return this.configuration[name]; 8 | } 9 | 10 | public async setSetting(name: string, value: T): Promise { 11 | this.configuration[name] = value; 12 | } 13 | 14 | public async getSettings(): Promise { 15 | return this.configuration; 16 | } 17 | } -------------------------------------------------------------------------------- /catalog/src/components/tag-input/tag-input.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 6 | 9 |
10 | 11 | 12 |
14 | 15 |
16 |
-------------------------------------------------------------------------------- /catalog/src/components/tag-input/tag-list.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 5 |
6 | 7 | 8 |
9 |
10 |
11 |
12 |
13 | 14 | 15 | 16 |
17 |
No tags found
18 |
19 | 20 |
-------------------------------------------------------------------------------- /catalog/src/components/users/validation-summary/ko/runtime/validation-summary.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
-------------------------------------------------------------------------------- /catalog/src/components/users/validation-summary/ko/validationSummary.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /catalog/src/components/users/validation-summary/ko/validationSummaryEditor.html: -------------------------------------------------------------------------------- 1 |
2 | Coming soon 3 |

4 | An editor for this widget is not yet ready.
5 |

6 |
-------------------------------------------------------------------------------- /catalog/src/components/users/validation-summary/ko/validationSummaryEditor.ts: -------------------------------------------------------------------------------- 1 | import template from "./validationSummaryEditor.html"; 2 | import { Component, Param } from "@paperbits/common/ko/decorators"; 3 | import { ValidationSummaryModel } from "../../validation-summary/validationSummaryModel"; 4 | 5 | @Component({ 6 | selector: "validation-summary-editor", 7 | template: template 8 | }) 9 | export class ValidationSummaryEditor { 10 | @Param() 11 | public model: ValidationSummaryModel; 12 | } -------------------------------------------------------------------------------- /catalog/src/components/users/validation-summary/ko/validationSummaryViewModel.ts: -------------------------------------------------------------------------------- 1 | import template from "./validationSummary.html"; 2 | import { Component } from "@paperbits/common/ko/decorators"; 3 | 4 | @Component({ 5 | selector: "validationSummary", 6 | template: template 7 | }) 8 | export class ValidationSummaryViewModel { 9 | } -------------------------------------------------------------------------------- /catalog/src/components/users/validation-summary/ko/validationSummaryViewModelBinder.ts: -------------------------------------------------------------------------------- 1 | import { Bag } from "@paperbits/common"; 2 | import { ComponentFlow } from "@paperbits/common/editing"; 3 | import { ViewModelBinder } from "@paperbits/common/widgets"; 4 | import { ValidationSummaryModel } from "../validationSummaryModel"; 5 | import { ValidationSummaryViewModel } from "./validationSummaryViewModel"; 6 | 7 | 8 | export class ValidationSummaryViewModelBinder implements ViewModelBinder { 9 | public async modelToViewModel(model: ValidationSummaryModel, viewModel?: ValidationSummaryViewModel, bindingContext?: Bag): Promise { 10 | if (!viewModel) { 11 | viewModel = new ValidationSummaryViewModel(); 12 | 13 | viewModel["widgetBinding"] = { 14 | displayName: "Validation summary", 15 | model: model, 16 | flow: ComponentFlow.Block, 17 | draggable: true 18 | }; 19 | } 20 | 21 | return viewModel; 22 | } 23 | 24 | public canHandleModel(model: ValidationSummaryModel): boolean { 25 | return model instanceof ValidationSummaryModel; 26 | } 27 | } -------------------------------------------------------------------------------- /catalog/src/components/users/validation-summary/validationSummary.design.module.ts: -------------------------------------------------------------------------------- 1 | import { IInjectorModule, IInjector } from "@paperbits/common/injection"; 2 | import { ValidationSummaryHandlers } from "./validationSummaryHandlers"; 3 | import { ValidationSummaryEditor } from "./ko/validationSummaryEditor"; 4 | 5 | export class ValidationSummaryDesignModule implements IInjectorModule { 6 | public register(injector: IInjector): void { 7 | injector.bind("validationSummaryEditor", ValidationSummaryEditor); 8 | injector.bindToCollection("widgetHandlers", ValidationSummaryHandlers, "validationSummaryHandlers"); 9 | } 10 | } -------------------------------------------------------------------------------- /catalog/src/components/users/validation-summary/validationSummary.module.ts: -------------------------------------------------------------------------------- 1 | import { IInjectorModule, IInjector } from "@paperbits/common/injection"; 2 | import { ValidationSummaryModelBinder } from "./validationSummaryModelBinder"; 3 | import { ValidationSummaryViewModelBinder } from "./ko/validationSummaryViewModelBinder"; 4 | 5 | 6 | export class ValidationSummaryModule implements IInjectorModule { 7 | public register(injector: IInjector): void { 8 | injector.bindToCollection("modelBinders", ValidationSummaryModelBinder); 9 | injector.bindToCollection("viewModelBinders", ValidationSummaryViewModelBinder); 10 | } 11 | } -------------------------------------------------------------------------------- /catalog/src/components/users/validation-summary/validationSummaryContract.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from "@paperbits/common"; 2 | 3 | export interface ValidationSummaryContract extends Contract { } -------------------------------------------------------------------------------- /catalog/src/components/users/validation-summary/validationSummaryHandlers.ts: -------------------------------------------------------------------------------- 1 | import { IWidgetOrder, IWidgetHandler } from "@paperbits/common/editing"; 2 | import { ValidationSummaryModel } from "../validation-summary/validationSummaryModel"; 3 | 4 | export class ValidationSummaryHandlers implements IWidgetHandler { 5 | public async getWidgetOrder(): Promise { 6 | const widgetOrder: IWidgetOrder = { 7 | name: "validation-summary", 8 | category: "User", 9 | displayName: "Validation summary", 10 | iconClass: "widget-icon widget-icon-api-management", 11 | requires: ["html"], 12 | createModel: async () => new ValidationSummaryModel() 13 | }; 14 | 15 | return widgetOrder; 16 | } 17 | } -------------------------------------------------------------------------------- /catalog/src/components/users/validation-summary/validationSummaryModel.ts: -------------------------------------------------------------------------------- 1 | export class ValidationSummaryModel { } 2 | -------------------------------------------------------------------------------- /catalog/src/components/users/validation-summary/validationSummaryModelBinder.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from "@paperbits/common"; 2 | import { IModelBinder } from "@paperbits/common/editing"; 3 | import { ValidationSummaryModel } from "./validationSummaryModel"; 4 | import { ValidationSummaryContract } from "./validationSummaryContract"; 5 | 6 | 7 | export class ValidationSummaryModelBinder implements IModelBinder { 8 | public canHandleModel(model: Object): boolean { 9 | return model instanceof ValidationSummaryModel; 10 | } 11 | 12 | public async contractToModel(contract: ValidationSummaryContract): Promise { 13 | return new ValidationSummaryModel(); 14 | } 15 | 16 | public canHandleContract(contract: Contract): boolean { 17 | return contract.type === "validationSummary"; 18 | } 19 | 20 | public modelToContract(model: ValidationSummaryModel): Contract { 21 | const contract: ValidationSummaryContract = { 22 | type: "validationSummary" 23 | }; 24 | 25 | return contract; 26 | } 27 | } -------------------------------------------------------------------------------- /catalog/src/config.design.json: -------------------------------------------------------------------------------- 1 | { 2 | "environment": "development" 3 | } -------------------------------------------------------------------------------- /catalog/src/config.host.json: -------------------------------------------------------------------------------- 1 | { 2 | "environment": "host", 3 | "dataFilesPath": "../../data", 4 | "mediaFilesPath": "../../data/media", 5 | "openapiSpecsPath": "../../../api-specs" 6 | } -------------------------------------------------------------------------------- /catalog/src/config.publish.json: -------------------------------------------------------------------------------- 1 | { 2 | "environment": "publishing", 3 | "dataFilesPath": "../../data", 4 | "mediaFilesPath": "../../data/media", 5 | "openapiSpecsPath": "../../../api-specs" 6 | } -------------------------------------------------------------------------------- /catalog/src/config.runtime.json: -------------------------------------------------------------------------------- 1 | { 2 | "environment": "runtime" 3 | } -------------------------------------------------------------------------------- /catalog/src/contracts/aadB2CClientConfig.ts: -------------------------------------------------------------------------------- 1 | export interface AadB2CClientConfig { 2 | /** 3 | * Client ID of the Application in the external Identity Provider. 4 | * It is App ID for Facebook login, Client ID for Google login, App ID for Microsoft. 5 | */ 6 | clientId: string; 7 | 8 | /** 9 | * OpenID Connect discovery endpoint hostname for AAD or AAD B2C, e.g. login.windows.net 10 | */ 11 | authority: string; 12 | 13 | /** 14 | * The TenantId to use instead of Common when logging into Active Directory. 15 | */ 16 | signinTenant: string; 17 | 18 | /** 19 | * Sign-in policy name. Only applies to AAD B2C identity provider. 20 | */ 21 | signinPolicyName: string; 22 | 23 | /** 24 | * Sign-up policy name. Only applies to AAD B2C identity provider. 25 | */ 26 | signupPolicyName: string; 27 | 28 | /** 29 | * Password reset policy name. Only applies to AAD B2C identity provider. 30 | */ 31 | passwordResetPolicyName: string; 32 | } -------------------------------------------------------------------------------- /catalog/src/contracts/aadClientConfig.ts: -------------------------------------------------------------------------------- 1 | export interface AadClientConfig { 2 | /** 3 | * Client ID of the Application in the external Identity Provider. 4 | * It is App ID for Facebook login, Client ID for Google login, App ID for Microsoft. 5 | */ 6 | clientId: string; 7 | 8 | /** 9 | * OpenID Connect discovery endpoint hostname for AAD or AAD B2C, e.g. login.windows.net 10 | */ 11 | authority: string; 12 | 13 | /** 14 | * The TenantId to use instead of Common when logging into Active Directory. 15 | */ 16 | signinTenant: string; 17 | } -------------------------------------------------------------------------------- /catalog/src/contracts/apiChangeLog.ts: -------------------------------------------------------------------------------- 1 | import { ArmResource } from "./armResource"; 2 | 3 | /** 4 | * Contract of API change log's property 5 | */ 6 | export interface ChangeLogPropertyContract { 7 | 8 | /** 9 | * The date when this API change log is created 10 | */ 11 | createdDateTime?: string; 12 | 13 | /** 14 | * The date when this API change log is edited and updated 15 | */ 16 | updatedDateTime?: string; 17 | 18 | /** 19 | * The notes of this API change 20 | */ 21 | notes?: string; 22 | } 23 | 24 | /** 25 | * Contract of API change log 26 | */ 27 | export interface ChangeLogContract extends ArmResource { 28 | properties: ChangeLogPropertyContract; 29 | } -------------------------------------------------------------------------------- /catalog/src/contracts/apiTagDescription.ts: -------------------------------------------------------------------------------- 1 | import { TagContract } from "./tag"; 2 | 3 | export interface ApiTagDescriptionContract { 4 | /** 5 | * Example: /apiTagDescriptions/DCD501300701F346BA206320 6 | */ 7 | id: string; 8 | 9 | /** 10 | * Example: /apis/echo-api 11 | */ 12 | apiId: string; 13 | 14 | /** 15 | * Example: /tags/34CB3A8E1F77FB46BFD268E9 16 | */ 17 | tagId: string; 18 | 19 | description: string; 20 | 21 | externalDocsDescription: string; 22 | 23 | externalDocsUrl: string; 24 | 25 | tag: TagContract; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /catalog/src/contracts/apiVersionSet.ts: -------------------------------------------------------------------------------- 1 | import { ArmResource } from "./armResource"; 2 | 3 | export interface VersionSetPropertiesContract { 4 | displayName?: string; 5 | description?: string; 6 | versioningScheme?: string; 7 | versionQueryName?: string; 8 | versionHeaderName?: string; 9 | } 10 | 11 | export interface VersionSetContract extends ArmResource { 12 | properties: VersionSetPropertiesContract; 13 | } -------------------------------------------------------------------------------- /catalog/src/contracts/armResource.ts: -------------------------------------------------------------------------------- 1 | export interface ArmResource { 2 | id?: string; 3 | type?: string; 4 | name?: string; 5 | properties: any; 6 | } -------------------------------------------------------------------------------- /catalog/src/contracts/authenticationSettings.ts: -------------------------------------------------------------------------------- 1 | export interface BearerTokenSendingMethod { 2 | sendingMethodType: string; 3 | isChecked: boolean; 4 | } 5 | 6 | export interface OAuth2AuthenticationSettings { 7 | authorizationServerId?: string; 8 | scope?: string; 9 | } 10 | 11 | export interface OpenIdAuthenticationSettings { 12 | openidProviderId?: string; 13 | bearerTokenSendingMethods?: BearerTokenSendingMethod[]; 14 | } 15 | 16 | export interface AuthenticationSettings { 17 | oAuth2?: OAuth2AuthenticationSettings; 18 | openid?: OpenIdAuthenticationSettings; 19 | } -------------------------------------------------------------------------------- /catalog/src/contracts/captchaParams.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Cotract of HipCaptcha params 3 | */ 4 | 5 | export interface CaptchaParams { 6 | HipUrl: string; 7 | EncryptedFlowId: string; 8 | } 9 | -------------------------------------------------------------------------------- /catalog/src/contracts/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Example object. 3 | */ 4 | export interface Example { 5 | /** 6 | * Example description. 7 | */ 8 | description: string; 9 | 10 | /** 11 | * Example value. 12 | */ 13 | value: any; 14 | 15 | /** 16 | * A URL that points to the example 17 | */ 18 | externalValue: string; 19 | } -------------------------------------------------------------------------------- /catalog/src/contracts/hostname.ts: -------------------------------------------------------------------------------- 1 | import { ArmResource } from "./armResource"; 2 | 3 | export interface Hostname extends ArmResource { 4 | properties: HostnameProperties; 5 | } 6 | 7 | export interface HostnameProperties { 8 | value: string; 9 | } -------------------------------------------------------------------------------- /catalog/src/contracts/identity.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * User identity contract. 3 | */ 4 | export interface Identity { 5 | /** 6 | * User unique identifier. 7 | */ 8 | id: string; 9 | } -------------------------------------------------------------------------------- /catalog/src/contracts/identitySettings.ts: -------------------------------------------------------------------------------- 1 | import { ArmResource } from "./armResource"; 2 | 3 | /** 4 | * Contract that describes the identity setting for signup 5 | */ 6 | export interface IdentitySettingContract extends ArmResource { 7 | /** 8 | * The id of the identity settings 9 | */ 10 | id: string; 11 | 12 | /** 13 | * The name of the identity settings, ex. signup 14 | */ 15 | name: string; 16 | 17 | /** 18 | * The property of the identity settings 19 | */ 20 | properties: IdentitySettingProperties; 21 | } 22 | 23 | export interface IdentitySettingProperties { 24 | /** 25 | * Enable setting edition 26 | */ 27 | enabled: boolean; 28 | 29 | /** 30 | * Terms of service: including term of use; require consent for the term of use 31 | */ 32 | termsOfService: TermsOfService; 33 | } 34 | 35 | export interface TermsOfService { 36 | /** 37 | * Require the consent of the term of use 38 | */ 39 | consentRequired: boolean; 40 | 41 | /** 42 | * Show terms of use on signup page 43 | */ 44 | enabled: boolean; 45 | 46 | /** 47 | * The content of the term of use 48 | */ 49 | text: string; 50 | } 51 | -------------------------------------------------------------------------------- /catalog/src/contracts/jwtToken.ts: -------------------------------------------------------------------------------- 1 | export interface JwtToken { 2 | /** 3 | * Authentication context class 4 | */ 5 | acr: string; 6 | 7 | /** 8 | * Authentication methods array 9 | */ 10 | amr: string[]; 11 | 12 | /** 13 | * Application ID 14 | */ 15 | appid: string; 16 | 17 | /** 18 | * Audience (who or what the token is intended for) 19 | */ 20 | aud: string; 21 | 22 | /** 23 | * Expiration time. 24 | */ 25 | exp: Date; 26 | 27 | /** 28 | * Family name of the user 29 | */ 30 | family_name: string; 31 | 32 | /** 33 | * Given name of the user 34 | */ 35 | given_name: string; 36 | 37 | /** 38 | * Issued at. 39 | */ 40 | iat: Date; 41 | 42 | /** 43 | * IP address 44 | */ 45 | ipaddr: string; 46 | 47 | /** 48 | * Issuer (who created and signed this token) 49 | */ 50 | iss: string; 51 | 52 | /** 53 | * Not valid before. 54 | */ 55 | nbf: Date; 56 | 57 | /** 58 | * Object ID. 59 | */ 60 | oid: string; 61 | 62 | /** 63 | * Subject (whom the token refers to) 64 | */ 65 | sub: string; 66 | 67 | /** 68 | * Email address. 69 | */ 70 | email: string; 71 | 72 | /** 73 | * Array of email addresses, e.g. AAD B2C. 74 | */ 75 | emails: string; 76 | } -------------------------------------------------------------------------------- /catalog/src/contracts/nameValuePair.ts: -------------------------------------------------------------------------------- 1 | export interface NameValuePair { 2 | name: string; 3 | value: string; 4 | } 5 | -------------------------------------------------------------------------------- /catalog/src/contracts/oauthSession.ts: -------------------------------------------------------------------------------- 1 | export interface OAuthSession { 2 | authenticationFlow: string; 3 | authenticationCallback: (accessToken: string) => void; 4 | authenticationErrorCallback: (error: Error) => void; 5 | loginUrl: string; 6 | redirectUri: string; 7 | clientId: string; 8 | issuer: string; 9 | tokenEndpoint: string; 10 | scope: string; 11 | } -------------------------------------------------------------------------------- /catalog/src/contracts/openIdConnectMetadata.ts: -------------------------------------------------------------------------------- 1 | export interface OpenIdConnectMetadata { 2 | /** 3 | * e.g. "https://sts.windows.net/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx". 4 | */ 5 | issuer: string; 6 | 7 | /** 8 | * e.g. "https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/oauth2/v2.0/authorize". 9 | */ 10 | authorization_endpoint: string; 11 | 12 | /** 13 | * e.g. "https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/oauth2/token". 14 | */ 15 | token_endpoint: string; 16 | 17 | /** 18 | * e.g. "openid". 19 | */ 20 | scopes_supported: string[]; 21 | 22 | /** 23 | * e.g. "code", "id_token", "code id_token", "token id_token", "token". 24 | */ 25 | response_types_supported: string[]; 26 | 27 | /** 28 | * e.g. "query", "fragment", "form_post". 29 | */ 30 | response_modes_supported: string[]; 31 | 32 | /** 33 | * e.g. "authorization_code", "implicit". 34 | */ 35 | grant_types_supported: string[]; 36 | 37 | /** 38 | * e.g. "client_secret_post", "private_key_jwt", "client_secret_basic". 39 | */ 40 | token_endpoint_auth_methods_supported: string[]; 41 | } -------------------------------------------------------------------------------- /catalog/src/contracts/openIdConnectProvider.ts: -------------------------------------------------------------------------------- 1 | import { ArmResource } from "./armResource"; 2 | 3 | /** 4 | * OpenId Connect Provider details. 5 | */ 6 | export interface OpenIdConnectProviderContract extends ArmResource { 7 | properties: OpenIdConnectProviderProperties; 8 | } 9 | 10 | export interface OpenIdConnectProviderProperties { 11 | /** 12 | * User-friendly OpenID Connect Provider name. 13 | */ 14 | displayName: string; 15 | 16 | /** 17 | * User-friendly description of OpenID Connect Provider. 18 | */ 19 | description: string; 20 | 21 | /** 22 | * Metadata endpoint URI. 23 | */ 24 | metadataEndpoint: string; 25 | 26 | /** 27 | * Client ID of developer console which is the client application. 28 | */ 29 | clientId: string; 30 | 31 | /** 32 | * Client Secret of developer console which is the client application. 33 | */ 34 | clientSecret: string; 35 | } -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./openApiComponents"; 2 | export * from "./openApiExample"; 3 | export * from "./openApiExternalDoc"; 4 | export * from "./openApiMediaType"; 5 | export * from "./openApiObjectInfo"; 6 | export * from "./openApiOperation"; 7 | export * from "./openApiParameter"; 8 | export * from "./openApiPath"; 9 | export * from "./openApiPaths"; 10 | export * from "./openApiReference"; 11 | export * from "./openApiRequestBody"; 12 | export * from "./openApiResponse"; 13 | export * from "./openApiResponses"; 14 | export * from "./openApiSchema"; 15 | export * from "./openApiServer"; 16 | export * from "./openApiTag"; -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiComponents.ts: -------------------------------------------------------------------------------- 1 | export interface OpenApiComponents { 2 | schemas?: any; 3 | } -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiExample.ts: -------------------------------------------------------------------------------- 1 | export interface OpenApiExample { 2 | /** 3 | * Short description for the example. 4 | */ 5 | summary: string; 6 | 7 | /** 8 | * Long description for the example. 9 | */ 10 | description: string; 11 | 12 | /** 13 | * Embedded literal example. The value field and externalValue field are mutually exclusive. To represent examples of media types that cannot naturally represented in JSON or YAML, use a string value to contain the example, escaping where necessary. 14 | */ 15 | value: any; 16 | 17 | /** 18 | * A URL that points to the literal example. This provides the capability to reference examples that cannot easily be included in JSON or YAML documents. The value field and externalValue field are mutually exclusive. 19 | */ 20 | externalValue: string; 21 | } 22 | -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiExternalDoc.ts: -------------------------------------------------------------------------------- 1 | export interface OpenApiExternalDoc { 2 | url: string; 3 | description?: string; 4 | } 5 | -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiMediaType.ts: -------------------------------------------------------------------------------- 1 | import { OpenApiExample } from "./openApiExample"; 2 | 3 | 4 | export interface OpenApiMediaType { 5 | schema: any; // OpenApiSchema | OpenApiReference; 6 | example: OpenApiExample; 7 | examples: any; 8 | encoding: any; 9 | } 10 | -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiObjectInfo.ts: -------------------------------------------------------------------------------- 1 | export interface OpenApiObjectInfo { 2 | title: string; 3 | description?: string; 4 | version: string; 5 | termsOfService?: string; 6 | } 7 | -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiOperation.ts: -------------------------------------------------------------------------------- 1 | import { OpenApiParameter } from "./openApiParameter"; 2 | import { OpenApiResponses } from "./openApiResponses"; 3 | import { OpenApiRequestBody } from "./openApiRequestBody"; 4 | 5 | 6 | export interface OpenApiOperation { 7 | operationId: string; 8 | description: string; 9 | parameters: OpenApiParameter[]; 10 | responses: OpenApiResponses; 11 | summary: string; 12 | consumes?: string[]; 13 | produces?: string[]; 14 | requestBody?: OpenApiRequestBody; 15 | } 16 | -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiParameter.ts: -------------------------------------------------------------------------------- 1 | import { Bag } from "@paperbits/common/bag"; 2 | import { OpenApiExample } from "./openApiExample"; 3 | 4 | export interface OpenApiParameter { 5 | name: string; 6 | in: string; 7 | required: boolean; 8 | description: string; 9 | type?: string; 10 | schema?: any; 11 | default?: string; 12 | enum: string[]; 13 | examples: Bag; 14 | } 15 | -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiPath.ts: -------------------------------------------------------------------------------- 1 | import { OpenApiOperation } from "./openApiOperation"; 2 | 3 | 4 | export interface OpenApiPath { 5 | [key: string]: OpenApiOperation; 6 | } 7 | -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiPaths.ts: -------------------------------------------------------------------------------- 1 | import { OpenApiPath } from "./openApiPath"; 2 | 3 | export interface OpenApiPaths { 4 | [key: string]: OpenApiPath; 5 | } 6 | -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiReference.ts: -------------------------------------------------------------------------------- 1 | export interface OpenApiReference { 2 | $ref: string; 3 | } 4 | -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiRequestBody.ts: -------------------------------------------------------------------------------- 1 | import { Bag } from "@paperbits/common"; 2 | import { OpenApiMediaType } from "./openApiMediaType"; 3 | 4 | /** 5 | * Describes a single request body. 6 | */ 7 | export interface OpenApiRequestBody { 8 | /** 9 | * A brief description of the request body. This could contain examples of use. 10 | */ 11 | description: string; 12 | 13 | /** 14 | * Determines if the request body is required in the request. Defaults to false. 15 | */ 16 | required: boolean; 17 | 18 | /** 19 | * The content of the request body. The key is a media type or media type range and the value describes it. 20 | * For requests that match multiple keys, only the most specific key is applicable, 21 | * e.g. text/plain overrides text/* 22 | */ 23 | content: Bag; 24 | } 25 | -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiResponse.ts: -------------------------------------------------------------------------------- 1 | import { Bag } from "@paperbits/common"; 2 | import { OpenApiMediaType } from "./openApiMediaType"; 3 | import { OpenApiParameter } from "./openApiParameter"; 4 | 5 | 6 | export interface OpenApiResponse { 7 | description: string; 8 | headers: Bag; 9 | content: Bag; 10 | } 11 | -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiResponses.ts: -------------------------------------------------------------------------------- 1 | import { OpenApiResponse } from "./openApiResponse"; 2 | 3 | export interface OpenApiResponses { 4 | [key: string]: OpenApiResponse; 5 | } 6 | -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiSchema.ts: -------------------------------------------------------------------------------- 1 | export interface OpenApiSchema { } -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiServer.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface OpenApiServer { 3 | url: string; 4 | description?: string; 5 | } 6 | -------------------------------------------------------------------------------- /catalog/src/contracts/openapi/openApiTag.ts: -------------------------------------------------------------------------------- 1 | import { OpenApiExternalDoc } from "./openApiExternalDoc"; 2 | 3 | 4 | export interface OpenApiTag { 5 | name: string; 6 | description?: string; 7 | externalDocs?: OpenApiExternalDoc; 8 | } 9 | -------------------------------------------------------------------------------- /catalog/src/contracts/operation.ts: -------------------------------------------------------------------------------- 1 | import { ParameterContract } from "./parameter"; 2 | import { RequestContract } from "./request"; 3 | import { ResponseContract } from "./response"; 4 | import { ArmResource } from "./armResource"; 5 | 6 | /** 7 | * Model of API operation 8 | */ 9 | export interface OperationContract extends ArmResource { 10 | properties: { 11 | displayName: string; 12 | description: string; 13 | urlTemplate: string; 14 | templateParameters: ParameterContract[]; 15 | method: string; 16 | backend?: string; 17 | version?: string; 18 | request?: RequestContract; 19 | responses?: ResponseContract[]; 20 | }; 21 | } -------------------------------------------------------------------------------- /catalog/src/contracts/page.ts: -------------------------------------------------------------------------------- 1 | export interface PageContract { 2 | value: T[]; 3 | count: number; 4 | nextLink?: string; 5 | } -------------------------------------------------------------------------------- /catalog/src/contracts/parameter.ts: -------------------------------------------------------------------------------- 1 | import { Bag } from "@paperbits/common"; 2 | import { Example } from "./example"; 3 | 4 | /** 5 | * Model of API operation request parameter 6 | */ 7 | export interface ParameterContract { 8 | /** 9 | * Parameter name, e.g. api-version. 10 | */ 11 | name: string; 12 | 13 | /** 14 | * Parameter description. 15 | */ 16 | description: string; 17 | 18 | /** 19 | * Parameter placement, e.g. "query", "template", "header", "body". 20 | */ 21 | in: string; 22 | 23 | /** 24 | * Parameter type, e.g. "string", "int64", etc. 25 | */ 26 | type: string; 27 | 28 | /** 29 | * Parameter default value, e.g. "2018-06-01-preview". 30 | */ 31 | defaultValue: string; 32 | 33 | /** 34 | * Parameter value suggestions, e.g. ["2016-07-07","2016-10-10", "2018-06-01-preview"] 35 | */ 36 | values: string[]; 37 | 38 | /** 39 | * Indicates if the parameter is required to make a request. 40 | */ 41 | required: boolean; 42 | 43 | /** 44 | * Object containing examples of the parameter. 45 | */ 46 | examples: Bag; 47 | } 48 | -------------------------------------------------------------------------------- /catalog/src/contracts/product.ts: -------------------------------------------------------------------------------- 1 | import { ArmResource } from "./armResource"; 2 | 3 | export interface ProductContract extends ArmResource { 4 | properties: { 5 | displayName: string; 6 | description: string; 7 | approvalRequired: boolean; 8 | state: string; 9 | subscriptionRequired: boolean; 10 | subscriptionsLimit: number; 11 | terms: string; 12 | }; 13 | } -------------------------------------------------------------------------------- /catalog/src/contracts/reportRecordByApi.ts: -------------------------------------------------------------------------------- 1 | import { ReportRecord } from "./reportRecord"; 2 | 3 | /** 4 | * Metrics aggregated by API. 5 | */ 6 | export interface ReportRecordByApi extends ReportRecord { 7 | /** 8 | * API name, e.g. "HTTP Bin". 9 | */ 10 | name: string; 11 | 12 | /** 13 | * API identifier, e.g. "/apis/httpbin". 14 | */ 15 | apiId: string; 16 | } -------------------------------------------------------------------------------- /catalog/src/contracts/reportRecordByGeo.ts: -------------------------------------------------------------------------------- 1 | import { ReportRecord } from "./reportRecord"; 2 | 3 | /** 4 | * Metrics aggregated by geographical region. 5 | */ 6 | export interface ReportRecordByGeo extends ReportRecord { 7 | /** 8 | * e.g. "US" 9 | */ 10 | country: string; 11 | 12 | /** 13 | * e.g. "CA" 14 | */ 15 | region: string; 16 | 17 | /** 18 | * e.g. 98065 19 | */ 20 | zip: number; 21 | } -------------------------------------------------------------------------------- /catalog/src/contracts/reportRecordByOperation.ts: -------------------------------------------------------------------------------- 1 | import { ReportRecord } from "./reportRecord"; 2 | 3 | /** 4 | * Metrics aggregated by operation. 5 | */ 6 | export interface ReportRecordByOperation extends ReportRecord { 7 | /** 8 | * Operation name, e.g. "Get". 9 | */ 10 | name: string; 11 | 12 | /** 13 | * Operation identifier, e.g. "/apis/httpbin/operations/get". 14 | */ 15 | operationId: string; 16 | 17 | /** 18 | * API identifier, e.g. "/apis/httpbin". 19 | */ 20 | apiId: string; 21 | } 22 | -------------------------------------------------------------------------------- /catalog/src/contracts/reportRecordByProduct.ts: -------------------------------------------------------------------------------- 1 | import { ReportRecord } from "./reportRecord"; 2 | 3 | /** 4 | * Metrics aggregated by product. 5 | */ 6 | export interface ReportRecordByProduct extends ReportRecord { 7 | /** 8 | * Product name, e.g. "Starter". 9 | */ 10 | name: string; 11 | 12 | /** 13 | * Product unique identifier, e.g. "/products/starter" 14 | */ 15 | productId: string; 16 | } -------------------------------------------------------------------------------- /catalog/src/contracts/reportRecordBySubscription.ts: -------------------------------------------------------------------------------- 1 | import { ReportRecord } from "./reportRecord"; 2 | 3 | /** 4 | * Metrics aggregated by product subscription. 5 | */ 6 | export interface ReportRecordBySubscription extends ReportRecord { 7 | /** 8 | * Subscription name, e.g. "My subscription". 9 | */ 10 | name: string; 11 | 12 | /** 13 | * Product identifier, e.g. "/products/unlimited". 14 | */ 15 | productId: string; 16 | 17 | /** 18 | * Subscription identifier, e.g. "/subscriptions/my-subscription" 19 | */ 20 | subscriptionId: string; 21 | 22 | /** 23 | * User identifier, e.g. "/users/john-doe" 24 | */ 25 | userId: string; 26 | } -------------------------------------------------------------------------------- /catalog/src/contracts/reportRecordByTime.ts: -------------------------------------------------------------------------------- 1 | import { ReportRecord } from "./reportRecord"; 2 | 3 | /** 4 | * Metrics aggregated over a period of time. 5 | */ 6 | export interface ReportRecordByTime extends ReportRecord { 7 | /** 8 | * e.g. "2019-09-05T19:30:00Z" 9 | */ 10 | timestamp: string; 11 | 12 | /** 13 | * Interval must be multiple of 15 minutes and may not be zero, e.g. "PT15M" 14 | */ 15 | interval: string; 16 | } -------------------------------------------------------------------------------- /catalog/src/contracts/representation.ts: -------------------------------------------------------------------------------- 1 | import { Bag } from "@paperbits/common"; 2 | import { Example } from "./example"; 3 | import { ParameterContract } from "./parameter"; 4 | 5 | /** 6 | * Contract for API operation representation. 7 | */ 8 | export interface RepresentationContract { 9 | /** 10 | * Content type, e.g. application/json. 11 | */ 12 | contentType: string; 13 | 14 | /** 15 | * @deprecated User created sample. 16 | */ 17 | sample?: string; 18 | 19 | /** 20 | * @deprecated Sample generated during API import. 21 | */ 22 | generatedSample?: string; 23 | 24 | /** 25 | * Identifier of the schema the representation belongs to. 26 | */ 27 | schemaId?: string; 28 | 29 | /** 30 | * Name of the type describing representation. 31 | */ 32 | typeName?: string; 33 | 34 | /** 35 | * Description of the form parameters, if the representation has form-like payload. 36 | */ 37 | formParameters?: ParameterContract[]; 38 | 39 | /** 40 | * Object containing examples of the representation. 41 | */ 42 | examples: Bag; 43 | } 44 | -------------------------------------------------------------------------------- /catalog/src/contracts/request.ts: -------------------------------------------------------------------------------- 1 | import { ParameterContract } from "./parameter"; 2 | import { RepresentationContract } from "./representation"; 3 | 4 | /* 5 | Model of API operation request 6 | */ 7 | export interface RequestContract { 8 | description?: string; 9 | queryParameters?: ParameterContract[]; 10 | headers?: ParameterContract[]; 11 | representations?: RepresentationContract[]; 12 | } 13 | -------------------------------------------------------------------------------- /catalog/src/contracts/resetRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Cotract of Reset password request 3 | */ 4 | export interface ResetRequest { 5 | solution: string; 6 | token: string; 7 | type: string; 8 | flowId: string; 9 | email: string; 10 | } 11 | 12 | /** 13 | * Cotract of user change password 14 | */ 15 | export interface ChangePasswordRequest { 16 | solution: string; 17 | token: string; 18 | type: string; 19 | flowId: string; 20 | userId: string; 21 | newPassword: string; 22 | } 23 | 24 | /** 25 | * Cotract of user reset password 26 | */ 27 | export interface ResetPassword { 28 | userid: string; 29 | ticketid: string; 30 | ticket: string; 31 | password: string; 32 | } -------------------------------------------------------------------------------- /catalog/src/contracts/response.ts: -------------------------------------------------------------------------------- 1 | import { RepresentationContract } from "./representation"; 2 | import { ParameterContract } from "./parameter"; 3 | 4 | /* 5 | * Model of API operation response 6 | */ 7 | export interface ResponseContract { 8 | headers?: ParameterContract[]; 9 | statusCode: number; 10 | representations?: RepresentationContract[]; 11 | description?: string; 12 | } -------------------------------------------------------------------------------- /catalog/src/contracts/revision.ts: -------------------------------------------------------------------------------- 1 | export interface RevisionContract { 2 | apiId: string; 3 | 4 | /** 5 | * Example: "1" 6 | */ 7 | apiRevision: string; 8 | 9 | /** 10 | * Example: "2016-12-01T19:30:35.763" 11 | */ 12 | createdDateTime: string; 13 | 14 | /** 15 | * Example: "2016-12-01T19:30:35.763" 16 | */ 17 | updatedDateTime: string; 18 | 19 | description: string; 20 | 21 | /** 22 | * Example: "/amazons3;rev=0" 23 | */ 24 | privateUrl: string; 25 | 26 | isOnline: boolean; 27 | 28 | isCurrent: boolean; 29 | } -------------------------------------------------------------------------------- /catalog/src/contracts/searchQuery.ts: -------------------------------------------------------------------------------- 1 | import { Tag } from "./../models/tag"; 2 | 3 | /** 4 | * Search query. 5 | */ 6 | export interface SearchQuery { 7 | /** 8 | * Name of the property to search. 9 | */ 10 | propertyName?: string; 11 | 12 | /** 13 | * The value of the property to search. 14 | */ 15 | pattern?: string; 16 | 17 | /** 18 | * The tags to search for. 19 | */ 20 | tags?: Tag[]; 21 | 22 | /** 23 | * Number of items to skip. 24 | */ 25 | skip?: number; 26 | 27 | /** 28 | * Number of items to return. 29 | */ 30 | take?: number; 31 | 32 | /** 33 | * Result grouping, e.g. `tag` or `none`. 34 | */ 35 | grouping?: string; 36 | } -------------------------------------------------------------------------------- /catalog/src/contracts/signupRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Cotract of user sign up request 3 | */ 4 | export interface SignupRequest { 5 | solution: string; 6 | token: string; 7 | type: string; 8 | flowId: string; 9 | signupData: MapiSignupRequest; 10 | } 11 | 12 | export interface MapiSignupRequest { 13 | email: string; 14 | firstName: string; 15 | lastName: string; 16 | password: string; 17 | confirmation: string; 18 | state?: string; 19 | note?: string; 20 | identities?: { id: string; name: string }[]; 21 | appType: string; 22 | } -------------------------------------------------------------------------------- /catalog/src/contracts/subscription.ts: -------------------------------------------------------------------------------- 1 | import { ArmResource } from "./armResource"; 2 | 3 | 4 | export interface SubscriptionContract extends ArmResource { 5 | properties: { 6 | displayName: string; 7 | createdDate: string; 8 | endDate: string; 9 | expirationDate: string; 10 | notificationDate: string; 11 | primaryKey: string; 12 | scope: string; 13 | secondaryKey: string; 14 | startDate: string; 15 | state: string; 16 | stateComment: string; 17 | ownerId: string; 18 | } 19 | } 20 | 21 | export enum SubscriptionState { 22 | suspended = "Suspended", 23 | active = "Active", 24 | expired = "Expired", 25 | submitted = "Submitted", 26 | rejected = "Rejected", 27 | cancelled = "Cancelled" 28 | } -------------------------------------------------------------------------------- /catalog/src/contracts/subscriptionSecrets.ts: -------------------------------------------------------------------------------- 1 | export interface SubscriptionSecrets { 2 | primaryKey: string; 3 | secondaryKey: string; 4 | } -------------------------------------------------------------------------------- /catalog/src/contracts/swaggerObject.ts: -------------------------------------------------------------------------------- 1 | export interface SwaggerObjectInfo { 2 | title: string; 3 | description: string; 4 | version: string; 5 | } 6 | 7 | export interface SwaggerParameter { 8 | name: string; 9 | in: string; 10 | required: boolean; 11 | description: string; 12 | type?: string; 13 | schema?: Object; 14 | default?: string; 15 | enum: string[]; 16 | } 17 | 18 | export interface SwaggerOperation { 19 | operationId: string; 20 | description: string; 21 | parameters: SwaggerParameter[]; 22 | responses: Object; 23 | security: SecurityType[]; 24 | summary: string; 25 | } 26 | 27 | export interface PathItem { 28 | [key: string]: SwaggerOperation; 29 | } 30 | 31 | export interface SwaggerPath { 32 | [key: string]: PathItem; 33 | } 34 | 35 | export interface SwaggerObject { 36 | swagger: string; 37 | info: SwaggerObjectInfo; 38 | host: string; 39 | basePath: string; 40 | schemes: string[]; 41 | consumes: string[]; 42 | produces: string[]; 43 | paths: SwaggerPath; 44 | definitions?: Object; 45 | securityDefinitions?: SecurityDefinitions; 46 | } 47 | 48 | export interface SecurityDefinitions { 49 | apikeyQuery: SecurityType; 50 | apikeyHeader: SecurityType; 51 | } 52 | 53 | export interface SecurityType { 54 | type: string; 55 | name: string; 56 | in: string; 57 | } -------------------------------------------------------------------------------- /catalog/src/contracts/tag.ts: -------------------------------------------------------------------------------- 1 | import { ArmResource } from "./armResource"; 2 | 3 | export interface TagProperties { 4 | displayName: string; 5 | } 6 | 7 | export interface TagContract extends ArmResource { 8 | properties: TagProperties; 9 | } -------------------------------------------------------------------------------- /catalog/src/contracts/tagResource.ts: -------------------------------------------------------------------------------- 1 | import { ApiContract } from "./api"; 2 | import { OperationContract } from "./operation"; 3 | import { TagContract } from "./tag"; 4 | 5 | 6 | /** 7 | * Contract of TagResource 8 | */ 9 | export interface ApiTagResourceContract { 10 | api?: ApiContract; 11 | operation?: OperationContract; 12 | tag?: TagContract; 13 | } 14 | -------------------------------------------------------------------------------- /catalog/src/contracts/trace.ts: -------------------------------------------------------------------------------- 1 | export interface TraceEntry { 2 | source: string; 3 | timestamp: string; 4 | elapsed: string; 5 | data: any; 6 | } 7 | 8 | export interface TraceEntries { 9 | inbound: TraceEntry[]; 10 | backend: TraceEntry[]; 11 | outbound: TraceEntry[]; 12 | } 13 | 14 | export interface Trace { 15 | traceId: string; 16 | traceEntries: TraceEntries; 17 | } -------------------------------------------------------------------------------- /catalog/src/contracts/url.ts: -------------------------------------------------------------------------------- 1 | export interface Url { 2 | scheme: string; 3 | host: string; 4 | path: string; 5 | } -------------------------------------------------------------------------------- /catalog/src/contracts/validationReport.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Cotract of validation Report 3 | */ 4 | export interface ValidationReport { 5 | source: string; 6 | errors: string[]; 7 | } -------------------------------------------------------------------------------- /catalog/src/errors/appError.ts: -------------------------------------------------------------------------------- 1 | export class AppError extends Error { 2 | constructor( 3 | public readonly message: string, 4 | public readonly innerError?: Error 5 | ) { 6 | super(); 7 | Object.setPrototypeOf(this, AppError.prototype); 8 | } 9 | 10 | public toString(): string { 11 | return `${this.stack} `; 12 | } 13 | } -------------------------------------------------------------------------------- /catalog/src/errors/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./appError"; 2 | export * from "./sessionExpirationErrorHandler"; 3 | export * from "./unhandledErrorHandler"; 4 | export * from "./unauthorizedError"; -------------------------------------------------------------------------------- /catalog/src/errors/mapiError.ts: -------------------------------------------------------------------------------- 1 | import { HttpResponse } from "@paperbits/common/http"; 2 | 3 | export interface SmapiErrorDetails { 4 | target: string; 5 | message: string; 6 | } 7 | 8 | export class MapiError extends Error { 9 | constructor( 10 | public readonly code: string, 11 | public readonly message: string, 12 | public readonly details?: SmapiErrorDetails[] 13 | ) { 14 | super(); 15 | Object.setPrototypeOf(this, MapiError.prototype); 16 | } 17 | 18 | public static fromResponse(response: HttpResponse): MapiError { 19 | const responseObject = response.toObject(); 20 | const code = responseObject?.error?.code || "Error"; 21 | const message = responseObject?.error?.message || "Server error"; 22 | const details = responseObject?.error?.details || []; 23 | 24 | return new MapiError(code, message, details); 25 | } 26 | 27 | public toString(): string { 28 | return `${this.code}: ${this.message}`; 29 | } 30 | } -------------------------------------------------------------------------------- /catalog/src/errors/sessionExpirationErrorHandler.ts: -------------------------------------------------------------------------------- 1 | import { ViewManager } from "@paperbits/common/ui"; 2 | import { EventManager } from "@paperbits/common/events"; 3 | 4 | 5 | export class SessionExpirationErrorHandler { 6 | constructor(private readonly viewManager: ViewManager, eventManager: EventManager) { 7 | eventManager.addEventListener("error", this.handlerError.bind(this)); 8 | window.addEventListener("unhandledrejection", this.handlerPromiseRejection.bind(this), true); 9 | } 10 | 11 | private handleSessionExpiration(error: Error): void { 12 | if (!error.message?.includes("Unauthorized request.")) { 13 | return; 14 | } 15 | 16 | event.preventDefault(); 17 | event.stopImmediatePropagation(); 18 | this.viewManager.hideToolboxes(); 19 | this.viewManager.addToast("Session expired", `Please re-authenticate through Azure portal.`); 20 | this.viewManager.setShutter(); 21 | return; 22 | } 23 | 24 | public handlerError(event: ErrorEvent): void { 25 | this.handleSessionExpiration(event.error); 26 | } 27 | 28 | public handlerPromiseRejection(event: PromiseRejectionEvent): void { 29 | this.handleSessionExpiration(event.reason); 30 | } 31 | } -------------------------------------------------------------------------------- /catalog/src/errors/unauthorizedError.ts: -------------------------------------------------------------------------------- 1 | export class UnauthorizedError extends Error { 2 | constructor( 3 | public readonly message: string, 4 | public readonly innerError?: Error 5 | ) { 6 | super(); 7 | Object.setPrototypeOf(this, UnauthorizedError.prototype); 8 | } 9 | 10 | public toString(): string { 11 | return `${this.stack} `; 12 | } 13 | } -------------------------------------------------------------------------------- /catalog/src/errors/unhandledErrorHandler.ts: -------------------------------------------------------------------------------- 1 | import { Logger } from "@paperbits/common/logging"; 2 | 3 | 4 | export class UnhandledErrorHandler { 5 | constructor( 6 | private readonly logger: Logger 7 | ) { 8 | window.addEventListener("error", this.handlerError.bind(this), true,); 9 | window.addEventListener("unhandledrejection", this.handlerPromiseRejection.bind(this), true); 10 | } 11 | 12 | public handlerError(event: ErrorEvent): void { 13 | this.logger.trackError(event.error); 14 | } 15 | 16 | public handlerPromiseRejection(event: PromiseRejectionEvent): void { 17 | this.logger.trackError(event.reason); 18 | } 19 | } -------------------------------------------------------------------------------- /catalog/src/injection/inversifyAdapter.ts: -------------------------------------------------------------------------------- 1 | import { InversifyInjector } from "@paperbits/common/injection"; 2 | import { IocAdapter, ClassConstructor, Action } from "routing-controllers"; 3 | 4 | export class InversifyAdapter implements IocAdapter { 5 | constructor(private readonly injector: InversifyInjector) { } 6 | 7 | public get(classConstructor: ClassConstructor, action?: Action): T { 8 | return this.injector["container"].resolve(classConstructor); 9 | } 10 | } -------------------------------------------------------------------------------- /catalog/src/libraries/icon-fonts.json: -------------------------------------------------------------------------------- 1 | { 2 | "fonts": [ 3 | { 4 | "displayName": "Font Awesome icons", 5 | "key": "fonts/default", 6 | "variants": [ 7 | { 8 | "file": "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/webfonts/fa-regular-400.ttf", 9 | "style": "normal", 10 | "weight": "400" 11 | } 12 | ] 13 | }, 14 | { 15 | "displayName": "Material Design icons", 16 | "variants": [ 17 | { 18 | "file": "https://cdnjs.cloudflare.com/ajax/libs/material-design-icons/3.0.2/iconfont/MaterialIcons-Regular.ttf", 19 | "style": "normal", 20 | "weight": "400" 21 | } 22 | ] 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /catalog/src/middlewares/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./staticContentMiddleware"; 2 | export * from "./unhandledErrorMiddleware"; -------------------------------------------------------------------------------- /catalog/src/middlewares/unhandledErrorMiddleware.ts: -------------------------------------------------------------------------------- 1 | import * as express from "express"; 2 | import { Middleware, ExpressErrorMiddlewareInterface, NotFoundError } from "routing-controllers"; 3 | import { Logger } from "@paperbits/common/logging"; 4 | 5 | @Middleware({ type: "after" }) 6 | export class UnhandledErrorMiddleware implements ExpressErrorMiddlewareInterface { 7 | constructor(private readonly logger: Logger) { } 8 | 9 | public error(error: any, request: express.Request, response: express.Response, next: express.NextFunction): void { 10 | this.logger.trackError(error, { httpMethod: request.method, url: request.url }); 11 | 12 | if (error instanceof NotFoundError) { 13 | response.status(404).send({ 14 | code: "NotFound", 15 | message: error.message || "Resoure not found." 16 | }); 17 | return; 18 | } 19 | 20 | response 21 | .header("Content-Type", "application/json") 22 | .status(500) 23 | .send({ 24 | code: "InternalServerError", 25 | message: `Oops, something went wrong.` 26 | }); 27 | } 28 | } -------------------------------------------------------------------------------- /catalog/src/models/console/consoleHost.ts: -------------------------------------------------------------------------------- 1 | import * as ko from "knockout"; 2 | // import { ValidateIf, IsNotEmpty } from "class-validator"; 3 | 4 | export class ConsoleHost { 5 | public readonly hostname: ko.Observable; 6 | 7 | // @ValidateIf(x => x.hostname && x.hostname.indexOf("*") >= 0) 8 | // @IsNotEmpty({ message: "Wildcard segment is required." }) 9 | public readonly wildcard: ko.Observable; 10 | 11 | constructor() { 12 | this.hostname = ko.observable(); 13 | this.wildcard = ko.observable(); 14 | } 15 | } -------------------------------------------------------------------------------- /catalog/src/models/console/consoleRepresentation.ts: -------------------------------------------------------------------------------- 1 | import { Representation } from "../representation"; 2 | 3 | export class ConsoleRepresentation { 4 | public readonly sample: string; 5 | public readonly contentType: string; 6 | public readonly schemaId?: string; 7 | public readonly typeName?: string; 8 | 9 | constructor(representation: Representation) { 10 | this.sample = representation.examples?.length > 0 ? representation.examples[0].value : ""; 11 | this.contentType = representation.contentType; 12 | this.schemaId = representation.schemaId; 13 | this.typeName = representation.typeName; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /catalog/src/models/console/consoleResponse.ts: -------------------------------------------------------------------------------- 1 | import { ConsoleHeader } from "./consoleHeader"; 2 | import { ConsoleRepresentation } from "./consoleRepresentation"; 3 | // import { ValidateNested } from "class-validator"; 4 | import { StatusCode } from "../statusCode"; 5 | import { Response } from "../response"; 6 | 7 | export class ConsoleResponse { 8 | // @ValidateNested() 9 | public headers: ConsoleHeader[]; 10 | 11 | // @ValidateNested() 12 | public statusCode: StatusCode; 13 | 14 | // @ValidateNested() 15 | public representations: ConsoleRepresentation[]; 16 | 17 | public description: string; 18 | 19 | constructor(response: Response) { 20 | this.statusCode = response.statusCode; 21 | this.description = response.description; 22 | this.headers = response.headers.map(x => new ConsoleHeader(x)); 23 | 24 | if (!this.headers) { 25 | this.headers = []; 26 | } 27 | 28 | this.representations = response.representations.map(x => new ConsoleRepresentation(x)); 29 | 30 | if (!this.representations) { 31 | this.representations = []; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /catalog/src/models/knownHttpHeaders.ts: -------------------------------------------------------------------------------- 1 | export enum KnownHttpHeaders { 2 | Authorization = "Authorization", 3 | CacheControl = "Cache-Control", 4 | ContentType = "Content-Type", 5 | OcpApimSubscriptionKey = "Ocp-Apim-Subscription-Key", 6 | OcpApimTrace = "Ocp-Apim-Trace", 7 | OcpApimTraceLocation = "Ocp-Apim-Trace-Location", 8 | OcpApimSasToken = "Ocp-Apim-Sas-Token", 9 | SoapAction = "SOAPAction", 10 | IfMatch = "If-Match" 11 | } -------------------------------------------------------------------------------- /catalog/src/models/knownMimeTypes.ts: -------------------------------------------------------------------------------- 1 | export enum KnownMimeTypes { 2 | FormData = "multipart/form-data", 3 | Json = "application/json", 4 | Xml = "text/xml" 5 | } -------------------------------------------------------------------------------- /catalog/src/models/openIdConnectProvider.ts: -------------------------------------------------------------------------------- 1 | import { OpenIdConnectProviderContract } from "../contracts/openIdConnectProvider"; 2 | 3 | export class OpenIdConnectProvider { 4 | constructor(contract: OpenIdConnectProviderContract) { 5 | this.name = contract.name; 6 | this.displayName = contract.properties.displayName; 7 | this.description = contract.properties.description; 8 | this.clientId = contract.properties.clientId; 9 | this.metadataEndpoint = contract.properties.metadataEndpoint; 10 | } 11 | 12 | /** 13 | * Resource name. 14 | */ 15 | public name: string; 16 | 17 | /** 18 | * User-friendly OpenID Connect Provider name. 19 | */ 20 | public displayName: string; 21 | 22 | /** 23 | * User-friendly description of OpenID Connect Provider. 24 | */ 25 | public description: string; 26 | 27 | /** 28 | * Metadata endpoint URI. 29 | */ 30 | public metadataEndpoint: string; 31 | 32 | /** 33 | * Client ID of developer console which is the client application. 34 | */ 35 | 36 | public clientId: string; 37 | } -------------------------------------------------------------------------------- /catalog/src/models/page.ts: -------------------------------------------------------------------------------- 1 | export class Page { 2 | /** 3 | * Collection of items on the page. 4 | */ 5 | public value: T[]; 6 | 7 | /** 8 | * Number of items in the page. 9 | */ 10 | public count: number; 11 | 12 | /** 13 | * A link to the next page of the query result. 14 | */ 15 | public nextLink?: string; // TODO: Implement .next() instead of link. 16 | 17 | constructor() { 18 | this.value = []; 19 | this.count = 0; 20 | this.nextLink = null; 21 | } 22 | 23 | public getSkip(): number { 24 | if (!this.nextLink) { 25 | return undefined; 26 | } 27 | 28 | const url = new URL(this.nextLink); 29 | const queryParams = new URLSearchParams(decodeURIComponent(url.search)); 30 | 31 | if (queryParams.has("$skip")) { 32 | return parseInt(queryParams.get("$skip")); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /catalog/src/models/parameterExample.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Request parameter/header example. 3 | */ 4 | export class ParameterExample { 5 | constructor( 6 | /** 7 | * Title, e.g. `Short version` 8 | */ 9 | public title: string, 10 | 11 | /** 12 | * Description, e.g. `Short version of the API`. 13 | */ 14 | public description: string, 15 | 16 | /** 17 | * Example value, e.g. `api-version`. 18 | */ 19 | public value: string 20 | ) { } 21 | } -------------------------------------------------------------------------------- /catalog/src/models/product.ts: -------------------------------------------------------------------------------- 1 | import { ProductContract } from "../contracts/product"; 2 | import { Utils } from "../utils"; 3 | 4 | export class Product { 5 | public readonly id: string; 6 | public readonly name: string; 7 | public readonly displayName: string; 8 | public readonly description: string; 9 | public readonly approvalRequired: boolean; 10 | public readonly state: string; 11 | public readonly subscriptionRequired: boolean; 12 | public readonly subscriptionsLimit?: number; 13 | public readonly terms: string; 14 | 15 | constructor(contract?: ProductContract) { 16 | this.id = Utils.getResourceName("products", contract.id, "shortId"); 17 | this.name = contract.name; 18 | this.displayName = contract.properties.displayName; 19 | this.description = contract.properties.description; 20 | this.approvalRequired = contract.properties.approvalRequired; 21 | this.state = contract.properties.state; 22 | this.subscriptionRequired = contract.properties.subscriptionRequired; 23 | this.subscriptionsLimit = contract.properties.subscriptionsLimit; 24 | this.terms = contract.properties.terms; 25 | } 26 | } -------------------------------------------------------------------------------- /catalog/src/models/representationExample.ts: -------------------------------------------------------------------------------- 1 | import { Utils } from "../utils"; 2 | 3 | export class RepresentationExample { 4 | /** 5 | * Example format, e.g. `json`, `xml`, `plain`. Used for syntax highlight language selection. 6 | */ 7 | public readonly format: string; 8 | 9 | constructor( 10 | /** 11 | * Example title. 12 | */ 13 | public readonly title: string, 14 | 15 | /** 16 | * Example description. 17 | */ 18 | public readonly description: string, 19 | 20 | /** 21 | * Example value. 22 | */ 23 | public readonly value: string, 24 | 25 | /** 26 | * Example content type. 27 | */ 28 | public readonly contentType: string 29 | ) { 30 | if (/\bxml\b/i.test(this.contentType)) { 31 | this.value = Utils.formatXml(value); 32 | this.format = "xml"; 33 | 34 | if (!title) { 35 | title = "XML"; 36 | } 37 | } 38 | 39 | if (/\bjson\b/i.test(this.contentType)) { 40 | this.value = Utils.formatJson(value); 41 | this.format = "json"; 42 | 43 | if (!title) { 44 | title = "JSON"; 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /catalog/src/models/revision.ts: -------------------------------------------------------------------------------- 1 | import { RevisionContract } from "../contracts/revision"; 2 | 3 | export class Revision { 4 | public apiId: string; 5 | public apiRevision: string; 6 | public createdDateTime: string; 7 | public updatedDateTime: string; 8 | public description: string; 9 | public privateUrl: string; 10 | public isOnline: boolean; 11 | public isCurrent: boolean; 12 | 13 | constructor(contract?: RevisionContract) { 14 | this.apiId = contract.apiId; 15 | this.apiRevision = contract.apiRevision; 16 | this.createdDateTime = contract.createdDateTime; 17 | this.updatedDateTime = contract.updatedDateTime; 18 | this.description = contract.description; 19 | this.privateUrl = contract.privateUrl; 20 | this.isOnline = contract.isOnline; 21 | this.isCurrent = contract.isCurrent; 22 | } 23 | } -------------------------------------------------------------------------------- /catalog/src/models/service.ts: -------------------------------------------------------------------------------- 1 | import { ServiceDescriptionContract, HostnameConfiguration, ServiceSku } from "./../contracts/service"; 2 | 3 | export class ServiceDescription { 4 | public name: string; 5 | public hostnameConfigurations: HostnameConfiguration[]; 6 | public sku: ServiceSku; 7 | public gatewayUrl: string; 8 | 9 | constructor(contract: ServiceDescriptionContract) { 10 | this.name = contract.name; 11 | this.sku = contract.sku; 12 | this.gatewayUrl = contract.properties.gatewayUrl; 13 | this.hostnameConfigurations = contract.properties.hostnameConfigurations; 14 | } 15 | } -------------------------------------------------------------------------------- /catalog/src/models/statusCode.ts: -------------------------------------------------------------------------------- 1 | import { KnownStatusCodes } from "../models/knownStatusCodes"; 2 | 3 | export class StatusCode { 4 | public code: number; 5 | public description: string; 6 | 7 | constructor(code: number) { 8 | this.code = code; 9 | 10 | const knownStatusCode = KnownStatusCodes.find(x => x.code.toString() === code.toString()); 11 | 12 | if (knownStatusCode) { 13 | this.description = knownStatusCode.description; 14 | } 15 | } 16 | 17 | public toString(): string { 18 | if (!this.description) { 19 | return `${this.code} User defined status code`; 20 | } 21 | return `${this.code} ${this.description}`; 22 | } 23 | } -------------------------------------------------------------------------------- /catalog/src/models/tag.ts: -------------------------------------------------------------------------------- 1 | import { TagContract } from "../contracts/tag"; 2 | 3 | export class Tag { 4 | public readonly id: string; 5 | public readonly name: string; 6 | 7 | constructor(contract: TagContract) { 8 | this.id = contract.id; 9 | this.name = contract.properties.displayName; 10 | } 11 | } -------------------------------------------------------------------------------- /catalog/src/models/tagGroup.ts: -------------------------------------------------------------------------------- 1 | export class TagGroup { 2 | public tag: string; 3 | public readonly items: TResource[]; 4 | 5 | constructor() { 6 | this.items = []; 7 | } 8 | } -------------------------------------------------------------------------------- /catalog/src/models/versionSet.ts: -------------------------------------------------------------------------------- 1 | import { VersionSetContract } from "../contracts/apiVersionSet"; 2 | import { Utils } from "../utils"; 3 | 4 | export class VersionSet { 5 | public readonly id: string; 6 | public name: string; 7 | public description: string; 8 | public versioningScheme: string; 9 | public versionQueryName: string; 10 | public versionHeaderName: string; 11 | 12 | constructor(id: string, contract?: VersionSetContract) { 13 | this.id = Utils.getResourceName("apiVersionSets", id, "shortId"); 14 | 15 | if (!contract) { 16 | return; 17 | } 18 | 19 | if (contract.properties) { 20 | this.name = contract.properties.displayName; 21 | this.description = contract.properties.description; 22 | this.versioningScheme = contract.properties.versioningScheme; 23 | this.versionQueryName = contract.properties.versionQueryName; 24 | this.versionHeaderName = contract.properties.versionHeaderName; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /catalog/src/modules.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.html" { 2 | const content: string; 3 | export default content; 4 | } 5 | 6 | declare module "*.liquid" { 7 | const content: string; 8 | export default content; 9 | } 10 | 11 | declare module "*.txt" { 12 | const content: string; 13 | export default content; 14 | } 15 | 16 | declare module "*.raw" { 17 | const content: string; 18 | export default content; 19 | } -------------------------------------------------------------------------------- /catalog/src/persistence/cachedObjectStorage.ts: -------------------------------------------------------------------------------- 1 | import { LruCache } from "@paperbits/common/caching"; 2 | import { IObjectStorage, Page, Query } from "@paperbits/common/persistence"; 3 | 4 | export class CachedObjectStorage { 5 | private readonly cache: LruCache>; 6 | 7 | constructor( 8 | private readonly underlyingStorage: IObjectStorage 9 | ) { 10 | this.cache = new LruCache(100, () => { return; }); 11 | } 12 | 13 | public addObject(key: string, dataObject: T): Promise { 14 | throw new Error("Not supported."); 15 | } 16 | 17 | public getObject(key: string): Promise { 18 | const cachedItemPromise = this.cache.getItem(key); 19 | 20 | if (cachedItemPromise) { 21 | return cachedItemPromise; 22 | } 23 | 24 | const fetchPromise = this.underlyingStorage.getObject(key); 25 | 26 | this.cache.setItem(key, fetchPromise); 27 | 28 | return fetchPromise; 29 | } 30 | 31 | public deleteObject(key: string): Promise { 32 | throw new Error("Not supported."); 33 | } 34 | 35 | public updateObject(key: string, dataObject: T): Promise { 36 | throw new Error("Not supported."); 37 | } 38 | 39 | public async searchObjects(key: string, query?: Query): Promise> { 40 | return await this.underlyingStorage.searchObjects(key, query); 41 | } 42 | } -------------------------------------------------------------------------------- /catalog/src/persistence/dataProvider.ts: -------------------------------------------------------------------------------- 1 | export interface DataProvider { 2 | loadData(): Promise; 3 | 4 | saveData(data: Object): Promise; 5 | } -------------------------------------------------------------------------------- /catalog/src/persistence/fileSystemDataProvider.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Paperbits. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file and at https://paperbits.io/license/mit. 7 | */ 8 | 9 | import * as fs from "fs"; 10 | 11 | async function loadFileAsString(filepath: string): Promise { 12 | return new Promise((resolve, reject) => { 13 | fs.readFile(filepath, "utf8", (error, content) => { 14 | if (error) { 15 | reject(error); 16 | return; 17 | } 18 | 19 | resolve(content); 20 | }); 21 | }); 22 | } 23 | 24 | export class FileSystemDataProvider { 25 | private storageDataObject: Object; 26 | 27 | constructor(private readonly dataPath: string) { } 28 | 29 | protected async getDataObject(): Promise { 30 | if (!this.storageDataObject) { 31 | this.storageDataObject = JSON.parse(await loadFileAsString(this.dataPath)); 32 | } 33 | return this.storageDataObject; 34 | } 35 | } -------------------------------------------------------------------------------- /catalog/src/persistence/fileSystemObjectStorage.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Paperbits. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file and at https://paperbits.io/license/mit. 7 | */ 8 | 9 | import * as fs from "fs"; 10 | import * as Objects from "@paperbits/common/objects"; 11 | import { MemoryObjectStorage } from "./memoryObjectStorage"; 12 | 13 | 14 | async function loadFileAsString(filepath: string): Promise { 15 | return new Promise((resolve, reject) => { 16 | fs.readFile(filepath, "utf8", (error, content) => { 17 | if (error) { 18 | reject(error); 19 | return; 20 | } 21 | 22 | resolve(content); 23 | }); 24 | }); 25 | } 26 | 27 | export class FileSystemObjectStorage extends MemoryObjectStorage { 28 | private storageDataObject: Object; 29 | 30 | constructor(private readonly dataPath: string) { 31 | super(null); 32 | } 33 | 34 | protected async getDataObject(): Promise { 35 | if (!this.storageDataObject) { 36 | this.storageDataObject = JSON.parse(await loadFileAsString(this.dataPath)); 37 | Objects.deepFreeze(this.storageDataObject); 38 | } 39 | 40 | return this.storageDataObject; 41 | } 42 | } -------------------------------------------------------------------------------- /catalog/src/persistence/httpDataProvider.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient } from "@paperbits/common/http"; 2 | import { DataProvider } from "./dataProvider"; 3 | 4 | export class HttpDataProvider implements DataProvider { 5 | private initPromise: Promise; 6 | private dataObject: Object; 7 | 8 | constructor(private readonly httpClient: HttpClient) { } 9 | 10 | private async initialize(): Promise { 11 | if (this.initPromise) { 12 | return this.initPromise; 13 | } 14 | 15 | this.initPromise = new Promise(async (resolve) => { 16 | const response = await this.httpClient.send({ 17 | url: "/data/content.json", 18 | method: "GET" 19 | }); 20 | 21 | this.dataObject = response.toObject(); 22 | 23 | resolve(); 24 | }); 25 | 26 | return this.initPromise; 27 | } 28 | 29 | public async loadData(): Promise { 30 | await this.initialize(); 31 | 32 | return this.dataObject; 33 | } 34 | 35 | public async saveData(data: Object): Promise { 36 | await this.httpClient.send({ 37 | url: "/data/content.json", 38 | method: "PUT", 39 | headers: [{ name: "Content-Type", value: "application/json" }], 40 | body: JSON.stringify(data) 41 | }); 42 | } 43 | } -------------------------------------------------------------------------------- /catalog/src/persistence/publishingCacheModule.ts: -------------------------------------------------------------------------------- 1 | import { IObjectStorage } from "@paperbits/common/persistence"; 2 | import { IInjector, IInjectorModule } from "@paperbits/common/injection"; 3 | import { CachedObjectStorage } from "./cachedObjectStorage"; 4 | 5 | 6 | export class PublishingCacheModule implements IInjectorModule { 7 | public register(injector: IInjector): void { 8 | const underlyingObjectStorage = injector.resolve("objectStorage"); 9 | 10 | injector.bindSingletonFactory("objectStorage", (ctx: IInjector) => { 11 | return new CachedObjectStorage(underlyingObjectStorage); 12 | }); 13 | } 14 | } -------------------------------------------------------------------------------- /catalog/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | import "@webcomponents/custom-elements"; 2 | import "core-js/es/array"; 3 | import "core-js/es/object"; 4 | import "core-js/es/promise"; 5 | import "core-js/es/reflect"; 6 | import "core-js/es/symbol"; 7 | import "core-js/web/immediate"; -------------------------------------------------------------------------------- /catalog/src/publishing/runtimeConfigBuilder.ts: -------------------------------------------------------------------------------- 1 | import { Bag } from "@paperbits/common"; 2 | 3 | /** 4 | * Runtime config builder helps content publishers to compose runtime configuration. 5 | */ 6 | export class RuntimeConfigBuilder { 7 | private readonly configuration: Bag = {}; 8 | 9 | /** 10 | * Adds setting to runtime configuration. 11 | * @param key {string} Setting key. 12 | * @param value {Object} Serializable object. 13 | */ 14 | public addSetting(key: string, value: Object): void { 15 | this.configuration[key] = value; 16 | } 17 | 18 | public build(): Bag { 19 | return this.configuration; 20 | } 21 | } -------------------------------------------------------------------------------- /catalog/src/publishing/runtimeConfigPublisher.ts: -------------------------------------------------------------------------------- 1 | import * as Utils from "@paperbits/common/utils"; 2 | import { IBlobStorage } from "@paperbits/common/persistence"; 3 | import { IPublisher } from "@paperbits/common/publishing"; 4 | import { RuntimeConfigBuilder } from "./runtimeConfigBuilder"; 5 | 6 | /** 7 | * Runtime configuration publisher outputs runtime settings to the target website. 8 | */ 9 | export class RuntimeConfigPublisher implements IPublisher { 10 | constructor( 11 | private readonly runtimeConfigBuilder: RuntimeConfigBuilder, 12 | private readonly outputBlobStorage: IBlobStorage 13 | ) { } 14 | 15 | public async publish(): Promise { 16 | const configuration = this.runtimeConfigBuilder.build(); 17 | const content = Utils.stringToUnit8Array(JSON.stringify(configuration)); 18 | 19 | await this.outputBlobStorage.uploadBlob("/config-apim.json", content); 20 | 21 | // const servers = await this.oauthService.loadAllServers(); 22 | // if(servers) { 23 | // const serversContent = Utils.stringToUnit8Array(JSON.stringify(servers)); 24 | // await this.outputBlobStorage.uploadBlob("/auth-servers.json", serversContent); 25 | // } 26 | } 27 | } -------------------------------------------------------------------------------- /catalog/src/services/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./userService"; 2 | -------------------------------------------------------------------------------- /catalog/src/services/markdownService.ts: -------------------------------------------------------------------------------- 1 | import * as ko from "knockout"; 2 | import { remark } from "remark"; 3 | import remarkParse from "remark-parse"; 4 | import remarkGfm from "remark-gfm"; 5 | import remarkRehype from "remark-rehype"; 6 | import rehypeRaw from "rehype-raw"; 7 | import rehypeSanitize, { defaultSchema } from "rehype-sanitize"; 8 | import rehypeStringify from "rehype-stringify"; 9 | import * as truncateHtml from "truncate-html"; 10 | 11 | /** 12 | * A service to process markdown input. 13 | */ 14 | export class MarkdownService { 15 | public processMarkdown(markdown: string): string { 16 | let processedHtml: string; 17 | 18 | remark() 19 | .use(remarkParse) 20 | .use(remarkGfm) 21 | .use(remarkRehype, { allowDangerousHtml: true }) 22 | .use(rehypeRaw) 23 | .use(rehypeSanitize, { 24 | ...defaultSchema, 25 | attributes: { 26 | "*": ["className", "role", "style"], 27 | "img": ["src", "alt", "width", "height"], 28 | "a": ["href", "target"] 29 | } 30 | }) 31 | .use(rehypeStringify) 32 | .process(markdown, (err: any, html: any) => { 33 | processedHtml = truncateHtml.default(html, { length: length, reserveLastWord: true }); 34 | }); 35 | 36 | return processedHtml; 37 | } 38 | } -------------------------------------------------------------------------------- /catalog/src/services/reportQuery.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Query object used for making queries to Analtics service. 3 | */ 4 | export interface ReportQuery { 5 | /** 6 | * Report start time. 7 | */ 8 | startTime: Date; 9 | 10 | /** 11 | * Report end time. 12 | */ 13 | endTime: Date; 14 | 15 | /** 16 | * Amount of records to skip. 17 | */ 18 | skip?: number; 19 | 20 | /** 21 | * Amount of records to take. 22 | */ 23 | take?: number; 24 | 25 | /** 26 | * A field the report needs to be order by. 27 | */ 28 | orderBy?: string; 29 | 30 | /** 31 | * Order direction. 32 | */ 33 | orderDirection?: string; 34 | } -------------------------------------------------------------------------------- /catalog/src/services/roleService.ts: -------------------------------------------------------------------------------- 1 | import { BuiltInRoles, RoleModel } from "@paperbits/common/user"; 2 | 3 | /** 4 | * Static role service for demo purposes. 5 | */ 6 | export class StaticRoleService { 7 | public async getRoles(): Promise { 8 | return [BuiltInRoles.everyone, BuiltInRoles.anonymous, BuiltInRoles.authenticated]; 9 | } 10 | } -------------------------------------------------------------------------------- /catalog/src/services/tagService.ts: -------------------------------------------------------------------------------- 1 | import { TagContract } from "../contracts/tag"; 2 | import { PageContract } from "../contracts/page"; 3 | import { Page } from "../models/page"; 4 | import { Tag } from "../models/tag"; 5 | import { Utils } from "../utils"; 6 | 7 | export class TagService { 8 | 9 | public async getTags(scope?: string, filter?: string): Promise> { 10 | return new Page(); 11 | 12 | // let query = "/tags"; 13 | 14 | // if (scope) { 15 | // query = Utils.addQueryParameter(query, `scope=${scope}`); 16 | // } 17 | 18 | // if (filter) { 19 | // query = Utils.addQueryParameter(query, `$filter=(startswith(properties/displayName,'${filter}'))`); 20 | // } 21 | 22 | // const pageOfTags = await this.mapiClient.get>(query); 23 | 24 | // const page = new Page(); 25 | // page.value = pageOfTags.value.map(x => new Tag(x)); 26 | // page.nextLink = pageOfTags.nextLink; 27 | 28 | // return page; 29 | } 30 | } -------------------------------------------------------------------------------- /catalog/src/services/templatingService.ts: -------------------------------------------------------------------------------- 1 | import { Liquid } from "liquidjs"; 2 | 3 | export class TemplatingService { 4 | public static async render(template: string, model: Object): Promise { 5 | const engine = new Liquid(); 6 | const result = await engine.parseAndRender(template, model, null); 7 | 8 | return result; 9 | } 10 | } -------------------------------------------------------------------------------- /catalog/src/services/ttlCache.ts: -------------------------------------------------------------------------------- 1 | export class TtlCache { 2 | private cache: { 3 | [key: string]: { 4 | expires: number, 5 | promise: Promise 6 | } 7 | } = {}; 8 | 9 | public getOrAddAsync(key: string, fetch: () => Promise, ttl: number): Promise { 10 | let cached = this.cache[key]; 11 | const now = Date.now(); 12 | 13 | if (cached) { 14 | if (cached.expires >= now) { 15 | return cached.promise; 16 | } 17 | else { 18 | delete this.cache[key]; 19 | } 20 | } 21 | 22 | const fetchPromise = fetch(); 23 | 24 | this.cache[key] = cached = { 25 | expires: Number.MAX_VALUE, 26 | promise: fetchPromise 27 | }; 28 | 29 | fetchPromise.then(() => { 30 | cached.expires = now + ttl; 31 | this.cleanup(now); 32 | }, () => { 33 | cached.expires = now + ttl; 34 | this.cleanup(now); 35 | }); 36 | 37 | return fetchPromise; 38 | } 39 | 40 | private cleanup(now: number): void { 41 | for (const key in this.cache) { 42 | if (this.cache[key].expires < now) { 43 | delete this.cache[key]; 44 | } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /catalog/src/services/userService.ts: -------------------------------------------------------------------------------- 1 | import { UserService, BuiltInRoles } from "@paperbits/common/user"; 2 | 3 | export class StaticUserService implements UserService { 4 | 5 | public async getUserName(): Promise { 6 | return ""; 7 | } 8 | 9 | public async getUserPhotoUrl(): Promise { 10 | return ""; 11 | } 12 | 13 | /** 14 | * Returns current user's role keys. 15 | */ 16 | public async getUserRoles(): Promise { 17 | return [BuiltInRoles.anonymous.key]; 18 | } 19 | 20 | /** 21 | * Assigns roles to current user. 22 | * @param roles 23 | */ 24 | public async setUserRoles(roles: string[]): Promise { 25 | throw new Error("Not implemented."); 26 | } 27 | } -------------------------------------------------------------------------------- /catalog/src/startup.design.ts: -------------------------------------------------------------------------------- 1 | import "./polyfills"; 2 | import * as ko from "knockout"; 3 | import { InversifyInjector } from "@paperbits/common/injection"; 4 | import { CoreDesignModule } from "@paperbits/core/core.design.module"; 5 | import { StylesDesignModule } from "@paperbits/styles/styles.design.module"; 6 | import { ProseMirrorModule } from "@paperbits/prosemirror/prosemirror.module"; 7 | import { OfflineModule } from "@paperbits/common/persistence/offline.module"; 8 | import { SessionExpirationErrorHandler } from "./errors/sessionExpirationErrorHandler"; 9 | import { MainDesignModule } from "./main.design.module"; 10 | 11 | 12 | /* Initializing dependency injection container */ 13 | const injector = new InversifyInjector(); 14 | injector.bindToCollection("autostart", SessionExpirationErrorHandler); 15 | injector.bindModule(new CoreDesignModule()); 16 | injector.bindModule(new StylesDesignModule()); 17 | injector.bindModule(new ProseMirrorModule()); 18 | injector.bindModule(new MainDesignModule()); 19 | injector.bindModule(new OfflineModule({ autosave: false })); 20 | injector.resolve("autostart"); 21 | 22 | /* Bootstrapping the application */ 23 | document.addEventListener("DOMContentLoaded", () => { 24 | setImmediate(() => ko.applyBindings(undefined, document.body)); 25 | }); -------------------------------------------------------------------------------- /catalog/src/startup.host.ts: -------------------------------------------------------------------------------- 1 | import "reflect-metadata"; 2 | import * as express from "express"; 3 | import * as bodyParser from "body-parser"; 4 | import { InversifyInjector } from "@paperbits/common/injection"; 5 | import { useExpressServer, useContainer } from "routing-controllers"; 6 | import { UnhandledErrorMiddleware, StaticContentMiddleware } from "./middlewares"; 7 | import { MainHostModule } from "./main.host.module"; 8 | import { InversifyAdapter } from "./injection/inversifyAdapter"; 9 | import { ContentController } from "./controller/contentController"; 10 | 11 | process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0"; 12 | 13 | const injector = new InversifyInjector(); 14 | injector.bindModule(new MainHostModule()); 15 | 16 | const adapter = new InversifyAdapter(injector); 17 | useContainer(adapter); 18 | 19 | const app = express(); 20 | app.use(bodyParser.json({ limit: "50mb" })); 21 | app.use(bodyParser.urlencoded({ extended: false, limit: "50mb" })); 22 | 23 | 24 | useExpressServer(app, { 25 | defaultErrorHandler: false, 26 | middlewares: [ 27 | UnhandledErrorMiddleware, 28 | StaticContentMiddleware 29 | ], 30 | controllers: [ 31 | ContentController 32 | ] 33 | }); 34 | 35 | const port = process.env.PORT || 3000; 36 | app.listen(port); 37 | 38 | console.log(`Website proxy started. Listening port ${port}...`); -------------------------------------------------------------------------------- /catalog/src/startup.runtime.ts: -------------------------------------------------------------------------------- 1 | import { InversifyInjector } from "@paperbits/common/injection"; 2 | import { CoreRuntimeModule } from "@paperbits/core/core.runtime.module"; 3 | import { StyleRuntimeModule } from "@paperbits/styles/styles.runtime.module"; 4 | import { MainRuntimeModule } from "./main.runtime.module"; 5 | 6 | 7 | const injector = new InversifyInjector(); 8 | injector.bindModule(new CoreRuntimeModule()); 9 | injector.bindModule(new StyleRuntimeModule()); 10 | injector.bindModule(new MainRuntimeModule()); 11 | 12 | document.addEventListener("DOMContentLoaded", () => { 13 | injector.resolve("autostart"); 14 | }); -------------------------------------------------------------------------------- /catalog/src/themes/designer/assets/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | API Management 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/codeEditor.scss: -------------------------------------------------------------------------------- 1 | code-editor { 2 | min-height: 200px; 3 | 4 | /* fix for positioning of the IntelliSense window of Monaco Editor */ 5 | .monaco-editor .overflowingContentWidgets { 6 | position: absolute; 7 | top: 0; 8 | } 9 | } -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/confirmation.scss: -------------------------------------------------------------------------------- 1 | .confirmation { 2 | max-width: 300px; 3 | padding: 15px; 4 | } -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/draggables.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | 3 | .dragtarget { 4 | width: 100px; 5 | height: 100px; 6 | border: 1px dashed #ccc; 7 | } 8 | 9 | .dragsource { 10 | border: 1px solid #ccc; 11 | position: fixed; 12 | background: #fff; 13 | } 14 | 15 | .dragged { 16 | @include no-select(); 17 | @include no-drag(); 18 | @include no-pointer-events(); 19 | z-index: $z-index-dragging; 20 | cursor: grab; 21 | position: fixed; 22 | background: #fff; 23 | } 24 | 25 | .placeholder { 26 | border: 2px dashed #ccc; 27 | border: 2px dashed darken($toolbox-background, 20%); 28 | transition: height .5s ease-in-out; 29 | position: relative; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/dropbucket.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | @import "toolboxes.scss"; 3 | @import "animation.scss"; 4 | @import "buttons.scss"; 5 | 6 | dropbucket { 7 | right: 20px; 8 | bottom: 20px; 9 | position: fixed; 10 | z-index: $z-index-base; 11 | 12 | .btn-dismiss { 13 | padding: 0; 14 | margin: 0; 15 | top: 0; 16 | right: 0; 17 | } 18 | 19 | .droppedcontent { 20 | @include surface(); 21 | @include animation-fadein(); 22 | position: relative; 23 | border-radius: $toolbox-border-radius; 24 | display: flex; 25 | flex-direction: column; 26 | } 27 | 28 | .droppedcontent-details { 29 | @include text-overflow(); 30 | } 31 | 32 | .droppedcontent-preview { 33 | width: 280px; 34 | height: 150px; 35 | background-image: data-uri("../svgs/icons-unknown.svg"); 36 | background-repeat: no-repeat; 37 | background-position: center; 38 | background-size: contain; 39 | display: block; 40 | margin: 10px 0; 41 | } 42 | 43 | .list-item { 44 | position: relative; 45 | } 46 | 47 | .btn { 48 | height: 100%; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/dropdowns.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | 3 | .toolbox-dropdown { 4 | display: inline-block; 5 | box-sizing: border-box; 6 | border: none; 7 | 8 | & > span { 9 | line-height: $toolbox-btn-size; 10 | padding: 0 10px; 11 | } 12 | 13 | a { 14 | text-decoration: none; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/editors/colorSelector.scss: -------------------------------------------------------------------------------- 1 | .color { 2 | cursor: pointer; 3 | border-radius: 50%; 4 | box-shadow: inset -1px 1px 1px 0 rgba(0, 0, 0, 0.1); 5 | width: 30px; 6 | height: 30px; 7 | margin: 10px; 8 | padding: 0; 9 | display: block; 10 | position: relative; 11 | text-align: center; 12 | line-height: 30px; 13 | } 14 | 15 | .pseudo-transparent-bckg { 16 | position: relative; 17 | overflow: hidden; 18 | @include pseudo-transparent-bckg(); 19 | } 20 | 21 | .palette { 22 | list-style: none; 23 | padding: 0; 24 | max-width: 250px; 25 | 26 | .color-box { 27 | float: left; 28 | position: relative; 29 | 30 | &.selected:before { 31 | position: absolute; 32 | content: ""; 33 | border: 2px solid #4c5866; 34 | border-radius: 50%; 35 | width: 36px; 36 | height: 36px; 37 | pointer-events: none; 38 | top: 50%; 39 | left: 50%; 40 | transform: translate(-50%, -50%); 41 | } 42 | 43 | &:hover { 44 | @include selection(10px); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/editors/fontEditor.scss: -------------------------------------------------------------------------------- 1 | .font-variant-item { 2 | border-bottom: 1px solid #ccc; 3 | padding: 10px; 4 | 5 | &:last-child { 6 | border-bottom: none; 7 | } 8 | 9 | .font-variant-display { 10 | text-decoration: none; 11 | color: $color-base; 12 | font-size: 40px; 13 | overflow: hidden; 14 | } 15 | } -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/editors/fontSelector.scss: -------------------------------------------------------------------------------- 1 | .fonts { 2 | list-style: none; 3 | padding: 0; 4 | margin: 0; 5 | } 6 | 7 | .font { 8 | font-size: 20px; 9 | text-decoration: none; 10 | color: $color-base; 11 | padding: 5px 10px; 12 | 13 | &.font-italic { 14 | font-style: italic; 15 | } 16 | 17 | &.font-thin { 18 | font-weight: 100; 19 | } 20 | 21 | &.font-extra-light { 22 | font-weight: 200; 23 | } 24 | 25 | &.font-light { 26 | font-weight: 300; 27 | } 28 | 29 | &.font-regular { 30 | font-weight: 400; 31 | } 32 | 33 | &.font-medium { 34 | font-weight: 500; 35 | } 36 | 37 | &.font-semi-bold { 38 | font-weight: 600; 39 | } 40 | 41 | &.font-bold { 42 | font-weight: 700; 43 | } 44 | 45 | &.font-extra-bold { 46 | font-weight: 800; 47 | } 48 | 49 | &.font-black { 50 | font-weight: 900; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/editors/rowLayoutSelector.scss: -------------------------------------------------------------------------------- 1 | .row-layout-selector { 2 | width: 400px; 3 | } -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/editors/videoEditor.scss: -------------------------------------------------------------------------------- 1 | .video-player-editor { 2 | position: fixed; 3 | top: 20px; 4 | left: 100px; 5 | 6 | video { 7 | width: 100%; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/flex.scss: -------------------------------------------------------------------------------- 1 | .flex { 2 | display: flex; 3 | justify-content: flex-start; 4 | align-content: flex-start; 5 | min-height: 0; // fixes issue with oveflow in Edge, FF and other browsers 6 | 7 | &.flex-row { 8 | flex-direction: row; 9 | } 10 | 11 | &.flex-column { 12 | flex-direction: column; 13 | } 14 | 15 | .flex-item { 16 | flex: 0 1 auto; 17 | align-self: auto; 18 | 19 | &.flex-item-grow { 20 | flex: 1 1 auto; 21 | } 22 | } 23 | 24 | .flex-wrap { 25 | flex-wrap: wrap; 26 | } 27 | } 28 | 29 | .flex-end { 30 | align-items: flex-end; 31 | } 32 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/fonts/OpenSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/API-Portal/27e74d620111ee864533ec94516ad9ba71a8091c/catalog/src/themes/designer/styles/fonts/OpenSans-Bold.ttf -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/fonts/OpenSans-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/API-Portal/27e74d620111ee864533ec94516ad9ba71a8091c/catalog/src/themes/designer/styles/fonts/OpenSans-BoldItalic.ttf -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/fonts/OpenSans-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/API-Portal/27e74d620111ee864533ec94516ad9ba71a8091c/catalog/src/themes/designer/styles/fonts/OpenSans-Italic.ttf -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/fonts/OpenSans-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/API-Portal/27e74d620111ee864533ec94516ad9ba71a8091c/catalog/src/themes/designer/styles/fonts/OpenSans-Light.ttf -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/fonts/OpenSans-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/API-Portal/27e74d620111ee864533ec94516ad9ba71a8091c/catalog/src/themes/designer/styles/fonts/OpenSans-LightItalic.ttf -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/fonts/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/API-Portal/27e74d620111ee864533ec94516ad9ba71a8091c/catalog/src/themes/designer/styles/fonts/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/fonts/paperbits.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/API-Portal/27e74d620111ee864533ec94516ad9ba71a8091c/catalog/src/themes/designer/styles/fonts/paperbits.eot -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/fonts/paperbits.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/API-Portal/27e74d620111ee864533ec94516ad9ba71a8091c/catalog/src/themes/designer/styles/fonts/paperbits.ttf -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/fonts/paperbits.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/API-Portal/27e74d620111ee864533ec94516ad9ba71a8091c/catalog/src/themes/designer/styles/fonts/paperbits.woff -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/fonts/paperbits.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/API-Portal/27e74d620111ee864533ec94516ad9ba71a8091c/catalog/src/themes/designer/styles/fonts/paperbits.woff2 -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/host.scss: -------------------------------------------------------------------------------- 1 | .host { 2 | height: 100%; 3 | width: 100%; 4 | border: 0; 5 | padding: 0; 6 | margin: 0; 7 | // box-shadow: 0 5px 10px #c6c6c6; 8 | } 9 | 10 | .viewport { 11 | position: fixed; 12 | top: 0; 13 | left: 0; 14 | right: 0; 15 | bottom: 0; 16 | padding: 0; 17 | background: #ececec; 18 | 19 | &.viewport-xl { 20 | padding-left: 0; 21 | padding-right: 0; 22 | } 23 | 24 | &.viewport-lg { 25 | padding-left: calc((100% - #{$breakpoint-xl - 1})/2); 26 | padding-right: calc((100% - #{$breakpoint-xl - 1})/2); 27 | } 28 | 29 | &.viewport-md { 30 | padding-left: calc((100% - #{$breakpoint-lg - 1})/2); 31 | padding-right: calc((100% - #{$breakpoint-lg - 1})/2); 32 | } 33 | 34 | &.viewport-sm { 35 | padding-left: calc((100% - #{$breakpoint-md - 1})/2); 36 | padding-right: calc((100% - #{$breakpoint-md - 1})/2); 37 | } 38 | 39 | &.viewport-xs { 40 | padding-left: calc((100% - #{$breakpoint-sm - 1})/2); 41 | padding-right: calc((100% - #{$breakpoint-sm - 1})/2); 42 | } 43 | 44 | &.viewport-zoomout .host { 45 | transform: scale(0.5); 46 | transform-origin: center top 0; 47 | height: 200%; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-api-management.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-button.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-card.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-collapsible-panel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-component.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-date-input.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-email-input.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-form.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-map.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-multi-line-input.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-picture.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-range-input.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-search-box.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-select-input.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-submit-form-button.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-tab-panel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-table.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-video-player.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/icons/icon-youtube-player.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/scaffolding.scss: -------------------------------------------------------------------------------- 1 | @import "mixins.scss"; 2 | html, 3 | body { 4 | width: 100%; 5 | height: 100%; 6 | padding: 0; 7 | margin: 0; 8 | overflow: hidden; 9 | } 10 | 11 | * { 12 | @include box-sizing(border-box); 13 | position: relative; 14 | } 15 | 16 | *:before, 17 | *:after { 18 | @include box-sizing(border-box); 19 | } 20 | 21 | // Reset fonts for relevant elements 22 | input, 23 | button, 24 | select, 25 | textarea { 26 | font-family: inherit; 27 | font-size: inherit; 28 | } 29 | 30 | figure { 31 | margin: 0; 32 | } 33 | 34 | img { 35 | vertical-align: middle; 36 | } 37 | 38 | [role="button"] { 39 | cursor: pointer; 40 | } 41 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/slider.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | 3 | .slider-display { 4 | width: 100%; 5 | height: 25px; 6 | margin-top: 15px; 7 | } 8 | 9 | .slider { 10 | width: 100%; 11 | height: 15px; 12 | 13 | .slider-thumb { 14 | @include slider-thumb(); 15 | position: absolute; 16 | transform: translate(-$form-control-slider-thumb-size / 2, -$form-control-slider-thumb-size / 2); 17 | } 18 | } -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/styles.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | @import "typography.scss"; 3 | @import "flex.scss"; 4 | @import "balloons.scss"; 5 | @import "buttons.scss"; 6 | @import "dropdowns.scss"; 7 | @import "icons-toolboxes.scss"; 8 | @import "icons-widgets.scss"; 9 | @import "lists.scss"; 10 | @import "mixins.scss"; 11 | @import "scaffolding.scss"; 12 | @import "toolbox.paragraph.scss"; 13 | @import "toolboxes.scss"; 14 | @import "workshops.scss"; 15 | @import "dropbucket.scss"; 16 | @import "toasts.scss"; 17 | @import "layouts.scss"; 18 | @import "animation.scss"; 19 | @import "draggables.scss"; 20 | @import "forms.scss"; 21 | @import "tabs.scss"; 22 | @import "widgets.scss"; 23 | @import "arrows.scss"; 24 | @import "spinners.scss"; 25 | @import "host.scss"; 26 | @import "scrollbars.scss"; 27 | @import "thumbnails.scss"; 28 | @import "dropzones.scss"; 29 | @import "utils.scss"; 30 | @import "tooltips.scss"; 31 | @import "confirmation.scss"; 32 | @import "cropper.scss"; 33 | @import "lightbox.scss"; 34 | @import "codeEditor.scss"; 35 | 36 | 37 | 38 | @import "editors/boxEditor.scss"; 39 | @import "editors/fontSelector.scss"; 40 | @import "editors/colorPicker.scss"; 41 | 42 | 43 | @import "grid.scss"; -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/tabs.scss: -------------------------------------------------------------------------------- 1 | 2 | .tabs { 3 | border-bottom: 1px solid $form-control-border; 4 | margin-bottom: 12px; 5 | display: flex; 6 | width: 100%; 7 | 8 | .tab { 9 | & > a { 10 | min-width: 60px; 11 | display: inline-block; 12 | vertical-align: middle; 13 | text-align: center; 14 | line-height: 35px; 15 | color: $color-base; 16 | padding: 0 10px; 17 | text-decoration: none; 18 | font-weight: bold; 19 | 20 | &:active, 21 | &:focus, 22 | &:hover { 23 | outline: none; 24 | @include selection(); 25 | } 26 | } 27 | 28 | &.tab-is-active { 29 | border-bottom: 2px solid $tab-selected-color; 30 | } 31 | } 32 | } 33 | 34 | .tab-panel { 35 | min-height: 200px; 36 | max-height: 350px; 37 | } -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/thumbnails.scss: -------------------------------------------------------------------------------- 1 | .thumbnail { 2 | width: 120px; 3 | height: 100px; 4 | background-size: contain; 5 | background-repeat: no-repeat; 6 | background-color: transparent; 7 | background-position: center; 8 | position: relative; 9 | margin: 5px; 10 | float: left; 11 | text-align: center; 12 | 13 | & div { 14 | width: 50px; 15 | height: 50px; 16 | top: 25%; 17 | left: 25%; 18 | } 19 | 20 | &:before { 21 | opacity: 0; 22 | transition: opacity .6s; 23 | top: 0; 24 | left: 0; 25 | right: 0; 26 | bottom: 0; 27 | content: attr(title); 28 | position: absolute; 29 | background-color: #000; 30 | color: #fff; 31 | line-height: normal; 32 | white-space: nowrap; 33 | overflow: hidden; 34 | text-overflow: ellipsis; 35 | padding: 5px; 36 | } 37 | 38 | &:hover { 39 | &:before { 40 | opacity: .7; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/toolbox.paragraph.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | @import "buttons.scss"; 3 | 4 | 5 | .tools-paragraph-style { 6 | @include tabable(); 7 | display: block; 8 | padding: 5px 10px; 9 | text-decoration: none; 10 | color: $color-base; 11 | } 12 | 13 | .tools-paragraph-style { 14 | &:last-child { 15 | border: none; 16 | } 17 | } 18 | 19 | .tools-paragraph-style-normal { 20 | @extend .tools-paragraph-style; 21 | } 22 | 23 | .tools-paragraph-style-h1 { 24 | @extend .tools-paragraph-style; 25 | font-size: 2.6em; 26 | } 27 | 28 | .tools-paragraph-style-h2 { 29 | @extend .tools-paragraph-style; 30 | font-size: 2.3em; 31 | } 32 | 33 | .tools-paragraph-style-h3 { 34 | @extend .tools-paragraph-style; 35 | font-size: 1.7em; 36 | } 37 | 38 | .tools-paragraph-style-h4 { 39 | @extend .tools-paragraph-style; 40 | font-size: 1.4em; 41 | } 42 | 43 | .tools-paragraph-style-h5 { 44 | @extend .tools-paragraph-style; 45 | font-size: 1em; 46 | } 47 | 48 | .tools-paragraph-style-h6 { 49 | @extend .tools-paragraph-style; 50 | font-size: .85em; 51 | } 52 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/tooltips.scss: -------------------------------------------------------------------------------- 1 | .tooltip { 2 | padding: 10px; 3 | max-width: 300px; 4 | display: block; 5 | line-height: 1.5em; 6 | p { 7 | margin: 0; 8 | } 9 | 10 | h1 { 11 | margin-bottom: 5px; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/utils.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | 3 | .text-center { 4 | text-align: center; 5 | } 6 | 7 | .text-hide { 8 | overflow: hidden; 9 | position: fixed; 10 | top: -1000px; 11 | left: -1000px; 12 | width: 0; 13 | height: 0; 14 | } 15 | 16 | .text-overflow { 17 | white-space: nowrap; 18 | overflow: hidden; 19 | text-overflow: ellipsis; 20 | } 21 | 22 | .no-overflow { 23 | overflow: hidden; 24 | } 25 | 26 | .d-none { 27 | display: none !important; 28 | } 29 | 30 | .d-xl-inline-block { 31 | @media (min-width: $breakpoint-xl) { 32 | display: inline-block !important; 33 | } 34 | } 35 | 36 | .d-lg-inline-block { 37 | @media (min-width: $breakpoint-lg) { 38 | display: inline-block !important; 39 | } 40 | } 41 | .d-md-inline-block { 42 | @media (min-width: $breakpoint-md) { 43 | display: inline-block !important; 44 | } 45 | } 46 | 47 | .d-sm-inline-block { 48 | @media (min-width: $breakpoint-sm) { 49 | display: inline-block !important; 50 | } 51 | } 52 | 53 | .mt-0 { 54 | margin-top: 0; 55 | } 56 | 57 | .ml-5 { 58 | margin-left: 5px; 59 | } 60 | 61 | .max-w300 { 62 | max-width: 300px; 63 | } -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/widgets.scss: -------------------------------------------------------------------------------- 1 | @import "widgets/map.scss"; 2 | @import "widgets/video.scss"; 3 | @import "editors/videoEditor.scss"; 4 | @import "editors/rowLayoutSelector.scss"; 5 | @import "editors/colorSelector.scss"; 6 | @import "editors/fontEditor.scss"; -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/widgets/map.scss: -------------------------------------------------------------------------------- 1 | .paperbits-googlemaps { 2 | width: 100%; 3 | height: 100%; 4 | height: 200px; 5 | border: 0; 6 | } -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/widgets/textblock.scss: -------------------------------------------------------------------------------- 1 | [contenteditable]:focus { 2 | outline: none; 3 | } 4 | 5 | .ProseMirror { 6 | position: relative; 7 | word-wrap: break-word; 8 | white-space: pre-wrap; 9 | white-space: break-spaces; 10 | -webkit-font-variant-ligatures: none; 11 | font-variant-ligatures: none; 12 | font-feature-settings: "liga" 0; /* the above doesn't seem to work in Edge */ 13 | 14 | pre { 15 | white-space: pre-wrap; 16 | } 17 | 18 | li { 19 | position: relative; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/widgets/video.scss: -------------------------------------------------------------------------------- 1 | video { 2 | width: 100%; 3 | display: block; 4 | } -------------------------------------------------------------------------------- /catalog/src/themes/designer/styles/widgets/youtube.scss: -------------------------------------------------------------------------------- 1 | .youtube-player { 2 | width: 100%; 3 | } -------------------------------------------------------------------------------- /catalog/src/themes/website/assets/page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/alerts.scss: -------------------------------------------------------------------------------- 1 | .alert { 2 | position: relative; 3 | padding: .75rem 1.25rem; 4 | margin-bottom: 1rem; 5 | border: 1px solid transparent; 6 | border-radius: .25rem; 7 | } 8 | 9 | .alert-danger { 10 | color: #721c24; 11 | background-color: #f8d7da; 12 | border-color: #f5c6cb; 13 | } -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/animations.scss: -------------------------------------------------------------------------------- 1 | @keyframes bounce { 2 | 20%, 3 | 53%, 4 | 80%, 5 | from, 6 | to { 7 | animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); 8 | transform: translate3d(0, 0, 0); 9 | } 10 | 11 | 40%, 12 | 43% { 13 | animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); 14 | transform: translate3d(0, -30px, 0); 15 | } 16 | 17 | 70% { 18 | animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); 19 | transform: translate3d(0, -15px, 0); 20 | } 21 | 22 | 90% { 23 | transform: translate3d(0, -4px, 0); 24 | } 25 | } 26 | 27 | .bounce { 28 | animation-name: bounce; 29 | transform-origin: center bottom; 30 | } 31 | 32 | @keyframes fadeInLeft { 33 | from { 34 | opacity: 0; 35 | transform: translate3d(-100%, 0, 0); 36 | } 37 | 38 | to { 39 | opacity: 1; 40 | transform: translate3d(0, 0, 0); 41 | } 42 | } 43 | 44 | .fadeInLeft { 45 | animation-name: fadeInLeft; 46 | } 47 | 48 | @keyframes fadeInRight { 49 | from { 50 | opacity: 0; 51 | transform: translate3d(100%, 0, 0); 52 | } 53 | 54 | to { 55 | opacity: 1; 56 | transform: translate3d(0, 0, 0); 57 | } 58 | } 59 | 60 | .fadeInRight { 61 | animation-name: fadeInRight; 62 | } -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/badges.scss: -------------------------------------------------------------------------------- 1 | .badge { 2 | background: none; 3 | border: 1px solid #aaa; 4 | color: #636363; 5 | border-radius: 0; 6 | } 7 | 8 | .badge-soap { 9 | display: inline; 10 | font-weight: normal; 11 | font-family: Menlo,Monaco,Consolas,"Courier New",monospace; 12 | font-size: 10px; 13 | padding: 0 2px; 14 | margin: 2px; 15 | 16 | order: 1; 17 | vertical-align: middle; 18 | display: inline; 19 | line-height: 1.7em; 20 | } -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/breadcrumbs.scss: -------------------------------------------------------------------------------- 1 | .breadcrumb { 2 | display: flex; 3 | flex-wrap: wrap; 4 | padding: 0; 5 | margin-bottom: 20px; 6 | list-style: none; 7 | background-color: none; 8 | a { 9 | text-decoration: underline; 10 | } 11 | } 12 | 13 | .breadcrumb-item+.breadcrumb-item { 14 | padding-left: .5rem; 15 | 16 | &::before { 17 | display: inline-block; 18 | padding-right: .5rem; 19 | color: #6c757d; 20 | content: "/"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/buttons.scss: -------------------------------------------------------------------------------- 1 | .btn-centered-vert { 2 | display: flex; 3 | align-items: center; 4 | height: 100%; 5 | } 6 | 7 | .btn-inline { 8 | padding-bottom: 1rem; 9 | } 10 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/charts.scss: -------------------------------------------------------------------------------- 1 | .subunit { 2 | fill: none; 3 | stroke: #f0f0f0; 4 | stroke-width: 1px; 5 | } 6 | 7 | text.subunit-label { 8 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 9 | font-size: 14px; 10 | font-weight: 300; 11 | text-anchor: middle; 12 | fill: #000; 13 | } 14 | 15 | .subunit-label { 16 | display: none; 17 | } 18 | 19 | .graticule { 20 | fill: none; 21 | stroke: #aaa; 22 | stroke-opacity: .5; 23 | stroke-width: .5px; 24 | } 25 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/flex.scss: -------------------------------------------------------------------------------- 1 | .flex { 2 | display: flex; 3 | flex-wrap: nowrap; 4 | justify-content: flex-start; 5 | align-content: stretch; 6 | } 7 | 8 | .flex-row { 9 | flex-direction: row; 10 | } 11 | 12 | .flex-column { 13 | flex-direction: column; 14 | } 15 | 16 | .flex-item { 17 | flex: 0 1 auto; 18 | align-self: auto; 19 | 20 | &.flex-item-grow { 21 | flex: 1 1 auto; 22 | } 23 | } 24 | 25 | .flex-grow { 26 | flex: 1; 27 | } 28 | 29 | .expand { 30 | width: 100%; 31 | } 32 | 33 | .justify-content-end { 34 | justify-content: flex-end!important; 35 | } 36 | 37 | .align-items-center { 38 | align-items: center; 39 | } 40 | 41 | .align-self-center { 42 | align-self: center; 43 | } 44 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/fonts/icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/API-Portal/27e74d620111ee864533ec94516ad9ba71a8091c/catalog/src/themes/website/styles/fonts/icons.eot -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/fonts/icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/API-Portal/27e74d620111ee864533ec94516ad9ba71a8091c/catalog/src/themes/website/styles/fonts/icons.ttf -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/fonts/icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/API-Portal/27e74d620111ee864533ec94516ad9ba71a8091c/catalog/src/themes/website/styles/fonts/icons.woff -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/icons/icon-wadl.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/icons/icon-wsdl.svg: -------------------------------------------------------------------------------- 1 | S -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/lists.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | 3 | .list { 4 | .list-item { 5 | padding: 10px; 6 | display: block; 7 | color: $default-text-color; 8 | cursor: default; 9 | 10 | &:hover { 11 | background-color: #edebe9; 12 | text-decoration: none; 13 | } 14 | 15 | &:focus { 16 | outline: 1px solid #605e5c; 17 | text-decoration: none; 18 | } 19 | } 20 | 21 | .list-item-empty { 22 | padding: 10px; 23 | display: block; 24 | color: $default-text-color; 25 | } 26 | } -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/mixins.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | 3 | @mixin fit($spacing: 0) { 4 | top: $spacing; 5 | left: $spacing; 6 | right: $spacing; 7 | bottom: $spacing; 8 | position: absolute; 9 | } 10 | 11 | @mixin icon-18px() { 12 | margin-left: 5px; 13 | background-position: center; 14 | background-repeat: no-repeat; 15 | width: 18px; 16 | height: 18px; 17 | } -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/monaco.editor.scss: -------------------------------------------------------------------------------- 1 | //this class is used indirectly for the monaco editor intelliense 2 | .overflowingContentWidgets { 3 | position: initial; 4 | } -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/pagination.scss: -------------------------------------------------------------------------------- 1 | .pagination { 2 | display: flex; 3 | padding-left: 0; 4 | list-style: none; 5 | margin-top: 20px; 6 | 7 | .page-link { 8 | border: none; 9 | position: relative; 10 | display: block; 11 | padding: .5rem .5rem; 12 | line-height: 1.25; 13 | color: $default-text-color; 14 | background-color: #fff; 15 | border: 1px solid $default-text-color; 16 | margin: 2px; 17 | 18 | &:hover { 19 | text-decoration: none; 20 | } 21 | 22 | .icon { 23 | font-weight: 900; 24 | } 25 | 26 | &.active { 27 | font-weight: bold; 28 | outline: 1px solid $default-text-color; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/pills.scss: -------------------------------------------------------------------------------- 1 | .nav-pills { 2 | margin: 5px 0; 3 | 4 | .nav-item { 5 | margin: 1px; 6 | 7 | .nav-link { 8 | border-radius: .25rem; 9 | font-size: 1.3em; 10 | padding: 5px 10px; 11 | border: 1px solid transparent; 12 | background: inherit; 13 | 14 | &:hover { 15 | background-color: $border-color-hover; 16 | } 17 | 18 | &.active { 19 | border-color: $border-color-active; 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/resizables.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | 3 | .resize-handle { 4 | background: transparent; 5 | position: absolute; 6 | z-index: $z-index-base + 1; 7 | 8 | &.resize-handle-right { 9 | cursor: e-resize; 10 | width: 5px; 11 | right: 0; 12 | top: 0; 13 | bottom: 0; 14 | } 15 | 16 | &.resize-handle-left { 17 | cursor: w-resize; 18 | width: 5px; 19 | left: 0; 20 | top: 0; 21 | bottom: 0; 22 | } 23 | 24 | &.resize-handle-top { 25 | cursor: n-resize; 26 | height: 5px; 27 | left: 0; 28 | right: 0; 29 | top: 0; 30 | } 31 | 32 | &.resize-handle-bottom { 33 | cursor: s-resize; 34 | height: 5px; 35 | left: 0; 36 | right: 0; 37 | bottom: 0; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/spinners.scss: -------------------------------------------------------------------------------- 1 | spinner { 2 | display: flex; 3 | text-align: center; 4 | align-items: center; 5 | flex-basis: 100%; 6 | justify-content: center; 7 | margin: 20px; 8 | 9 | & > div { 10 | width: 14px; 11 | height: 14px; 12 | margin: 5px; 13 | border-radius: 100%; 14 | display: inline-block; 15 | animation: sk-bouncedelay 1.4s infinite ease-in-out both; 16 | border: 1px solid #003255; 17 | 18 | &:nth-child(1) { 19 | animation-delay: -0.32s; 20 | } 21 | 22 | &:nth-child(2) { 23 | animation-delay: -0.16s; 24 | } 25 | } 26 | 27 | &.inverted > div { 28 | border: 1px solid #fff; 29 | background: #fff; 30 | } 31 | } 32 | @keyframes sk-bouncedelay { 33 | 0%, 34 | 100%, 35 | 80% { 36 | transform: scale(0); 37 | } 38 | 39 | 40% { 40 | transform: scale(1.0); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/styles.scss: -------------------------------------------------------------------------------- 1 | @import "reboot.scss"; 2 | @import "mixins.scss"; 3 | @import "layouts.scss"; 4 | @import "variables.scss"; 5 | @import "text.scss"; 6 | @import "icons.scss"; 7 | @import "animations.scss"; 8 | @import "flex.scss"; 9 | @import "docs.scss"; 10 | @import "breadcrumbs.scss"; 11 | @import "prism.scss"; 12 | @import "spinners.scss"; 13 | @import "tables.scss"; 14 | @import "tabs.scss"; 15 | @import "charts.scss"; 16 | @import "pagination.scss"; 17 | @import "tags.scss"; 18 | @import "forms.scss"; 19 | @import "navs.scss"; 20 | @import "widgets/widgets.scss"; 21 | @import "balloons.scss"; 22 | @import "lists.scss"; 23 | @import "alerts.scss"; 24 | @import "utils.scss"; 25 | @import "pills.scss"; 26 | @import "resizables.scss"; 27 | @import "buttons.scss"; 28 | @import "badges.scss"; 29 | @import "panels.scss"; 30 | @import "monaco.editor.scss"; 31 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/svgs/download.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/svgs/wadl.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/svgs/wsdl.svg: -------------------------------------------------------------------------------- 1 | S -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/tabs.scss: -------------------------------------------------------------------------------- 1 | .tabs { 2 | display: flex; 3 | flex-wrap: wrap; 4 | 5 | .tab-content { 6 | width: 100%; 7 | margin-top: -1px; 8 | padding: 1em; 9 | border: 1px solid #ddd; 10 | order: 1; 11 | } 12 | 13 | .tab-label { 14 | border: 1px solid #ddd; 15 | padding: .7em 1em; 16 | cursor: pointer; 17 | z-index: 1; 18 | margin-left: -1px; 19 | margin-bottom: 0; 20 | } 21 | 22 | .tab-label:first-of-type { 23 | margin-left: 0; 24 | } 25 | 26 | .tab-content, 27 | .tab-radio { 28 | display: none; 29 | } 30 | 31 | .tab-radio:checked + .tab-label { 32 | background: #fff; 33 | border-bottom: 1px solid #fff; 34 | } 35 | 36 | .tab-radio:checked + .tab-label + .tab-content { 37 | display: block; 38 | } 39 | } -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/tags.scss: -------------------------------------------------------------------------------- 1 | .tag-group { 2 | padding-top: 20px; 3 | padding-bottom: 10px; 4 | flex-basis: 100%; 5 | } 6 | 7 | .tag-item, 8 | .tag-item:active, 9 | .tag-item:hover { 10 | border: 1px solid $default-text-color; 11 | padding: 2px 7px; 12 | color: $default-text-color; 13 | cursor: default; 14 | display: inline-flex; 15 | text-decoration: none; 16 | align-items: center; 17 | margin: 2px; 18 | min-height: 2em; 19 | } 20 | 21 | .tag-item.tag-add { 22 | cursor: pointer; 23 | } 24 | 25 | .tag-remove { 26 | font-size: .7em; 27 | margin-left: 4px; 28 | cursor: pointer; 29 | } 30 | 31 | .list { 32 | overflow-y: auto; 33 | 34 | .tag-item { 35 | cursor: pointer; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/text.scss: -------------------------------------------------------------------------------- 1 | @import "variables.scss"; 2 | 3 | h1, 4 | h2, 5 | h3, 6 | h4, 7 | h5, 8 | h6 { 9 | font-weight: $default-heading-font-weight; 10 | line-height: $default-heading-line-height; 11 | color: $default-heading-color; 12 | } 13 | 14 | pre { 15 | white-space: pre-wrap; 16 | } 17 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/widgets/button.scss: -------------------------------------------------------------------------------- 1 | .button { 2 | display: inline-block; 3 | 4 | .icon { 5 | padding-right: .5em; 6 | vertical-align: middle; 7 | } 8 | } -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/widgets/card.scss: -------------------------------------------------------------------------------- 1 | .card { 2 | flex-direction: row; 3 | flex-wrap: wrap; 4 | flex-basis: 100%; 5 | &.item-tile { 6 | margin-left: 0; 7 | margin-right: 0; 8 | } 9 | } -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/widgets/map.scss: -------------------------------------------------------------------------------- 1 | map, 2 | map-runtime { 3 | display: block; 4 | } 5 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/widgets/popups.scss: -------------------------------------------------------------------------------- 1 | .popup { 2 | display: none; 3 | 4 | &.show { 5 | display: block; 6 | } 7 | 8 | .popup-backdrop { 9 | position: fixed; 10 | top: 0; 11 | left: 0; 12 | right: 0; 13 | bottom: 0; 14 | z-index: 1000; 15 | } 16 | 17 | .popup-container { 18 | z-index: 1001; 19 | } 20 | 21 | .popup-close { 22 | position: absolute; 23 | top: 5px; 24 | right: 5px; 25 | border: none; 26 | background: none; 27 | z-index: 1002; 28 | } 29 | } 30 | 31 | .popup-host { 32 | display: contents; 33 | } 34 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/widgets/slider.scss: -------------------------------------------------------------------------------- 1 | .carousel-item > * { 2 | flex: 1; 3 | } 4 | 5 | .carousel.carousel-short { 6 | .carousel-item > div { 7 | height: 300px; 8 | } 9 | } 10 | 11 | .carousel { 12 | .carousel-item > div { 13 | height: 400px; 14 | } 15 | } 16 | 17 | .carousel.carousel-tall { 18 | .carousel-item > div { 19 | height: 600px; 20 | } 21 | } 22 | 23 | .carousel-toasts.carousel-toasts-thumbnails { 24 | position: absolute; 25 | right: 0; 26 | bottom: -70px; 27 | left: 0; 28 | z-index: 15; 29 | display: flex; 30 | justify-content: center; 31 | padding-left: 0; 32 | margin-right: 15%; 33 | margin-left: 15%; 34 | list-style: none; 35 | align-items: center; 36 | 37 | li { 38 | border-radius: 50%; 39 | display: block; 40 | width: 70px; 41 | height: 70px; 42 | background: #ccc; 43 | margin: 10px; 44 | max-width: 70px; 45 | cursor: pointer; 46 | 47 | &.active { 48 | zoom: 1.3; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/widgets/table-of-contents.scss: -------------------------------------------------------------------------------- 1 | .table-of-contents { 2 | .nav { 3 | .nav { 4 | margin-left: 2px; 5 | padding-left: 15px; 6 | border-left: 2px solid #e6e6e6; 7 | } 8 | } 9 | 10 | .nav-item { 11 | display: block; 12 | 13 | .nav-link { 14 | padding: .2em 0; 15 | } 16 | 17 | &.active > .nav-link { 18 | font-weight: bold; 19 | } 20 | } 21 | 22 | .nav-link.active { 23 | color: $link-active-color; 24 | font-weight: bold; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/widgets/tabs.scss: -------------------------------------------------------------------------------- 1 | .tab-panel { 2 | display: flex; 3 | flex-direction: column; 4 | position: relative; 5 | overflow: hidden; 6 | 7 | .tab-navs { 8 | display: flex; 9 | } 10 | 11 | .tab-content { 12 | display: none; 13 | flex-grow: 1; 14 | 15 | &.tab-content-active { 16 | display: flex; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/widgets/textblock.scss: -------------------------------------------------------------------------------- 1 | [contenteditable]:focus { 2 | outline: none; 3 | } 4 | 5 | p:empty { 6 | &:before { 7 | content: " "; 8 | } 9 | } 10 | 11 | .ProseMirror { 12 | position: relative; 13 | word-wrap: break-word; 14 | white-space: pre-wrap; 15 | white-space: break-spaces; 16 | -webkit-font-variant-ligatures: none; 17 | font-variant-ligatures: none; 18 | font-feature-settings: "liga" 0; /* the above doesn't seem to work in Edge */ 19 | 20 | pre { 21 | white-space: pre-wrap; 22 | } 23 | 24 | li { 25 | position: relative; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/widgets/video.scss: -------------------------------------------------------------------------------- 1 | .video-player { 2 | width: 100%; 3 | min-height: 150px; 4 | position: relative; 5 | 6 | video { 7 | width: 100%; 8 | display: block; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/widgets/widgets.scss: -------------------------------------------------------------------------------- 1 | @import "button.scss"; 2 | @import "card.scss"; 3 | @import "map.scss"; 4 | @import "textblock.scss"; 5 | @import "collapsibles.scss"; 6 | @import "carousel.scss"; 7 | @import "tabs.scss"; 8 | @import "popups.scss"; 9 | @import "tabs.scss"; -------------------------------------------------------------------------------- /catalog/src/themes/website/styles/widgets/youtube.scss: -------------------------------------------------------------------------------- 1 | .youtube-player { 2 | display: block; 3 | width: 100%; 4 | height: 100%; 5 | 6 | iframe { 7 | width: 100%; 8 | height: 100%; 9 | pointer-events: none; 10 | } 11 | } -------------------------------------------------------------------------------- /catalog/src/types/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.html" { 2 | const content: string; 3 | export default content; 4 | } 5 | 6 | declare module "*.liquid" { 7 | const content: string; 8 | export default content; 9 | } 10 | 11 | declare module "*.txt" { 12 | const content: string; 13 | export default content; 14 | } 15 | 16 | declare module '*!text' { 17 | var _: string; 18 | export default _; 19 | } -------------------------------------------------------------------------------- /catalog/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "lib": [ 5 | "dom", 6 | "es2019" 7 | ], 8 | "module": "commonjs", 9 | "moduleResolution": "node", 10 | "noStrictGenericChecks": true, 11 | "removeComments": true, 12 | "noLib": false, 13 | "skipLibCheck": true, 14 | "experimentalDecorators": true, 15 | "emitDecoratorMetadata": true, 16 | "allowUnreachableCode": true, 17 | "sourceMap": true, 18 | "incremental": true 19 | }, 20 | "include": [ 21 | "./src/**/*", 22 | "./node_modules/@paperbits/**/*" 23 | ], 24 | "exclude": [ 25 | "./node_modules" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /catalog/webpack.build.js: -------------------------------------------------------------------------------- 1 | const { merge } = require("webpack-merge"); 2 | const TerserPlugin = require("terser-webpack-plugin"); 3 | const { designerConfig, designerRuntimeConfig } = require("./webpack.designer.js"); 4 | const { publisherConfig, publisherRuntimeConfig } = require("./webpack.publisher.js"); 5 | 6 | 7 | const productionConfig = { 8 | mode: "production", 9 | optimization: { 10 | minimizer: [ 11 | new TerserPlugin({ 12 | terserOptions: { 13 | mangle: false, 14 | output: { 15 | comments: false 16 | } 17 | } 18 | }) 19 | ] 20 | } 21 | } 22 | 23 | module.exports = [ 24 | designerConfig, 25 | designerRuntimeConfig, 26 | publisherConfig, 27 | publisherRuntimeConfig 28 | ].map(x => merge(x, productionConfig)); -------------------------------------------------------------------------------- /catalog/webpack.develop.js: -------------------------------------------------------------------------------- 1 | const { merge } = require("webpack-merge"); 2 | const CopyWebpackPlugin = require("copy-webpack-plugin"); 3 | const { designerConfig, designerRuntimeConfig } = require("./webpack.designer.js"); 4 | 5 | const developmentConfig = { 6 | mode: "development", 7 | devtool: "inline-source-map", 8 | devServer: { 9 | hot: true, 10 | historyApiFallback: true 11 | }, 12 | plugins: [ 13 | new CopyWebpackPlugin({ 14 | patterns: [ 15 | { from: `./src/config.design.json`, to: `./config.json` } 16 | ] 17 | }) 18 | ] 19 | } 20 | 21 | module.exports = [ 22 | merge(designerConfig, developmentConfig), 23 | designerRuntimeConfig 24 | ] -------------------------------------------------------------------------------- /catalog/webpack.host.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const CopyWebpackPlugin = require("copy-webpack-plugin"); 3 | 4 | 5 | const apiConfig = { 6 | mode: "development", 7 | target: "node", 8 | node: { 9 | __dirname: false, 10 | __filename: false, 11 | }, 12 | entry: { 13 | "index": ["./src/startup.host.ts"] 14 | }, 15 | output: { 16 | filename: "./[name].js", 17 | path: path.resolve(__dirname, "./dist/host") 18 | }, 19 | module: { 20 | rules: [ 21 | { 22 | test: /\.tsx?$/, 23 | loader: "ts-loader", 24 | options: { 25 | allowTsInNodeModules: true 26 | } 27 | } 28 | ] 29 | }, 30 | plugins: [ 31 | new CopyWebpackPlugin({ 32 | patterns: [ 33 | { from: `./data`, to: `./data` }, 34 | { from: "./src/config.host.json", to: "config.json" } 35 | ] 36 | }) 37 | ], 38 | resolve: { 39 | extensions: [".ts", ".tsx", ".js", ".jsx"] 40 | } 41 | }; 42 | 43 | module.exports = [apiConfig] -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "API-Portal", 3 | "lockfileVersion": 2, 4 | "requires": true, 5 | "packages": {} 6 | } 7 | -------------------------------------------------------------------------------- /readme.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/API-Portal/27e74d620111ee864533ec94516ad9ba71a8091c/readme.gif --------------------------------------------------------------------------------