├── .babelrc ├── .circleci └── config.yml ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .github ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── stale.yml ├── .gitignore ├── .jshintrc ├── .meteor ├── .finished-upgraders ├── .gitignore ├── .id ├── cordova-plugins ├── packages ├── platforms ├── release └── versions ├── .meteorignore ├── .nvmrc ├── .prettierrc.js ├── .storybook ├── addons.js ├── config.js ├── decorators │ ├── BootstrapDecorator.js │ └── MaterialUIDecorator.js ├── helpers.js ├── loaders │ └── starter-example-loader.js ├── mocks │ ├── Meteor.js │ ├── Mongo.js │ ├── Vulcan.js │ ├── meteor-apollo.js │ ├── meteor-server-render.js │ └── vulcan-email.js ├── startup.js └── webpack.config.js ├── .vscode └── launch.json ├── .vulcan ├── .gitignore ├── prestart_vulcan.js ├── prettier │ └── index.js ├── shared │ ├── listChangedFiles.js │ └── pathsByLanguageVersion.js └── update_package.js ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── MIGRATING.md ├── README.md ├── RELEASE.md ├── jsconfig.json ├── jsdoc-conf.json ├── jsdoc.json ├── license.md ├── package-lock.json ├── package.json ├── packages ├── .gitignore ├── _boilerplate-generator │ ├── .gitignore │ ├── .npm │ │ └── package │ │ │ ├── .gitignore │ │ │ ├── README │ │ │ └── npm-shrinkwrap.json │ ├── README.md │ ├── generator.js │ ├── package.js │ ├── template-web.browser.js │ ├── template-web.cordova.js │ └── template.js ├── _buffer │ ├── buffer.js │ └── package.js ├── meteor-mocha │ ├── browser-shim.js │ ├── client.js │ ├── package.js │ ├── package.json │ ├── prepForHTMLReporter.js │ ├── runtimeArgs.js │ ├── server.handleCoverage.js │ └── server.js ├── vulcan-accounts │ ├── README.md │ ├── imports │ │ ├── accounts_ui.js │ │ ├── api │ │ │ └── server │ │ │ │ └── servicesListPublication.js │ │ ├── components.js │ │ ├── emailTemplates.js │ │ ├── helpers.js │ │ ├── login_session.js │ │ ├── oauth_config.js │ │ ├── routes.js │ │ ├── ui │ │ │ └── components │ │ │ │ ├── Button.jsx │ │ │ │ ├── Buttons.jsx │ │ │ │ ├── EnrollAccount.jsx │ │ │ │ ├── Field.jsx │ │ │ │ ├── Fields.jsx │ │ │ │ ├── Form.jsx │ │ │ │ ├── FormMessage.jsx │ │ │ │ ├── FormMessages.jsx │ │ │ │ ├── LoginForm.jsx │ │ │ │ ├── LoginFormInner.jsx │ │ │ │ ├── PasswordOrService.jsx │ │ │ │ ├── ResetPassword.jsx │ │ │ │ ├── SocialButtons.jsx │ │ │ │ ├── StateSwitcher.jsx │ │ │ │ ├── TrackerComponent.jsx │ │ │ │ └── VerifyEmail.jsx │ │ └── useMeteorLogout.js │ ├── main_client.js │ ├── main_server.js │ └── package.js ├── vulcan-admin │ ├── README.md │ ├── lib │ │ ├── client │ │ │ └── main.js │ │ ├── components │ │ │ ├── AdminHome.jsx │ │ │ ├── AdminLayout.jsx │ │ │ └── users │ │ │ │ └── columns │ │ │ │ ├── AdminUsersActions.jsx │ │ │ │ ├── AdminUsersCreated.jsx │ │ │ │ ├── AdminUsersEmail.jsx │ │ │ │ └── AdminUsersName.jsx │ │ ├── modules │ │ │ ├── columns.js │ │ │ ├── fragments.js │ │ │ ├── i18n.js │ │ │ ├── index.js │ │ │ └── routes.js │ │ ├── server │ │ │ └── main.js │ │ └── stylesheets │ │ │ └── style.scss │ └── package.js ├── vulcan-backoffice │ ├── .gitignore │ ├── README.md │ ├── lib │ │ ├── client │ │ │ └── main.js │ │ ├── components │ │ │ ├── BackofficeIndex.jsx │ │ │ ├── BackofficeLayout.jsx │ │ │ ├── CollectionItem.jsx │ │ │ └── CollectionList.jsx │ │ ├── hocs │ │ │ ├── withDocumentId.js │ │ │ └── withRouteParam.js │ │ ├── modules │ │ │ ├── components.js │ │ │ ├── createCollectionComponents │ │ │ │ ├── createCollectionComponents.js │ │ │ │ ├── createItemComponent.js │ │ │ │ ├── createListComponent.js │ │ │ │ └── index.js │ │ │ ├── index.js │ │ │ ├── namingHelpers.js │ │ │ ├── options.js │ │ │ ├── settings.js │ │ │ ├── setupBackoffice.js │ │ │ ├── setupCollectionMenuItems.js │ │ │ ├── setupCollectionRoutes.js │ │ │ └── startup.js │ │ └── server │ │ │ └── main.js │ ├── package-lock.json │ ├── package.js │ ├── package.json │ └── test │ │ ├── index.js │ │ ├── namingHelpers.test.js │ │ ├── options.js │ │ └── routes.test.js ├── vulcan-cloudinary │ ├── README.md │ ├── lib │ │ ├── client │ │ │ ├── main.js │ │ │ └── make_cloudinary.js │ │ ├── modules │ │ │ ├── custom_fields.js │ │ │ └── index.js │ │ └── server │ │ │ ├── cloudinary.js │ │ │ ├── main.js │ │ │ └── make_cloudinary.js │ └── package.js ├── vulcan-core │ ├── README.md │ ├── lib │ │ ├── client │ │ │ ├── components │ │ │ │ └── AppGenerator.jsx │ │ │ ├── main.js │ │ │ └── start.jsx │ │ ├── modules │ │ │ ├── callbacks.js │ │ │ ├── components.js │ │ │ ├── components │ │ │ │ ├── AccessControl.jsx │ │ │ │ ├── App.jsx │ │ │ │ ├── Avatar.jsx │ │ │ │ ├── Card │ │ │ │ │ ├── Card.jsx │ │ │ │ │ ├── CardItemArray.jsx │ │ │ │ │ ├── CardItemDate.jsx │ │ │ │ │ ├── CardItemDefault.jsx │ │ │ │ │ ├── CardItemHTML.jsx │ │ │ │ │ ├── CardItemImage.jsx │ │ │ │ │ ├── CardItemNumber.jsx │ │ │ │ │ ├── CardItemObject.jsx │ │ │ │ │ ├── CardItemRelationHasMany.jsx │ │ │ │ │ ├── CardItemRelationHasOne.jsx │ │ │ │ │ ├── CardItemRelationItem.jsx │ │ │ │ │ ├── CardItemString.jsx │ │ │ │ │ ├── CardItemSwitcher.jsx │ │ │ │ │ ├── CardItemURL.jsx │ │ │ │ │ └── index.js │ │ │ │ ├── Datatable │ │ │ │ │ ├── Datatable.jsx │ │ │ │ │ ├── DatatableCell.jsx │ │ │ │ │ ├── DatatableContents.jsx │ │ │ │ │ ├── DatatableFilter.jsx │ │ │ │ │ ├── DatatableHeader.jsx │ │ │ │ │ ├── DatatableRow.jsx │ │ │ │ │ ├── DatatableSelect.jsx │ │ │ │ │ ├── DatatableSorter.jsx │ │ │ │ │ ├── DatatableSubmitSelected.jsx │ │ │ │ │ └── index.js │ │ │ │ ├── DeleteButton.jsx │ │ │ │ ├── Dummy.jsx │ │ │ │ ├── DynamicLoading.jsx │ │ │ │ ├── EditButton.jsx │ │ │ │ ├── Error404.jsx │ │ │ │ ├── Flash.jsx │ │ │ │ ├── FlashMessages.jsx │ │ │ │ ├── HeadTags.jsx │ │ │ │ ├── HelloWorld.jsx │ │ │ │ ├── Icon.jsx │ │ │ │ ├── Layout.jsx │ │ │ │ ├── Loading.jsx │ │ │ │ ├── LoadingButton.jsx │ │ │ │ ├── MutationButton.jsx │ │ │ │ ├── NewButton.jsx │ │ │ │ ├── PaginatedList │ │ │ │ │ ├── PaginatedList.jsx │ │ │ │ │ └── index.js │ │ │ │ ├── RouterHook.jsx │ │ │ │ ├── ScrollToTop.jsx │ │ │ │ ├── ShowIf.jsx │ │ │ │ ├── VerticalMenuLayout │ │ │ │ │ ├── MenuLayout.jsx │ │ │ │ │ └── VerticalMenuLayout.jsx │ │ │ │ └── Welcome.jsx │ │ │ ├── containers │ │ │ │ ├── cacheUpdate.js │ │ │ │ ├── create.js │ │ │ │ ├── create2.js │ │ │ │ ├── currentUser.js │ │ │ │ ├── delete.js │ │ │ │ ├── delete2.js │ │ │ │ ├── index.js │ │ │ │ ├── localeData.js │ │ │ │ ├── multi.js │ │ │ │ ├── multi2.js │ │ │ │ ├── registeredMutation.js │ │ │ │ ├── single.js │ │ │ │ ├── single2.js │ │ │ │ ├── siteData.js │ │ │ │ ├── update.js │ │ │ │ ├── update2.js │ │ │ │ ├── upsert.js │ │ │ │ ├── upsert2.js │ │ │ │ ├── variables.js │ │ │ │ ├── withAccess.js │ │ │ │ ├── withComponents.js │ │ │ │ ├── withMessages-state-link.js │ │ │ │ └── withMessages.js │ │ │ ├── decorators │ │ │ │ ├── autocomplete.js │ │ │ │ ├── checkboxgroup.js │ │ │ │ ├── index.js │ │ │ │ ├── likert.js │ │ │ │ └── radiogroup.js │ │ │ ├── index.js │ │ │ └── menu.js │ │ └── server │ │ │ ├── main.js │ │ │ └── start.js │ ├── package.js │ └── test │ │ ├── client │ │ ├── index.js │ │ └── mutations2.test.js │ │ ├── components.test.js │ │ ├── containers │ │ ├── mutations.test.js │ │ └── queries.test.js │ │ ├── containers2 │ │ ├── mutations.test.js │ │ └── queries.test.js │ │ ├── index.js │ │ ├── menu.test.js │ │ ├── server │ │ └── index.js │ │ └── withComponents.test.js ├── vulcan-debug │ ├── README.md │ ├── lib │ │ ├── client │ │ │ └── main.js │ │ ├── components │ │ │ ├── Callbacks.jsx │ │ │ ├── Components.jsx │ │ │ ├── Dashboard.jsx │ │ │ ├── Database.jsx │ │ │ ├── DebugLayout.jsx │ │ │ ├── Emails.jsx │ │ │ ├── ErrorCatcherContents.jsx │ │ │ ├── Groups.jsx │ │ │ ├── I18n.jsx │ │ │ ├── Routes.jsx │ │ │ └── Settings.jsx │ │ ├── modules │ │ │ ├── callbacks │ │ │ │ ├── collection.js │ │ │ │ ├── fragments.js │ │ │ │ └── schema.js │ │ │ ├── components.js │ │ │ ├── emails │ │ │ │ ├── collection.js │ │ │ │ └── schema.js │ │ │ ├── index.js │ │ │ ├── permissions.js │ │ │ ├── routes.js │ │ │ └── settings │ │ │ │ ├── collection.js │ │ │ │ └── schema.js │ │ ├── server │ │ │ ├── callbacks │ │ │ │ ├── collection.js │ │ │ │ ├── index.js │ │ │ │ └── resolvers.js │ │ │ ├── database │ │ │ │ ├── index.js │ │ │ │ └── queries.js │ │ │ ├── emails │ │ │ │ ├── collection.js │ │ │ │ ├── index.js │ │ │ │ └── resolvers.js │ │ │ ├── main.js │ │ │ └── settings │ │ │ │ ├── collection.js │ │ │ │ ├── index.js │ │ │ │ └── resolvers.js │ │ └── stylesheets │ │ │ └── debug.scss │ └── package.js ├── vulcan-email │ ├── .gitignore │ ├── README.md │ ├── lib │ │ ├── client │ │ │ └── main.js │ │ ├── modules │ │ │ ├── fragments.js │ │ │ ├── index.js │ │ │ └── namespace.js │ │ └── server │ │ │ ├── email.js │ │ │ ├── main.js │ │ │ ├── mutations.js │ │ │ ├── routes.js │ │ │ └── templates │ │ │ ├── index.js │ │ │ └── template_error.handlebars │ └── package.js ├── vulcan-embed │ ├── .gitignore │ ├── README.md │ ├── lib │ │ ├── client │ │ │ └── main.js │ │ ├── components │ │ │ └── EmbedURL.jsx │ │ ├── modules │ │ │ ├── embed.js │ │ │ ├── i18n.js │ │ │ └── index.js │ │ ├── server │ │ │ ├── integrations │ │ │ │ ├── builtin.js │ │ │ │ ├── embedapi.js │ │ │ │ └── embedly.js │ │ │ ├── main.js │ │ │ ├── methods.js │ │ │ └── mutations.js │ │ └── stylesheets │ │ │ └── embedly.scss │ └── package.js ├── vulcan-errors-sentry │ ├── README.md │ ├── lib │ │ ├── client │ │ │ ├── main.js │ │ │ └── sentry-client.js │ │ ├── modules │ │ │ ├── index.js │ │ │ ├── sentry.js │ │ │ └── settings.js │ │ └── server │ │ │ ├── main.js │ │ │ └── sentry-server.js │ └── package.js ├── vulcan-errors │ ├── README.md │ ├── lib │ │ ├── client │ │ │ ├── init.js │ │ │ └── main.js │ │ ├── components │ │ │ ├── ErrorCatcher.jsx │ │ │ └── ErrorsUserMonitor.jsx │ │ ├── modules │ │ │ ├── errors.js │ │ │ ├── extended-NOTUSED.js │ │ │ ├── index.js │ │ │ └── rethrown-NOTUSED.js │ │ └── server │ │ │ ├── init.js │ │ │ └── main.js │ └── package.js ├── vulcan-events-ga │ ├── README.md │ ├── lib │ │ ├── client │ │ │ ├── ga.js │ │ │ └── main.js │ │ ├── modules │ │ │ └── index.js │ │ └── server │ │ │ └── main.js │ └── package.js ├── vulcan-events-intercom │ ├── README.md │ ├── lib │ │ ├── client │ │ │ ├── intercom-client.js │ │ │ └── main.js │ │ ├── modules │ │ │ └── index.js │ │ └── server │ │ │ ├── intercom-server.js │ │ │ └── main.js │ └── package.js ├── vulcan-events-internal │ ├── README.md │ ├── lib │ │ ├── client │ │ │ ├── internal-client.js │ │ │ └── main.js │ │ ├── modules │ │ │ ├── collection.js │ │ │ ├── fragments.js │ │ │ ├── index.js │ │ │ └── schema.js │ │ └── server │ │ │ ├── internal-server.js │ │ │ └── main.js │ └── package.js ├── vulcan-events-segment │ ├── README.md │ ├── lib │ │ ├── client │ │ │ ├── main.js │ │ │ └── segment-client.js │ │ ├── modules │ │ │ └── index.js │ │ └── server │ │ │ ├── main.js │ │ │ └── segment-server.js │ └── package.js ├── vulcan-events │ ├── README.md │ ├── lib │ │ ├── client │ │ │ └── main.js │ │ ├── modules │ │ │ ├── events.js │ │ │ └── index.js │ │ └── server │ │ │ └── main.js │ └── package.js ├── vulcan-forms-tags │ ├── README.md │ ├── lib │ │ ├── components │ │ │ └── Tags.jsx │ │ └── export.js │ └── package.js ├── vulcan-forms-upload │ ├── README.md │ ├── lib │ │ ├── Upload.jsx │ │ ├── Upload.scss │ │ ├── i18n.js │ │ └── modules.js │ └── package.js ├── vulcan-forms │ ├── README.md │ ├── lib │ │ ├── client │ │ │ └── main.js │ │ ├── components │ │ │ ├── FieldErrors.jsx │ │ │ ├── Form.jsx │ │ │ ├── FormClear.jsx │ │ │ ├── FormComponent.jsx │ │ │ ├── FormComponentLoader.jsx │ │ │ ├── FormElement.jsx │ │ │ ├── FormError.jsx │ │ │ ├── FormErrors.jsx │ │ │ ├── FormGroup.jsx │ │ │ ├── FormIntl.jsx │ │ │ ├── FormLayout.jsx │ │ │ ├── FormNestedArray.jsx │ │ │ ├── FormNestedArrayLayout.jsx │ │ │ ├── FormNestedDivider.jsx │ │ │ ├── FormNestedItem.jsx │ │ │ ├── FormNestedObject.jsx │ │ │ ├── FormOptionLabel.jsx │ │ │ ├── FormSubmit.jsx │ │ │ ├── FormWrapper.jsx │ │ │ ├── propTypes.js │ │ │ └── withCollectionProps.js │ │ ├── modules │ │ │ ├── components.js │ │ │ ├── formFragments.js │ │ │ ├── index.js │ │ │ ├── path_utils.js │ │ │ ├── schema_utils.js │ │ │ └── utils.js │ │ └── server │ │ │ └── main.js │ ├── package.js │ └── test │ │ ├── Form.test.js │ │ ├── FormComponent.test.js │ │ ├── FormNestedArray.test.js │ │ ├── FormNestedObject.test.js │ │ ├── formFragments.test.js │ │ ├── index.js │ │ ├── package.test.js │ │ └── schema_utils.test.js ├── vulcan-i18n-en-us │ ├── README.md │ ├── lib │ │ └── en_US.js │ └── package.js ├── vulcan-i18n-es-es │ ├── README.md │ ├── lib │ │ └── es_ES.js │ └── package.js ├── vulcan-i18n-fa-ir │ ├── README.md │ ├── lib │ │ └── fa_IR.js │ └── package.js ├── vulcan-i18n-fr-fr │ ├── README.md │ ├── lib │ │ └── fr_FR.js │ └── package.js ├── vulcan-i18n │ ├── README.md │ ├── lib │ │ ├── client │ │ │ └── main.js │ │ ├── modules │ │ │ ├── context.js │ │ │ ├── index.js │ │ │ ├── message.js │ │ │ ├── provider.js │ │ │ ├── shape.js │ │ │ └── useIntl.js │ │ └── server │ │ │ ├── graphql.js │ │ │ └── main.js │ ├── package.js │ └── test │ │ ├── index.js │ │ └── provider.test.js ├── vulcan-lib │ ├── README.md │ ├── lib │ │ ├── client │ │ │ ├── apollo-client │ │ │ │ ├── apolloClient.js │ │ │ │ ├── cache.js │ │ │ │ ├── index.js │ │ │ │ └── links │ │ │ │ │ ├── error.js │ │ │ │ │ ├── http.js │ │ │ │ │ ├── meteor.js │ │ │ │ │ └── registerLinks.js │ │ │ ├── auth.js │ │ │ ├── connectors.js │ │ │ ├── errors.js │ │ │ ├── inject_data.js │ │ │ ├── main.js │ │ │ └── mock.js │ │ ├── modules │ │ │ ├── admin.js │ │ │ ├── apollo-common │ │ │ │ ├── index.js │ │ │ │ ├── links │ │ │ │ │ └── state.js │ │ │ │ └── settings.js │ │ │ ├── callbacks.js │ │ │ ├── collections.js │ │ │ ├── components.js │ │ │ ├── compose.js │ │ │ ├── config.js │ │ │ ├── debug.js │ │ │ ├── deep.js │ │ │ ├── deep_extend.js │ │ │ ├── dynamic_loader.js │ │ │ ├── errors.js │ │ │ ├── findbyids.js │ │ │ ├── fragment_matcher.js │ │ │ ├── fragments.js │ │ │ ├── graphql │ │ │ │ ├── defaultFragment.js │ │ │ │ ├── index.js │ │ │ │ └── utils.js │ │ │ ├── graphql_templates │ │ │ │ ├── filtering.js │ │ │ │ ├── index.js │ │ │ │ ├── mutations.js │ │ │ │ ├── other.js │ │ │ │ ├── queries.js │ │ │ │ └── types.js │ │ │ ├── handleOptions.js │ │ │ ├── headtags.js │ │ │ ├── icons.js │ │ │ ├── index.js │ │ │ ├── intl.js │ │ │ ├── intl_polyfill.js │ │ │ ├── mongoParams.js │ │ │ ├── mongo_redux.js │ │ │ ├── random_id.js │ │ │ ├── reactive-state.js │ │ │ ├── routes.js │ │ │ ├── routes.ts │ │ │ ├── schema_utils.js │ │ │ ├── settings.js │ │ │ ├── simpleSchema_utils.js │ │ │ ├── startup.js │ │ │ ├── ui_utils.js │ │ │ ├── utils.js │ │ │ └── validation.js │ │ └── server │ │ │ ├── accounts_helpers.js │ │ │ ├── apollo-server │ │ │ ├── apollo_server.js │ │ │ ├── context.js │ │ │ ├── engine.js │ │ │ ├── graphiql.js │ │ │ ├── index.js │ │ │ ├── initGraphQL.js │ │ │ ├── playground.js │ │ │ ├── settings.js │ │ │ ├── startup.js │ │ │ └── voyager.js │ │ │ ├── apollo-ssr │ │ │ ├── apolloClient.js │ │ │ ├── components │ │ │ │ ├── ApolloState.jsx │ │ │ │ ├── AppGenerator.jsx │ │ │ │ └── Head.jsx │ │ │ ├── enableSSR.js │ │ │ ├── index.js │ │ │ ├── injectDefaultData.js │ │ │ ├── inject_data.js │ │ │ └── renderPage.js │ │ │ ├── caching.js │ │ │ ├── connectors.js │ │ │ ├── connectors │ │ │ └── mongo.js │ │ │ ├── debug.js │ │ │ ├── default_mutations.js │ │ │ ├── default_mutations2.js │ │ │ ├── default_resolvers.js │ │ │ ├── default_resolvers2.js │ │ │ ├── errors.js │ │ │ ├── graphql │ │ │ ├── collection.js │ │ │ ├── graphql.js │ │ │ ├── index.js │ │ │ ├── relations.js │ │ │ ├── resolvers.js │ │ │ ├── schemaFields.js │ │ │ └── typedefs.js │ │ │ ├── intl.js │ │ │ ├── intl_polyfill.js │ │ │ ├── main.js │ │ │ ├── meteor_patch.js │ │ │ ├── mutators.js │ │ │ ├── query.js │ │ │ ├── site.js │ │ │ ├── source_version.js │ │ │ └── utils.js │ ├── package.js │ └── test │ │ ├── client │ │ ├── apolloClient.test.js │ │ └── index.js │ │ ├── components.test.js │ │ ├── documentValidation.test.js │ │ ├── handleOptions.test.js │ │ ├── index.js │ │ ├── intl.test.js │ │ ├── mongoParams.test.js │ │ ├── reactive-state.test.js │ │ ├── routes.test.js │ │ ├── schema_utils.test.js │ │ ├── server │ │ ├── apollo-server.test.js │ │ ├── apollo-ssr.test.js │ │ ├── fixtures │ │ │ └── minimalSchema.js │ │ ├── fragments.test.js │ │ ├── graphql.test.js │ │ ├── index.js │ │ ├── mutations.test.js │ │ ├── mutators.test.js │ │ └── resolvers.test.js │ │ └── utils.test.js ├── vulcan-newsletter │ ├── .gitignore │ ├── README.md │ ├── lib │ │ ├── client │ │ │ └── main.js │ │ ├── components │ │ │ └── NewsletterSubscribe.jsx │ │ ├── modules │ │ │ ├── collection.js │ │ │ ├── custom_fields.js │ │ │ ├── fragments.js │ │ │ ├── i18n.js │ │ │ ├── index.js │ │ │ └── schema.js │ │ └── server │ │ │ ├── callbacks.js │ │ │ ├── cron.js │ │ │ ├── integrations │ │ │ ├── emailoctopus.js │ │ │ ├── index.js │ │ │ ├── mailchimp.js │ │ │ ├── sample.js │ │ │ └── sendy.js │ │ │ ├── main.js │ │ │ ├── mutations.js │ │ │ └── newsletters.js │ ├── package.js │ └── scss.json ├── vulcan-payments │ ├── README.md │ ├── lib │ │ ├── client │ │ │ └── main.js │ │ ├── components │ │ │ ├── ChargesDashboard.jsx │ │ │ └── Checkout.jsx │ │ ├── containers │ │ │ └── withPaymentAction.js │ │ ├── modules │ │ │ ├── charges │ │ │ │ ├── collection.js │ │ │ │ └── schema.js │ │ │ ├── components.js │ │ │ ├── custom_fields.js │ │ │ ├── fragments.js │ │ │ ├── i18n.js │ │ │ ├── index.js │ │ │ ├── products.js │ │ │ └── routes.js │ │ ├── server │ │ │ ├── integrations │ │ │ │ └── stripe.js │ │ │ ├── main.js │ │ │ └── mutations.js │ │ └── stylesheets │ │ │ └── style.scss │ └── package.js ├── vulcan-redux │ ├── README.md │ ├── lib │ │ ├── client │ │ │ ├── main.js │ │ │ ├── reduxInitialState.js │ │ │ └── setupRedux.js │ │ ├── modules │ │ │ ├── index.js │ │ │ └── redux.js │ │ └── server │ │ │ ├── main.js │ │ │ ├── reduxInitialState.js │ │ │ └── setupRedux.js │ ├── package.js │ └── test │ │ ├── client │ │ ├── index.js │ │ └── initialState.test.js │ │ └── server │ │ ├── index.js │ │ ├── initialState.test.js │ │ └── initialStateWithValue.test.js ├── vulcan-scss │ ├── .github │ │ └── workflows │ │ │ └── comment-issue.yml │ ├── .gitignore │ ├── .travis.yml │ ├── .versions │ ├── ISSUE_TEMPLATE.md │ ├── LICENSE.txt │ ├── README.md │ ├── package.js │ ├── plugin │ │ └── compile-scss.js │ ├── scss-config.json │ ├── test │ │ ├── include-paths │ │ │ ├── include-paths.scss │ │ │ └── modules │ │ │ │ └── module │ │ │ │ └── _module.scss │ │ └── scss │ │ │ ├── _emptyimport.scss │ │ │ ├── _not-included.scss │ │ │ ├── _top.scss │ │ │ ├── _top3.scss │ │ │ ├── dir │ │ │ ├── _in-dir.scss │ │ │ ├── _in-dir2.scss │ │ │ ├── root.scss │ │ │ └── subdir │ │ │ │ └── _in-subdir.scss │ │ │ ├── empty.scss │ │ │ └── top2.scss │ └── tests.js ├── vulcan-styled-components │ ├── README.md │ ├── lib │ │ ├── client │ │ │ └── main.js │ │ ├── modules │ │ │ └── index.js │ │ └── server │ │ │ ├── main.js │ │ │ └── setupStyledComponents.js │ └── package.js ├── vulcan-subscribe │ ├── README.md │ ├── lib │ │ ├── callbacks.js │ │ ├── components │ │ │ └── SubscribeTo.jsx │ │ ├── custom_fields.js │ │ ├── fragments.js │ │ ├── helpers.js │ │ ├── modules.js │ │ ├── mutations.js │ │ ├── permissions.js │ │ └── views.js │ └── package.js ├── vulcan-test │ ├── README.md │ ├── lib │ │ ├── client │ │ │ ├── initComponentTest.js │ │ │ └── main.js │ │ ├── modules │ │ │ ├── createDummyCollection.js │ │ │ ├── graphqlSchema.js │ │ │ ├── index.js │ │ │ └── initComponentTest.js │ │ └── server │ │ │ ├── initComponentTest.js │ │ │ ├── initGraphQLTest.js │ │ │ ├── initServerTest.js │ │ │ ├── isoCreateCollection.js │ │ │ └── main.js │ └── package.js ├── vulcan-ui-bootstrap │ ├── README.md │ ├── lib │ │ ├── client │ │ │ └── main.js │ │ ├── components │ │ │ ├── backoffice │ │ │ │ ├── BackofficeNavbar.jsx │ │ │ │ ├── BackofficePageLayout.jsx │ │ │ │ └── BackofficeVerticalMenuLayout.jsx │ │ │ ├── forms │ │ │ │ ├── Autocomplete.jsx │ │ │ │ ├── AutocompleteMultiple.jsx │ │ │ │ ├── Checkbox.jsx │ │ │ │ ├── Checkboxgroup.jsx │ │ │ │ ├── Date.jsx │ │ │ │ ├── Date2.jsx │ │ │ │ ├── Datetime.jsx │ │ │ │ ├── Default.jsx │ │ │ │ ├── Email.jsx │ │ │ │ ├── FormComponentInner.jsx │ │ │ │ ├── FormControl.jsx │ │ │ │ ├── FormDescription.jsx │ │ │ │ ├── FormElement.jsx │ │ │ │ ├── FormGroupDefault.jsx │ │ │ │ ├── FormInputLoading.jsx │ │ │ │ ├── FormItem.jsx │ │ │ │ ├── FormLabel.jsx │ │ │ │ ├── Likert.jsx │ │ │ │ ├── Number.jsx │ │ │ │ ├── Password.jsx │ │ │ │ ├── Radiogroup.jsx │ │ │ │ ├── Select.jsx │ │ │ │ ├── SelectMultiple.jsx │ │ │ │ ├── StaticText.jsx │ │ │ │ ├── Textarea.jsx │ │ │ │ ├── Time.jsx │ │ │ │ └── Url.jsx │ │ │ └── ui │ │ │ │ ├── Alert.jsx │ │ │ │ ├── Button.jsx │ │ │ │ ├── Dropdown.jsx │ │ │ │ ├── Modal.jsx │ │ │ │ ├── ModalTrigger.jsx │ │ │ │ ├── Table.jsx │ │ │ │ ├── TooltipTrigger.jsx │ │ │ │ └── VerticalNavigation.jsx │ │ ├── modules │ │ │ ├── components.js │ │ │ └── index.js │ │ ├── server │ │ │ └── main.js │ │ └── stylesheets │ │ │ ├── bootstrap.min.css │ │ │ ├── datetime.scss │ │ │ ├── likert.scss │ │ │ ├── style.scss │ │ │ ├── typeahead-bs4.scss │ │ │ └── typeahead.scss │ └── package.js ├── vulcan-ui-material │ ├── accounts.css │ ├── en_US.js │ ├── forms.css │ ├── fr_FR.js │ ├── history.md │ ├── lib │ │ ├── client │ │ │ ├── main.js │ │ │ └── wrapWithMuiTheme.jsx │ │ ├── components │ │ │ ├── accounts │ │ │ │ ├── AccountsButton.jsx │ │ │ │ ├── AccountsButtons.jsx │ │ │ │ ├── AccountsField.jsx │ │ │ │ ├── AccountsFields.jsx │ │ │ │ ├── AccountsForm.jsx │ │ │ │ ├── AccountsPasswordOrService.jsx │ │ │ │ └── AccountsSocialButtons.jsx │ │ │ ├── backoffice │ │ │ │ ├── BackofficeNavbar.jsx │ │ │ │ ├── BackofficePageLayout.jsx │ │ │ │ └── BackofficeVerticalMenuLayout.jsx │ │ │ ├── bonus │ │ │ │ ├── DatatableFromArray.jsx │ │ │ │ ├── KeyEventHandler.jsx │ │ │ │ ├── LoadMore.jsx │ │ │ │ ├── ScrollTrigger.jsx │ │ │ │ ├── SearchInput.jsx │ │ │ │ ├── TooltipButton.jsx │ │ │ │ ├── TooltipIconButton.jsx │ │ │ │ └── TooltipIntl.jsx │ │ │ ├── core │ │ │ │ ├── Avatar.jsx │ │ │ │ ├── Card.jsx │ │ │ │ ├── Datatable.jsx │ │ │ │ ├── EditButton.jsx │ │ │ │ ├── Flash.jsx │ │ │ │ ├── Loading.jsx │ │ │ │ └── NewButton.jsx │ │ │ ├── forms │ │ │ │ ├── FormComponentInner.jsx │ │ │ │ ├── FormErrors.jsx │ │ │ │ ├── FormGroupDefault.jsx │ │ │ │ ├── FormGroupLine.jsx │ │ │ │ ├── FormGroupNone.jsx │ │ │ │ ├── FormNestedArrayLayout.jsx │ │ │ │ ├── FormNestedDivider.jsx │ │ │ │ ├── FormSubmit.jsx │ │ │ │ ├── base-controls │ │ │ │ │ ├── EndAdornment.jsx │ │ │ │ │ ├── FormCheckbox.jsx │ │ │ │ │ ├── FormCheckboxGroup.jsx │ │ │ │ │ ├── FormControlLayout.jsx │ │ │ │ │ ├── FormHelper.jsx │ │ │ │ │ ├── FormInput.jsx │ │ │ │ │ ├── FormPicker.jsx │ │ │ │ │ ├── FormRadioGroup.jsx │ │ │ │ │ ├── FormSelect.jsx │ │ │ │ │ ├── FormSuggest.jsx │ │ │ │ │ ├── FormSwitch.jsx │ │ │ │ │ ├── FormText.jsx │ │ │ │ │ ├── RequiredIndicator.jsx │ │ │ │ │ ├── StartAdornment.jsx │ │ │ │ │ └── mixins │ │ │ │ │ │ └── component.jsx │ │ │ │ └── controls │ │ │ │ │ ├── Checkbox.jsx │ │ │ │ │ ├── CheckboxGroup.jsx │ │ │ │ │ ├── CountrySelect.jsx │ │ │ │ │ ├── Date.jsx │ │ │ │ │ ├── DateRdt.jsx │ │ │ │ │ ├── DateTime.jsx │ │ │ │ │ ├── DateTimeRdt.jsx │ │ │ │ │ ├── Default.jsx │ │ │ │ │ ├── Email.jsx │ │ │ │ │ ├── Number.jsx │ │ │ │ │ ├── Password.jsx │ │ │ │ │ ├── PostalCode.jsx │ │ │ │ │ ├── RadioGroup.jsx │ │ │ │ │ ├── RegionSelect.jsx │ │ │ │ │ ├── Select.jsx │ │ │ │ │ ├── SelectMultiple.jsx │ │ │ │ │ ├── StaticText.jsx │ │ │ │ │ ├── Textarea.jsx │ │ │ │ │ ├── Time.jsx │ │ │ │ │ ├── TimeRdt.jsx │ │ │ │ │ ├── Url.jsx │ │ │ │ │ └── countries.js │ │ │ ├── index.js │ │ │ ├── theme │ │ │ │ ├── JssCleanup.jsx │ │ │ │ ├── ThemeProvider.jsx │ │ │ │ └── ThemeStyles.jsx │ │ │ ├── ui │ │ │ │ ├── Alert.jsx │ │ │ │ ├── Button.jsx │ │ │ │ ├── Modal.jsx │ │ │ │ ├── ModalTrigger.jsx │ │ │ │ ├── Table.jsx │ │ │ │ └── VerticalNavigation.jsx │ │ │ └── upload │ │ │ │ ├── UploadImage.jsx │ │ │ │ └── UploadInner.jsx │ │ ├── example │ │ │ ├── Header.jsx │ │ │ ├── Layout.jsx │ │ │ └── SideNavigation.jsx │ │ ├── modules │ │ │ ├── components.js │ │ │ ├── index.js │ │ │ ├── routes.js │ │ │ ├── sampleTheme.js │ │ │ └── themes.js │ │ └── server │ │ │ ├── main.js │ │ │ └── wrapWithMuiTheme.jsx │ ├── package.js │ └── readme.md ├── vulcan-users │ ├── README.md │ ├── TESTS.md │ ├── lib │ │ ├── client │ │ │ └── main.js │ │ ├── modules │ │ │ ├── avatar.js │ │ │ ├── collection.js │ │ │ ├── fragments.js │ │ │ ├── helpers.js │ │ │ ├── index.js │ │ │ ├── mutations.js │ │ │ ├── permissions.js │ │ │ ├── schema.js │ │ │ └── views.js │ │ └── server │ │ │ ├── AuthPassword.js │ │ │ ├── callbacks.js │ │ │ ├── create_user.js │ │ │ ├── graphql_context.js │ │ │ ├── main.js │ │ │ ├── mutations.js │ │ │ ├── on_create_user.js │ │ │ ├── queries.js │ │ │ └── urls.js │ ├── package.js │ └── test │ │ ├── index.js │ │ ├── permissions.test.js │ │ └── server │ │ ├── callback.test.js │ │ ├── index.js │ │ └── mutation.test.js └── vulcan-voting │ ├── README.md │ ├── lib │ ├── client │ │ ├── fragment_matcher.js │ │ └── main.js │ ├── containers │ │ └── withVote.js │ ├── modules │ │ ├── custom_fields.js │ │ ├── fragments.js │ │ ├── helpers.js │ │ ├── index.js │ │ ├── make_voteable.js │ │ ├── scoring.js │ │ ├── vote.js │ │ └── votes │ │ │ ├── collection.js │ │ │ └── schema.js │ └── server │ │ ├── callbacks.js │ │ ├── cron.js │ │ ├── graphql.js │ │ ├── indexes.js │ │ ├── main.js │ │ └── scoring.js │ └── package.js ├── sample_settings.json ├── stories ├── MUI │ ├── forms │ │ └── formBaseControls.stories.js │ └── ui-material.stories.js ├── card.stories.js ├── dataSample │ ├── dummyCollection.js │ └── schema.js ├── datatable.stories.js ├── form │ ├── form.stories.js │ ├── formControls.stories.js │ └── upload.stories.js ├── helpers.js ├── modal.stories.js ├── ref.stories.js └── vulcan.stories.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | ], 4 | "presets": [ 5 | [ 6 | "@babel/preset-env", 7 | { 8 | "shippedProposals": true, 9 | "corejs":2, 10 | "useBuiltIns": "usage" 11 | } 12 | ], 13 | "@babel/preset-react" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*.{js,html}] 6 | 7 | charset = utf-8 8 | end_of_line = lf 9 | indent_brace_style = 1TBS 10 | indent_size = 2 11 | indent_style = space 12 | insert_final_newline = true 13 | max_line_length = 120 14 | quote_type = auto 15 | spaces_around_operators = true 16 | trim_trailing_whitespace = true 17 | 18 | [*.md] 19 | 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | packages/_* 2 | **/*.test.js 3 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Before starting on a new feature, please [check out the roadmap](https://trello.com/b/dwPR0LTz/vulcanjs-roadmap) and come check-in in the [Vulcan Slack channel](http://slack.telescopeapp.org/). 2 | 3 | Also, all PRs should be made to the `devel` branch, not `master`. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots (if applicable)** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Device (if applicable):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: stale 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false -------------------------------------------------------------------------------- /.meteor/.finished-upgraders: -------------------------------------------------------------------------------- 1 | # This file contains information which helps Meteor properly upgrade your 2 | # app when you run 'meteor update'. You should check it into version control 3 | # with your project. 4 | 5 | notices-for-0.9.0 6 | notices-for-0.9.1 7 | 0.9.4-platform-file 8 | notices-for-facebook-graph-api-2 9 | 1.2.0-standard-minifiers-package 10 | 1.2.0-meteor-platform-split 11 | 1.2.0-cordova-changes 12 | 1.2.0-breaking-changes 13 | 1.3.0-split-minifiers-package 14 | 1.3.5-remove-old-dev-bundle-link 15 | 1.4.0-remove-old-dev-bundle-link 16 | 1.4.1-add-shell-server-package 17 | 1.4.3-split-account-service-packages 18 | 1.5-add-dynamic-import-package 19 | 1.7-split-underscore-from-meteor-base 20 | 1.8.3-split-jquery-from-blaze 21 | -------------------------------------------------------------------------------- /.meteor/.gitignore: -------------------------------------------------------------------------------- 1 | dev_bundle 2 | local 3 | meteorite 4 | -------------------------------------------------------------------------------- /.meteor/.id: -------------------------------------------------------------------------------- 1 | # This file contains a token that is unique to your project. 2 | # Check it into your repository along with the rest of this directory. 3 | # It can be used for purposes such as: 4 | # - ensuring you don't accidentally deploy one app on top of another 5 | # - providing package authors with aggregated statistics 6 | 7 | 1txv9r51kxht481ysl8bb 8 | -------------------------------------------------------------------------------- /.meteor/cordova-plugins: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VulcanJS/Vulcan/b3e50d061f22e758cb1a7e3502883ebc1d70f68e/.meteor/cordova-plugins -------------------------------------------------------------------------------- /.meteor/packages: -------------------------------------------------------------------------------- 1 | # see http://docs.vulcanjs.org/packages 2 | 3 | vulcan:core 4 | 5 | ############ Language Packages ############ 6 | 7 | vulcan:i18n-en-us 8 | # vulcan:i18n-es-es 9 | 10 | ############ Accounts Packages ############ 11 | 12 | accounts-base@2.0.0 13 | accounts-password@2.0.0 14 | # accounts-twitter 15 | # accounts-facebook 16 | 17 | vulcan:debug 18 | # To run the backoffice 19 | vulcan:backoffice 20 | vulcan:accounts 21 | # Ui 22 | vulcan:ui-bootstrap 23 | # vulcan:ui-material 24 | 25 | meteortesting:mocha 26 | apollo 27 | service-configuration@1.1.0 28 | -------------------------------------------------------------------------------- /.meteor/platforms: -------------------------------------------------------------------------------- 1 | server 2 | browser 3 | -------------------------------------------------------------------------------- /.meteor/release: -------------------------------------------------------------------------------- 1 | METEOR@2.3.4 2 | -------------------------------------------------------------------------------- /.meteorignore: -------------------------------------------------------------------------------- 1 | stories 2 | storybook-static 3 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v12.21.0 2 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const {esNextPaths} = require('./.vulcan/shared/pathsByLanguageVersion'); 4 | 5 | module.exports = { 6 | bracketSpacing: true, 7 | singleQuote: true, 8 | jsxBracketSameLine: true, 9 | trailingComma: 'es5', 10 | printWidth: 140, 11 | parser: 'babylon', 12 | 13 | overrides: [ 14 | { 15 | files: esNextPaths, 16 | options: { 17 | trailingComma: 'all', 18 | }, 19 | }, 20 | ], 21 | }; 22 | -------------------------------------------------------------------------------- /.storybook/addons.js: -------------------------------------------------------------------------------- 1 | // Init storybook addons here 2 | import '@storybook/addon-knobs/register'; 3 | import '@storybook/addon-actions/register'; 4 | import '@storybook/addon-links/register'; 5 | import 'storybook-addon-intl/register'; 6 | -------------------------------------------------------------------------------- /.storybook/decorators/BootstrapDecorator.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Use this decorator to setup Bootstrap 3 | */ 4 | import React from 'react' 5 | 6 | import 'meteor/vulcan:ui-bootstrap/lib/stylesheets/bootstrap.min.css'; 7 | import 'meteor/vulcan:ui-bootstrap/lib/stylesheets/style.scss'; 8 | import 'meteor/vulcan:ui-bootstrap/lib/stylesheets/datetime.scss'; 9 | 10 | // load UI components 11 | import 'meteor/vulcan:ui-bootstrap/lib/modules/components.js'; 12 | 13 | export default storyFn => (
{storyFn()}
) -------------------------------------------------------------------------------- /.storybook/decorators/MaterialUIDecorator.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Use this decorator to load Material UI 4 | 5 | */ 6 | import { Components } from 'meteor/vulcan:lib'; 7 | // load UI components 8 | import React from 'react' 9 | import 'meteor/vulcan:ui-material/lib/modules/components.js'; 10 | import { wrapWithMuiTheme } from 'meteor/vulcan:ui-material'; 11 | 12 | 13 | export default storyFn => ( 14 | 15 |
{storyFn()}
16 |
17 | ) 18 | -------------------------------------------------------------------------------- /.storybook/mocks/Meteor.js: -------------------------------------------------------------------------------- 1 | // FIXME: we can't use ES6 imports in mocks, not sure why 2 | module.exports = { 3 | settings: {}, 4 | startup: () => { }, 5 | _localStorage: window ? window.localStorage : { setItem: () => {}, getItem: () => {} }, 6 | isClient: () => true, 7 | isServer: () => false, 8 | absoluteUrl: () => 'http://vulcanjs.org/' 9 | } -------------------------------------------------------------------------------- /.storybook/mocks/Mongo.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Collection: class Collection {} 3 | } -------------------------------------------------------------------------------- /.storybook/mocks/Vulcan.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 3 | } -------------------------------------------------------------------------------- /.storybook/mocks/meteor-apollo.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | MeteorAccountsLink: class MeteorAccountsLink {} 3 | } -------------------------------------------------------------------------------- /.storybook/mocks/meteor-server-render.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | onPageLoad: () => { } 3 | } -------------------------------------------------------------------------------- /.storybook/mocks/vulcan-email.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | addEmails: () => {} 3 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "chrome", 9 | "request": "launch", 10 | "name": "Launch Chrome against localhost", 11 | "url": "http://localhost:8080", 12 | "webRoot": "${workspaceFolder}" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /.vulcan/.gitignore: -------------------------------------------------------------------------------- 1 | bkp 2 | package.json 3 | -------------------------------------------------------------------------------- /.vulcan/shared/pathsByLanguageVersion.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 'use strict'; 8 | 9 | // Files that are transformed and can use ES6/Flow/JSX. 10 | const esNextPaths = [ 11 | // Internal forwarding modules 12 | 'packages/*/*.js', 13 | 'packages/*/*.jsx', 14 | ]; 15 | 16 | module.exports = { 17 | esNextPaths, 18 | }; -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM abernix/meteord:onbuild -------------------------------------------------------------------------------- /jsdoc-conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["plugins/markdown"], 3 | "markdown": { 4 | "parser": "gfm" 5 | }, 6 | "source": { 7 | "exclude": [ 8 | ".git", 9 | ".meteor", 10 | "node_modules" 11 | ], 12 | "includePattern": ".+\\.js(x|doc)?$" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/.gitignore: -------------------------------------------------------------------------------- 1 | /bootstrap3-datepicker 2 | /npm-container -------------------------------------------------------------------------------- /packages/_boilerplate-generator/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/_boilerplate-generator/.npm/package/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/_boilerplate-generator/.npm/package/README: -------------------------------------------------------------------------------- 1 | This directory and the files immediately inside it are automatically generated 2 | when you change this package's NPM dependencies. Commit the files in this 3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control 4 | so that others run the same versions of sub-dependencies. 5 | 6 | You should NOT check in the node_modules directory that Meteor automatically 7 | creates; if you are using git, the .gitignore file tells git to ignore it. 8 | -------------------------------------------------------------------------------- /packages/_boilerplate-generator/README.md: -------------------------------------------------------------------------------- 1 | # boilerplate-generator 2 | [Source code of released version](https://github.com/meteor/meteor/tree/master/packages/boilerplate-generator) | [Source code of development version](https://github.com/meteor/meteor/tree/devel/packages/boilerplate-generator) 3 | *** 4 | 5 | This is an internal Meteor package. -------------------------------------------------------------------------------- /packages/_boilerplate-generator/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | summary: "Generates the boilerplate html from program's manifest", 3 | version: '1.7.1', 4 | name: 'boilerplate-generator-not-used', 5 | }); 6 | 7 | Npm.depends({ 8 | 'combined-stream2': '1.1.2', 9 | }); 10 | 11 | Package.onUse(api => { 12 | api.use('ecmascript'); 13 | api.use('underscore', 'server'); 14 | api.mainModule('generator.js', 'server'); 15 | api.export('Boilerplate', 'server'); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/_boilerplate-generator/template.js: -------------------------------------------------------------------------------- 1 | import { _ } from 'meteor/underscore'; 2 | 3 | // As identified in issue #9149, when an application overrides the default 4 | // _.template settings using _.templateSettings, those new settings are 5 | // used anywhere _.template is used, including within the 6 | // boilerplate-generator. To handle this, _.template settings that have 7 | // been verified to work are overridden here on each _.template call. 8 | export default function template(text) { 9 | return _.template(text, null, { 10 | evaluate : /<%([\s\S]+?)%>/g, 11 | interpolate : /<%=([\s\S]+?)%>/g, 12 | escape : /<%-([\s\S]+?)%>/g, 13 | }); 14 | }; -------------------------------------------------------------------------------- /packages/_buffer/buffer.js: -------------------------------------------------------------------------------- 1 | global.Buffer = global.Buffer || require("buffer").Buffer; -------------------------------------------------------------------------------- /packages/_buffer/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: "buffer" 3 | }); 4 | 5 | Package.onUse( function(api) { 6 | 7 | api.use([ 8 | 'ecmascript' 9 | ]); 10 | 11 | api.addFiles([ 12 | 'buffer.js' 13 | ], ['client']); 14 | 15 | }); 16 | -------------------------------------------------------------------------------- /packages/meteor-mocha/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'meteortesting:mocha', 3 | summary: 'Run Meteor package or app tests with Mocha', 4 | git: 'https://github.com/meteortesting/meteor-mocha.git', 5 | documentation: '../README.md', 6 | version: '2.0.2', 7 | testOnly: true, 8 | }); 9 | 10 | Package.onUse(function onUse(api) { 11 | api.use([ 12 | 'meteortesting:mocha-core@8.1.2', 13 | 'ecmascript@0.3.0', 14 | 'lmieulet:meteor-coverage@4.0.0', 15 | ]); 16 | 17 | api.use(['meteortesting:browser-tests@1.3.4', 'http@2.0.0'], 'server'); 18 | api.use('browser-policy@1.1.0', 'server', { weak: true }); 19 | 20 | api.mainModule('client.js', 'client'); 21 | api.mainModule('server.js', 'server'); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/meteor-mocha/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mocha", 3 | "version": "0.0.0-semantic-release", 4 | "repository": { 5 | "type": "git", 6 | "url": "https://github.com/meteortesting/meteor-mocha" 7 | }, 8 | "author": "Dispatch Technologies, Inc. (http://www.dispatch.me/)", 9 | "license": "MIT", 10 | "release": { 11 | "verifyConditions": ["semantic-release-meteor", "@semantic-release/github"], 12 | "getLastRelease": "semantic-release-meteor", 13 | "publish": ["semantic-release-meteor", "@semantic-release/github"] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/meteor-mocha/prepForHTMLReporter.js: -------------------------------------------------------------------------------- 1 | export default function prepForHTMLReporter() { 2 | // Add the CSS from CDN 3 | const link = document.createElement('link'); 4 | link.setAttribute('rel', 'stylesheet'); 5 | link.setAttribute('href', 'https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.css'); 6 | document.head.appendChild(link); 7 | 8 | // Add the div#mocha in which test results HTML will be placed 9 | const div = document.createElement('div'); 10 | div.setAttribute('id', 'mocha'); 11 | document.body.appendChild(div); 12 | } 13 | -------------------------------------------------------------------------------- /packages/vulcan-accounts/README.md: -------------------------------------------------------------------------------- 1 | Vulcan accounts package (forked from https://github.com/studiointeract/accounts-ui) -------------------------------------------------------------------------------- /packages/vulcan-accounts/imports/api/server/servicesListPublication.js: -------------------------------------------------------------------------------- 1 | import { Meteor } from 'meteor/meteor'; 2 | import { getLoginServices } from '../../helpers.js'; 3 | 4 | Meteor.publish('servicesList', function() { 5 | let services = getLoginServices(); 6 | if (Package['accounts-password']) { 7 | services.push({name: 'password'}); 8 | } 9 | let fields = {}; 10 | // Publish the existing services for a user, only name or nothing else. 11 | services.forEach(service => fields[`services.${service.name}.name`] = 1); 12 | return Meteor.users.find({ _id: this.userId }, { fields: fields}); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/vulcan-accounts/imports/components.js: -------------------------------------------------------------------------------- 1 | import './ui/components/Button.jsx'; 2 | import './ui/components/Buttons.jsx'; 3 | import './ui/components/Field.jsx'; 4 | import './ui/components/Fields.jsx'; 5 | import './ui/components/Form.jsx'; 6 | import './ui/components/FormMessage.jsx'; 7 | import './ui/components/FormMessages.jsx'; 8 | import './ui/components/StateSwitcher.jsx'; 9 | import './ui/components/LoginForm.jsx'; 10 | import './ui/components/LoginFormInner.jsx'; 11 | import './ui/components/PasswordOrService.jsx'; 12 | import './ui/components/SocialButtons.jsx'; 13 | import './ui/components/ResetPassword.jsx'; 14 | import './ui/components/EnrollAccount.jsx'; 15 | import './ui/components/VerifyEmail.jsx'; 16 | -------------------------------------------------------------------------------- /packages/vulcan-accounts/imports/emailTemplates.js: -------------------------------------------------------------------------------- 1 | import {Accounts} from 'meteor/accounts-base'; 2 | import {getSetting} from 'meteor/vulcan:core'; 3 | 4 | // the emailTemplates are made available by accounts-password, which we don't want to depend on 5 | if (Package['accounts-password']) { 6 | Accounts.emailTemplates.siteName = getSetting('public.title', ''); 7 | Accounts.emailTemplates.from = 8 | getSetting('public.title', '') + 9 | ' <' + 10 | getSetting('defaultEmail', 'no-reply@example.com') + 11 | '>'; 12 | } 13 | -------------------------------------------------------------------------------- /packages/vulcan-accounts/imports/oauth_config.js: -------------------------------------------------------------------------------- 1 | import { ServiceConfiguration } from 'meteor/service-configuration'; 2 | import { getSetting } from 'meteor/vulcan:lib'; 3 | 4 | const services = getSetting('oAuth'); 5 | 6 | if (services) { 7 | Object.keys(services).forEach(serviceName => { 8 | ServiceConfiguration.configurations.upsert({service: serviceName}, { 9 | $set: services[serviceName] 10 | }); 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /packages/vulcan-accounts/imports/routes.js: -------------------------------------------------------------------------------- 1 | import { addRoute } from 'meteor/vulcan:core'; 2 | 3 | addRoute({name: 'resetPassword', path: '/reset-password/:token', componentName: 'AccountsResetPassword'}); 4 | addRoute({name: 'enrollAccount', path: '/enroll-account/:token', componentName: 'AccountsEnrollAccount'}); 5 | addRoute({name: 'verifyEmail', path: '/verify-email/:token', componentName: 'AccountsVerifyEmail'}); 6 | -------------------------------------------------------------------------------- /packages/vulcan-accounts/imports/ui/components/Buttons.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './Button.jsx'; 3 | import { Components, registerComponent } from 'meteor/vulcan:core'; 4 | 5 | export class Buttons extends React.Component { 6 | render () { 7 | let { buttons = {}, className = 'buttons' } = this.props; 8 | return ( 9 |
10 | {Object.keys(buttons).map((id, i) => 11 | 12 | )} 13 |
14 | ); 15 | } 16 | } 17 | 18 | registerComponent('AccountsButtons', Buttons); -------------------------------------------------------------------------------- /packages/vulcan-accounts/imports/ui/components/Fields.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Components, registerComponent } from 'meteor/vulcan:core'; 3 | 4 | export class AccountsFields extends React.Component { 5 | render () { 6 | let { fields = {}, className = 'fields' } = this.props; 7 | return ( 8 |
9 | {Object.keys(fields).map((id, i) => 10 | 11 | )} 12 |
13 | ); 14 | } 15 | } 16 | 17 | registerComponent('AccountsFields', AccountsFields); -------------------------------------------------------------------------------- /packages/vulcan-accounts/imports/ui/components/FormMessage.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { registerComponent } from 'meteor/vulcan:core'; 3 | 4 | export class AccountsFormMessage extends React.Component { 5 | render () { 6 | let { message, type, className = 'message', style = {} } = this.props; 7 | message = _.isObject(message) ? message.message : message; // If message is object, then try to get message from it 8 | return message ? ( 9 |
{ message }
10 | ) : null; 11 | } 12 | } 13 | 14 | registerComponent('AccountsFormMessage', AccountsFormMessage); 15 | -------------------------------------------------------------------------------- /packages/vulcan-accounts/imports/ui/components/FormMessages.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Components, registerComponent } from 'meteor/vulcan:core'; 3 | 4 | export class AccountsFormMessages extends Component { 5 | render () { 6 | const { messages = [], className = 'messages', style = {} } = this.props; 7 | return messages.length > 0 && ( 8 |
9 | {messages 10 | .filter(message => !('field' in message)) 11 | .map(({ message, type }, i) => 12 | 17 | )} 18 |
19 | ); 20 | } 21 | } 22 | 23 | registerComponent('AccountsFormMessages', AccountsFormMessages); -------------------------------------------------------------------------------- /packages/vulcan-accounts/imports/ui/components/LoginForm.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Components, registerComponent } from 'meteor/vulcan:core'; 3 | 4 | export class AccountsLoginForm extends React.Component { 5 | 6 | render() { 7 | return( 8 | 9 | ); 10 | } 11 | } 12 | 13 | registerComponent('AccountsLoginForm', AccountsLoginForm); -------------------------------------------------------------------------------- /packages/vulcan-accounts/imports/ui/components/SocialButtons.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './Button.jsx'; 3 | import { Components, registerComponent } from 'meteor/vulcan:core'; 4 | 5 | 6 | export class AccountsSocialButtons extends React.Component { 7 | render() { 8 | let { oauthServices = {}, className = 'social-buttons' } = this.props; 9 | return( 10 |
11 | {Object.keys(oauthServices).map((id, i) => { 12 | return ; 13 | })} 14 |
15 | ); 16 | } 17 | } 18 | 19 | registerComponent('AccountsSocialButtons', AccountsSocialButtons); -------------------------------------------------------------------------------- /packages/vulcan-accounts/imports/useMeteorLogout.js: -------------------------------------------------------------------------------- 1 | import { useApolloClient } from '@apollo/client'; 2 | 3 | /** 4 | * Hook used to sign the user out. 5 | * 6 | * @param {function} callback called after the logout and the Apollo store reset 7 | * @returns {function} a function to execute when you log the user out 8 | */ 9 | 10 | const useMeteorLogout = (callback = () => {}) => { 11 | const client = useApolloClient(); 12 | return () => 13 | Meteor.logout(() => { 14 | const resetStoreCallback = () => { 15 | callback(); 16 | removeResetStoreCallback(resetStoreCallback); 17 | }; 18 | const removeResetStoreCallback = client.onResetStore(resetStoreCallback); 19 | client.resetStore(); 20 | }); 21 | }; 22 | 23 | export default useMeteorLogout; 24 | -------------------------------------------------------------------------------- /packages/vulcan-accounts/main_client.js: -------------------------------------------------------------------------------- 1 | import { Accounts } from 'meteor/accounts-base'; 2 | import './imports/accounts_ui.js'; 3 | import './imports/components.js'; 4 | import './imports/login_session.js'; 5 | import './imports/routes.js'; 6 | import { STATES } from './imports/helpers.js'; 7 | import useMeteorLogout from './imports/useMeteorLogout.js'; 8 | 9 | import './imports/ui/components/LoginForm.jsx'; 10 | 11 | export { Accounts, STATES, useMeteorLogout }; 12 | export default Accounts; 13 | -------------------------------------------------------------------------------- /packages/vulcan-accounts/main_server.js: -------------------------------------------------------------------------------- 1 | import { Accounts } from 'meteor/accounts-base'; 2 | import './imports/accounts_ui.js'; 3 | import './imports/components.js'; 4 | import './imports/login_session.js'; 5 | import './imports/routes.js'; 6 | import './imports/oauth_config.js'; 7 | import './imports/emailTemplates.js'; 8 | import { redirect, STATES } from './imports/helpers.js'; 9 | import './imports/api/server/servicesListPublication.js'; 10 | import useMeteorLogout from './imports/useMeteorLogout.js'; 11 | 12 | import './imports/ui/components/LoginForm.jsx'; 13 | 14 | export { Accounts, redirect, STATES, useMeteorLogout }; 15 | export default Accounts; 16 | -------------------------------------------------------------------------------- /packages/vulcan-accounts/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:accounts', 3 | version: '1.16.9', 4 | summary: 'Accounts UI for React in Meteor 1.3+', 5 | git: 'https://github.com/studiointeract/accounts-ui', 6 | documentation: 'README.md', 7 | }); 8 | 9 | Package.onUse(function(api) { 10 | api.use('vulcan:core@=1.16.9'); 11 | 12 | api.use('tracker@1.2.0'); 13 | api.use('session@1.2.0'); 14 | api.use('accounts-oauth@1.3.0', { weak: true }); 15 | api.use('accounts-password@2.0.0', { weak: true }); 16 | api.use('service-configuration@1.1.0'); 17 | api.use('accounts-base@2.0.0'); 18 | 19 | api.mainModule('main_client.js', 'client'); 20 | api.mainModule('main_server.js', 'server'); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/vulcan-admin/README.md: -------------------------------------------------------------------------------- 1 | VulcanJS admin package. -------------------------------------------------------------------------------- /packages/vulcan-admin/lib/client/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; -------------------------------------------------------------------------------- /packages/vulcan-admin/lib/components/AdminLayout.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @Author: Apollinaire Lecocq 3 | * @Date: 08-01-19 4 | * @Last modified by: apollinaire 5 | * @Last modified time: 10-01-19 6 | */ 7 | import React from 'react'; 8 | import {registerComponent, Components, withAccess, Dummy} from 'meteor/vulcan:core'; 9 | 10 | const RestrictToAdmins = withAccess({groups: ['admins']})(Dummy); 11 | 12 | /** 13 | * A simple component that renders the existing layout and checks whether the currentUser is an admin or not. 14 | */ 15 | 16 | function AdminLayout({children}) { 17 | return ( 18 | 19 | {children} 20 | 21 | ); 22 | } 23 | 24 | registerComponent({ 25 | name: 'AdminLayout', 26 | component: AdminLayout, 27 | }); 28 | -------------------------------------------------------------------------------- /packages/vulcan-admin/lib/components/users/columns/AdminUsersActions.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Users from 'meteor/vulcan:users'; 3 | import { Components, withRemove } from 'meteor/vulcan:core'; 4 | 5 | const AdminUsersActions = ({ document: user, deleteUser }) => { 6 | const deleteHandler = e => { 7 | e.preventDefault(); 8 | if (confirm(`Delete user ${Users.getDisplayName(user)}?`)) { 9 | deleteUser({ documentId: user._id }); 10 | } 11 | }; 12 | 13 | return ( 14 | 15 | Delete 16 | 17 | ); 18 | }; 19 | 20 | const removeOptions = { 21 | collection: Users, 22 | }; 23 | 24 | export default withRemove(removeOptions)(AdminUsersActions); 25 | -------------------------------------------------------------------------------- /packages/vulcan-admin/lib/components/users/columns/AdminUsersCreated.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Components } from 'meteor/vulcan:core'; 3 | import moment from 'moment'; 4 | 5 | const AdminUsersCreated = ({ document: user }) => 6 |
7 | {moment(new Date(user.createdAt)).format('MM/DD/YY')} 8 |
; 9 | 10 | export default AdminUsersCreated; -------------------------------------------------------------------------------- /packages/vulcan-admin/lib/components/users/columns/AdminUsersEmail.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Users from 'meteor/vulcan:users'; 3 | import { Components } from 'meteor/vulcan:core'; 4 | 5 | const AdminUsersEmail = ({ document: user }) => 6 | {Users.getEmail(user)}; 7 | 8 | export default AdminUsersEmail; -------------------------------------------------------------------------------- /packages/vulcan-admin/lib/components/users/columns/AdminUsersName.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Users from 'meteor/vulcan:users'; 3 | import { Components } from 'meteor/vulcan:core'; 4 | 5 | const AdminUsersName = ({ document: user, flash }) => 6 |
7 | 8 | 9 | 10 | {Users.getDisplayName(user)} 11 | 12 |   13 | 14 | {_.rest(Users.getGroups(user)).map(group => {group})} 15 | 16 |
; 17 | 18 | export default AdminUsersName; 19 | -------------------------------------------------------------------------------- /packages/vulcan-admin/lib/modules/columns.js: -------------------------------------------------------------------------------- 1 | import { addAdminColumn } from 'meteor/vulcan:core'; 2 | 3 | import AdminUsersName from '../components/users/columns/AdminUsersName.jsx'; 4 | import AdminUsersEmail from '../components/users/columns/AdminUsersEmail.jsx'; 5 | import AdminUsersCreated from '../components/users/columns/AdminUsersCreated.jsx'; 6 | 7 | addAdminColumn([ 8 | { 9 | name: 'name', 10 | order: 1, 11 | component: AdminUsersName 12 | }, 13 | { 14 | name: 'email', 15 | order: 10, 16 | component: AdminUsersEmail 17 | }, 18 | { 19 | name: 'created', 20 | order: 20, 21 | component: AdminUsersCreated 22 | }, 23 | ]); -------------------------------------------------------------------------------- /packages/vulcan-admin/lib/modules/fragments.js: -------------------------------------------------------------------------------- 1 | import { registerFragment } from 'meteor/vulcan:lib'; 2 | 3 | // ------------------------------ Vote ------------------------------ // 4 | 5 | // note: fragment used by default on the UsersProfile fragment 6 | registerFragment(` 7 | fragment UsersAdmin on User { 8 | _id 9 | username 10 | createdAt 11 | isAdmin 12 | displayName 13 | email 14 | emailHash 15 | slug 16 | groups 17 | services 18 | avatarUrl 19 | pageUrl 20 | pagePath 21 | } 22 | `); 23 | -------------------------------------------------------------------------------- /packages/vulcan-admin/lib/modules/i18n.js: -------------------------------------------------------------------------------- 1 | import { addStrings } from 'meteor/vulcan:core'; 2 | 3 | addStrings('en', { 4 | 'users.name': 'Name', 5 | 'users.created': 'Created', 6 | 'users.groups': 'Groups', 7 | 'users.actions': 'Actions', 8 | 'users.email': 'Email', 9 | }); -------------------------------------------------------------------------------- /packages/vulcan-admin/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | import './fragments.js'; 2 | import './routes.js'; 3 | import './i18n.js'; 4 | import '../components/AdminLayout'; 5 | -------------------------------------------------------------------------------- /packages/vulcan-admin/lib/modules/routes.js: -------------------------------------------------------------------------------- 1 | import {addRoute, getDynamicComponent} from 'meteor/vulcan:core'; 2 | import React from 'react'; 3 | 4 | addRoute({ 5 | name: 'admin', 6 | path: '/admin', 7 | component: () => getDynamicComponent(import('../components/AdminHome.jsx')), 8 | layoutName: 'AdminLayout', 9 | }); 10 | addRoute({ 11 | name: 'admin2', 12 | path: '/admin/users', 13 | component: () => getDynamicComponent(import('../components/AdminHome.jsx')), 14 | }); 15 | -------------------------------------------------------------------------------- /packages/vulcan-admin/lib/server/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; -------------------------------------------------------------------------------- /packages/vulcan-admin/lib/stylesheets/style.scss: -------------------------------------------------------------------------------- 1 | .datatable-users{ 2 | .datatable-search{ 3 | margin-bottom: 10px; 4 | padding: 2px 7px; 5 | } 6 | 7 | .datatable-item-name{ 8 | .modal-trigger{ 9 | display: inline-block; 10 | cursor: pointer; 11 | } 12 | .avatar{ 13 | display: inline-block; 14 | margin-right: 5px; 15 | } 16 | a{ 17 | display: flex; 18 | align-items: center; 19 | div{ 20 | margin-right: 5px; 21 | } 22 | } 23 | } 24 | 25 | .datatable-item-groups{ 26 | code{ 27 | display: inline-block; 28 | margin-right: 5px; 29 | } 30 | } 31 | 32 | .datatable-load-more{ 33 | display: flex; 34 | align-items: center; 35 | justify-content: center; 36 | } 37 | 38 | .avatar img{ 39 | width: 20px; 40 | } 41 | } -------------------------------------------------------------------------------- /packages/vulcan-admin/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:admin', 3 | summary: 'Vulcan components package', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use([ 10 | 'vulcan:scss@4.12.0', 11 | 'dynamic-import@0.1.1', 12 | // Vulcan packages 13 | 'vulcan:core@=1.16.9', 14 | ]); 15 | 16 | api.mainModule('lib/server/main.js', 'server'); 17 | api.mainModule('lib/client/main.js', 'client'); 18 | 19 | api.addFiles(['lib/stylesheets/style.scss'], ['client']); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/.gitignore: -------------------------------------------------------------------------------- 1 | ./node_modules 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/README.md: -------------------------------------------------------------------------------- 1 | Vulcan back-office package, used internally. -------------------------------------------------------------------------------- /packages/vulcan-backoffice/lib/client/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules'; 2 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/lib/components/BackofficeIndex.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Components, registerComponent } from 'meteor/vulcan:core'; 3 | import NoSSR from 'react-no-ssr'; 4 | 5 | const BackofficeIndex = () => { 6 | return ( 7 |
8 |

Welcome to Vulcan autogenerated backoffice

9 | {/** AccountsLoginForm is SSR only */} 10 |
11 | 12 | 13 | 14 |
15 |
16 | );}; 17 | registerComponent({ name: 'VulcanBackofficeIndex', component: BackofficeIndex, hocs: [] }); 18 | 19 | export default BackofficeIndex; 20 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/lib/components/CollectionList.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Generic page for a collection 3 | * Must be handled by the parent : 4 | * - providing the documents and callbacks 5 | */ 6 | 7 | import React from 'react'; 8 | import { Components, registerComponent, withCurrentUser, withAccess } from 'meteor/vulcan:core'; 9 | // TODO: get options from backoffice config 10 | const accessOptions = { 11 | groups: ['admins'], 12 | redirect: '/backoffice', 13 | message: 'Sorry, you do not have the rights to access this page.', 14 | }; 15 | 16 | export const CollectionList = props => { 17 | return ; 18 | }; 19 | 20 | export default CollectionList; 21 | registerComponent({ 22 | name: 'VulcanBackofficeCollectionList', 23 | component: CollectionList, 24 | hocs: [withCurrentUser, [withAccess, accessOptions]], 25 | }); 26 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/lib/hocs/withDocumentId.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the documentId from parent props or from the route 3 | */ 4 | import React from 'react'; 5 | export const withDocumentId = (fieldName = 'documentId') => Component => { 6 | const withDocumentId = props => ( 7 | 11 | ); 12 | withDocumentId.displayName = `withDocumentId(${Component.displayName})`; 13 | return withDocumentId; 14 | }; 15 | export default withDocumentId; 16 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/lib/hocs/withRouteParam.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Pass a route param to its child 3 | * 4 | */ 5 | import React from 'react'; 6 | import PropTypes from 'prop-types'; 7 | 8 | export const withRouteParam = fieldName => Component => { 9 | const Wrapper = props => ( 10 | 16 | ); 17 | 18 | Wrapper.propTypes = { 19 | // @see React router 4 withRouter API 20 | match: PropTypes.shape({ 21 | params: PropTypes.object, 22 | }), 23 | }; 24 | Wrapper.displayName = `withRouteParam(${fieldName})(${Component.displayName})`; 25 | return Wrapper; 26 | }; 27 | export default withRouteParam; 28 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/lib/modules/components.js: -------------------------------------------------------------------------------- 1 | // load generic components 2 | import '../components/CollectionItem'; 3 | import '../components/CollectionList'; 4 | import '../components/BackofficeLayout'; 5 | import '../components/BackofficeIndex'; 6 | //import '../components/BackofficeVerticalMenuLayout'; 7 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/lib/modules/createCollectionComponents/createCollectionComponents.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Create List and Item components for the provided collection, 3 | * based on the generic Vulcan backoffice components 4 | */ 5 | import createListComponent from './createListComponent'; 6 | import createItemComponent from './createItemComponent'; 7 | import { mergeDefaultCollectionOptions } from '../options'; 8 | 9 | const createCollectionComponents = (collection, options) => { 10 | const mergedOptions = mergeDefaultCollectionOptions(options); 11 | const ListComponent = createListComponent(collection, mergedOptions); 12 | const ItemComponent = createItemComponent(collection, mergedOptions); 13 | return { ListComponent, ItemComponent }; 14 | }; 15 | export default createCollectionComponents; 16 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/lib/modules/createCollectionComponents/index.js: -------------------------------------------------------------------------------- 1 | export { default as createListComponent } from './createListComponent'; 2 | export { default as createItemComponent } from './createItemComponent'; 3 | 4 | export { default } from './createCollectionComponents'; 5 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | import './settings'; 2 | import './startup'; 3 | import './components'; 4 | 5 | export { default as withDocumentId } from '../hocs/withDocumentId'; 6 | export { default as createCollectionComponents } from './createCollectionComponents'; 7 | export * from './setupCollectionMenuItems'; 8 | 9 | export { default as setupCollectionRoutes } from './setupCollectionRoutes'; 10 | 11 | export { default, default as setupBackoffice } from './setupBackoffice'; 12 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/lib/modules/settings.js: -------------------------------------------------------------------------------- 1 | import { registerSetting } from 'meteor/vulcan:core'; 2 | registerSetting('backoffice.enable', Meteor.isDevelopment, 'Automatically generate a backoffice', true); 3 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/lib/modules/startup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generate the backoffice on startup 3 | */ 4 | import {getSetting, Collections} from 'meteor/vulcan:core'; 5 | import setupBackoffice from './setupBackoffice'; 6 | import {devOptions} from './options'; 7 | import {addCallback} from 'meteor/vulcan:lib'; 8 | 9 | const enabled = getSetting('backoffice.enabled', Meteor.isDevelopment); 10 | 11 | if (enabled) { 12 | const options = Meteor.isDevelopment ? devOptions : undefined; // loose permissions during development 13 | // setupBackoffice must be run before routes and components are populated 14 | // but after startup so that Collections are available 15 | addCallback('populate.before', function _setupBackoffice() { 16 | setupBackoffice(Collections, options); 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/lib/server/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules'; 2 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:backoffice', 3 | summary: 'Vulcan automated backoffice generator', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(api => { 9 | api.use(['vulcan:core@=1.16.9', 'vulcan:i18n@=1.16.9', 'vulcan:accounts@1.16.9']); 10 | 11 | api.mainModule('lib/server/main.js', 'server'); 12 | api.mainModule('lib/client/main.js', 'client'); 13 | }); 14 | 15 | Package.onTest(function(api) { 16 | api.use(['ecmascript', 'meteortesting:mocha', 'vulcan:core']); 17 | api.mainModule('./test/index.js'); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vulcan-backoffice", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "package.js", 6 | "directories": { 7 | "lib": "lib" 8 | }, 9 | "scripts": { 10 | "test": "npm run test-unit", 11 | "test-unit": "TEST_WATCH=1 meteor test-packages ./ --port 3002 --driver-package meteortesting:mocha --raw-logs" 12 | }, 13 | "devDependencies": { 14 | "expect": "^23.6.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/test/index.js: -------------------------------------------------------------------------------- 1 | import './namingHelpers.test'; 2 | 3 | import './routes.test'; 4 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/test/options.js: -------------------------------------------------------------------------------- 1 | import expect from 'expect'; 2 | import { 3 | mergeDefaultBackofficeOptions, 4 | mergeDefaultCollectionOptions, 5 | } from '../lib/modules/options'; 6 | describe('options', function () { 7 | it('merge defaultOptions', function () { 8 | const givenOptions = { 9 | menuItem: { groups: ['members', 'admins', 'foobars'] }, 10 | }; 11 | const mergedOptions = mergeDefaultBackofficeOptions(givenOptions); 12 | expect(mergedOptions.menuItem.groups).toEqual(['members', 'admins', 'foobars']); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/vulcan-backoffice/test/routes.test.js: -------------------------------------------------------------------------------- 1 | import expect from 'expect'; 2 | import { generateRoutes } from '../lib/modules/setupCollectionRoutes'; 3 | 4 | const DummyCollection = { 5 | options: { 6 | collectionName: 'Dummies', 7 | }, 8 | }; 9 | describe('vulcan:backoffice/setupCollectionRoutes', function () { 10 | it('generate routes', function () { 11 | const options = {} 12 | const { listRoute, itemRoute } = generateRoutes(DummyCollection, options); 13 | //expect(baseRoute.path).toEqual('/dummies'); 14 | expect(listRoute.path).toEqual('/dummies'); 15 | expect(itemRoute.path).toEqual('/dummies/:documentId'); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/vulcan-cloudinary/README.md: -------------------------------------------------------------------------------- 1 | Vulcan file upload package, used internally. 2 | 3 | ### Custom Posts Fields 4 | 5 | - `cloudinaryId` 6 | - `cloudinaryUrls` 7 | 8 | ### Public Settings 9 | 10 | - `cloudinaryCloudName` 11 | - `cloudinaryFormats` 12 | 13 | ### Private Settings 14 | 15 | - `cloudinaryAPIKey` 16 | - `cloudinaryAPISecret` 17 | 18 | ### Sample Settings 19 | 20 | ```js 21 | { 22 | "public": { 23 | "cloudinaryCloudName": "myCloudName", 24 | "cloudinaryFormats": [ 25 | { 26 | "name": "small", 27 | "width": 120, 28 | "height": 90 29 | }, 30 | { 31 | "name": "medium", 32 | "width": 480, 33 | "height": 360 34 | } 35 | ] 36 | }, 37 | "cloudinaryAPIKey": "abcfoo", 38 | "cloudinaryAPISecret": "123bar", 39 | } 40 | ``` -------------------------------------------------------------------------------- /packages/vulcan-cloudinary/lib/client/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; 2 | export * from './make_cloudinary.js'; 3 | -------------------------------------------------------------------------------- /packages/vulcan-cloudinary/lib/client/make_cloudinary.js: -------------------------------------------------------------------------------- 1 | import { addCustomFields } from '../modules/index.js'; 2 | 3 | export const makeCloudinary = ({collection, fieldName}) => { 4 | addCustomFields(collection); 5 | }; -------------------------------------------------------------------------------- /packages/vulcan-cloudinary/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | export * from './custom_fields.js'; -------------------------------------------------------------------------------- /packages/vulcan-cloudinary/lib/server/main.js: -------------------------------------------------------------------------------- 1 | export * from './cloudinary.js'; 2 | export * from '../modules/index.js'; 3 | export * from './make_cloudinary.js'; 4 | -------------------------------------------------------------------------------- /packages/vulcan-cloudinary/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:cloudinary', 3 | summary: 'Vulcan file upload package.', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9']); 10 | 11 | api.mainModule('lib/client/main.js', 'client'); 12 | api.mainModule('lib/server/main.js', 'server'); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/vulcan-core/README.md: -------------------------------------------------------------------------------- 1 | Vulcan core package, used internally. -------------------------------------------------------------------------------- /packages/vulcan-core/lib/client/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; 2 | 3 | export * from './start.jsx'; 4 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/callbacks.js: -------------------------------------------------------------------------------- 1 | import { registerCallback } from 'meteor/vulcan:lib'; 2 | 3 | registerCallback({ 4 | name: 'populate.before', 5 | description: 'Run before Vulcan objects are populated. Use if you need to add routes dynamically on startup for example.', 6 | arguments: [], 7 | runs: 'sync', 8 | returns: 'nothing', 9 | }); -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Also imported by Storybook 4 | 5 | */ 6 | 7 | import './components/Avatar.jsx'; 8 | import './components/Loading.jsx'; 9 | import './components/LoadingButton.jsx'; 10 | import './components/NewButton.jsx'; 11 | import './components/EditButton.jsx'; 12 | import './components/DeleteButton.jsx'; 13 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Card/CardItemArray.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | 4 | // Array 5 | const CardItemArray = ({ nestingLevel, value, Components }) => ( 6 |
    7 | {value.map((item, index) => ( 8 |
  1. 9 | { 10 | 16 | } 17 |
  2. 18 | ))} 19 |
20 | ); 21 | registerComponent({ name: 'CardItemArray', component: CardItemArray }); 22 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Card/CardItemDate.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | import moment from 'moment'; 4 | 5 | // Date 6 | const CardItemDate = ({ value }) => ( 7 | {moment(new Date(value)).format('YYYY/MM/DD, hh:mm')} 8 | ); 9 | registerComponent({ name: 'CardItemDate', component: CardItemDate }); 10 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Card/CardItemDefault.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | 4 | // Default 5 | const CardItemDefault = ({ value }) => {value.toString()}; 6 | registerComponent({ name: 'CardItemDefault', component: CardItemDefault }); 7 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Card/CardItemHTML.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | 4 | // HTML 5 | const CardItemHTML = ({ value }) => ( 6 |
7 | ); 8 | registerComponent({ name: 'CardItemHTML', component: CardItemHTML }); -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Card/CardItemImage.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | 4 | /* 5 | 6 | Card Item Components 7 | 8 | */ 9 | 10 | // Image 11 | const CardItemImage = ({ value, force = false, Components }) => { 12 | const isImage = 13 | ['.png', '.jpg', '.gif'].indexOf(value.substr(-4)) !== -1 || 14 | ['.webp', '.jpeg'].indexOf(value.substr(-5)) !== -1; 15 | return isImage || force ? ( 16 | {value} 22 | ) : ( 23 | 24 | ); 25 | }; 26 | registerComponent({ name: 'CardItemImage', component: CardItemImage }); 27 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Card/CardItemNumber.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | 4 | // Number 5 | const CardItemNumber = ({ value }) => {value.toString()}; 6 | registerComponent({ name: 'CardItemNumber', component: CardItemNumber }); 7 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Card/CardItemRelationHasMany.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | 4 | // HasMany Relation 5 | const CardItemRelationHasMany = ({ relatedDocument: relatedDocuments, Components, ...rest }) => ( 6 |
7 | {relatedDocuments.map(relatedDocument => ( 8 | 14 | ))} 15 |
16 | ); 17 | registerComponent({ name: 'CardItemRelationHasMany', component: CardItemRelationHasMany }); 18 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Card/CardItemRelationHasOne.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | 4 | // HasOne Relation 5 | const CardItemRelationHasOne = ({ Components, ...rest }) => ( 6 |
7 | {} 8 |
9 | ); 10 | registerComponent({ name: 'CardItemRelationHasOne', component: CardItemRelationHasOne }); 11 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Card/CardItemString.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | 4 | // String 5 | const CardItemString = ({ string }) => ( 6 |
7 | {string.indexOf(' ') === -1 && string.length > 30 ? ( 8 | {string.substr(0, 30)}… 9 | ) : ( 10 | {string} 11 | )} 12 |
13 | ); 14 | registerComponent({ name: 'CardItemString', component: CardItemString }); 15 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Card/CardItemURL.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | 4 | // URL 5 | const CardItemURL = ({ value, force, Components }) => { 6 | return force || value.slice(0, 4) === 'http' ? ( 7 | 8 | 9 | 10 | ) : ( 11 | 12 | ); 13 | }; 14 | registerComponent({ name: 'CardItemURL', component: CardItemURL }); 15 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Card/index.js: -------------------------------------------------------------------------------- 1 | import './CardItemArray'; 2 | import './CardItemDate'; 3 | import './CardItemDefault'; 4 | import './CardItemHTML'; 5 | import './CardItemImage'; 6 | import './CardItemURL'; 7 | import './CardItemNumber'; 8 | import './CardItemObject'; 9 | import './CardItemString'; 10 | import './CardItemRelationItem'; 11 | import './CardItemRelationHasMany'; 12 | import './CardItemRelationHasOne'; 13 | import './CardItemSwitcher'; 14 | import './CardItemURL'; 15 | export { default } from './Card'; 16 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Datatable/DatatableSubmitSelected.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent, Components } from 'meteor/vulcan:lib'; 2 | import React, { memo } from 'react'; 3 | import PropTypes from 'prop-types'; 4 | 5 | /* 6 | 7 | DatatableSelect Component 8 | 9 | */ 10 | const DatatableSubmitSelected = ({ selectedItems, onSubmitSelected }) => ( 11 | { 14 | e.preventDefault(); 15 | onSubmitSelected(selectedItems); 16 | }}> 17 | 18 | 19 | ); 20 | 21 | registerComponent({ name: 'DatatableSubmitSelected', component: DatatableSubmitSelected, hocs: [memo] }); 22 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Datatable/index.js: -------------------------------------------------------------------------------- 1 | import './Datatable.jsx'; 2 | import './DatatableSorter.jsx'; 3 | import './DatatableFilter.jsx'; 4 | import './DatatableCell.jsx'; 5 | import './DatatableContents.jsx'; 6 | import './DatatableHeader.jsx'; 7 | import './DatatableRow.jsx'; 8 | import './DatatableSelect.jsx'; 9 | import './DatatableSubmitSelected.jsx'; 10 | export { default } from './Datatable.jsx'; 11 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Dummy.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {registerComponent} from 'meteor/vulcan:lib'; 3 | 4 | function Dummy({children}) { 5 | return children; 6 | } 7 | Dummy.displayName = 'Dummy'; 8 | 9 | registerComponent({name: 'Dummy', component: Dummy}); 10 | export default Dummy; 11 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/DynamicLoading.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Components, registerComponent } from 'meteor/vulcan:lib'; 3 | 4 | const DynamicLoading = ({ isLoading, pastDelay, error }) => { 5 | if (isLoading && pastDelay) { 6 | return ; 7 | } else if (error && !isLoading) { 8 | // eslint-disable-next-line no-console 9 | console.log(error); 10 | return

Error!

; 11 | } else { 12 | return null; 13 | } 14 | }; 15 | 16 | registerComponent('DynamicLoading', DynamicLoading); 17 | 18 | export default DynamicLoading; -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Error404.jsx: -------------------------------------------------------------------------------- 1 | import { Components, registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | 4 | const Error404 = () => { 5 | return ( 6 |
7 |

8 | 9 |

10 |
11 | ); 12 | }; 13 | 14 | Error404.displayName = 'Error404'; 15 | 16 | registerComponent('Error404', Error404); 17 | 18 | export default Error404; 19 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Icon.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent, Utils } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | 4 | const Icon = ({ name, iconClass, onClick }) => { 5 | const icons = Utils.icons; 6 | const iconCode = !!icons[name] ? icons[name] : name; 7 | iconClass = (typeof iconClass === 'string') ? ' '+iconClass : ''; 8 | const c = 'icon fa fa-fw fa-' + iconCode + ' icon-' + name + iconClass; 9 | return ; 10 | }; 11 | 12 | Icon.displayName = 'Icon'; 13 | 14 | registerComponent('Icon', Icon); 15 | 16 | export default Icon; -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Layout.jsx: -------------------------------------------------------------------------------- 1 | import { Components, registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | 4 | const Layout = ({children}) => 5 |
{children}
; 6 | 7 | Layout.displayName = 'Layout'; 8 | 9 | registerComponent('Layout', Layout); 10 | 11 | export default Layout; -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/Loading.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | 4 | const Loading = props => { 5 | return ( 6 |
7 |
8 |
9 |
10 |
11 | ); 12 | }; 13 | 14 | Loading.displayName = 'Loading'; 15 | 16 | registerComponent('Loading', Loading); 17 | 18 | export default Loading; 19 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/PaginatedList/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './PaginatedList.jsx'; -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/ScrollToTop.jsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {withRouter} from 'react-router'; 3 | import {registerComponent} from 'meteor/vulcan:lib'; 4 | 5 | // Scroll restoration based on https://reacttraining.com/react-router/web/guides/scroll-restoration. 6 | export default class ScrollToTop extends Component { 7 | componentDidUpdate(prevProps) { 8 | if (this.props.location.pathname !== prevProps.location.pathname) { 9 | window.scrollTo(0, 0); 10 | } 11 | } 12 | 13 | render() { 14 | return null; 15 | } 16 | } 17 | 18 | registerComponent('ScrollToTop', ScrollToTop, withRouter); 19 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/ShowIf.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import withCurrentUser from '../containers/currentUser.js'; 5 | 6 | const ShowIf = props => { 7 | const { check, document, failureComponent = null, currentUser, children } = props; 8 | return check(currentUser, document) ? children : failureComponent; 9 | }; 10 | 11 | ShowIf.propTypes = { 12 | check: PropTypes.func.isRequired, 13 | currentUser: PropTypes.object, 14 | document: PropTypes.object, 15 | failureComponent: PropTypes.object, 16 | }; 17 | 18 | ShowIf.displayName = 'ShowIf'; 19 | 20 | registerComponent('ShowIf', ShowIf, withCurrentUser); 21 | export default ShowIf; 22 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/VerticalMenuLayout/MenuLayout.jsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VulcanJS/Vulcan/b3e50d061f22e758cb1a7e3502883ebc1d70f68e/packages/vulcan-core/lib/modules/components/VerticalMenuLayout/MenuLayout.jsx -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/components/VerticalMenuLayout/VerticalMenuLayout.jsx: -------------------------------------------------------------------------------- 1 | import { registerComponent } from 'meteor/vulcan:lib'; 2 | import React from 'react'; 3 | 4 | const VerticalMenuLayout = ({menu}) => { 5 | return ( 6 |
7 | {menu} 8 |
9 | ); 10 | }; 11 | 12 | 13 | registerComponent('VerticalMenuLayout', VerticalMenuLayout); 14 | 15 | export default VerticalMenuLayout; 16 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/containers/index.js: -------------------------------------------------------------------------------- 1 | export * from './localeData'; -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/containers/variables.js: -------------------------------------------------------------------------------- 1 | import _merge from 'lodash/merge'; 2 | /** 3 | * Compute the _id or input based on default options of the hooks 4 | * + dynamic props (for single) or dynamic arguments (for update) 5 | * @param {*} options 6 | * @param {*} argsOrProps 7 | */ 8 | export const computeQueryVariables = (options, argsOrProps) => { 9 | const { _id: optionsId, input: optionsInput = {} } = options; 10 | const { _id: argsId, input: argsInput = {} } = argsOrProps; 11 | const _id = argsId || optionsId || undefined; // use dynamic _id in priority, default _id otherwise 12 | const input = !_id ? _merge({}, optionsInput, argsInput) : undefined; // if _id is defined ignore input, else use dynamic input in priority 13 | return { _id, input }; 14 | }; -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/decorators/checkboxgroup.js: -------------------------------------------------------------------------------- 1 | import get from 'lodash/get'; 2 | 3 | export const makeCheckboxgroup = (field = {}) => { 4 | const hasOther = !!get(field, 'itemProperties.showOther'); 5 | 6 | if (!field.options) { 7 | throw new Error(`Checkboxgroup fields need an 'options' property`); 8 | } 9 | 10 | // add additional field object properties 11 | const cbgField = { 12 | ...field, 13 | type: Array, 14 | input: 'checkboxgroup', 15 | }; 16 | 17 | // if field doesn't allow "other" responses, limit it to whitelist of allowed values 18 | if (!hasOther) { 19 | cbgField.arrayItem = { ...cbgField.arrayItem, allowedValues: field.options.map(({ value }) => value) }; 20 | } 21 | 22 | return cbgField; 23 | }; 24 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/decorators/index.js: -------------------------------------------------------------------------------- 1 | export * from './likert'; 2 | export * from './checkboxgroup'; 3 | export * from './radiogroup'; 4 | export * from './autocomplete'; 5 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/modules/decorators/radiogroup.js: -------------------------------------------------------------------------------- 1 | import get from 'lodash/get'; 2 | 3 | export const makeRadiogroup = (field = {}) => { 4 | const hasOther = !!get(field, 'itemProperties.showOther'); 5 | 6 | if (!field.options) { 7 | throw new Error(`Radiogroup fields need an 'options' property`); 8 | } 9 | 10 | const rgField = { 11 | ...field, 12 | type: Array, 13 | input: 'radiogroup', 14 | }; 15 | 16 | // if field doesn't allow "other" responses, limit it to whitelist of allowed values 17 | if (!hasOther) { 18 | rgField.arrayItem = {...rgField.arrayItem, allowedValues: field.options.map(({value}) => value)}; 19 | } 20 | 21 | return rgField; 22 | }; 23 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/server/main.js: -------------------------------------------------------------------------------- 1 | import './start.js'; 2 | 3 | export * from '../modules/index.js'; 4 | -------------------------------------------------------------------------------- /packages/vulcan-core/lib/server/start.js: -------------------------------------------------------------------------------- 1 | import { SyncedCron } from 'meteor/littledata:synced-cron'; 2 | import { getSetting, registerSetting } from 'meteor/vulcan:lib'; 3 | 4 | registerSetting('mailUrl', null, 'The SMTP URL used to send out email'); 5 | 6 | if (getSetting('mailUrl')) { 7 | process.env.MAIL_URL = getSetting('mailUrl'); 8 | } 9 | 10 | Meteor.startup(function() { 11 | if (process.env.NODE_ENV === 'development') { 12 | // eslint-disable-next-line no-undef 13 | Vulcan.getGraphQLSchema(); 14 | } 15 | if (typeof SyncedCron !== 'undefined') { 16 | SyncedCron.start(); 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /packages/vulcan-core/package.js: -------------------------------------------------------------------------------- 1 | const version = '1.16.9'; 2 | 3 | Package.describe({ 4 | name: 'vulcan:core', 5 | summary: 'Vulcan core package', 6 | version, 7 | git: 'https://github.com/VulcanJS/Vulcan.git', 8 | }); 9 | 10 | Package.onUse(function(api) { 11 | api.use([`vulcan:lib@=${version}`, `vulcan:i18n@=${version}`, `vulcan:users@=${version}`]); 12 | 13 | api.use([`vulcan:i18n@=${version}`], ['server', 'client'], { weak: true }); 14 | 15 | api.imply([`vulcan:lib@=${version}`]); 16 | 17 | api.mainModule('lib/server/main.js', 'server'); 18 | api.mainModule('lib/client/main.js', 'client'); 19 | }); 20 | 21 | Package.onTest(function(api) { 22 | api.use(['ecmascript', 'meteortesting:mocha', 'vulcan:core', 'vulcan:test', 'vulcan:users']); 23 | api.mainModule('./test/server/index.js', ['server']); 24 | api.mainModule('./test/client/index.js', ['client']); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/vulcan-core/test/client/index.js: -------------------------------------------------------------------------------- 1 | import '../index'; 2 | 3 | import './mutations2.test'; 4 | -------------------------------------------------------------------------------- /packages/vulcan-core/test/index.js: -------------------------------------------------------------------------------- 1 | import './components.test'; 2 | import './containers/queries.test'; 3 | import './containers/mutations.test'; 4 | import './containers2/queries.test'; 5 | import './containers2/mutations.test'; 6 | import './withComponents.test'; 7 | import './menu.test'; 8 | -------------------------------------------------------------------------------- /packages/vulcan-core/test/server/index.js: -------------------------------------------------------------------------------- 1 | import '../index'; -------------------------------------------------------------------------------- /packages/vulcan-debug/README.md: -------------------------------------------------------------------------------- 1 | Vulcan debug package. -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/client/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/components/DebugLayout.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Components, registerComponent } from 'meteor/vulcan:lib'; 3 | 4 | const debugStyles = { 5 | padding: '20px' 6 | }; 7 | 8 | const DebugLayout = props =>
{props.children}
; 9 | 10 | registerComponent('DebugLayout', DebugLayout); 11 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/components/Routes.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { registerComponent, Components, Routes } from 'meteor/vulcan:lib'; 3 | import { Link } from 'react-router-dom'; 4 | 5 | const RoutePath = ({document}) => ( 6 | {document.path} 7 | ); 8 | 9 | const RoutesDashboard = props => { 10 | return ( 11 |
12 | 27 |
28 | ); 29 | }; 30 | 31 | registerComponent('Routes', RoutesDashboard); 32 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/modules/callbacks/collection.js: -------------------------------------------------------------------------------- 1 | import { createCollection } from 'meteor/vulcan:lib'; 2 | import schema from './schema.js'; 3 | import './fragments.js'; 4 | 5 | const Callbacks = createCollection({ 6 | 7 | collectionName: 'Callbacks', 8 | 9 | typeName: 'Callback', 10 | 11 | schema, 12 | 13 | resolvers: null, 14 | 15 | mutations: null, 16 | 17 | }); 18 | 19 | 20 | export default Callbacks; 21 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/modules/callbacks/fragments.js: -------------------------------------------------------------------------------- 1 | import { registerFragment } from 'meteor/vulcan:lib'; 2 | 3 | registerFragment(` 4 | fragment CallbacksFragment on Callback { 5 | name 6 | iterator 7 | properties 8 | runs 9 | returns 10 | description 11 | hooks 12 | } 13 | `); 14 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/modules/components.js: -------------------------------------------------------------------------------- 1 | import '../components/DebugLayout.jsx'; 2 | 3 | import '../components/Emails.jsx'; 4 | import '../components/Groups.jsx'; 5 | import '../components/Settings.jsx'; 6 | import '../components/Callbacks.jsx'; 7 | import '../components/Routes.jsx'; 8 | import '../components/Components.jsx'; 9 | import '../components/I18n.jsx'; 10 | import '../components/Dashboard.jsx'; 11 | import '../components/Database.jsx'; 12 | import '../components/ErrorCatcherContents.jsx'; 13 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/modules/emails/collection.js: -------------------------------------------------------------------------------- 1 | import { createCollection } from 'meteor/vulcan:lib'; 2 | import schema from './schema.js'; 3 | 4 | const Emails = createCollection({ 5 | 6 | collectionName: 'Emails', 7 | 8 | typeName: 'Email', 9 | 10 | schema, 11 | 12 | resolvers: null, 13 | 14 | mutations: null, 15 | 16 | }); 17 | 18 | 19 | export default Emails; 20 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/modules/emails/schema.js: -------------------------------------------------------------------------------- 1 | import { readPermissions } from "../permissions"; 2 | 3 | const schema = { 4 | 5 | name: { 6 | type: String, 7 | canRead: readPermissions, 8 | }, 9 | 10 | template: { 11 | type: String, 12 | canRead: readPermissions, 13 | }, 14 | 15 | subject: { 16 | type: String, 17 | canRead: readPermissions, 18 | }, 19 | 20 | testPath: { 21 | type: String, 22 | canRead: readPermissions, 23 | }, 24 | 25 | }; 26 | 27 | export default schema; 28 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | import './components.js'; 2 | import './routes.js'; 3 | 4 | import './settings/collection.js'; 5 | 6 | import './emails/collection.js'; 7 | 8 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/modules/permissions.js: -------------------------------------------------------------------------------- 1 | export const readPermissions = ['guests', 'members']; 2 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/modules/settings/collection.js: -------------------------------------------------------------------------------- 1 | import { createCollection } from 'meteor/vulcan:lib'; 2 | import schema from './schema.js'; 3 | 4 | const Settings = createCollection({ 5 | 6 | collectionName: 'Settings', 7 | 8 | typeName: 'Setting', 9 | 10 | schema, 11 | 12 | resolvers: null, 13 | 14 | mutations: null, 15 | 16 | }); 17 | 18 | 19 | export default Settings; 20 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/modules/settings/schema.js: -------------------------------------------------------------------------------- 1 | import { readPermissions } from "../permissions"; 2 | 3 | const schema = { 4 | 5 | name: { 6 | label: 'Name', 7 | type: String, 8 | canRead: readPermissions, 9 | }, 10 | 11 | value: { 12 | label: 'Value', 13 | type: Object, 14 | canRead: readPermissions, 15 | }, 16 | 17 | defaultValue: { 18 | label: 'Default Value', 19 | type: Object, 20 | canRead: readPermissions, 21 | }, 22 | 23 | isPublic: { 24 | label: 'Public', 25 | type: Boolean, 26 | canRead: readPermissions, 27 | }, 28 | 29 | description: { 30 | label: 'Description', 31 | type: String, 32 | canRead: readPermissions, 33 | }, 34 | 35 | }; 36 | 37 | export default schema; 38 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/server/callbacks/collection.js: -------------------------------------------------------------------------------- 1 | import { extendCollection } from 'meteor/vulcan:lib'; 2 | import Callbacks from '../../modules/callbacks/collection'; 3 | import resolvers from './resolvers'; 4 | 5 | extendCollection(Callbacks, { 6 | 7 | resolvers, 8 | 9 | mutations: null, 10 | 11 | }); -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/server/callbacks/index.js: -------------------------------------------------------------------------------- 1 | export * from './collection'; 2 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/server/callbacks/resolvers.js: -------------------------------------------------------------------------------- 1 | import { CallbackHooks } from 'meteor/vulcan:lib'; 2 | 3 | const resolvers = { 4 | 5 | multi: { 6 | 7 | resolver(root, {terms = {}}, context, info) { 8 | return { results: CallbackHooks, totalCount: CallbackHooks.length }; 9 | }, 10 | 11 | }, 12 | 13 | }; 14 | 15 | export default resolvers; -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/server/database/index.js: -------------------------------------------------------------------------------- 1 | export * from './queries'; 2 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/server/database/queries.js: -------------------------------------------------------------------------------- 1 | import { Collections, Connectors, addGraphQLQuery, addGraphQLResolvers } from 'meteor/vulcan:lib'; 2 | 3 | const getDatabaseObject = async (root, { id }, context) => { 4 | let document; 5 | for (const collection of Collections) { 6 | try { 7 | // eslint-disable-next-line no-await-in-loop 8 | document = await Connectors.get(collection, { _id: id }); 9 | if (document) { 10 | return { collectionName: collection.options.collectionName, document }; 11 | } 12 | } catch (error) { 13 | // do nothing 14 | } 15 | } 16 | return null; 17 | }; 18 | 19 | addGraphQLQuery(`getDatabaseObject(id: String): JSON`); 20 | addGraphQLResolvers({ Query: { getDatabaseObject } }); 21 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/server/emails/collection.js: -------------------------------------------------------------------------------- 1 | import { extendCollection } from 'meteor/vulcan:lib'; 2 | import Emails from '../../modules/emails/collection'; 3 | import resolvers from './resolvers'; 4 | 5 | extendCollection(Emails, { 6 | 7 | resolvers, 8 | 9 | mutations: null, 10 | 11 | }); 12 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/server/emails/index.js: -------------------------------------------------------------------------------- 1 | export * from './collection'; 2 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/server/emails/resolvers.js: -------------------------------------------------------------------------------- 1 | import VulcanEmail from 'meteor/vulcan:email'; 2 | 3 | const resolvers = { 4 | multi: { 5 | resolver() { 6 | const results = Object.keys(VulcanEmail.emails).map(name => { 7 | const email = VulcanEmail.emails[name]; 8 | const subject = typeof email.subject === 'function' ? email.subject({}) : email.subject; 9 | return { ...email, subject, name }; 10 | }); 11 | return { results, totalCount: results.length }; 12 | }, 13 | }, 14 | }; 15 | 16 | export default resolvers; 17 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/server/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; 2 | export * from './callbacks'; 3 | export * from './settings'; 4 | export * from './emails'; 5 | export * from './database'; 6 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/server/settings/collection.js: -------------------------------------------------------------------------------- 1 | import { extendCollection } from 'meteor/vulcan:lib'; 2 | import Settings from '../../modules/settings/collection'; 3 | import resolvers from './resolvers'; 4 | 5 | extendCollection(Settings, { 6 | 7 | resolvers, 8 | 9 | mutations: null, 10 | 11 | }); -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/server/settings/index.js: -------------------------------------------------------------------------------- 1 | export * from './collection'; 2 | -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/server/settings/resolvers.js: -------------------------------------------------------------------------------- 1 | import { getAllSettings } from 'meteor/vulcan:lib'; 2 | 3 | const resolvers = { 4 | 5 | multi: { 6 | 7 | resolver(root, {terms = {}}, context, info) { 8 | const settings = getAllSettings(); 9 | return { results: settings, totalCount: settings.length }; 10 | }, 11 | 12 | }, 13 | 14 | }; 15 | 16 | export default resolvers; -------------------------------------------------------------------------------- /packages/vulcan-debug/lib/stylesheets/debug.scss: -------------------------------------------------------------------------------- 1 | .test-email{ 2 | position: relative; 3 | .spinner{ 4 | position: absolute; 5 | top: 0px; 6 | width: 100%; 7 | height: 100%; 8 | } 9 | } -------------------------------------------------------------------------------- /packages/vulcan-debug/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:debug', 3 | summary: 'Vulcan debug package', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | debugOnly: true, 7 | }); 8 | 9 | Package.onUse(function(api) { 10 | api.use([ 11 | 'vulcan:scss@4.12.0', 12 | 'dynamic-import@0.1.1', 13 | 14 | // Vulcan packages 15 | 16 | 'vulcan:lib@=1.16.9', 17 | 'vulcan:email@=1.16.9', 18 | ]); 19 | 20 | api.use(['vulcan:errors@=1.16.9']), ['server', 'client'], { weak: true }; 21 | 22 | api.addFiles(['lib/stylesheets/debug.scss'], ['client']); 23 | 24 | api.mainModule('lib/server/main.js', 'server'); 25 | api.mainModule('lib/client/main.js', 'client'); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/vulcan-email/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/vulcan-email/README.md: -------------------------------------------------------------------------------- 1 | Vulcan email package, used internally. -------------------------------------------------------------------------------- /packages/vulcan-email/lib/client/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; 2 | export { VulcanEmail as default } from '../modules/index.js'; 3 | -------------------------------------------------------------------------------- /packages/vulcan-email/lib/modules/fragments.js: -------------------------------------------------------------------------------- 1 | import { registerFragment } from 'meteor/vulcan:lib'; 2 | 3 | registerFragment(` 4 | fragment EmailFragment on EmailResponse { 5 | to 6 | from 7 | subject 8 | success 9 | error 10 | } 11 | `); 12 | -------------------------------------------------------------------------------- /packages/vulcan-email/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | export * from './fragments.js'; 2 | export * from './namespace.js'; 3 | -------------------------------------------------------------------------------- /packages/vulcan-email/lib/modules/namespace.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @summary Vulcan VulcanEmail namespace 3 | * @namespace VulcanEmail 4 | */ 5 | export const VulcanEmail = {}; 6 | 7 | VulcanEmail.emails = {}; 8 | 9 | VulcanEmail.addEmails = emails => { 10 | // copy over "path" to "testPath" for backwards compatibility 11 | Object.keys(emails).forEach(key => { 12 | emails[key].testPath = emails[key].testPath || emails[key].path; 13 | }); 14 | VulcanEmail.emails = Object.assign(VulcanEmail.emails, emails); 15 | }; 16 | 17 | export default VulcanEmail; 18 | -------------------------------------------------------------------------------- /packages/vulcan-email/lib/server/main.js: -------------------------------------------------------------------------------- 1 | export { VulcanEmail as default } from '../modules/index.js'; 2 | 3 | export * from './email.js'; 4 | export * from './mutations.js'; 5 | export * from './routes.js'; 6 | export * from './templates/index.js'; 7 | -------------------------------------------------------------------------------- /packages/vulcan-email/lib/server/templates/index.js: -------------------------------------------------------------------------------- 1 | import { addTemplates } from '../email.js'; 2 | 3 | addTemplates({ 4 | templateError: Assets.getText('lib/server/templates/template_error.handlebars'), 5 | }); 6 | -------------------------------------------------------------------------------- /packages/vulcan-email/lib/server/templates/template_error.handlebars: -------------------------------------------------------------------------------- 1 |

Template Error

2 |
The template engine encountered the following error:
3 |
{{error}}
-------------------------------------------------------------------------------- /packages/vulcan-email/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:email', 3 | summary: 'Vulcan email package', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:lib@=1.16.9']); 10 | 11 | api.mainModule('lib/server/main.js', 'server'); 12 | api.mainModule('lib/client/main.js', 'client'); 13 | 14 | api.addAssets(['lib/server/templates/template_error.handlebars'], ['server']); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/vulcan-embed/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/vulcan-embed/README.md: -------------------------------------------------------------------------------- 1 | ### Built-in 2 | 3 | Settings: 4 | 5 | ``` 6 | "embedProvider": "builtin", 7 | ``` 8 | 9 | ### Embedly 10 | 11 | Settings: 12 | 13 | ``` 14 | "embedProvider": "embedly", 15 | "embedly": { 16 | "apiKey": "123foo" 17 | }, 18 | ``` 19 | 20 | ### EmbedAPI 21 | 22 | Settings: 23 | 24 | ``` 25 | "embedProvider": "embedAPI", 26 | "embedAPI": { 27 | "apiKey": "123foo" 28 | }, 29 | ``` -------------------------------------------------------------------------------- /packages/vulcan-embed/lib/client/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; -------------------------------------------------------------------------------- /packages/vulcan-embed/lib/modules/embed.js: -------------------------------------------------------------------------------- 1 | import { registerSetting } from 'meteor/vulcan:core'; 2 | 3 | export const Embed = {}; 4 | 5 | registerSetting('thumbnailWidth', 400, 'Image thumbnails width'); 6 | registerSetting('thumbnailHeight', 300, 'Image thumbnails height'); -------------------------------------------------------------------------------- /packages/vulcan-embed/lib/modules/i18n.js: -------------------------------------------------------------------------------- 1 | import { addStrings } from 'meteor/vulcan:core'; 2 | 3 | addStrings('en', { 4 | 'embedurl.error_fetching_data': 'Sorry, we were not able to fetch metadata for this URL.' 5 | }); 6 | -------------------------------------------------------------------------------- /packages/vulcan-embed/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | export { EmbedURL } from '../components/EmbedURL.jsx'; 2 | 3 | import './i18n'; 4 | 5 | export * from './embed.js'; -------------------------------------------------------------------------------- /packages/vulcan-embed/lib/server/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; 2 | 3 | import './integrations/builtin.js'; 4 | import './integrations/embedly.js'; 5 | import './integrations/embedapi.js'; 6 | 7 | import './mutations.js'; -------------------------------------------------------------------------------- /packages/vulcan-embed/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:embed', 3 | summary: 'Vulcan Embed package', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['http@2.0.0', 'vulcan:core@=1.16.9', 'vulcan:scss@4.12.0']); 10 | 11 | api.addFiles(['lib/stylesheets/embedly.scss'], ['client']); 12 | 13 | api.mainModule('lib/client/main.js', 'client'); 14 | api.mainModule('lib/server/main.js', 'server'); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/vulcan-errors-sentry/README.md: -------------------------------------------------------------------------------- 1 | Vulcan error tracking adapter for Sentry. -------------------------------------------------------------------------------- /packages/vulcan-errors-sentry/lib/client/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index'; 2 | import './sentry-client.js'; -------------------------------------------------------------------------------- /packages/vulcan-errors-sentry/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | export * from './settings'; 2 | // import './logToRollbar'; 3 | -------------------------------------------------------------------------------- /packages/vulcan-errors-sentry/lib/modules/sentry.js: -------------------------------------------------------------------------------- 1 | export const getUserObject = currentUser => ({ 2 | id: currentUser._id, 3 | username: currentUser.displayName, 4 | email: currentUser.email, 5 | }); -------------------------------------------------------------------------------- /packages/vulcan-errors-sentry/lib/modules/settings.js: -------------------------------------------------------------------------------- 1 | import { registerSetting } from 'meteor/vulcan:core'; 2 | 3 | export const clientDSNSetting = 'sentry.clientDSN'; 4 | export const serverDSNSetting = 'sentry.serverDSN'; 5 | export const tokensUrl = 'https://sentry.io/onboarding/{account}/{project}/configure/node'; 6 | 7 | registerSetting(clientDSNSetting, null, `Sentry client DSN access token (from ${tokensUrl})`); 8 | registerSetting(serverDSNSetting, null, `Sentry client DSN access token (from ${tokensUrl})`); 9 | -------------------------------------------------------------------------------- /packages/vulcan-errors-sentry/lib/server/main.js: -------------------------------------------------------------------------------- 1 | import './sentry-server.js'; 2 | export * from '../modules/index'; 3 | -------------------------------------------------------------------------------- /packages/vulcan-errors-sentry/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:errors-sentry', 3 | summary: 'Vulcan Sentry error tracking package', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9', 'vulcan:users@=1.16.9', 'vulcan:errors@=1.16.9']); 10 | 11 | api.mainModule('lib/server/main.js', 'server'); 12 | api.mainModule('lib/client/main.js', 'client'); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/vulcan-errors/README.md: -------------------------------------------------------------------------------- 1 | Vulcan error tracking package. -------------------------------------------------------------------------------- /packages/vulcan-errors/lib/client/init.js: -------------------------------------------------------------------------------- 1 | import { addCallback } from 'meteor/vulcan:core'; 2 | import { initFunctions } from '../modules/index.js'; 3 | 4 | // on client, init function will be executed once App is ready 5 | export const addInitFunction = fn => { 6 | initFunctions.push(fn); 7 | }; 8 | 9 | function runInitFunctions(props) { 10 | initFunctions.forEach(f => { 11 | f(props); 12 | }); 13 | } 14 | addCallback('app.mounted', runInitFunctions); 15 | -------------------------------------------------------------------------------- /packages/vulcan-errors/lib/client/main.js: -------------------------------------------------------------------------------- 1 | export * from './init.js'; 2 | export * from '../modules/index.js'; -------------------------------------------------------------------------------- /packages/vulcan-errors/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | import '../components/ErrorsUserMonitor'; 2 | import '../components/ErrorCatcher'; 3 | export * from './errors.js'; -------------------------------------------------------------------------------- /packages/vulcan-errors/lib/server/init.js: -------------------------------------------------------------------------------- 1 | import { initFunctions } from '../modules/index.js'; 2 | 3 | export const addInitFunction = fn => { 4 | initFunctions.push(fn); // on server, this does nothing 5 | // on server, execute init function as soon as possible 6 | fn(); 7 | }; -------------------------------------------------------------------------------- /packages/vulcan-errors/lib/server/main.js: -------------------------------------------------------------------------------- 1 | export * from './init.js'; 2 | export * from '../modules/index.js'; 3 | -------------------------------------------------------------------------------- /packages/vulcan-errors/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:errors', 3 | summary: 'Vulcan error tracking package', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9']); 10 | 11 | api.mainModule('lib/server/main.js', 'server'); 12 | api.mainModule('lib/client/main.js', 'client'); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/vulcan-events-ga/README.md: -------------------------------------------------------------------------------- 1 | Vulcan events package, used internally. -------------------------------------------------------------------------------- /packages/vulcan-events-ga/lib/client/main.js: -------------------------------------------------------------------------------- 1 | import './ga.js'; 2 | export * from '../modules/index.js'; -------------------------------------------------------------------------------- /packages/vulcan-events-ga/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | import { registerSetting } from 'meteor/vulcan:core'; 2 | 3 | registerSetting('googleAnalytics.apiKey', null, 'Google Analytics ID'); 4 | -------------------------------------------------------------------------------- /packages/vulcan-events-ga/lib/server/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; 2 | -------------------------------------------------------------------------------- /packages/vulcan-events-ga/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:events-ga', 3 | summary: 'Vulcan Google Analytics event tracking package', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9', 'vulcan:events@=1.16.9']); 10 | 11 | api.mainModule('lib/server/main.js', 'server'); 12 | api.mainModule('lib/client/main.js', 'client'); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/vulcan-events-intercom/README.md: -------------------------------------------------------------------------------- 1 | Intercom package. 2 | 3 | ### Settings 4 | 5 | ``` 6 | { 7 | "public": { 8 | 9 | "intercom": { 10 | "appId": "123foo" 11 | } 12 | 13 | }, 14 | 15 | "intercom": { 16 | "accessToken": "456bar" 17 | } 18 | } 19 | ``` 20 | 21 | Requires installing the [react-intercom](https://github.com/nhagen/react-intercom) package (`npm install --save react-intercom`). -------------------------------------------------------------------------------- /packages/vulcan-events-intercom/lib/client/main.js: -------------------------------------------------------------------------------- 1 | import './intercom-client.js'; 2 | 3 | export * from '../modules/index.js'; -------------------------------------------------------------------------------- /packages/vulcan-events-intercom/lib/modules/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VulcanJS/Vulcan/b3e50d061f22e758cb1a7e3502883ebc1d70f68e/packages/vulcan-events-intercom/lib/modules/index.js -------------------------------------------------------------------------------- /packages/vulcan-events-intercom/lib/server/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; 2 | export * from './intercom-server.js'; 3 | -------------------------------------------------------------------------------- /packages/vulcan-events-intercom/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:events-intercom', 3 | summary: 'Vulcan Intercom integration package.', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9', 'vulcan:events@=1.16.9']); 10 | 11 | api.mainModule('lib/client/main.js', 'client'); 12 | api.mainModule('lib/server/main.js', 'server'); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/vulcan-events-internal/README.md: -------------------------------------------------------------------------------- 1 | Vulcan events package, used internally. -------------------------------------------------------------------------------- /packages/vulcan-events-internal/lib/client/internal-client.js: -------------------------------------------------------------------------------- 1 | import { addTrackFunction } from 'meteor/vulcan:events'; 2 | import { getApolloClient, getFragment, createClientTemplate } from 'meteor/vulcan:lib'; 3 | import gql from 'graphql-tag'; 4 | 5 | function trackInternal(eventName, eventProperties) { 6 | const apolloClient = getApolloClient(); 7 | 8 | const fragmentName = 'AnalyticsEventFragment'; 9 | const fragment = getFragment(fragmentName); 10 | 11 | const mutation = gql` 12 | ${createClientTemplate({ typeName: 'AnalyticsEvent', fragmentName })} 13 | ${fragment} 14 | `; 15 | 16 | const variables = { 17 | data: { 18 | name: eventName, 19 | properties: eventProperties, 20 | }, 21 | }; 22 | apolloClient.mutate({ mutation, variables }); 23 | } 24 | 25 | addTrackFunction(trackInternal); 26 | -------------------------------------------------------------------------------- /packages/vulcan-events-internal/lib/client/main.js: -------------------------------------------------------------------------------- 1 | import './internal-client.js'; 2 | 3 | export {default} from '../modules/index.js'; -------------------------------------------------------------------------------- /packages/vulcan-events-internal/lib/modules/collection.js: -------------------------------------------------------------------------------- 1 | import { createCollection, getDefaultMutations } from 'meteor/vulcan:core'; 2 | import schema from './schema.js'; 3 | import Users from 'meteor/vulcan:users'; 4 | 5 | const Events = createCollection({ 6 | collectionName: 'AnalyticsEvents', 7 | 8 | typeName: 'AnalyticsEvent', 9 | 10 | schema, 11 | 12 | mutations: { 13 | update: null, 14 | upsert: null, 15 | delete: null 16 | }, 17 | 18 | permissions: { 19 | canRead: ({ user: currentUser }) => { 20 | return Users.isAdmin(currentUser); 21 | }, 22 | canCreate: ['guests'], 23 | canUpdate: () => false, 24 | canDelete: () => false, 25 | }, 26 | }); 27 | 28 | export default Events; 29 | -------------------------------------------------------------------------------- /packages/vulcan-events-internal/lib/modules/fragments.js: -------------------------------------------------------------------------------- 1 | import { registerFragment } from 'meteor/vulcan:core'; 2 | 3 | registerFragment(/* GraphQL */` 4 | fragment AnalyticsEventFragment on AnalyticsEvent { 5 | __typename 6 | name 7 | createdAt 8 | userId 9 | description 10 | unique 11 | important 12 | properties 13 | user { 14 | _id 15 | displayName 16 | pagePath 17 | pageUrl 18 | } 19 | } 20 | `); -------------------------------------------------------------------------------- /packages/vulcan-events-internal/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | import Events from './collection.js'; 2 | 3 | import './fragments'; 4 | 5 | export default Events; -------------------------------------------------------------------------------- /packages/vulcan-events-internal/lib/server/internal-server.js: -------------------------------------------------------------------------------- 1 | import { addTrackFunction } from 'meteor/vulcan:events'; 2 | import { newMutation } from 'meteor/vulcan:lib'; 3 | import Events from '../modules/collection'; 4 | 5 | async function trackInternalServer(eventName, eventProperties, currentUser) { 6 | const document = { 7 | name: eventName, 8 | properties: eventProperties, 9 | }; 10 | return await newMutation({ 11 | collection: Events, 12 | document, 13 | currentUser, 14 | validate: false, 15 | context: {}, 16 | }); 17 | } 18 | 19 | addTrackFunction(trackInternalServer); 20 | -------------------------------------------------------------------------------- /packages/vulcan-events-internal/lib/server/main.js: -------------------------------------------------------------------------------- 1 | import './internal-server'; 2 | 3 | export {default} from '../modules/index.js'; -------------------------------------------------------------------------------- /packages/vulcan-events-internal/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:events-internal', 3 | summary: 'Vulcan internal event tracking package', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9', 'vulcan:events@=1.16.9']); 10 | 11 | api.mainModule('lib/server/main.js', 'server'); 12 | api.mainModule('lib/client/main.js', 'client'); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/vulcan-events-segment/README.md: -------------------------------------------------------------------------------- 1 | Vulcan events package, used internally. -------------------------------------------------------------------------------- /packages/vulcan-events-segment/lib/client/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index'; 2 | 3 | import './segment-client.js'; -------------------------------------------------------------------------------- /packages/vulcan-events-segment/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | import { registerSetting } from 'meteor/vulcan:core'; 2 | 3 | registerSetting('segment.clientKey', null, 'Segment client-side API key'); 4 | registerSetting('segment.serverKey', null, 'Segment server-side API key'); 5 | -------------------------------------------------------------------------------- /packages/vulcan-events-segment/lib/server/main.js: -------------------------------------------------------------------------------- 1 | // export * from '../modules/index'; 2 | 3 | export * from './segment-server.js'; -------------------------------------------------------------------------------- /packages/vulcan-events-segment/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:events-segment', 3 | summary: 'Vulcan Segment', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9', 'vulcan:events@=1.16.9']); 10 | 11 | api.mainModule('lib/server/main.js', 'server'); 12 | api.mainModule('lib/client/main.js', 'client'); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/vulcan-events/README.md: -------------------------------------------------------------------------------- 1 | Vulcan events package, used internally. -------------------------------------------------------------------------------- /packages/vulcan-events/lib/client/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; -------------------------------------------------------------------------------- /packages/vulcan-events/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | export * from './events'; -------------------------------------------------------------------------------- /packages/vulcan-events/lib/server/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; -------------------------------------------------------------------------------- /packages/vulcan-events/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:events', 3 | summary: 'Vulcan event tracking package', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9']); 10 | 11 | api.mainModule('lib/server/main.js', 'server'); 12 | api.mainModule('lib/client/main.js', 'client'); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/vulcan-forms-tags/README.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | 1. Add `vulcan:forms-tags` to your `.meteor/packages` file. 4 | 2. Add `vulcan:forms-tags` to your custom package's dependencies in `package.js`. 5 | 3. Add the [react-tag-input](https://www.npmjs.com/package/react-tag-input) NPM package with `npm install react-tag-input --save`. 6 | 4. In your code, `import Tags from 'meteor/vulcan:forms-tags'` and then set `control: Tags` on a custom field. -------------------------------------------------------------------------------- /packages/vulcan-forms-tags/lib/export.js: -------------------------------------------------------------------------------- 1 | import Tags from './components/Tags.jsx'; 2 | 3 | export default Tags; 4 | -------------------------------------------------------------------------------- /packages/vulcan-forms-tags/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:forms-tags', 3 | summary: 'Vulcan tag input package', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9', 'vulcan:forms@=1.16.9']); 10 | 11 | api.mainModule('lib/export.js', ['client', 'server']); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/vulcan-forms-upload/lib/i18n.js: -------------------------------------------------------------------------------- 1 | import { addStrings } from 'meteor/vulcan:core'; 2 | 3 | addStrings('en', { 4 | 'upload.prompt': 'Drop an image here, or click to select an image to upload.', 5 | 'upload.uploading': 'Uploading…' 6 | }); -------------------------------------------------------------------------------- /packages/vulcan-forms-upload/lib/modules.js: -------------------------------------------------------------------------------- 1 | import Upload from './Upload.jsx'; 2 | 3 | import './i18n.js'; 4 | 5 | export default Upload; 6 | -------------------------------------------------------------------------------- /packages/vulcan-forms-upload/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:forms-upload', 3 | summary: 'Vulcan package extending vulcan:forms to upload images to Cloudinary from a drop zone.', 4 | version: '1.16.9', 5 | git: 'https://github.com/xavcz/nova-forms-upload.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9', 'vulcan:forms@=1.16.9', 'vulcan:scss@4.12.0']); 10 | 11 | api.addFiles(['lib/Upload.scss'], 'client'); 12 | 13 | api.mainModule('lib/modules.js', ['client', 'server']); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/vulcan-forms/README.md: -------------------------------------------------------------------------------- 1 | # Vulcan Forms 2 | 3 | This package provides a `SmartForm` component. 4 | -------------------------------------------------------------------------------- /packages/vulcan-forms/lib/client/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; -------------------------------------------------------------------------------- /packages/vulcan-forms/lib/components/FieldErrors.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { registerComponent, Components } from 'meteor/vulcan:core'; 4 | 5 | const FieldErrors = ({ errors }) => ( 6 |
    7 | {errors.map((error, index) => ( 8 |
  • 9 | 10 |
  • 11 | ))} 12 |
13 | ); 14 | FieldErrors.propTypes = { 15 | errors: PropTypes.array.isRequired 16 | }; 17 | registerComponent('FieldErrors', FieldErrors); 18 | -------------------------------------------------------------------------------- /packages/vulcan-forms/lib/components/FormElement.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { registerComponent } from 'meteor/vulcan:core'; 3 | 4 | // this component receives a ref, so it must be a class component 5 | class FormElement extends React.Component { 6 | render(){ 7 | const { children, ...otherProps } = this.props; 8 | return
{children}
; 9 | } 10 | } 11 | registerComponent({ 12 | name:'FormElement', 13 | component: FormElement 14 | }); -------------------------------------------------------------------------------- /packages/vulcan-forms/lib/components/FormLayout.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { registerComponent } from 'meteor/vulcan:core'; 4 | 5 | const FormLayout = ({ FormComponents, commonProps, formProps, errorProps, repeatErrors, submitProps, children }) => ( 6 | 7 | 8 | 9 | {children} 10 | 11 | {repeatErrors && } 12 | 13 | 14 | 15 | ); 16 | 17 | export default FormLayout; 18 | 19 | registerComponent('FormLayout', FormLayout); 20 | -------------------------------------------------------------------------------- /packages/vulcan-forms/lib/components/FormNestedDivider.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { registerComponent } from 'meteor/vulcan:core'; 4 | 5 | const FormNestedDivider = ({ label, addItem }) =>
; 6 | 7 | FormNestedDivider.propTypes = { 8 | label: PropTypes.string, 9 | addItem: PropTypes.func, 10 | }; 11 | 12 | registerComponent('FormNestedDivider', FormNestedDivider); 13 | -------------------------------------------------------------------------------- /packages/vulcan-forms/lib/components/FormOptionLabel.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { registerComponent } from 'meteor/vulcan:core'; 3 | 4 | const FormOptionLabel = ({ option }) => { 5 | const { label } = option; 6 | return {label}; 7 | }; 8 | 9 | registerComponent('FormOptionLabel', FormOptionLabel); 10 | -------------------------------------------------------------------------------- /packages/vulcan-forms/lib/modules/components.js: -------------------------------------------------------------------------------- 1 | import '../components/FieldErrors.jsx'; 2 | import '../components/FormElement.jsx'; 3 | import '../components/FormErrors.jsx'; 4 | import '../components/FormError.jsx'; 5 | import '../components/FormComponent.jsx'; 6 | import '../components/FormNestedArray.jsx'; 7 | import '../components/FormNestedArrayLayout.jsx'; 8 | import '../components/FormNestedDivider.jsx'; 9 | import '../components/FormNestedObject.jsx'; 10 | import '../components/FormNestedItem.jsx'; 11 | import '../components/FormIntl.jsx'; 12 | import '../components/FormGroup.jsx'; 13 | import '../components/FormSubmit.jsx'; 14 | import '../components/FormWrapper.jsx'; 15 | import '../components/Form.jsx'; 16 | import '../components/FormLayout.jsx'; 17 | import '../components/FormComponentLoader.jsx'; 18 | import '../components/FormOptionLabel.jsx'; 19 | import '../components/FormClear.jsx'; 20 | -------------------------------------------------------------------------------- /packages/vulcan-forms/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | import { registerComponent, registerSetting } from 'meteor/vulcan:core'; 2 | 3 | registerSetting('forms.warnUnsavedChanges', false, 'Warn user about unsaved changes before leaving route', true); 4 | 5 | import './components.js'; 6 | 7 | export * from './utils'; 8 | export { default as FormWrapper } from '../components/FormWrapper.jsx'; 9 | -------------------------------------------------------------------------------- /packages/vulcan-forms/lib/server/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; -------------------------------------------------------------------------------- /packages/vulcan-forms/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:forms', 3 | summary: 'Form containers for React', 4 | version: '1.16.9', 5 | git: 'https://github.com/meteor-utilities/react-form-containers.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9']); 10 | 11 | api.mainModule('lib/client/main.js', ['client']); 12 | api.mainModule('lib/server/main.js', ['server']); 13 | }); 14 | 15 | Package.onTest(function(api) { 16 | api.use(['ecmascript', 'meteortesting:mocha', 'vulcan:test', 'vulcan:forms', 'vulcan:ui-bootstrap']); 17 | api.mainModule('./test/index.js'); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/vulcan-forms/test/index.js: -------------------------------------------------------------------------------- 1 | import './schema_utils.test.js'; 2 | import './formFragments.test'; 3 | //import './components.test.js'; 4 | import './Form.test.js'; 5 | import './FormComponent.test.js'; 6 | import './FormNestedObject.test.js'; 7 | import './FormNestedArray.test.js'; 8 | -------------------------------------------------------------------------------- /packages/vulcan-forms/test/package.test.js: -------------------------------------------------------------------------------- 1 | import FormWrapper from 'meteor/vulcan:forms'; 2 | import expect from 'expect'; 3 | describe('vulcan:forms', function () { 4 | it.skip('initialize', function () { 5 | expect(FormWrapper.name).toEqual('GraphQL'); 6 | }); 7 | }); -------------------------------------------------------------------------------- /packages/vulcan-i18n-en-us/README.md: -------------------------------------------------------------------------------- 1 | Vulcan i18n en_US package. -------------------------------------------------------------------------------- /packages/vulcan-i18n-en-us/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:i18n-en-us', 3 | summary: 'Vulcan i18n package (en_US)', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9']); 10 | 11 | api.addFiles(['lib/en_US.js'], ['client', 'server']); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/vulcan-i18n-es-es/README.md: -------------------------------------------------------------------------------- 1 | Vulcan i18n es_ES package. -------------------------------------------------------------------------------- /packages/vulcan-i18n-es-es/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:i18n-es-es', 3 | summary: 'Vulcan i18n package (es_ES)', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9']); 10 | 11 | api.addFiles(['lib/es_ES.js'], ['client', 'server']); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/vulcan-i18n-fa-ir/README.md: -------------------------------------------------------------------------------- 1 | Vulcan i18n fa_IR package. -------------------------------------------------------------------------------- /packages/vulcan-i18n-fa-ir/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:i18n-fa-ir', 3 | summary: 'Vulcan i18n package (fa_IR)', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9']); 10 | 11 | api.addFiles(['lib/fa_IR.js'], ['client', 'server']); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/vulcan-i18n-fr-fr/README.md: -------------------------------------------------------------------------------- 1 | Vulcan i18n fr_FR package. 2 | -------------------------------------------------------------------------------- /packages/vulcan-i18n-fr-fr/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:i18n-fr-fr', 3 | summary: 'Vulcan i18n package (fr_FR)', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan.git', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:core@=1.16.9']); 10 | 11 | api.addFiles(['lib/fr_FR.js'], ['client', 'server']); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/vulcan-i18n/README.md: -------------------------------------------------------------------------------- 1 | Vulcan i18n package. -------------------------------------------------------------------------------- /packages/vulcan-i18n/lib/client/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; 2 | -------------------------------------------------------------------------------- /packages/vulcan-i18n/lib/modules/context.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const IntlContext = React.createContext({ 4 | locale: '', 5 | key: '', 6 | messages: [], 7 | }); 8 | 9 | export default IntlContext; 10 | -------------------------------------------------------------------------------- /packages/vulcan-i18n/lib/modules/index.js: -------------------------------------------------------------------------------- 1 | import { registerSetting } from 'meteor/vulcan:lib'; 2 | 3 | registerSetting('locale', 'en-US', 'Your app\'s locale (“en”, “fr”, etc.)'); 4 | 5 | export { default as FormattedMessage } from './message.js'; 6 | export { intlShape } from './shape.js'; 7 | export { default as IntlProvider } from './provider.js'; 8 | export { default as IntlContext } from './context.js'; 9 | export { default as useIntl } from './useIntl.js'; 10 | -------------------------------------------------------------------------------- /packages/vulcan-i18n/lib/modules/useIntl.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import IntlContext from './context'; 3 | 4 | export default function useIntl() { 5 | const intl = useContext(IntlContext); 6 | return intl; 7 | } 8 | -------------------------------------------------------------------------------- /packages/vulcan-i18n/lib/server/graphql.js: -------------------------------------------------------------------------------- 1 | import { addGraphQLQuery, addGraphQLResolvers, addGraphQLSchema, Locales, getLocale, getStrings } from 'meteor/vulcan:lib'; 2 | 3 | // const localEnum = `enum LocaleID { 4 | // ${Locales.map(locale => locale.id).join('/n')} 5 | // }`; 6 | 7 | // console.log(Locales) 8 | // console.log(localEnum) 9 | // addGraphQLSchema(localEnum); 10 | 11 | const localeType = `type Locale { 12 | id: String, 13 | label: String 14 | dynamic: Boolean 15 | strings: JSON 16 | }`; 17 | 18 | addGraphQLSchema(localeType); 19 | 20 | const locale = async (root, { localeId }, context) => { 21 | const locale = getLocale(localeId); 22 | const strings = getStrings(localeId); 23 | const localeObject = { ...locale, strings }; 24 | return localeObject; 25 | }; 26 | 27 | addGraphQLQuery('locale(localeId: String): Locale'); 28 | addGraphQLResolvers({ Query: { locale } }); 29 | -------------------------------------------------------------------------------- /packages/vulcan-i18n/lib/server/main.js: -------------------------------------------------------------------------------- 1 | export * from '../modules/index.js'; 2 | 3 | import './graphql.js'; -------------------------------------------------------------------------------- /packages/vulcan-i18n/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'vulcan:i18n', 3 | summary: 'i18n client polyfill', 4 | version: '1.16.9', 5 | git: 'https://github.com/VulcanJS/Vulcan', 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use(['vulcan:lib@=1.16.9']); 10 | 11 | api.mainModule('lib/server/main.js', 'server'); 12 | api.mainModule('lib/client/main.js', 'client'); 13 | }); 14 | 15 | Package.onTest(function(api) { 16 | api.use(['ecmascript', 'meteortesting:mocha', 'vulcan:test', 'vulcan:i18n']); 17 | api.mainModule('./test/index.js'); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/vulcan-i18n/test/index.js: -------------------------------------------------------------------------------- 1 | import './provider.test.js'; 2 | -------------------------------------------------------------------------------- /packages/vulcan-lib/README.md: -------------------------------------------------------------------------------- 1 | Vulcan libraries package, used internally. -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/client/apollo-client/cache.js: -------------------------------------------------------------------------------- 1 | import { InMemoryCache } from '@apollo/client'; 2 | import { getFragmentMatcher } from '../../modules/fragment_matcher'; 3 | 4 | const createCache = () => new InMemoryCache({ fragmentMatcher: getFragmentMatcher() }) 5 | //ssr 6 | .restore(window.__APOLLO_STATE__); 7 | 8 | export default createCache; 9 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/client/apollo-client/index.js: -------------------------------------------------------------------------------- 1 | export * from './apolloClient'; 2 | export * from './links/registerLinks'; 3 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/client/apollo-client/links/error.js: -------------------------------------------------------------------------------- 1 | import { onError } from '@apollo/client/link/error'; 2 | 3 | const locationsToStr = (locations=[]) => locations.map(({column, line}) => `line ${line}, col ${column}`).join(';'); 4 | const errorLink = onError(error => { 5 | const { graphQLErrors, networkError } = error; 6 | if (graphQLErrors) 7 | graphQLErrors.map(({ message, locations, path }) => { 8 | // eslint-disable-next-line no-console 9 | console.log(`[GraphQL error]: Message: ${message}, Location: ${locationsToStr(locations)}, Path: ${path}`); 10 | }); 11 | if (networkError) { 12 | // eslint-disable-next-line no-console 13 | console.log(`[${networkError.statusCode} ${networkError.response?.statusText}]: ${networkError.message}`); 14 | } 15 | }); 16 | 17 | export default errorLink; 18 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/client/apollo-client/links/http.js: -------------------------------------------------------------------------------- 1 | import { HttpLink } from '@apollo/client'; 2 | 3 | const httpLink = new HttpLink({ 4 | uri: '/graphql', 5 | credentials: 'same-origin', 6 | }); 7 | export default httpLink; 8 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/client/apollo-client/links/meteor.js: -------------------------------------------------------------------------------- 1 | import { MeteorAccountsLink } from 'meteor/apollo'; 2 | 3 | const meteorAccountsLink = new MeteorAccountsLink(); 4 | export default meteorAccountsLink; 5 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/client/apollo-client/links/registerLinks.js: -------------------------------------------------------------------------------- 1 | const terminatingLinksRegistry = []; 2 | const linksRegistry = []; 3 | 4 | // register one or more links 5 | export const registerLink = (link) => { 6 | const links = Array.isArray(link) ? link : [link]; 7 | linksRegistry.unshift(...links); 8 | }; 9 | 10 | export const registerTerminatingLink = (link) => { 11 | const links = Array.isArray(link) ? link : [link]; 12 | terminatingLinksRegistry.push(...links); 13 | }; 14 | 15 | 16 | 17 | export const getLinks = () => linksRegistry; 18 | export const getTerminatingLinks = () => terminatingLinksRegistry; 19 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/client/connectors.js: -------------------------------------------------------------------------------- 1 | // Mock exports so resolver/mutation build doesn't fail client side 2 | export const DatabaseConnectors = null; 3 | export const Connectors = null; -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/client/errors.js: -------------------------------------------------------------------------------- 1 | // mock apollo server errors 2 | export const throwError = (error) => { if (error) throw new Error(error.id, error); }; -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/client/main.js: -------------------------------------------------------------------------------- 1 | import './auth.js'; 2 | 3 | export * from '../modules/index.js'; 4 | export * from './inject_data.js'; 5 | 6 | export * from './apollo-client'; 7 | 8 | // createCollection, resolvers and mutations mocks 9 | // avoid warnings when building with webpack 10 | export * from './connectors'; 11 | export * from './mock'; 12 | export * from './errors'; -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/client/mock.js: -------------------------------------------------------------------------------- 1 | // mock mutators 2 | export const createMutator = null; 3 | export const updateMutator = null; 4 | export const deleteMutator = null; 5 | 6 | // mock default mutations and resolvers 7 | export const getDefaultResolvers = () => ({}); 8 | export const getDefaultMutations = () => ({}); -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/modules/admin.js: -------------------------------------------------------------------------------- 1 | export let AdminColumns = []; 2 | 3 | export const addAdminColumn = columnOrColumns => { 4 | if (Array.isArray(columnOrColumns)) { 5 | AdminColumns = AdminColumns.concat(columnOrColumns); 6 | } else { 7 | AdminColumns.push(columnOrColumns); 8 | } 9 | }; -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/modules/apollo-common/index.js: -------------------------------------------------------------------------------- 1 | export * from './links/state'; 2 | import './settings'; 3 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/modules/apollo-common/settings.js: -------------------------------------------------------------------------------- 1 | import { registerSetting } from '../settings'; 2 | 3 | registerSetting('apolloSsr.disable', false, 'Disable Server Side Rendering'); 4 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/modules/findbyids.js: -------------------------------------------------------------------------------- 1 | import { Connectors } from '../server/connectors.js'; 2 | 3 | /** 4 | * @summary Find by ids, for DataLoader, inspired by https://github.com/tmeasday/mongo-find-by-ids/blob/master/index.js 5 | */ 6 | const findByIds = async function(collection, ids, context) { 7 | 8 | // get documents 9 | const documents = await Connectors.find(collection, { _id: { $in: ids } }); 10 | 11 | // order documents in the same order as the ids passed as argument 12 | const orderedDocuments = ids.map(id => _.findWhere(documents, {_id: id})); 13 | 14 | return orderedDocuments; 15 | }; 16 | 17 | export default findByIds; -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/modules/fragment_matcher.js: -------------------------------------------------------------------------------- 1 | import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory'; 2 | 3 | export const FragmentMatcher = []; 4 | 5 | export const addToFragmentMatcher = fragmentMatcher => { 6 | FragmentMatcher.push(fragmentMatcher); 7 | }; 8 | 9 | export const getFragmentMatcher = () => { 10 | const fm = { 11 | introspectionQueryResultData: { 12 | __schema: { 13 | types: FragmentMatcher, 14 | }, 15 | } 16 | }; 17 | return new IntrospectionFragmentMatcher(fm); 18 | }; 19 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/modules/graphql/index.js: -------------------------------------------------------------------------------- 1 | export * from './defaultFragment'; 2 | export * from './utils'; 3 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/modules/graphql_templates/index.js: -------------------------------------------------------------------------------- 1 | export * from './types.js'; 2 | export * from './queries.js'; 3 | export * from './mutations.js'; 4 | export * from './filtering.js'; 5 | export * from './other.js'; 6 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/modules/headtags.js: -------------------------------------------------------------------------------- 1 | export const Head = { 2 | meta: [], 3 | link: [], 4 | script: [], 5 | components: [], 6 | }; 7 | 8 | export const removeFromHeadTags = (type, name)=>{ 9 | Head[type] = Head[type].filter((tag)=>{ 10 | return (!tag.name || tag.name && tag.name !== name); 11 | }); 12 | 13 | return Head; 14 | }; 15 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/modules/random_id.js: -------------------------------------------------------------------------------- 1 | export const Random = {}; 2 | import range from 'lodash/range'; 3 | import sample from 'lodash/sample'; 4 | 5 | Random.id = function(length = 17) { 6 | const chars = '23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz'; 7 | return range(length) 8 | .map(() => sample(chars)) 9 | .join(''); 10 | }; 11 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/modules/startup.js: -------------------------------------------------------------------------------- 1 | import { runCallbacks } from './callbacks'; 2 | 3 | Meteor.startup(() => { 4 | runCallbacks('app.startup'); 5 | }); -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/server/apollo-server/engine.js: -------------------------------------------------------------------------------- 1 | import { getSetting } from '../../modules/settings.js'; 2 | // @see https://www.apollographql.com/docs/apollo-server/api/apollo-server.html#EngineReportingOptions 3 | 4 | let engineConfigObject = getSetting('apolloEngine'); 5 | 6 | if (!engineConfigObject || !engineConfigObject.apiKey) { 7 | engineConfigObject = { 8 | apiKey: process.env.ENGINE_API_KEY, 9 | schemaTag: process.env.ENGINE_SCHEMA_TAG 10 | }; 11 | } 12 | 13 | export const engineConfig = engineConfigObject && engineConfigObject.apiKey ? engineConfigObject : undefined; 14 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/server/apollo-server/index.js: -------------------------------------------------------------------------------- 1 | export * from './apollo_server'; 2 | export * from './settings'; 3 | export * from './context.js'; 4 | 5 | export { default as initGraphQL } from './initGraphQL'; 6 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/server/apollo-server/startup.js: -------------------------------------------------------------------------------- 1 | const { onStart } = require('./apollo_server'); 2 | // createApolloServer when server startup 3 | Meteor.startup(onStart); 4 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/server/apollo-server/voyager.js: -------------------------------------------------------------------------------- 1 | export const getVoyagerConfig = currentConfig => ({ 2 | endpointUrl: currentConfig.path, 3 | }); 4 | export default getVoyagerConfig; 5 | -------------------------------------------------------------------------------- /packages/vulcan-lib/lib/server/apollo-ssr/components/ApolloState.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Component that serialize the Apollo client state 3 | * 4 | * The client can then deserialize it and avoid unecessary requests 5 | */ 6 | import React from 'react'; 7 | 8 | const ApolloState = ({ initialState }) => ( 9 |