├── .codeclimate.yml ├── .eslintrc.js ├── .github ├── FUNDING.yml ├── contributing.md ├── issue_template.md ├── pull_request_template.md └── workflows │ ├── nodejs.yml │ └── update-dependencies.yml ├── .gitignore ├── .mocharc.json ├── .nycrc ├── .prettierrc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── docs ├── .vitepress │ ├── components.d.ts │ ├── components │ │ ├── Badges.vue │ │ ├── BlockQuote.vue │ │ ├── Contributors.vue │ │ ├── DatabaseBlock.vue │ │ ├── DatabaseSelect.vue │ │ ├── FeaturesList.vue │ │ ├── LanguageBlock.vue │ │ ├── LanguageSelect.vue │ │ ├── ListItem.vue │ │ ├── Logo.vue │ │ ├── Select.vue │ │ ├── Tab.vue │ │ ├── Tabs.vue │ │ └── TeamMember.vue │ ├── config.nav.ts │ ├── config.sidebar.ts │ ├── config.ts │ ├── meta.ts │ ├── scripts │ │ └── assets.ts │ ├── style │ │ ├── element-plus.scss │ │ ├── main.postcss │ │ └── vars.postcss │ ├── theme │ │ ├── FeathersLayout.vue │ │ ├── index.ts │ │ ├── pwa.ts │ │ └── store.ts │ └── vite-env.d.ts ├── api │ ├── application.md │ ├── assets │ │ └── architecture-overview.svg │ ├── authentication │ │ ├── client.md │ │ ├── hook.md │ │ ├── index.md │ │ ├── jwt.md │ │ ├── local.md │ │ ├── oauth.md │ │ ├── service.md │ │ └── strategy.md │ ├── channels.md │ ├── client.md │ ├── client │ │ ├── rest.md │ │ └── socketio.md │ ├── configuration.md │ ├── databases │ │ ├── adapters.md │ │ ├── common.md │ │ ├── knex.md │ │ ├── memory.md │ │ ├── mongodb.md │ │ └── querying.md │ ├── errors.md │ ├── events.md │ ├── express.md │ ├── hooks.md │ ├── index.md │ ├── koa.md │ ├── schema │ │ ├── index.md │ │ ├── resolvers.md │ │ ├── schema.md │ │ ├── typebox.md │ │ └── validators.md │ ├── services.md │ └── socketio.md ├── auto-imports.d.ts ├── comparison.md ├── components │ ├── CTAButton.vue │ ├── Footer.vue │ ├── FooterList.vue │ ├── HomeCTATextSection.vue │ ├── HomeCreateFirstApp.vue │ ├── HomeFeature1.vue │ ├── HomeFeature1Content.vue │ ├── HomeFeature2.vue │ ├── HomeFeature2Content.vue │ ├── HomeFeatureGrid.vue │ ├── HomeFeatureGridCard.vue │ ├── HomeHero.vue │ ├── HomeIndustryPartners.vue │ └── HomeQuickStart.vue ├── cookbook │ ├── assets │ │ ├── auth0-app.png │ │ └── facebook-app.png │ ├── authentication │ │ ├── _discord.md │ │ ├── anonymous.md │ │ ├── apiKey.md │ │ ├── auth0.md │ │ ├── facebook.md │ │ ├── firebase.md │ │ ├── google.md │ │ ├── revoke-jwt.md │ │ └── stateless.md │ ├── deploy │ │ └── docker.md │ ├── express │ │ ├── file-uploading.md │ │ └── view-engine.md │ ├── general │ │ ├── client-test.md │ │ └── scaling.md │ └── index.md ├── ecosystem │ ├── PackageCard.vue │ ├── Packages.vue │ ├── helpers.ts │ ├── index.md │ ├── types.ts │ └── useQuery.ts ├── feathers-vs-firebase.md ├── feathers-vs-loopback.md ├── feathers-vs-meteor.md ├── feathers-vs-nest.md ├── feathers-vs-sails.md ├── guides │ ├── basics │ │ ├── assets │ │ │ ├── feathers-chat.png │ │ │ ├── generate-app-mongodb.png │ │ │ ├── generate-app.png │ │ │ ├── generate-authentication-mongodb.png │ │ │ ├── generate-authentication.png │ │ │ ├── generate-hook.png │ │ │ ├── generate-service-mongodb.png │ │ │ ├── generate-service.png │ │ │ └── github-app.png │ │ ├── authentication.md │ │ ├── generator.md │ │ ├── hooks.md │ │ ├── login.md │ │ ├── schemas.md │ │ ├── services.md │ │ ├── starting.md │ │ └── testing.md │ ├── cli │ │ ├── app.md │ │ ├── app.test.md │ │ ├── authentication.md │ │ ├── channels.md │ │ ├── client.md │ │ ├── client.test.md │ │ ├── configuration.md │ │ ├── custom-environment-variables.md │ │ ├── databases.md │ │ ├── declarations.md │ │ ├── default.json.md │ │ ├── hook.md │ │ ├── index.md │ │ ├── knexfile.md │ │ ├── log-error.md │ │ ├── logger.md │ │ ├── package.md │ │ ├── prettierrc.md │ │ ├── service.class.md │ │ ├── service.md │ │ ├── service.schemas.md │ │ ├── service.shared.md │ │ ├── service.test.md │ │ ├── tsconfig.md │ │ └── validators.md │ ├── frameworks.md │ ├── frontend │ │ └── javascript.md │ ├── index.md │ ├── migrating.md │ ├── security.md │ └── whats-new.md ├── help │ ├── faq.md │ └── index.md ├── index.md ├── package.json ├── public │ ├── _headers │ ├── _redirects │ ├── apple-touch-icon.png │ ├── bg.png │ ├── favicon.ico │ ├── feathers-chat.css │ ├── feathersjs-colored.svg │ ├── feathersjs.svg │ ├── img │ │ ├── client-bird.svg │ │ ├── coding-bird.svg │ │ ├── favicon.ico │ │ ├── favicon.png │ │ ├── feathers-isotype.svg │ │ ├── feathers-logo-horizontal-inverted.svg │ │ ├── feathers-logo-horizontal.svg │ │ ├── feathers-logo-wide.png │ │ ├── feature-icons │ │ │ ├── Fast_Icon.svg │ │ │ ├── Flexible_Icon.svg │ │ │ └── Universal_Icon.svg │ │ ├── illustration │ │ │ ├── 1.front-layer.svg │ │ │ ├── 2.birds-layer.svg │ │ │ ├── 3.trees-layer.svg │ │ │ ├── 4.tree-house-layer.svg │ │ │ ├── 5.land-layer.svg │ │ │ ├── 6.green-mountains-layer.svg │ │ │ ├── 7.rocky-mountains-layer.svg │ │ │ ├── 8.clouds-layer.svg │ │ │ ├── 9.sky-layer.svg │ │ │ ├── Final_Header_Illustration.jpg │ │ │ ├── Final_Header_Illustration.svg │ │ │ ├── birds-hero-day.svg │ │ │ ├── birds-hero-night.svg │ │ │ ├── combined-centered.jpg │ │ │ ├── combined-night-centered.jpg │ │ │ ├── combined-night.jpg │ │ │ ├── combined-night.svg │ │ │ ├── combined.jpg │ │ │ ├── combined.svg │ │ │ ├── hero-day-bg.svg │ │ │ ├── hero-day-foreground.svg │ │ │ ├── hero-day-sun-solo.svg │ │ │ ├── hero-day-sun.svg │ │ │ ├── hero-night-bg.svg │ │ │ ├── hero-night-foreground.svg │ │ │ ├── hero-night-moon-solo.svg │ │ │ └── hero-night-moon.svg │ │ ├── isotype-inverted.svg │ │ ├── main-character-bench.svg │ │ ├── main-character-coding.svg │ │ ├── main-character-starting.svg │ │ ├── partners │ │ │ ├── 1.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ └── 5.jpg │ │ ├── professor-bird-server.svg │ │ ├── server-bird.svg │ │ └── tutorial │ │ │ ├── docsVersionDropdown.png │ │ │ └── localeDropdown.png │ ├── logo-shadow.svg │ ├── logo.svg │ ├── netlify.svg │ ├── og.png │ ├── pwa-192x192.png │ ├── pwa-512x512.png │ └── robots.txt ├── tsconfig.json └── vite.config.ts ├── generators ├── package.ts └── package │ ├── index.tpl.ts │ ├── license.tpl.ts │ ├── package.json.tpl.ts │ ├── readme.md.tpl.ts │ ├── test.tpl.ts │ └── tsconfig.json.tpl.ts ├── lerna.json ├── package-lock.json ├── package.json ├── packages ├── adapter-commons │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── declarations.ts │ │ ├── index.ts │ │ ├── query.ts │ │ ├── service.ts │ │ └── sort.ts │ ├── test │ │ ├── commons.test.ts │ │ ├── fixture.ts │ │ ├── query.test.ts │ │ ├── service.test.ts │ │ └── sort.test.ts │ └── tsconfig.json ├── adapter-tests │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── basic.ts │ │ ├── declarations.ts │ │ ├── index.ts │ │ ├── methods.ts │ │ └── syntax.ts │ ├── test │ │ └── index.test.ts │ └── tsconfig.json ├── authentication-client │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── core.ts │ │ ├── hooks │ │ │ ├── authentication.ts │ │ │ ├── index.ts │ │ │ └── populate-header.ts │ │ ├── index.ts │ │ └── storage.ts │ ├── test │ │ ├── index.test.ts │ │ └── integration │ │ │ ├── commons.ts │ │ │ ├── express.test.ts │ │ │ ├── fixture.ts │ │ │ └── socketio.test.ts │ └── tsconfig.json ├── authentication-local │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── hooks │ │ │ ├── hash-password.ts │ │ │ └── protect.ts │ │ ├── index.ts │ │ └── strategy.ts │ ├── test │ │ ├── fixture.ts │ │ ├── hooks │ │ │ ├── hash-password.test.ts │ │ │ └── protect.test.ts │ │ └── strategy.test.ts │ └── tsconfig.json ├── authentication-oauth │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── service.ts │ │ ├── strategy.ts │ │ └── utils.ts │ ├── test │ │ ├── index.test.ts │ │ ├── service.test.ts │ │ ├── strategy.test.ts │ │ ├── utils.test.ts │ │ └── utils │ │ │ ├── fixture.ts │ │ │ └── provider.ts │ └── tsconfig.json ├── authentication │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── core.ts │ │ ├── hooks │ │ │ ├── authenticate.ts │ │ │ ├── connection.ts │ │ │ ├── event.ts │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── jwt.ts │ │ ├── options.ts │ │ ├── service.ts │ │ └── strategy.ts │ ├── test │ │ ├── core.test.ts │ │ ├── fixtures.ts │ │ ├── hooks │ │ │ ├── authenticate.test.ts │ │ │ └── event.test.ts │ │ ├── jwt.test.ts │ │ └── service.test.ts │ └── tsconfig.json ├── cli │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── bin │ │ └── feathers.js │ ├── package.json │ ├── src │ │ └── index.ts │ ├── test │ │ └── cli.test.ts │ └── tsconfig.json ├── client │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── core.js │ ├── package.json │ ├── src │ │ ├── core.ts │ │ └── feathers.ts │ ├── test │ │ ├── fetch.test.ts │ │ ├── fixture.ts │ │ ├── socketio.test.ts │ │ └── superagent.test.ts │ ├── tsconfig.json │ └── webpack │ │ ├── core.js │ │ ├── core.min.js │ │ ├── create-config.js │ │ ├── feathers.js │ │ └── feathers.min.js ├── commons │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── debug.ts │ │ └── index.ts │ ├── test │ │ ├── debug.test.ts │ │ ├── module.test.ts │ │ └── utils.test.ts │ └── tsconfig.json ├── configuration │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ ├── test │ │ ├── config │ │ │ └── default.json │ │ └── index.test.ts │ └── tsconfig.json ├── create-feathers │ ├── CHANGELOG.md │ ├── README.md │ ├── bin │ │ └── create-feathers.js │ └── package.json ├── errors │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ ├── test │ │ └── index.test.ts │ └── tsconfig.json ├── express │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── public │ │ ├── 401.html │ │ ├── 404.html │ │ └── default.html │ ├── src │ │ ├── authentication.ts │ │ ├── declarations.ts │ │ ├── handlers.ts │ │ ├── index.ts │ │ └── rest.ts │ ├── test │ │ ├── authentication.test.ts │ │ ├── error-handler.test.ts │ │ ├── index.test.ts │ │ ├── not-found-handler.test.ts │ │ └── rest.test.ts │ └── tsconfig.json ├── feathers │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── application.ts │ │ ├── declarations.ts │ │ ├── events.ts │ │ ├── hooks.ts │ │ ├── index.ts │ │ ├── service.ts │ │ └── version.ts │ ├── test │ │ ├── application.test.ts │ │ ├── declarations.test.ts │ │ ├── events.test.ts │ │ └── hooks │ │ │ ├── after.test.ts │ │ │ ├── app.test.ts │ │ │ ├── around.test.ts │ │ │ ├── before.test.ts │ │ │ ├── error.test.ts │ │ │ └── hooks.test.ts │ └── tsconfig.json ├── generators │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── index.ts │ │ │ └── templates │ │ │ │ ├── app.test.tpl.ts │ │ │ │ ├── app.tpl.ts │ │ │ │ ├── channels.tpl.ts │ │ │ │ ├── client.test.tpl.ts │ │ │ │ ├── client.tpl.ts │ │ │ │ ├── configuration.tpl.ts │ │ │ │ ├── declarations.tpl.ts │ │ │ │ ├── gitignore.tpl.ts │ │ │ │ ├── index.html.tpl.ts │ │ │ │ ├── index.tpl.ts │ │ │ │ ├── logger.tpl.ts │ │ │ │ ├── package.json.tpl.ts │ │ │ │ ├── prettierrc.tpl.ts │ │ │ │ ├── readme.md.tpl.ts │ │ │ │ ├── services.tpl.ts │ │ │ │ ├── tsconfig.json.tpl.ts │ │ │ │ └── validators.tpl.ts │ │ ├── authentication │ │ │ ├── index.ts │ │ │ └── templates │ │ │ │ ├── authentication.tpl.ts │ │ │ │ ├── client.test.tpl.ts │ │ │ │ ├── config.tpl.ts │ │ │ │ └── declarations.tpl.ts │ │ ├── commons.ts │ │ ├── connection │ │ │ ├── index.ts │ │ │ └── templates │ │ │ │ ├── knex.tpl.ts │ │ │ │ └── mongodb.tpl.ts │ │ ├── hook │ │ │ ├── index.ts │ │ │ └── templates │ │ │ │ └── hook.tpl.ts │ │ ├── index.ts │ │ └── service │ │ │ ├── index.ts │ │ │ ├── templates │ │ │ ├── client.tpl.ts │ │ │ ├── schema.json.tpl.ts │ │ │ ├── schema.typebox.tpl.ts │ │ │ ├── service.tpl.ts │ │ │ ├── shared.tpl.ts │ │ │ └── test.tpl.ts │ │ │ └── type │ │ │ ├── custom.tpl.ts │ │ │ ├── knex.tpl.ts │ │ │ └── mongodb.tpl.ts │ ├── test │ │ ├── build │ │ │ └── .gitkeep │ │ ├── commons.test.ts │ │ ├── generators.test.ts │ │ └── utils.ts │ └── tsconfig.json ├── knex │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── adapter.ts │ │ ├── declarations.ts │ │ ├── error-handler.ts │ │ ├── hooks.ts │ │ └── index.ts │ ├── test │ │ ├── connection.ts │ │ ├── error-handler.test.ts │ │ ├── index.test.ts │ │ └── overrides.test.ts │ └── tsconfig.json ├── koa │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── authentication.ts │ │ ├── declarations.ts │ │ ├── handlers.ts │ │ ├── index.ts │ │ └── rest.ts │ ├── test │ │ ├── app.fixture.ts │ │ ├── authentication.test.ts │ │ └── index.test.ts │ └── tsconfig.json ├── memory │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ ├── test │ │ └── index.test.ts │ └── tsconfig.json ├── mongodb │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── adapter.ts │ │ ├── converters.ts │ │ ├── error-handler.ts │ │ └── index.ts │ ├── test │ │ ├── converters.test.ts │ │ └── index.test.ts │ └── tsconfig.json ├── rest-client │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── axios.ts │ │ ├── base.ts │ │ ├── fetch.ts │ │ ├── index.ts │ │ └── superagent.ts │ ├── test │ │ ├── axios.test.ts │ │ ├── declarations.ts │ │ ├── fetch.test.ts │ │ ├── index.test.ts │ │ ├── server.ts │ │ └── superagent.test.ts │ └── tsconfig.json ├── schema │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── default-schemas.ts │ │ ├── hooks │ │ │ ├── index.ts │ │ │ ├── resolve.ts │ │ │ └── validate.ts │ │ ├── index.ts │ │ ├── json-schema.ts │ │ ├── resolver.ts │ │ └── schema.ts │ ├── test │ │ ├── fixture.ts │ │ ├── hooks.test.ts │ │ ├── json-schema.test.ts │ │ ├── resolver.test.ts │ │ └── schema.test.ts │ └── tsconfig.json ├── socketio-client │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ ├── test │ │ ├── index.test.ts │ │ └── server.ts │ └── tsconfig.json ├── socketio │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── middleware.ts │ ├── test │ │ ├── events.ts │ │ ├── index.test.ts │ │ └── methods.ts │ └── tsconfig.json ├── tests │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── resources │ │ ├── certificate.pem │ │ ├── certrequest.csr │ │ └── privatekey.pem │ ├── src │ │ ├── client.ts │ │ ├── fixture.ts │ │ ├── index.ts │ │ └── rest.ts │ └── tsconfig.json ├── transport-commons │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── client.d.ts │ ├── client.js │ ├── package.json │ ├── src │ │ ├── channels │ │ │ ├── channel │ │ │ │ ├── base.ts │ │ │ │ └── combined.ts │ │ │ ├── index.ts │ │ │ └── mixins.ts │ │ ├── client.ts │ │ ├── http.ts │ │ ├── index.ts │ │ ├── routing │ │ │ ├── index.ts │ │ │ └── router.ts │ │ └── socket │ │ │ ├── index.ts │ │ │ └── utils.ts │ ├── test │ │ ├── channels │ │ │ ├── channel.test.ts │ │ │ ├── dispatch.test.ts │ │ │ └── index.test.ts │ │ ├── client.test.ts │ │ ├── http.test.ts │ │ ├── routing │ │ │ ├── index.test.ts │ │ │ └── router.test.ts │ │ └── socket │ │ │ ├── index.test.ts │ │ │ └── utils.test.ts │ └── tsconfig.json └── typebox │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ ├── default-schemas.ts │ └── index.ts │ ├── test │ └── index.test.ts │ └── tsconfig.json └── tsconfig.json /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | version: "2" # required to adjust maintainability checks 2 | checks: 3 | argument-count: 4 | config: 5 | threshold: 6 6 | complex-logic: 7 | config: 8 | threshold: 50 9 | file-lines: 10 | config: 11 | threshold: 300 12 | method-complexity: 13 | config: 14 | threshold: 8 15 | method-count: 16 | config: 17 | threshold: 20 18 | method-lines: 19 | config: 20 | threshold: 100 21 | nested-control-flow: 22 | config: 23 | threshold: 6 24 | return-statements: 25 | config: 26 | threshold: 6 27 | similar-code: 28 | config: 29 | threshold: 50 30 | identical-code: 31 | config: 32 | threshold: 25 33 | plugins: 34 | duplication: 35 | enabled: true 36 | config: 37 | count_threshold: 4 38 | exclude_patterns: 39 | - "**/test/*" 40 | - "**/adapter-tests/*" 41 | - "**/dist/*" 42 | - "**/*.dist.js" 43 | - "**/templates/*" 44 | - "**/_**" 45 | - "**/adapter-commons/src/sort.ts" 46 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "mocha": true, 6 | "node": true 7 | }, 8 | "extends": [ 9 | "plugin:@typescript-eslint/recommended" 10 | ], 11 | "parser": "@typescript-eslint/parser", 12 | "parserOptions": { 13 | "project": "tsconfig.json", 14 | "sourceType": "module" 15 | }, 16 | "plugins": [ 17 | "@typescript-eslint", 18 | "prettier" 19 | ], 20 | "ignorePatterns": ["**/lib/", "**/dist/"], 21 | "rules": { 22 | "prettier/prettier": "error", 23 | "@typescript-eslint/no-explicit-any": "off", 24 | "@typescript-eslint/no-unused-vars": [ 25 | "warn", // or "error" 26 | { 27 | "argsIgnorePattern": "^_", 28 | "varsIgnorePattern": "^_", 29 | "caughtErrorsIgnorePattern": "^_", 30 | "ignoreRestSiblings": true 31 | } 32 | ] 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [daffl, marshallswain] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | custom: # Replace with a single custom sponsorship URL 10 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | ### Steps to reproduce 2 | 3 | (First please check that this issue is not already solved as [described 4 | here](https://github.com/feathersjs/feathers/blob/dove/.github/contributing.md#report-a-bug) - if it is a general question or suggestion please start a [Discussion](https://github.com/feathersjs/feathers/discussions)) 5 | 6 | - [ ] Tell us what broke. The more detailed the better. 7 | - [ ] If you can, please create a simple example that reproduces the issue and link to a gist, jrepo, etc. This makes it much easier for us to debug and issues that have a reproducible example will get higher priority. 8 | 9 | ### Expected behavior 10 | 11 | Tell us what should happen 12 | 13 | ### Actual behavior 14 | 15 | Tell us what happens instead 16 | 17 | ### System configuration 18 | 19 | Tell us about the applicable parts of your setup. 20 | 21 | **Module versions** (especially the part that's not working): 22 | 23 | **NodeJS version**: 24 | 25 | **Operating System**: 26 | 27 | **Browser Version**: 28 | 29 | **React Native Version**: 30 | 31 | **Module Loader**: 32 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### Summary 2 | 3 | (If you have not already please refer to the contributing guideline as [described 4 | here](https://github.com/feathersjs/feathers/blob/dove/.github/contributing.md#pull-requests)) 5 | 6 | - [ ] Tell us about the problem your pull request is solving. 7 | - [ ] Are there any open issues that are related to this? 8 | - [ ] Is this PR dependent on PRs in other repos? 9 | 10 | If so, please mention them to keep the conversations linked together. 11 | 12 | ### Other Information 13 | 14 | If there's anything else that's important and relevant to your pull 15 | request, mention that information here. This could include 16 | benchmarks, or other information. 17 | 18 | Your PR will be reviewed by a core team member and they will work with you to get your changes merged in a timely manner. If merged your PR will automatically be added to the changelog in the next release. 19 | 20 | If this is a new feature, please remember to add the appropriate documentation in their respective pages in the `docs` folder. 21 | 22 | Thanks for contributing to Feathers! :heart: 23 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | strategy: 10 | matrix: 11 | node-version: [18.x, 20.x] 12 | 13 | services: 14 | postgres: 15 | image: postgres:latest 16 | env: 17 | POSTGRES_DB: feathers 18 | POSTGRES_PASSWORD: postgres 19 | POSTGRES_PORT: 5432 20 | POSTGRES_USER: postgres 21 | ports: 22 | - 5432:5432 23 | options: >- 24 | --health-cmd pg_isready 25 | --health-interval 10s 26 | --health-timeout 5s 27 | --health-retries 5 28 | 29 | steps: 30 | - uses: actions/checkout@v2 31 | - name: Use Node.js ${{ matrix.node-version }} 32 | uses: actions/setup-node@v1 33 | with: 34 | node-version: ${{ matrix.node-version }} 35 | - run: npm i npm -g 36 | - run: npm install -g codeclimate-test-reporter 37 | - run: npm install 38 | - run: npm test 39 | env: 40 | CI: true 41 | TEST_DB: postgres 42 | - run: | 43 | if [ "$CODECLIMATE_REPO_TOKEN" != "" ]; then 44 | codeclimate-test-reporter < coverage/lcov.info 45 | fi 46 | env: 47 | CODECLIMATE_REPO_TOKEN: ${{ secrets.codeclimate }} 48 | -------------------------------------------------------------------------------- /.github/workflows/update-dependencies.yml: -------------------------------------------------------------------------------- 1 | name: Update dependencies 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 1 * *' 6 | workflow_dispatch: 7 | jobs: 8 | update-dependencies: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: Use Node.js 13 | uses: actions/setup-node@v1 14 | with: 15 | node-version: '18.x' 16 | - run: npm ci 17 | - run: | 18 | git config user.name "GitHub Actions Bot" 19 | git config user.email "hello@feathersjs.com" 20 | git checkout -b update-dependencies-$GITHUB_RUN_ID 21 | - run: | 22 | npm run update-dependencies 23 | npm install 24 | - run: | 25 | git commit -am "chore(dependencies): Update dependencies" 26 | git push origin update-dependencies-$GITHUB_RUN_ID 27 | - run: | 28 | gh pr create --title "chore(dependencies): Update all dependencies" --body "" 29 | env: 30 | GITHUB_TOKEN: ${{secrets.CI_ACCESS_TOKEN}} 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Logs 4 | logs 5 | *.log 6 | 7 | # Runtime data 8 | pids 9 | *.pid 10 | *.seed 11 | 12 | # Directory for instrumented libs generated by jscoverage/JSCover 13 | lib-cov 14 | 15 | # Coverage directory used by tools like istanbul 16 | coverage 17 | 18 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 19 | .grunt 20 | 21 | # Compiled binary addons (http://nodejs.org/api/addons.html) 22 | build/Release 23 | 24 | # Dependency directory 25 | # Commenting this out is preferred by some people, see 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 27 | node_modules 28 | .nyc_output 29 | 30 | # Users Environment Variables 31 | .lock-wscript 32 | 33 | # IDEs 34 | .idea 35 | 36 | # Distributables 37 | dist/ 38 | .nyc_output/ 39 | .cache 40 | 41 | # TypeScript compiled files 42 | packages/**/lib 43 | **/build/*.tgz 44 | *.sqlite 45 | docs/.vitepress/cache -------------------------------------------------------------------------------- /.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "timeout": 30000, 3 | "require": ["ts-node/register", "source-map-support/register"], 4 | "reporter": "Dot", 5 | "extension": ".test.ts", 6 | "exit": true 7 | } 8 | -------------------------------------------------------------------------------- /.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "verbose": false, 3 | "tempDirectory": "./coverage/.tmp", 4 | "semistandard": { 5 | "env": [ 6 | "mocha" 7 | ] 8 | }, 9 | "extension": [ 10 | ".ts", 11 | ".tsx", 12 | ".js" 13 | ], 14 | "exclude": [ 15 | "**/test/*", 16 | "**/dist/*", 17 | "**/*.dist.js", 18 | "**/_templates/*", 19 | "**/tests/*", 20 | "**/adapter-tests/*" 21 | ], 22 | "print": "detail", 23 | "reporter": [ 24 | "html", 25 | "text", 26 | "text-summary", 27 | "lcov" 28 | ], 29 | "watermarks": { 30 | "statements": [ 31 | 70, 32 | 90 33 | ], 34 | "lines": [ 35 | 70, 36 | 90 37 | ], 38 | "functions": [ 39 | 70, 40 | 90 41 | ], 42 | "branches": [ 43 | 70, 44 | 90 45 | ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "useTabs": false, 4 | "printWidth": 110, 5 | "semi": false, 6 | "trailingComma": "none", 7 | "singleQuote": true 8 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /docs/.vitepress/components.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // @ts-nocheck 3 | // Generated by unplugin-vue-components 4 | // Read more: https://github.com/vuejs/core/pull/3399 5 | export {} 6 | 7 | /* prettier-ignore */ 8 | declare module 'vue' { 9 | export interface GlobalComponents { 10 | Badges: typeof import('./components/Badges.vue')['default'] 11 | BlockQuote: typeof import('./components/BlockQuote.vue')['default'] 12 | Contributors: typeof import('./components/Contributors.vue')['default'] 13 | DatabaseBlock: typeof import('./components/DatabaseBlock.vue')['default'] 14 | DatabaseSelect: typeof import('./components/DatabaseSelect.vue')['default'] 15 | ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] 16 | ElInput: typeof import('element-plus/es')['ElInput'] 17 | ElOption: typeof import('element-plus/es')['ElOption'] 18 | ElRadio: typeof import('element-plus/es')['ElRadio'] 19 | ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] 20 | ElSelect: typeof import('element-plus/es')['ElSelect'] 21 | FeaturesList: typeof import('./components/FeaturesList.vue')['default'] 22 | LanguageBlock: typeof import('./components/LanguageBlock.vue')['default'] 23 | LanguageSelect: typeof import('./components/LanguageSelect.vue')['default'] 24 | ListItem: typeof import('./components/ListItem.vue')['default'] 25 | Logo: typeof import('./components/Logo.vue')['default'] 26 | Select: typeof import('./components/Select.vue')['default'] 27 | Tab: typeof import('./components/Tab.vue')['default'] 28 | Tabs: typeof import('./components/Tabs.vue')['default'] 29 | TeamMember: typeof import('./components/TeamMember.vue')['default'] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /docs/.vitepress/components/Badges.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 18 | -------------------------------------------------------------------------------- /docs/.vitepress/components/BlockQuote.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 25 | -------------------------------------------------------------------------------- /docs/.vitepress/components/Contributors.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /docs/.vitepress/components/DatabaseBlock.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 17 | -------------------------------------------------------------------------------- /docs/.vitepress/components/DatabaseSelect.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 27 | -------------------------------------------------------------------------------- /docs/.vitepress/components/LanguageBlock.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 17 | -------------------------------------------------------------------------------- /docs/.vitepress/components/LanguageSelect.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 25 | -------------------------------------------------------------------------------- /docs/.vitepress/components/Tab.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 34 | 35 | 46 | -------------------------------------------------------------------------------- /docs/.vitepress/config.nav.ts: -------------------------------------------------------------------------------- 1 | import { releases } from './meta' 2 | // import { version } from '../package.json' 3 | 4 | const version = 5 5 | 6 | export default [ 7 | { text: 'Guides', link: '/guides/' }, 8 | { text: 'API', link: '/api/' }, 9 | { text: 'Help', link: '/help/' }, 10 | { 11 | text: `v${version}`, 12 | items: [ 13 | { 14 | text: 'Release Notes ', 15 | link: releases 16 | }, 17 | { 18 | text: 'Crow v4 ', 19 | link: 'https://crow.docs.feathersjs.com' 20 | }, 21 | { 22 | text: 'Buzzard v3 ', 23 | link: 'https://buzzard.docs.feathersjs.com' 24 | } 25 | ] 26 | }, 27 | { 28 | text: 'Ecosystem', 29 | link: '/ecosystem/' 30 | } 31 | ] 32 | -------------------------------------------------------------------------------- /docs/.vitepress/meta.ts: -------------------------------------------------------------------------------- 1 | // noinspection ES6PreferShortImport: IntelliJ IDE hint to avoid warning to use `~/contributors`, will fail on build if changed 2 | 3 | /* Texts */ 4 | export const feathersName = 'feathers' 5 | export const feathersShortName = 'feathers' 6 | export const feathersDescription = 'The API & Real-time Application Framework' 7 | 8 | /* CDN fonts and styles */ 9 | export const googleapis = 'https://fonts.googleapis.com' 10 | export const gstatic = 'https://fonts.gstatic.com' 11 | export const font = `${googleapis}/css2?family=Readex+Pro:wght@200;400;600&display=swap` 12 | 13 | /* vitepress head */ 14 | export const ogUrl = 'https://feathersjs.com/' 15 | export const ogImage = `${ogUrl}og.png` 16 | 17 | /* GitHub and social links */ 18 | export const github = 'https://github.com/feathersjs/feathers' 19 | export const releases = 'https://github.com/feathersjs/feathers/releases' 20 | export const contributing = 'https://github.com/feathersjs/feathers/blob/master/.github/contributing.md' 21 | export const discord = 'https://discord.gg/qa8kez8QBx' 22 | export const twitter = null; 23 | 24 | /* Avatar/Image/Sponsors servers */ 25 | export const preconnectLinks = [googleapis, gstatic] 26 | export const preconnectHomeLinks = [googleapis, gstatic] 27 | 28 | /* PWA runtime caching urlPattern regular expressions */ 29 | export const pwaFontsRegex = new RegExp(`^${googleapis}/.*`, 'i') 30 | export const pwaFontStylesRegex = new RegExp(`^${gstatic}/.*`, 'i') 31 | -------------------------------------------------------------------------------- /docs/.vitepress/style/element-plus.scss: -------------------------------------------------------------------------------- 1 | @forward 'element-plus/theme-chalk/src/common/var.scss' with ( 2 | $colors: ( 3 | 'primary': ( 4 | 'base': #745847 5 | ) 6 | ) 7 | ); 8 | 9 | @use 'element-plus/theme-chalk/src/index.scss'; 10 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/FeathersLayout.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | import googleAnalytics from 'vitepress-plugin-google-analytics' 2 | import 'element-plus/theme-chalk/dark/css-vars.css' 3 | 4 | import '../vite-env.d' 5 | import Theme from 'vitepress/theme' 6 | import { inBrowser } from 'vitepress' 7 | import '../style/main.postcss' 8 | import '../style/vars.postcss' 9 | import 'uno.css' 10 | import FeathersLayout from './FeathersLayout.vue' 11 | import Tab from '../components/Tab.vue' 12 | import Tabs from '../components/Tabs.vue' 13 | import Select from '../components/Select.vue' 14 | import Badges from '../components/Badges.vue' 15 | import Logo from '../components/Logo.vue' 16 | import BlockQuote from '../components/BlockQuote.vue' 17 | import LanguageBlock from '../components/LanguageBlock.vue' 18 | import DatabaseBlock from '../components/DatabaseBlock.vue' 19 | 20 | import '../style/element-plus.scss' 21 | // import 'element-plus/dist/index.css' 22 | 23 | if (inBrowser) import('./pwa') 24 | 25 | export default { 26 | ...Theme, 27 | Layout: FeathersLayout, 28 | enhanceApp({ app }) { 29 | googleAnalytics({ 30 | id: 'G-XQ8CKCD9L6' 31 | }), 32 | // Globally register components so they don't have to be imported in the template. 33 | app.component('Tabs', Tabs) 34 | app.component('Tab', Tab) 35 | app.component('Select', Select) 36 | app.component('Badges', Badges) 37 | app.component('Logo', Logo) 38 | app.component('BlockQuote', BlockQuote) 39 | app.component('LanguageBlock', LanguageBlock) 40 | app.component('DatabaseBlock', DatabaseBlock) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/pwa.ts: -------------------------------------------------------------------------------- 1 | import { registerSW } from 'virtual:pwa-register' 2 | 3 | registerSW({ immediate: true }) 4 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/store.ts: -------------------------------------------------------------------------------- 1 | import { createGlobalState, useStorage } from '@vueuse/core' 2 | 3 | export const useGlobalLanguage = createGlobalState(() => useStorage('global-language', 'ts')) 4 | export const useGlobalDb = createGlobalState(() => useStorage('global-db', 'sql')) 5 | -------------------------------------------------------------------------------- /docs/.vitepress/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue' 5 | const component: DefineComponent<{}, {}, any> 6 | export default component 7 | } 8 | -------------------------------------------------------------------------------- /docs/api/authentication/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # Authentication Overview 6 | 7 | The `@feathersjs/authentication` plugins provide a collection of tools for username/password, JWT and OAuth (GitHub, Facebook etc.) authentication as well as custom authentication mechanisms. 8 | 9 | It consists of the following core modules: 10 | 11 | - `@feathersjs/authentication` which includes 12 | - The [AuthenticationService](./service.md) that allows to register [authentication strategies](./strategy.md) and create and manage access tokens 13 | - The [JWTStrategy](./jwt.md) to use JWTs to make authenticated requests 14 | - The [authenticate hook](./hook.md) to limit service calls to an authentication strategy. 15 | - [Local authentication](./local.md) for local username/password authentication 16 | - [OAuth authentication](./oauth.md) for Google, GitHub, Facebook etc. authentication 17 | - [The authentication client](./client.md) to use Feathers authentication on the client. 18 | 19 |
20 | 21 | `@feathersjs/authentication` is an abstraction for different authentication mechanisms. It does not handle things like user verification or password reset functionality etc. This can be implemented manually, with the help of libraries like [feathers-authentication-management](https://github.com/feathers-plus/feathers-authentication-management) or a platform like [Auth0](https://auth0.com/). 22 | 23 |
24 | -------------------------------------------------------------------------------- /docs/api/databases/adapters.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # Overview 6 | 7 | Feathers database adapters are modules that provide [services](../services.md) that implement standard [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) functionality for a specific database. They use a [common API](./common.md) for initialization and settings, and they provide a [common query syntax](./querying.md). 8 | 9 |
10 | 11 | [Services](../services.md) allow to implement access to _any_ database or API. The database adapters listed here are just convenience wrappers with a common API. See the community adapters section for support for other datastores. 12 | 13 |
14 | 15 | ## Core Adapters 16 | 17 | The following data storage adapters are available in Feathers core 18 | 19 | | Core Package | Supported Data Stores | 20 | | -------------------- | -------------------------------------------------------------------------------------------------------------- | 21 | | [Memory](./memory) | Memory | 22 | | [MongoDB](./mongodb) | MongoDB | 23 | | [SQL (Knex)](./knex) | MySQL
MariaDB
PostgreSQL
CockroachDB
SQLite
Amazon Redshift
OracleDB
MSSQL | 24 | 25 | ## Community Adapters 26 | 27 | There are also many community maintained adapters for other databases and ORMs which can be found on the [Ecosystem page](/ecosystem/?cat=Database&sort=lastPublish). 28 | -------------------------------------------------------------------------------- /docs/auto-imports.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* prettier-ignore */ 3 | // @ts-nocheck 4 | // noinspection JSUnusedGlobalSymbols 5 | // Generated by unplugin-auto-import 6 | // biome-ignore lint: disable 7 | export {} 8 | declare global { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /docs/comparison.md: -------------------------------------------------------------------------------- 1 | # Feathers vs others 2 | 3 | The following sections compare Feathers to other software choices that seem similar or may overlap with the use cases of Feathers. Due to the bias of these comparisons being on the Feathers website, we attempt to only use facts. Below you can find a feature comparison table and in each section you can get more detailed comparisons. If you find something invalid or out of date in the comparisons, please create an issue and we'll address it as soon as possible. 4 | 5 | - [Feathers vs Firebase](/feathers-vs-firebase) 6 | - [Feathers vs Meteor](/feathers-vs-meteor) 7 | - [Feathers vs Sails](/feathers-vs-sails) 8 | - [Feathers vs Loopback](/feathers-vs-loopback) 9 | - [Feathers vs Nest](/feathers-vs-nest) 10 | -------------------------------------------------------------------------------- /docs/components/CTAButton.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 25 | 26 | 59 | -------------------------------------------------------------------------------- /docs/components/FooterList.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 16 | -------------------------------------------------------------------------------- /docs/components/HomeCTATextSection.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 15 | -------------------------------------------------------------------------------- /docs/components/HomeCreateFirstApp.vue: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /docs/components/HomeFeature1.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 18 | -------------------------------------------------------------------------------- /docs/components/HomeFeature1Content.vue: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /docs/components/HomeFeature2.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 21 | -------------------------------------------------------------------------------- /docs/components/HomeFeature2Content.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 14 | -------------------------------------------------------------------------------- /docs/components/HomeFeatureGridCard.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | -------------------------------------------------------------------------------- /docs/components/HomeIndustryPartners.vue: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /docs/components/HomeQuickStart.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 13 | -------------------------------------------------------------------------------- /docs/cookbook/assets/auth0-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/cookbook/assets/auth0-app.png -------------------------------------------------------------------------------- /docs/cookbook/assets/facebook-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/cookbook/assets/facebook-app.png -------------------------------------------------------------------------------- /docs/cookbook/deploy/docker.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # Dockerize a Feathers application 6 | 7 | A Feathers application can be [dockerized like any other Node.js application](https://nodejs.org/en/docs/guides/nodejs-docker-webapp/). 8 | 9 | ## Create an app 10 | 11 | ```sh 12 | mkdir feathers-app 13 | cd feathers-app/ 14 | feathers generate app 15 | ``` 16 | 17 | ### Dockerfile 18 | 19 | Add the following `Dockerfile` to the project directory: 20 | 21 | ``` 22 | FROM node:lts-alpine 23 | 24 | WORKDIR /usr/src/app 25 | 26 | COPY package*.json ./ 27 | 28 | RUN npm install 29 | 30 | COPY . . 31 | 32 | EXPOSE 3030 33 | 34 | CMD ["npm", "run", "start"] 35 | ``` 36 | 37 | ## Build the image 38 | 39 | ```sh 40 | docker build -t my-feathers-image . 41 | ``` 42 | 43 | ## Start the container 44 | 45 | ```sh 46 | docker run -d -p 3030:3030 --name my-feathers-container my-feathers-image 47 | ``` 48 | -------------------------------------------------------------------------------- /docs/cookbook/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # The Feathers cookbook 6 | 7 | This cookbook contains a growing collection of recipes for common tasks you might run into with Feathers. Make sure you have [followed the Feathers guide first](../guides/) before jumping into the cookbook. 8 | 9 | Have a recipe idea? [Submit an issue with a suggestion](https://github.com/feathersjs/docs/issues/new?title=Cookbook%20Suggestion:). 10 | -------------------------------------------------------------------------------- /docs/ecosystem/helpers.ts: -------------------------------------------------------------------------------- 1 | export function nFormatter(num: number, digits?: number) { 2 | const lookup = [ 3 | { value: 1, symbol: '' }, 4 | { value: 1e3, symbol: 'k' }, 5 | { value: 1e6, symbol: 'M' }, 6 | { value: 1e9, symbol: 'G' }, 7 | { value: 1e12, symbol: 'T' }, 8 | { value: 1e15, symbol: 'P' }, 9 | { value: 1e18, symbol: 'E' } 10 | ] 11 | const rx = /\.0+$|(\.[0-9]*[1-9])0+$/ 12 | const item = lookup 13 | .slice() 14 | .reverse() 15 | .find(function (item) { 16 | return num >= item.value 17 | }) 18 | return item ? (num / item.value).toFixed(digits).replace(rx, '$1') + item.symbol : '0' 19 | } 20 | 21 | export const uniqBy = (arr: T[], selector: (item: T) => V) => { 22 | const map = new Map() 23 | arr.forEach((item) => { 24 | const prop = selector(item) 25 | if (!map.has(prop)) map.set(prop, item) 26 | }) 27 | return [...map.values()] 28 | } 29 | -------------------------------------------------------------------------------- /docs/ecosystem/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | lastUpdated: false 3 | --- 4 | 5 | 8 | 9 | # FeathersJS Ecosystem 10 | 11 | ## The Feathers Flightpath Blog 12 | 13 | Catch up on the latest FeathersJS news and community-contributed articles on the [Feathers Flightpath Blog](https://blog.feathersjs.com/). 14 | 15 | ## YouTube Playlist 16 | 17 | Watch the [FeathersJS Playlist on YouTube](https://www.youtube.com/playlist?list=PLwSdIiqnDlf_lb5y1liQK2OW5daXYgKOe). 18 | 19 | ## Awesome Packages 20 | 21 | This is a curated list of feathers packages. You can sort by various criteria. Core packages are hidden by default. 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /docs/ecosystem/types.ts: -------------------------------------------------------------------------------- 1 | export type PackageInput = { 2 | npm: string 3 | repo: string 4 | } 5 | 6 | export type PackagesInput = Record 7 | 8 | export type PackageOutput = { 9 | id: string 10 | name: string 11 | description: string 12 | keywords: string[] 13 | /** npm license */ 14 | license: string 15 | /** npm version */ 16 | version: string 17 | /** npm monthly downloads */ 18 | downloads: number 19 | /** npm last published Date */ 20 | lastPublish: Date 21 | /** npm last published Date as unix */ 22 | lastPublishUnix: number 23 | /** github: stars count */ 24 | stars: number 25 | /** github: open issues count */ 26 | issues: number 27 | /** github: age of repo */ 28 | createdAt: Date 29 | /** github: name of the owner */ 30 | ownerName: string 31 | /** github: url of the users avatar */ 32 | ownerAvatar: string 33 | /** github: url of the repo */ 34 | ghLink: string 35 | hasNPM: boolean 36 | /** npm: url of the package */ 37 | npmLink: string 38 | repository: { 39 | name: string 40 | directory: string 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /docs/ecosystem/useQuery.ts: -------------------------------------------------------------------------------- 1 | import { Ref, watch } from 'vue' 2 | import queryString from 'query-string' 3 | 4 | type MaybeArray = T | T[] 5 | 6 | type FieldType = MaybeArray<'string' | 'number' | 'boolean'> 7 | 8 | export const useQuery = (reference: Ref, field: string) => { 9 | function getQuery() { 10 | return queryString.parse(window.location.search, { 11 | parseNumbers: true, 12 | parseBooleans: true, 13 | arrayFormat: 'none' 14 | }) 15 | } 16 | 17 | function getFromUrl() { 18 | const q = getQuery() 19 | const result = q[field] 20 | // explicitly return false instead of undefined 21 | if (typeof reference.value === 'boolean' && !result) { 22 | return false 23 | } 24 | if (result == null) return 25 | if (Array.isArray(reference.value)) { 26 | return Array.isArray(result) ? result : [result] 27 | } 28 | return result 29 | } 30 | 31 | const fromUrl = getFromUrl() 32 | 33 | if (fromUrl != null) { 34 | // @ts-expect-error arbitrary type 35 | reference.value = fromUrl 36 | } 37 | 38 | function setToUrl(val: any) { 39 | const q = getQuery() 40 | if (val && (!Array.isArray(reference.value) || (Array.isArray(val) && val.length > 0))) { 41 | q[field] = val 42 | } else { 43 | delete q[field] 44 | } 45 | const prepend = Object.keys(q).length ? '?' : '' 46 | const newQuery = `${prepend}${queryString.stringify(q, { skipNull: true })}` 47 | window.history.replaceState(null, '', newQuery) 48 | } 49 | 50 | watch( 51 | reference, 52 | (val) => { 53 | setToUrl(val) 54 | }, 55 | { immediate: true } 56 | ) 57 | } 58 | -------------------------------------------------------------------------------- /docs/feathers-vs-nest.md: -------------------------------------------------------------------------------- 1 | # Feathers vs Nest 2 | 3 | Nest is a backend framework that have similar capabilities with Feathers. 4 | 5 | Nest uses dependency injection system and a module based architecture, Feathers uses service based architecture with a more functional approach. 6 | 7 | Nest can only be written in TypeScript whereas Feathers supports JavaScript and TypeScript. 8 | 9 | Feathers can generate client code for its server, Nest can't. 10 | 11 | Nest uses RxJS for running interceptors, guards, filters or validation pipes. Feathers uses before, after and around hooks. 12 | 13 | For more details on the difference between them you can read more here: [FeathersJS vs NestJS - Compared In 3 Key Areas](https://blog.feathersjs.com/feathersjs-vs-nestjs-compared-in-3-key-areas-427def783555) 14 | -------------------------------------------------------------------------------- /docs/guides/basics/assets/feathers-chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/guides/basics/assets/feathers-chat.png -------------------------------------------------------------------------------- /docs/guides/basics/assets/generate-app-mongodb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/guides/basics/assets/generate-app-mongodb.png -------------------------------------------------------------------------------- /docs/guides/basics/assets/generate-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/guides/basics/assets/generate-app.png -------------------------------------------------------------------------------- /docs/guides/basics/assets/generate-authentication-mongodb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/guides/basics/assets/generate-authentication-mongodb.png -------------------------------------------------------------------------------- /docs/guides/basics/assets/generate-authentication.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/guides/basics/assets/generate-authentication.png -------------------------------------------------------------------------------- /docs/guides/basics/assets/generate-hook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/guides/basics/assets/generate-hook.png -------------------------------------------------------------------------------- /docs/guides/basics/assets/generate-service-mongodb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/guides/basics/assets/generate-service-mongodb.png -------------------------------------------------------------------------------- /docs/guides/basics/assets/generate-service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/guides/basics/assets/generate-service.png -------------------------------------------------------------------------------- /docs/guides/basics/assets/github-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/guides/basics/assets/github-app.png -------------------------------------------------------------------------------- /docs/guides/cli/app.test.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # Application tests 6 | 7 | The `app.test` file starts the server and then tests that it shows the index page and that 404 (Not Found) JSON errors are being returned. It uses the [Axios HTTP](https://axios-http.com/) library to make the calls. 8 | 9 | This file can e.g. be used to test application [setup](../../api/application.md#setupserver) and [teardown](../../api/application.md#teardownserver). 10 | 11 | All tests are using [MochaJS](https://mochajs.org/) but will be moving to the [NodeJS test runner](https://nodejs.org/api/test.html) in the future. 12 | -------------------------------------------------------------------------------- /docs/guides/cli/authentication.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # Authentication 6 | 7 | The file in `src/authentication.ts` sets up an [authentication service](../../api/authentication/service.md) and registers [authentication strategies](../../api/authentication/strategy.md). Depending on the strategies you selected it looks similar to this: 8 | 9 | ```ts 10 | import { AuthenticationService, JWTStrategy } from '@feathersjs/authentication' 11 | import { LocalStrategy } from '@feathersjs/authentication-local' 12 | 13 | import type { Application } from './declarations' 14 | 15 | declare module './declarations' { 16 | interface ServiceTypes { 17 | authentication: AuthenticationService 18 | } 19 | } 20 | 21 | export const authentication = (app: Application) => { 22 | const authentication = new AuthenticationService(app) 23 | 24 | authentication.register('jwt', new JWTStrategy()) 25 | authentication.register('local', new LocalStrategy()) 26 | 27 | app.use('authentication', authentication) 28 | } 29 | ``` 30 | 31 | ## oAuth 32 | 33 | Note that when selecting oAuth logins (Google, Facebook, GitHub etc.), the standard registered oAuth strategy only uses the `Id` property to create a new user. This will fail validation against the default user [schema](./service.schemas.md) which requires an `email` property to exist. If the provider (and user) allows fetching the email, you can customize the oAuth strategy like shown for GitHub in the [oAuth authentication guide](../basics/authentication.md#login-with-github). You can also make the email in the schema optional with `email: Type.Optional(Type.String())`. 34 | -------------------------------------------------------------------------------- /docs/guides/cli/channels.md: -------------------------------------------------------------------------------- 1 | # Channels 2 | 3 | > This page is currently a work in progress 4 | 5 | For more information see the [channel API](../../api/channels.md). 6 | -------------------------------------------------------------------------------- /docs/guides/cli/client.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # Client 6 | 7 | A generated application can be used as an npm module that provides a [Feathers client](../../api/client.md). It gives you a fully typed client that can be installed in any TypeScript (e.g. React, VueJS, React Native etc.) application. 8 | 9 | ## Local installation 10 | 11 | The application can be linked into a client application by running 12 | 13 | ``` 14 | npm run bundle:client 15 | npm link 16 | ``` 17 | 18 | Then go to your client side app 19 | 20 | ``` 21 | cd path/to/client 22 | npm link my-app 23 | ``` 24 | 25 | ## Creating a package 26 | 27 | To create an installable SDK package that does not include any of the server code (other than the shared types) you can run 28 | 29 | ``` 30 | npm run bundle:client 31 | ``` 32 | 33 | By default this will create an `appname-x.x.x.tgz` npm package in the `public/` folder. 34 | This package can be installed from a running server via 35 | 36 | ``` 37 | npm install https://myapp.com/appname-x.x.x.tgz 38 | ``` 39 | 40 | ## Usage 41 | 42 | Once installed, the application can be used as follows with Socket.io: 43 | 44 | ```ts 45 | import io from 'socket.io-client' 46 | import socketio from '@feathersjs/socketio-client' 47 | import { createClient } from 'my-app' 48 | 49 | const connection = socketio(io('https://myapp.com')) 50 | 51 | const client = createClient(connection) 52 | ``` 53 | 54 | And like this with a REST client: 55 | 56 | ```ts 57 | import rest from '@feathersjs/rest-client' 58 | import { createClient } from 'my-app' 59 | 60 | const connection = rest('https://myapp.com').fetch(window.fetch.bind(window)) 61 | 62 | const client = createClient(connection) 63 | ``` 64 | -------------------------------------------------------------------------------- /docs/guides/cli/configuration.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | ### Configuration Schemas 6 | 7 | A generated application comes with a schema that validates the initial configuration when the application is started. This makes it much easier to catch configuration errors early which can otherwise be especially difficult to debug in remote environments. 8 | 9 | The configuration [schema definition](../../api/schema/index.md) can be found in `configuration.ts`. It is used as a [configuration schema](../../api/configuration.md#configuration-validation) and loads some default schemas for authentication and database connection configuration and adds values for `host`, `port` and the `public` hosted file folder. The types of this schema are also used for `app.get()` and `app.set()` [typings](./declarations.md). The initial configuration schema will be validated on application startup when calling [`app.listen()`](../../api/application.md#listenport) or [`app.setup()`](../../api/application.md#setupserver). 10 | -------------------------------------------------------------------------------- /docs/guides/cli/knexfile.md: -------------------------------------------------------------------------------- 1 | # Knexfile 2 | 3 | ## Migrations 4 | 5 | Migrations are a best practise for SQL databases to roll out and undo changes to the data model and are set up automatically with an SQL database connection. The generated `knexfile.ts` imports the [app object](./app.md) to establish the connection to the database. To run migration scripts for the connection from the [configuration environment](./configuration.md#environment-variables) use: 6 | 7 | ``` 8 | npm run migrate 9 | ``` 10 | 11 | To create a new migration, run 12 | 13 | ``` 14 | npm run migrate:make -- 15 | ``` 16 | 17 | and replace `` with the name of the migration you want to create. This will create a new file in the `migrations/` folder. 18 | 19 |
20 | 21 | For more information on what is available in migration files, see the [Knex migrations documentation](https://knexjs.org/guide/migrations.html). 22 | 23 |
24 | -------------------------------------------------------------------------------- /docs/guides/cli/log-error.md: -------------------------------------------------------------------------------- 1 | # Error logging hook 2 | 3 | The `src/hooks/log-error.ts` file exports a `logError` hook that uses the [logger](./logger.md) to log any error for a service method, including validation error details (when they are available). It is registered as an [application hook](./app.md#application-hooks) `all` hook, meaning it will log errors for any service method. 4 | -------------------------------------------------------------------------------- /docs/guides/cli/logger.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # Logging 6 | 7 | ## Logger 8 | 9 | The `src/logger.ts` file initialises the widely used [Winston logger](https://github.com/winstonjs/winston) library, by default with the `info` log level, logging to the console. 10 | 11 | ```ts 12 | import { createLogger, format, transports } from 'winston' 13 | 14 | // Configure the Winston logger. For the complete documentation see https://github.com/winstonjs/winston 15 | export const logger = createLogger({ 16 | // To see more detailed errors, change this to 'debug' 17 | level: 'info', 18 | format: format.combine(format.splat(), format.simple()), 19 | transports: [new transports.Console()] 20 | }) 21 | ``` 22 | 23 | You can import the logger directly in any file where you want to add logging information. 24 | 25 | ```ts 26 | import { logger } from './logger' 27 | 28 | logger.info('Log some information here') 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/guides/cli/package.md: -------------------------------------------------------------------------------- 1 | # package.json 2 | 3 | ## Folders 4 | 5 | The source and test folders to which files are generated is set in the `package.json`. To change them, rename the `src/` or `test/` folder to what you want it to and then update `package.json` `directories` section accordingly: 6 | 7 | ```json 8 | { 9 | "directories": { 10 | "lib": "api/src", 11 | "test": "api/test" 12 | } 13 | } 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/guides/cli/prettierrc.md: -------------------------------------------------------------------------------- 1 | # Prettier 2 | 3 | The Feathers CLI uses [Prettier](https://prettier.io/) for code formatting and generates a configuration for it in a new application. To change the options, like the use of semicolons, quotes etc, edit the `.prettierrc` file with the [options available](https://prettier.io/docs/en/options.html). To update all existing source files with the new code style run 4 | 5 | ``` 6 | npm run prettier 7 | ``` 8 | 9 | When new files are generated, they will use the current Prettier configuration. See the [Prettier Integration with Linters](https://prettier.io/docs/en/integrating-with-linters.html) documentation for how to integrate with tools like ESLint. 10 | -------------------------------------------------------------------------------- /docs/guides/cli/service.shared.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # Service Shared 6 | 7 | The `.shared` file contains variables and type declarations that are shared between the [client](./client.md) and the [server application](./app.md). It can also be used for shared utility functions or schemas (e.g. for client side validation). 8 | 9 | ## Variables 10 | 11 | By default two shared variables are exported: 12 | 13 | - `Path` - The path of the service. Changing this will change the path for the service in all places like the application, the client and types 14 | - `Methods` - The list of service methods available to the client. This can be updated with service and custom methods a client should be able to use. 15 | 16 | ## Client setup 17 | 18 | This file also includes the client side service registration which will be included in the [client](./client.md). It will register a client side service based on the shared path and methods. 19 | -------------------------------------------------------------------------------- /docs/guides/cli/tsconfig.md: -------------------------------------------------------------------------------- 1 | # tsconfig.json 2 | -------------------------------------------------------------------------------- /docs/guides/cli/validators.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # Validators 6 | 7 | For all currently supported schema types, AJV is used as the default validator. See the [validators API documentation](../../api/schema/validators.md) for more information. 8 | 9 | ## AJV validators 10 | 11 | The `src/validators.ts` file sets up two Ajv instances for data and querys (for which string types will be coerced automatically). It also sets up a collection of additional formats using [ajv-formats](https://ajv.js.org/packages/ajv-formats.html). The validators in this file can be customized according to the [Ajv documentation](https://ajv.js.org/) and [its plugins](https://ajv.js.org/packages/). You can find the available Ajv options in the [Ajs class API docs](https://ajv.js.org/options.html). 12 | 13 | ```ts 14 | import { Ajv, addFormats } from '@feathersjs/schema' 15 | import type { FormatsPluginOptions } from '@feathersjs/schema' 16 | 17 | const formats: FormatsPluginOptions = [ 18 | 'date-time', 19 | 'time', 20 | 'date', 21 | 'email', 22 | 'hostname', 23 | 'ipv4', 24 | 'ipv6', 25 | 'uri', 26 | 'uri-reference', 27 | 'uuid', 28 | 'uri-template', 29 | 'json-pointer', 30 | 'relative-json-pointer', 31 | 'regex' 32 | ] 33 | 34 | export const dataValidator = addFormats(new Ajv({}), formats) 35 | 36 | export const queryValidator = addFormats( 37 | new Ajv({ 38 | coerceTypes: true 39 | }), 40 | formats 41 | ) 42 | ``` 43 | 44 | ## MongoDB ObjectIds 45 | 46 | When choosing MongoDB, the validators file will also register the [`objectid` keyword](../../api/databases/mongodb.md#ajv-keyword) to convert strings to MongoDB Object ids. 47 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | sidebar: false 4 | 5 | title: Feathers 6 | titleTemplate: The API and Real-time Application Framework 7 | --- 8 | 9 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "dev": "vitepress --port 3333 --open", 7 | "build": "vitepress build", 8 | "serve": "vitepress serve", 9 | "preview-https": "pnpm run build && serve .vitepress/dist", 10 | "prefetch": "esno .vitepress/scripts/fetch-avatars.ts", 11 | "start": "npm run dev" 12 | }, 13 | "dependencies": { 14 | "@vueuse/core": "^12.7.0", 15 | "date-fns": "^4.1.0", 16 | "element-plus": "^2.9.5", 17 | "query-string": "^9.1.1", 18 | "shiki": "^3.0.0", 19 | "vue": "^3.5.13" 20 | }, 21 | "devDependencies": { 22 | "@feathersjs/generators": "^5.0.32", 23 | "@iconify-json/carbon": "^1.2.7", 24 | "@types/node": "^22.13.5", 25 | "@unocss/preset-typography": "^66.0.0", 26 | "@unocss/reset": "^66.0.0", 27 | "@unocss/transformer-directives": "^66.0.0", 28 | "@vitejs/plugin-vue": "^5.2.1", 29 | "esno": "^4.8.0", 30 | "fast-glob": "^3.3.3", 31 | "flexsearch": "^0.7.43", 32 | "https-localhost": "^4.7.1", 33 | "markdown-it": "^14.1.0", 34 | "sass": "^1.85.0", 35 | "sitemap": "^8.0.0", 36 | "unocss": "^66.0.0", 37 | "unplugin-auto-import": "^19.1.0", 38 | "unplugin-vue-components": "^28.4.0", 39 | "vite-plugin-pwa": "^0.21.1", 40 | "vitepress": "^1.6.3", 41 | "vitepress-plugin-google-analytics": "^1.0.2", 42 | "vitepress-plugin-search": "^1.0.4-alpha.22", 43 | "workbox-window": "^7.3.0" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /docs/public/_headers: -------------------------------------------------------------------------------- 1 | / 2 | X-Frame-Options: DENY 3 | X-XSS-Protection: 1; mode=block 4 | 5 | /api/ 6 | X-Frame-Options: DENY 7 | X-XSS-Protection: 1; mode=block 8 | 9 | /config/ 10 | X-Frame-Options: DENY 11 | X-XSS-Protection: 1; mode=block 12 | 13 | /guide/ 14 | X-Frame-Options: DENY 15 | X-XSS-Protection: 1; mode=block 16 | 17 | /*.html 18 | X-Frame-Options: DENY 19 | X-XSS-Protection: 1; mode=block 20 | 21 | /* 22 | X-Content-Type-Options: nosniff 23 | Referrer-Policy: no-referrer 24 | Strict-Transport-Security: max-age=31536000; includeSubDomains 25 | 26 | /assets/* 27 | cache-control: max-age=31536000 28 | cache-control: immutable 29 | -------------------------------------------------------------------------------- /docs/public/_redirects: -------------------------------------------------------------------------------- 1 | # Crow Redirects 2 | 3 | /migrating.html /guides/migrating.html 4 | /security.html /guides/security.html 5 | /help/readme.html /help/ 6 | /faq/readme.html /help/faq.html 7 | 8 | /api/authentication/oauth1.html /api/authentication/oauth.html 9 | /api/authentication/oauth2.html /api/authentication/oauth.html 10 | /api/authentication/server.html /api/authentication/ 11 | 12 | /guides/frameworks/readme.html /guides/frameworks.html 13 | /guides/basics/readme.html /guides/ 14 | /guides/basics/clients.html /guides/basics/starting.html 15 | /guides/basics/databases.html /guides/basics/services.html 16 | /guides/basics/real-time.html /guides/basics/services.html 17 | 18 | /guides/chat/readme.html /guides/ 19 | /guides/chat/authentication.html /guides/basics/authentication.html 20 | /guides/chat/creating.html /guides/basics/generator.html 21 | /guides/chat/frontend.html /guides/basics/frontend.html 22 | /guides/chat/processing.html /guides/basics/hooks.html 23 | /guides/chat/service.html /guides/basics/services.html 24 | /guides/chat/testing.html /guides/basics/testing.html 25 | 26 | /*/readme.html /:splat 301! 27 | -------------------------------------------------------------------------------- /docs/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/public/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/bg.png -------------------------------------------------------------------------------- /docs/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/favicon.ico -------------------------------------------------------------------------------- /docs/public/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/favicon.ico -------------------------------------------------------------------------------- /docs/public/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/favicon.png -------------------------------------------------------------------------------- /docs/public/img/feathers-logo-wide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/feathers-logo-wide.png -------------------------------------------------------------------------------- /docs/public/img/feature-icons/Flexible_Icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/public/img/illustration/Final_Header_Illustration.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/illustration/Final_Header_Illustration.jpg -------------------------------------------------------------------------------- /docs/public/img/illustration/combined-centered.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/illustration/combined-centered.jpg -------------------------------------------------------------------------------- /docs/public/img/illustration/combined-night-centered.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/illustration/combined-night-centered.jpg -------------------------------------------------------------------------------- /docs/public/img/illustration/combined-night.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/illustration/combined-night.jpg -------------------------------------------------------------------------------- /docs/public/img/illustration/combined.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/illustration/combined.jpg -------------------------------------------------------------------------------- /docs/public/img/illustration/hero-day-bg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/public/img/illustration/hero-day-sun-solo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/public/img/illustration/hero-day-sun.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /docs/public/img/illustration/hero-night-bg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/public/img/partners/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/partners/1.jpg -------------------------------------------------------------------------------- /docs/public/img/partners/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/partners/2.jpg -------------------------------------------------------------------------------- /docs/public/img/partners/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/partners/3.jpg -------------------------------------------------------------------------------- /docs/public/img/partners/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/partners/4.jpg -------------------------------------------------------------------------------- /docs/public/img/partners/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/partners/5.jpg -------------------------------------------------------------------------------- /docs/public/img/tutorial/docsVersionDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/tutorial/docsVersionDropdown.png -------------------------------------------------------------------------------- /docs/public/img/tutorial/localeDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/img/tutorial/localeDropdown.png -------------------------------------------------------------------------------- /docs/public/og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/og.png -------------------------------------------------------------------------------- /docs/public/pwa-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/pwa-192x192.png -------------------------------------------------------------------------------- /docs/public/pwa-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/docs/public/pwa-512x512.png -------------------------------------------------------------------------------- /docs/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "lib": ["esnext", "dom"], 6 | "moduleResolution": "node", 7 | "esModuleInterop": true, 8 | "strict": true, 9 | "strictNullChecks": true, 10 | "resolveJsonModule": true, 11 | "skipDefaultLibCheck": true, 12 | "skipLibCheck": true, 13 | "outDir": "./dist", 14 | "declaration": true, 15 | "inlineSourceMap": true, 16 | "paths": { 17 | "@vitest/ws-client": ["./packages/ws-client/src/index.ts"], 18 | "@vitest/ui": ["./packages/ui/node/index.ts"], 19 | "#types": ["./packages/vitest/src/index.ts"], 20 | "~/*": ["./packages/ui/client/*"], 21 | "vitest": ["./packages/vitest/src/index.ts"], 22 | "vitest/globals": ["./packages/vitest/globals.d.ts"], 23 | "vitest/node": ["./packages/vitest/src/node/index.ts"], 24 | "vitest/config": ["./packages/vitest/src/config.ts"], 25 | "vite-node": ["./packages/vite-node/src/index.ts"], 26 | "vite-node/client": ["./packages/vite-node/src/client.ts"], 27 | "vite-node/server": ["./packages/vite-node/src/server.ts"], 28 | "vite-node/utils": ["./packages/vite-node/src/utils.ts"] 29 | }, 30 | "types": [ 31 | "vite/client" 32 | ] 33 | }, 34 | "exclude": [ 35 | "**/dist/**", 36 | "./packages/vitest/dist/**", 37 | "./packages/ui/client/**", 38 | "./examples/**/*.*", 39 | "./bench/**" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /generators/package.ts: -------------------------------------------------------------------------------- 1 | import type { Callable, PinionContext } from '@featherscloud/pinion' 2 | import { generator, install, prompt, runGenerators, toFile } from '@featherscloud/pinion' 3 | 4 | export interface ModuleContext extends PinionContext { 5 | name: string 6 | uppername: string 7 | description: string 8 | moduleName: string 9 | packagePath: Callable 10 | } 11 | 12 | export const generate = (context: ModuleContext) => 13 | generator(context) 14 | .then( 15 | prompt([ 16 | { 17 | type: 'input', 18 | name: 'name', 19 | message: 'What is the name of the module?' 20 | }, 21 | { 22 | type: 'input', 23 | name: 'description', 24 | message: 'Write a short description' 25 | } 26 | ]) 27 | ) 28 | .then((ctx) => { 29 | return { 30 | ...ctx, 31 | moduleName: `@feathersjs/${ctx.name}`, 32 | uppername: ctx.name.charAt(0).toUpperCase() + ctx.name.slice(1), 33 | packagePath: toFile('packages', ctx.name) 34 | } 35 | }) 36 | .then(runGenerators(__dirname, 'package')) 37 | .then( 38 | install( 39 | ['@types/node', 'shx', 'ts-node', 'typescript', 'mocha'], 40 | true, 41 | (context) => `npm --workspace packages/${context.name}` 42 | ) 43 | ) 44 | -------------------------------------------------------------------------------- /generators/package/index.tpl.ts: -------------------------------------------------------------------------------- 1 | import { generator, renderTemplate, toFile } from '@featherscloud/pinion' 2 | import { ModuleContext } from '../package' 3 | 4 | interface Context extends ModuleContext {} 5 | 6 | const template = ({ name }: Context) => ` 7 | export function ${name}() { 8 | return 'Hello from ${name}' 9 | } 10 | ` 11 | 12 | export const generate = (context: Context) => 13 | generator(context).then(renderTemplate(template, toFile(context.packagePath, 'src', 'index.ts'))) 14 | -------------------------------------------------------------------------------- /generators/package/license.tpl.ts: -------------------------------------------------------------------------------- 1 | import { generator, renderTemplate, toFile } from '@featherscloud/pinion' 2 | import { ModuleContext } from '../package' 3 | 4 | interface Context extends ModuleContext {} 5 | 6 | export const generate = (context: Context) => 7 | generator(context).then( 8 | renderTemplate( 9 | `The MIT License (MIT) 10 | 11 | Copyright (c) ${new Date().getFullYear()} Feathers Contributors 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 29 | SOFTWARE. 30 | `, 31 | toFile(context.packagePath, 'LICENSE') 32 | ) 33 | ) 34 | -------------------------------------------------------------------------------- /generators/package/readme.md.tpl.ts: -------------------------------------------------------------------------------- 1 | import { generator, renderTemplate, toFile } from '@featherscloud/pinion' 2 | import { ModuleContext } from '../package' 3 | 4 | const template = ({ description, moduleName }: ModuleContext) => `# ${moduleName} 5 | 6 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 7 | [![Download Status](https://img.shields.io/npm/dm/${moduleName}.svg?style=flat-square)](https://www.npmjs.com/package/${moduleName}) 8 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 9 | 10 | > ${description} 11 | 12 | ## Installation 13 | 14 | \`\`\` 15 | npm install ${moduleName} --save 16 | \`\`\` 17 | 18 | ## Documentation 19 | 20 | Refer to the [Feathers API documentation](https://feathersjs.com/api) for more details. 21 | 22 | ## License 23 | 24 | Copyright (c) ${new Date().getFullYear()} [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 25 | 26 | Licensed under the [MIT license](LICENSE). 27 | ` 28 | 29 | export const generate = (context: ModuleContext) => 30 | generator(context).then(renderTemplate(template, toFile(context.packagePath, 'README.md'))) 31 | -------------------------------------------------------------------------------- /generators/package/test.tpl.ts: -------------------------------------------------------------------------------- 1 | import { generator, renderTemplate, toFile } from '@featherscloud/pinion' 2 | import { ModuleContext } from '../package' 3 | 4 | interface Context extends ModuleContext {} 5 | 6 | const template = ({ moduleName, name }: Context) => /** ts */ `import { strict as assert } from 'assert' 7 | import { ${name} } from '../src/index' 8 | 9 | describe('${moduleName}', () => { 10 | it('initializes', () => { 11 | assert.equal(${name}(), 'Hello from ${name}') 12 | }) 13 | }) 14 | ` 15 | 16 | export const generate = (context: Context) => 17 | generator(context).then( 18 | renderTemplate(template, toFile(context.packagePath, 'test', 'index.test.ts')) 19 | ) 20 | -------------------------------------------------------------------------------- /generators/package/tsconfig.json.tpl.ts: -------------------------------------------------------------------------------- 1 | import { generator, toFile, writeJSON } from '@featherscloud/pinion' 2 | import { ModuleContext } from '../package' 3 | 4 | export const generate = (context: ModuleContext) => 5 | generator(context).then( 6 | writeJSON( 7 | { 8 | extends: '../../tsconfig', 9 | include: ['src/**/*.ts'], 10 | compilerOptions: { 11 | outDir: 'lib' 12 | } 13 | }, 14 | toFile(context.packagePath, 'tsconfig.json') 15 | ) 16 | ) 17 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "ci": false, 3 | "packages": ["packages/*"], 4 | "version": "5.0.34", 5 | "command": { 6 | "bootstrap": { 7 | "hoist": true 8 | }, 9 | "publish": { 10 | "allowBranch": ["crow", "dove"], 11 | "message": "chore(release): publish %s", 12 | "conventionalCommits": true, 13 | "createRelease": "github" 14 | } 15 | }, 16 | "ignoreChanges": [ 17 | "**/changelog.md", 18 | "**/CHANGELOG.md", 19 | "**/package-lock.json", 20 | "**/yarn.lock", 21 | "**/test/**", 22 | "lerna.json", 23 | "readme.md" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /packages/adapter-commons/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/adapter-commons/README.md: -------------------------------------------------------------------------------- 1 | # Feathers Adapter Commons 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/Node.js%20CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3A%22Node.js+CI%22) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/adapter-commons.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/adapter-commons) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > Shared utility functions for Feathers adatabase adapters 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/adapter-commons --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers database adapter documentation](https://feathersjs.com/api/databases/common.html) for more details. 18 | 19 | ## Authors 20 | 21 | [Feathers contributors](https://github.com/feathersjs/adapter-commons/graphs/contributors) 22 | 23 | ## License 24 | 25 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 26 | 27 | Licensed under the [MIT license](LICENSE). 28 | -------------------------------------------------------------------------------- /packages/adapter-commons/src/index.ts: -------------------------------------------------------------------------------- 1 | import { _ } from '@feathersjs/commons' 2 | import { Params } from '@feathersjs/feathers' 3 | 4 | export * from './declarations' 5 | export * from './service' 6 | export * from './query' 7 | export * from './sort' 8 | 9 | // Return a function that filters a result object or array 10 | // and picks only the fields passed as `params.query.$select` 11 | // and additional `otherFields` 12 | export function select(params: Params, ...otherFields: string[]) { 13 | const queryFields: string[] | undefined = params?.query?.$select 14 | 15 | if (!queryFields) { 16 | return (result: any) => result 17 | } 18 | 19 | const resultFields = queryFields.concat(otherFields) 20 | const convert = (result: any) => _.pick(result, ...resultFields) 21 | 22 | return (result: any) => { 23 | if (Array.isArray(result)) { 24 | return result.map(convert) 25 | } 26 | 27 | return convert(result) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/adapter-commons/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/adapter-tests/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/adapter-tests/README.md: -------------------------------------------------------------------------------- 1 | # Feathers Adapter Tests 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/Node.js%20CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3A%22Node.js+CI%22) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/adapter-commons.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/adapter-commons) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > Feathers shared database adapter test suite 8 | 9 | ## About 10 | 11 | This is a repository that contains the test suite for the common database adapter syntax. See the [API documentation](https://docs.feathersjs.com/api/databases/common.html) for more information. 12 | 13 | ## Authors 14 | 15 | [Feathers contributors](https://github.com/feathersjs/adapter-tests/graphs/contributors) 16 | 17 | ## License 18 | 19 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 20 | 21 | Licensed under the [MIT license](LICENSE). 22 | -------------------------------------------------------------------------------- /packages/adapter-tests/src/basic.ts: -------------------------------------------------------------------------------- 1 | import assert from 'assert' 2 | import { AdapterBasicTest } from './declarations' 3 | 4 | export default (test: AdapterBasicTest, app: any, _errors: any, serviceName: string, idProp: string) => { 5 | describe('Basic Functionality', () => { 6 | let service: any 7 | 8 | beforeEach(() => { 9 | service = app.service(serviceName) 10 | }) 11 | 12 | it('.id', () => { 13 | assert.strictEqual(service.id, idProp, 'id property is set to expected name') 14 | }) 15 | 16 | test('.options', () => { 17 | assert.ok(service.options, 'Options are available in service.options') 18 | }) 19 | 20 | test('.events', () => { 21 | assert.ok(service.events.includes('testing'), 'service.events is set and includes "testing"') 22 | }) 23 | 24 | describe('Raw Methods', () => { 25 | test('._get', () => { 26 | assert.strictEqual(typeof service._get, 'function') 27 | }) 28 | 29 | test('._find', () => { 30 | assert.strictEqual(typeof service._find, 'function') 31 | }) 32 | 33 | test('._create', () => { 34 | assert.strictEqual(typeof service._create, 'function') 35 | }) 36 | 37 | test('._update', () => { 38 | assert.strictEqual(typeof service._update, 'function') 39 | }) 40 | 41 | test('._patch', () => { 42 | assert.strictEqual(typeof service._patch, 'function') 43 | }) 44 | 45 | test('._remove', () => { 46 | assert.strictEqual(typeof service._remove, 'function') 47 | }) 48 | }) 49 | }) 50 | } 51 | -------------------------------------------------------------------------------- /packages/adapter-tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/authentication-client/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/authentication-client/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/authentication-client 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/authentication-client.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/authentication-client) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > Feathers authentication client 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/authentication-client --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers authentication client API documentation](https://feathersjs.com/api/authentication/client.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/authentication-client/src/hooks/authentication.ts: -------------------------------------------------------------------------------- 1 | import { HookContext, NextFunction } from '@feathersjs/feathers' 2 | import { stripSlashes } from '@feathersjs/commons' 3 | 4 | export const authentication = () => { 5 | return (context: HookContext, next: NextFunction) => { 6 | const { 7 | app, 8 | params, 9 | path, 10 | method, 11 | app: { authentication: service } 12 | } = context 13 | 14 | if (stripSlashes(service.options.path) === path && method === 'create') { 15 | return next() 16 | } 17 | 18 | return Promise.resolve(app.get('authentication')) 19 | .then((authResult) => { 20 | if (authResult) { 21 | context.params = Object.assign({}, authResult, params) 22 | } 23 | }) 24 | .then(next) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/authentication-client/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export { authentication } from './authentication' 2 | export { populateHeader } from './populate-header' 3 | -------------------------------------------------------------------------------- /packages/authentication-client/src/hooks/populate-header.ts: -------------------------------------------------------------------------------- 1 | import { HookContext, NextFunction } from '@feathersjs/feathers' 2 | 3 | export const populateHeader = () => { 4 | return (context: HookContext, next: NextFunction) => { 5 | const { 6 | app, 7 | params: { accessToken } 8 | } = context 9 | const authentication = app.authentication 10 | 11 | // Set REST header if necessary 12 | if (app.rest && accessToken) { 13 | const { scheme, header } = authentication.options 14 | const authHeader = `${scheme} ${accessToken}` 15 | 16 | context.params.headers = Object.assign( 17 | {}, 18 | { 19 | [header]: authHeader 20 | }, 21 | context.params.headers 22 | ) 23 | } 24 | 25 | return next() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/authentication-client/src/storage.ts: -------------------------------------------------------------------------------- 1 | export interface Storage { 2 | getItem(key: string): any 3 | setItem?(key: string, value: any): any 4 | removeItem?(key: string): any 5 | } 6 | 7 | export class MemoryStorage implements Storage { 8 | store: { [key: string]: any } 9 | 10 | constructor() { 11 | this.store = {} 12 | } 13 | 14 | getItem(key: string) { 15 | return Promise.resolve(this.store[key]) 16 | } 17 | 18 | setItem(key: string, value: any) { 19 | return Promise.resolve((this.store[key] = value)) 20 | } 21 | 22 | removeItem(key: string) { 23 | const value = this.store[key] 24 | 25 | delete this.store[key] 26 | 27 | return Promise.resolve(value) 28 | } 29 | } 30 | 31 | export class StorageWrapper implements Storage { 32 | storage: any 33 | 34 | constructor(storage: any) { 35 | this.storage = storage 36 | } 37 | 38 | getItem(key: string) { 39 | return Promise.resolve(this.storage?.getItem(key)) 40 | } 41 | 42 | setItem(key: string, value: any) { 43 | return Promise.resolve(this.storage?.setItem(key, value)) 44 | } 45 | 46 | removeItem(key: string) { 47 | return Promise.resolve(this.storage?.removeItem(key)) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /packages/authentication-client/test/integration/express.test.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import { Server } from 'http' 3 | import { feathers, Application as FeathersApplication } from '@feathersjs/feathers' 4 | import * as express from '@feathersjs/express' 5 | import rest from '@feathersjs/rest-client' 6 | 7 | import authClient from '../../src' 8 | import getApp from './fixture' 9 | import commonTests from './commons' 10 | 11 | describe('@feathersjs/authentication-client Express integration', () => { 12 | let app: express.Application 13 | let server: Server 14 | 15 | before(async () => { 16 | const restApp = express 17 | .default(feathers()) 18 | .use(express.json()) 19 | .configure(express.rest()) 20 | .use(express.parseAuthentication()) 21 | app = getApp(restApp as unknown as FeathersApplication) as express.Application 22 | app.use(express.errorHandler()) 23 | 24 | server = await app.listen(9776) 25 | }) 26 | 27 | after((done) => server.close(() => done())) 28 | 29 | commonTests( 30 | () => app, 31 | () => { 32 | return feathers().configure(rest('http://localhost:9776').axios(axios)).configure(authClient()) 33 | }, 34 | { 35 | email: 'expressauth@feathersjs.com', 36 | password: 'secret', 37 | provider: 'rest' 38 | } 39 | ) 40 | }) 41 | -------------------------------------------------------------------------------- /packages/authentication-client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/authentication-local/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/authentication-local/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/authentication-local 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/authentication-local.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/authentication-local) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > Local username and password authentication strategy for Feathers authentication 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/authentication-local --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers local authentication API documentation](https://feathersjs.com/api/authentication/local.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/authentication-local/src/hooks/protect.ts: -------------------------------------------------------------------------------- 1 | import omit from 'lodash/omit' 2 | import { HookContext, NextFunction } from '@feathersjs/feathers' 3 | 4 | /** 5 | * @deprecated For reliable safe data representations use Feathers schema dispatch resolvers. 6 | * @see https://dove.feathersjs.comapi/authentication/local.html#protecting-fields 7 | */ 8 | export default (...fields: string[]) => { 9 | const o = (current: any) => { 10 | if (typeof current === 'object' && !Array.isArray(current)) { 11 | const data = typeof current.toJSON === 'function' ? current.toJSON() : current 12 | 13 | return omit(data, fields) 14 | } 15 | 16 | return current 17 | } 18 | 19 | return async (context: HookContext, next?: NextFunction) => { 20 | if (typeof next === 'function') { 21 | await next() 22 | } 23 | 24 | const result = context.dispatch || context.result 25 | 26 | if (result) { 27 | if (Array.isArray(result)) { 28 | context.dispatch = result.map(o) 29 | } else if (result.data && context.method === 'find') { 30 | context.dispatch = Object.assign({}, result, { 31 | data: result.data.map(o) 32 | }) 33 | } else { 34 | context.dispatch = o(result) 35 | } 36 | 37 | if (context.params && context.params.provider) { 38 | context.result = context.dispatch 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/authentication-local/src/index.ts: -------------------------------------------------------------------------------- 1 | import { HookContext } from '@feathersjs/feathers' 2 | import hashPassword from './hooks/hash-password' 3 | import protect from './hooks/protect' 4 | import { LocalStrategy } from './strategy' 5 | 6 | export const hooks = { hashPassword, protect } 7 | export { LocalStrategy } 8 | 9 | /** 10 | * Returns as property resolver that hashes a given plain text password using a Local 11 | * authentication strategy. 12 | * 13 | * @param options The authentication `service` and `strategy` name 14 | * @returns 15 | */ 16 | export const passwordHash = 17 | (options: { service?: string; strategy: string }) => 18 | async >(value: string | undefined, _data: any, context: H) => { 19 | if (value === undefined) { 20 | return value 21 | } 22 | 23 | const { app, params } = context 24 | const authService = app.defaultAuthentication(options.service) 25 | const localStrategy = authService.getStrategy(options.strategy) as LocalStrategy 26 | 27 | return localStrategy.hashPassword(value, params) 28 | } 29 | -------------------------------------------------------------------------------- /packages/authentication-local/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/authentication-oauth/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/authentication-oauth/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/authentication-oauth 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/authentication-oauth.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/authentication-oauth) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > OAuth 1 and 2 authentication for Feathers. Powered by Grant. 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/authentication-oauth --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers oAuth authentication API documentation](https://feathersjs.com/api/authentication/oauth.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/authentication-oauth/test/index.test.ts: -------------------------------------------------------------------------------- 1 | import { strict as assert } from 'assert' 2 | import { feathers } from '@feathersjs/feathers' 3 | import { oauth, OauthSetupSettings } from '../src' 4 | import { AuthenticationService } from '@feathersjs/authentication' 5 | 6 | describe('@feathersjs/authentication-oauth', () => { 7 | describe('setup', () => { 8 | it('errors when service does not exist', () => { 9 | const app = feathers() 10 | 11 | assert.throws( 12 | () => { 13 | app.configure(oauth({ authService: 'something' } as OauthSetupSettings)) 14 | }, 15 | { 16 | message: 'An authentication service must exist before registering @feathersjs/authentication-oauth' 17 | } 18 | ) 19 | }) 20 | 21 | it('does not error when service is configured', () => { 22 | const app = feathers() 23 | 24 | app.use('/authentication', new AuthenticationService(app)) 25 | 26 | app.configure(oauth()) 27 | }) 28 | }) 29 | }) 30 | -------------------------------------------------------------------------------- /packages/authentication-oauth/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/authentication/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/authentication/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/authentication 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/authentication.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/authentication) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > Add Authentication to your FeathersJS app. 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/authentication --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers authentication API documentation](https://feathersjs.com/api/authentication/) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/authentication/src/hooks/connection.ts: -------------------------------------------------------------------------------- 1 | import { HookContext, NextFunction } from '@feathersjs/feathers' 2 | import { AuthenticationBase, ConnectionEvent } from '../core' 3 | 4 | export default (event: ConnectionEvent) => async (context: HookContext, next: NextFunction) => { 5 | await next() 6 | 7 | const { 8 | result, 9 | params: { connection } 10 | } = context 11 | 12 | if (connection) { 13 | const service = context.service as unknown as AuthenticationBase 14 | 15 | await service.handleConnection(event, connection, result) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/authentication/src/hooks/event.ts: -------------------------------------------------------------------------------- 1 | import { HookContext, NextFunction } from '@feathersjs/feathers' 2 | import { createDebug } from '@feathersjs/commons' 3 | import { ConnectionEvent } from '../core' 4 | 5 | const debug = createDebug('@feathersjs/authentication/hooks/connection') 6 | 7 | export default (event: ConnectionEvent) => async (context: HookContext, next: NextFunction) => { 8 | await next() 9 | 10 | const { app, result, params } = context 11 | 12 | if (params.provider && result) { 13 | debug(`Sending authentication event '${event}'`) 14 | app.emit(event, result, params, context) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/authentication/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export { default as authenticate } from './authenticate' 2 | export { default as connection } from './connection' 3 | export { default as event } from './event' 4 | -------------------------------------------------------------------------------- /packages/authentication/src/index.ts: -------------------------------------------------------------------------------- 1 | export * as hooks from './hooks' 2 | export { authenticate } from './hooks' 3 | export { 4 | AuthenticationBase, 5 | AuthenticationRequest, 6 | AuthenticationResult, 7 | AuthenticationStrategy, 8 | AuthenticationParams, 9 | ConnectionEvent, 10 | JwtVerifyOptions 11 | } from './core' 12 | export { AuthenticationBaseStrategy } from './strategy' 13 | export { AuthenticationService } from './service' 14 | export { JWTStrategy } from './jwt' 15 | export { authenticationSettingsSchema, AuthenticationConfiguration } from './options' 16 | -------------------------------------------------------------------------------- /packages/authentication/src/options.ts: -------------------------------------------------------------------------------- 1 | import { FromSchema, authenticationSettingsSchema } from '@feathersjs/schema' 2 | 3 | export const defaultOptions = { 4 | authStrategies: [] as string[], 5 | jwtOptions: { 6 | header: { typ: 'access' }, // by default is an access token but can be any type 7 | audience: 'https://yourdomain.com', // The resource server where the token is processed 8 | issuer: 'feathers', // The issuing server, application or resource 9 | algorithm: 'HS256', 10 | expiresIn: '1d' 11 | } 12 | } 13 | 14 | export { authenticationSettingsSchema } 15 | 16 | export type AuthenticationConfiguration = FromSchema 17 | -------------------------------------------------------------------------------- /packages/authentication/src/strategy.ts: -------------------------------------------------------------------------------- 1 | import { AuthenticationStrategy, AuthenticationBase } from './core' 2 | import { Application, Service } from '@feathersjs/feathers' 3 | 4 | export class AuthenticationBaseStrategy implements AuthenticationStrategy { 5 | authentication?: AuthenticationBase 6 | app?: Application 7 | name?: string 8 | 9 | setAuthentication(auth: AuthenticationBase) { 10 | this.authentication = auth 11 | } 12 | 13 | setApplication(app: Application) { 14 | this.app = app 15 | } 16 | 17 | setName(name: string) { 18 | this.name = name 19 | } 20 | 21 | get configuration(): any { 22 | return this.authentication.configuration[this.name] 23 | } 24 | 25 | get entityService(): Service { 26 | const { service } = this.configuration 27 | 28 | if (!service) { 29 | return null 30 | } 31 | 32 | return this.app.service(service) || null 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/authentication/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/cli/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/cli 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/cli.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/cli) 5 | 6 | > The command line interface for creating Feathers applications 7 | 8 | ## Installation 9 | 10 | ``` 11 | npm install @feathersjs/cli --save-dev 12 | ``` 13 | 14 | ## Usage 15 | 16 | ``` 17 | $ npx feathers help 18 | ``` 19 | 20 | ## Documentation 21 | 22 | Refer to the [Feathers CLI guide](https://feathersjs.com/guides/cli/) for more details. 23 | 24 | ## License 25 | 26 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 27 | 28 | Licensed under the [MIT license](LICENSE). 29 | -------------------------------------------------------------------------------- /packages/cli/bin/feathers.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict' 3 | 4 | import { program } from '../lib/index.js' 5 | 6 | program.parse() 7 | -------------------------------------------------------------------------------- /packages/cli/test/cli.test.ts: -------------------------------------------------------------------------------- 1 | import { strict } from 'assert' 2 | import { program } from '../src' 3 | 4 | describe('cli tests', () => { 5 | it('exports the program', async () => { 6 | strict.ok(program) 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /packages/cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib", 8 | "module": "ESNext", 9 | "moduleResolution": "Node" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/client/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Feathers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/client/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/client 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/client.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/client) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > A client build for FeathersJS 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/client --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers client API documentation](https://docs.feathersjs.com/api/client.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/client/core.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./dist/core'); 2 | -------------------------------------------------------------------------------- /packages/client/src/core.ts: -------------------------------------------------------------------------------- 1 | export * from '@feathersjs/feathers' 2 | -------------------------------------------------------------------------------- /packages/client/src/feathers.ts: -------------------------------------------------------------------------------- 1 | import { feathers } from '@feathersjs/feathers' 2 | import authentication from '@feathersjs/authentication-client' 3 | import rest from '@feathersjs/rest-client' 4 | import socketio from '@feathersjs/socketio-client' 5 | 6 | export * from '@feathersjs/feathers' 7 | export * as errors from '@feathersjs/errors' 8 | export { authentication, rest, socketio } 9 | export default feathers 10 | 11 | if (typeof module !== 'undefined') { 12 | module.exports = Object.assign(feathers, module.exports) 13 | } 14 | -------------------------------------------------------------------------------- /packages/client/test/fetch.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/ban-ts-comment */ 2 | // @ts-ignore 3 | import fetch from 'node-fetch' 4 | import { Server } from 'http' 5 | import { clientTests } from '@feathersjs/tests' 6 | 7 | import * as feathers from '../dist/feathers' 8 | import app from './fixture' 9 | 10 | describe('fetch REST connector', function () { 11 | let server: Server 12 | const rest = feathers.rest('http://localhost:8889') 13 | const client = feathers.default().configure(rest.fetch(fetch)) 14 | 15 | before(async () => { 16 | server = await app().listen(8889) 17 | }) 18 | 19 | after(function (done) { 20 | server.close(done) 21 | }) 22 | 23 | clientTests(client, 'todos') 24 | }) 25 | -------------------------------------------------------------------------------- /packages/client/test/socketio.test.ts: -------------------------------------------------------------------------------- 1 | import { io } from 'socket.io-client' 2 | import socketio from '@feathersjs/socketio' 3 | import { Server } from 'http' 4 | import { clientTests } from '@feathersjs/tests' 5 | 6 | import * as feathers from '../dist/feathers' 7 | import app from './fixture' 8 | 9 | describe('Socket.io connector', function () { 10 | let server: Server 11 | const socket = io('http://localhost:9988') 12 | const client = feathers.default().configure(feathers.socketio(socket)) 13 | 14 | before(async () => { 15 | server = await app((app) => app.configure(socketio())).listen(9988) 16 | }) 17 | 18 | after(function (done) { 19 | socket.once('disconnect', () => { 20 | server.close() 21 | done() 22 | }) 23 | socket.disconnect() 24 | }) 25 | 26 | clientTests(client, 'todos') 27 | }) 28 | -------------------------------------------------------------------------------- /packages/client/test/superagent.test.ts: -------------------------------------------------------------------------------- 1 | import superagent from 'superagent' 2 | import { clientTests } from '@feathersjs/tests' 3 | import { Server } from 'http' 4 | 5 | import * as feathers from '../dist/feathers' 6 | import app from './fixture' 7 | 8 | describe('Superagent REST connector', function () { 9 | let server: Server 10 | const rest = feathers.rest('http://localhost:8889') 11 | const client = feathers.default().configure(rest.superagent(superagent)) 12 | 13 | before(async () => { 14 | server = await app().listen(8889) 15 | }) 16 | 17 | after(function (done) { 18 | server.close(done) 19 | }) 20 | 21 | clientTests(client, 'todos') 22 | }) 23 | -------------------------------------------------------------------------------- /packages/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "sourceMap": false, 4 | "include": [ 5 | "src/**/*.ts" 6 | ], 7 | "compilerOptions": { 8 | "outDir": "dist/" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/client/webpack/core.js: -------------------------------------------------------------------------------- 1 | const createConfig = require('./create-config'); 2 | 3 | module.exports = createConfig('core'); -------------------------------------------------------------------------------- /packages/client/webpack/core.min.js: -------------------------------------------------------------------------------- 1 | const createConfig = require('./create-config'); 2 | 3 | module.exports = createConfig('core', true); -------------------------------------------------------------------------------- /packages/client/webpack/create-config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const { merge } = require('webpack-merge'); 4 | 5 | module.exports = function createConfig (output, isProduction = false) { 6 | const commons = { 7 | entry: [ 8 | `./src/${output}.ts` 9 | ], 10 | output: { 11 | library: 'feathers', 12 | libraryTarget: 'umd', 13 | globalObject: 'this', 14 | path: path.resolve(__dirname, '..', 'dist'), 15 | filename: `${output}.js` 16 | }, 17 | resolve: { 18 | extensions: [ '.tsx', '.ts', '.js' ] 19 | }, 20 | module: { 21 | rules: [{ 22 | test: /\.tsx?$/, 23 | use: 'ts-loader', 24 | exclude: /node_modules/ 25 | }, { 26 | test: /\.js/, 27 | exclude: /node_modules\/(?!(@feathersjs|debug))/, 28 | loader: 'babel-loader', 29 | options: { 30 | presets: ['@babel/preset-env'] 31 | // plugins: ['@babel/plugin-transform-classes'] 32 | } 33 | }] 34 | } 35 | }; 36 | 37 | const dev = { 38 | mode: 'development', 39 | devtool: 'source-map' 40 | }; 41 | const production = { 42 | mode: 'production', 43 | output: { 44 | filename: `${output}.min.js` 45 | }, 46 | plugins: [ 47 | new webpack.DefinePlugin({ 48 | 'process.env.NODE_ENV': JSON.stringify('production') 49 | }) 50 | ] 51 | }; 52 | 53 | return merge(commons, isProduction ? production : dev); 54 | } 55 | -------------------------------------------------------------------------------- /packages/client/webpack/feathers.js: -------------------------------------------------------------------------------- 1 | const createConfig = require('./create-config'); 2 | 3 | module.exports = createConfig('feathers'); -------------------------------------------------------------------------------- /packages/client/webpack/feathers.min.js: -------------------------------------------------------------------------------- 1 | const createConfig = require('./create-config'); 2 | 3 | module.exports = createConfig('feathers', true); -------------------------------------------------------------------------------- /packages/commons/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/commons/README.md: -------------------------------------------------------------------------------- 1 | # Feathers Commons 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/commons.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/commons) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > Shared Feathers utility functions 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/commons --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers API](https://feathersjs.com/api) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/commons/src/debug.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-function */ 2 | export type DebugFunction = (...args: any[]) => void 3 | export type DebugInitializer = (name: string) => DebugFunction 4 | 5 | const debuggers: { [key: string]: DebugFunction } = {} 6 | 7 | export function noopDebug(): DebugFunction { 8 | return function () {} 9 | } 10 | 11 | let defaultInitializer: DebugInitializer = noopDebug 12 | 13 | export function setDebug(debug: DebugInitializer) { 14 | defaultInitializer = debug 15 | 16 | Object.keys(debuggers).forEach((name) => { 17 | debuggers[name] = debug(name) 18 | }) 19 | } 20 | 21 | export function createDebug(name: string) { 22 | if (!debuggers[name]) { 23 | debuggers[name] = defaultInitializer(name) 24 | } 25 | 26 | return (...args: any[]) => debuggers[name](...args) 27 | } 28 | -------------------------------------------------------------------------------- /packages/commons/test/debug.test.ts: -------------------------------------------------------------------------------- 1 | import { strict as assert } from 'assert' 2 | import { createDebug, setDebug, noopDebug } from '../src' 3 | 4 | const myDebug = createDebug('hello test') 5 | 6 | describe('debug', () => { 7 | it('default debug does nothing', () => { 8 | assert.equal(myDebug('hi', 'there'), undefined) 9 | }) 10 | 11 | it('can set custom debug later', () => { 12 | let call 13 | 14 | const customDebug = 15 | (name: string) => 16 | (...args: any[]) => { 17 | call = [name].concat(args) 18 | } 19 | 20 | setDebug(customDebug) 21 | 22 | assert.equal(myDebug('hi', 'there'), undefined) 23 | assert.deepEqual(call, ['hello test', 'hi', 'there']) 24 | 25 | const newDebug = createDebug('other test') 26 | 27 | assert.equal(newDebug('other', 'there'), undefined) 28 | assert.deepEqual(call, ['other test', 'other', 'there']) 29 | 30 | setDebug(noopDebug) 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /packages/commons/test/module.test.ts: -------------------------------------------------------------------------------- 1 | import { strict as assert } from 'assert' 2 | import { _ } from '../src' 3 | 4 | describe('module', () => { 5 | it('is commonjs compatible', () => { 6 | // eslint-disable-next-line 7 | const commons = require('../lib') 8 | 9 | assert.equal(typeof commons, 'object') 10 | assert.equal(typeof commons.stripSlashes, 'function') 11 | assert.equal(typeof commons._, 'object') 12 | }) 13 | 14 | it('exposes lodash methods under _', () => { 15 | assert.equal(typeof _.each, 'function') 16 | assert.equal(typeof _.some, 'function') 17 | assert.equal(typeof _.every, 'function') 18 | assert.equal(typeof _.keys, 'function') 19 | assert.equal(typeof _.values, 'function') 20 | assert.equal(typeof _.isMatch, 'function') 21 | assert.equal(typeof _.isEmpty, 'function') 22 | assert.equal(typeof _.isObject, 'function') 23 | assert.equal(typeof _.extend, 'function') 24 | assert.equal(typeof _.omit, 'function') 25 | assert.equal(typeof _.pick, 'function') 26 | assert.equal(typeof _.merge, 'function') 27 | }) 28 | }) 29 | -------------------------------------------------------------------------------- /packages/commons/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/configuration/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/configuration/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/configuration 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/configuration.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/configuration) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > A small configuration module for your Feathers application. 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/configuration --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers configuration API documentation](https://feathersjs.com/api/configuration.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/configuration/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Application, ApplicationHookContext, NextFunction } from '@feathersjs/feathers' 2 | import { createDebug } from '@feathersjs/commons' 3 | import { Schema, Validator } from '@feathersjs/schema' 4 | import config from 'config' 5 | 6 | const debug = createDebug('@feathersjs/configuration') 7 | 8 | export = function init(schema?: Schema | Validator) { 9 | const validator: Validator = typeof schema === 'function' ? schema : schema?.validate.bind(schema) 10 | 11 | return (app?: Application) => { 12 | if (!app) { 13 | return config 14 | } 15 | 16 | const configuration: { [key: string]: unknown } = { ...config } 17 | 18 | debug(`Initializing configuration for ${config.util.getEnv('NODE_ENV')} environment`) 19 | 20 | Object.keys(configuration).forEach((name) => { 21 | const value = configuration[name] 22 | debug(`Setting ${name} configuration value to`, value) 23 | app.set(name, value) 24 | }) 25 | 26 | if (validator) { 27 | app.hooks({ 28 | setup: [ 29 | async (_context: ApplicationHookContext, next: NextFunction) => { 30 | await validator(configuration) 31 | await next() 32 | } 33 | ] 34 | }) 35 | } 36 | 37 | return config 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/configuration/test/config/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "port": 3030, 3 | "array": ["one", "two", "three"], 4 | "deep": { "base": false }, 5 | "nullish": null 6 | } 7 | -------------------------------------------------------------------------------- /packages/configuration/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/create-feathers/README.md: -------------------------------------------------------------------------------- 1 | # create-feathers 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/configuration.svg?style=flat-square)](https://www.npmjs.com/package/create-feathers) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > Generate a Feathers application through the CLI 8 | 9 | ## Usage 10 | 11 | ``` 12 | npm create feathers my-app 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers guides](https://feathersjs.com/guides/) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/create-feathers/bin/create-feathers.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | import path from 'path' 5 | import { existsSync } from 'fs' 6 | import { mkdir } from 'fs/promises' 7 | import { Command, commandRunner, chalk } from '@feathersjs/cli' 8 | 9 | const program = new Command() 10 | const generateApp = commandRunner('app') 11 | 12 | program 13 | .name('npm init feathers') 14 | .description(`Create a new Feathers application 🕊️ 15 | 16 | ${chalk.grey('npm init feathers myapp')} 17 | `) 18 | .argument('', 'The name of your new application') 19 | // .version(version) 20 | .showHelpAfterError() 21 | .action(async (name, options) => { 22 | try { 23 | const cwd = path.join(process.cwd(), name) 24 | 25 | if (existsSync(cwd)) { 26 | throw new Error(`Can not create Feathers application, the folder "${name}" already exists`) 27 | } 28 | 29 | await mkdir(cwd) 30 | 31 | await generateApp({ 32 | name, 33 | cwd, 34 | ...options 35 | }) 36 | 37 | console.log(` 38 | 39 | ${chalk.green('Hooray')}! Your Feathers app is ready to go! 🚀 40 | Go to the ${chalk.grey(name)} folder to get started. 41 | 42 | To learn more visit ${chalk.grey('https://feathersjs.com/guides')} 43 | `) 44 | } catch (error) { 45 | console.error(`${chalk.red('Error')}: ${error.message}`) 46 | process.exit(1) 47 | } 48 | }) 49 | 50 | program.parse() 51 | -------------------------------------------------------------------------------- /packages/create-feathers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-feathers", 3 | "description": "Create a new Feathers application", 4 | "version": "5.0.34", 5 | "homepage": "https://feathersjs.com", 6 | "bin": { 7 | "create-feathers": "./bin/create-feathers.js" 8 | }, 9 | "type": "module", 10 | "keywords": [ 11 | "feathers", 12 | "feathers-plugin" 13 | ], 14 | "license": "MIT", 15 | "funding": { 16 | "type": "github", 17 | "url": "https://github.com/sponsors/daffl" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git://github.com/feathersjs/feathers.git" 22 | }, 23 | "author": { 24 | "name": "Feathers contributors", 25 | "email": "hello@feathersjs.com", 26 | "url": "https://feathersjs.com" 27 | }, 28 | "contributors": [], 29 | "bugs": { 30 | "url": "https://github.com/feathersjs/feathers/issues" 31 | }, 32 | "engines": { 33 | "node": ">= 18" 34 | }, 35 | "files": [ 36 | "CHANGELOG.md", 37 | "LICENSE", 38 | "README.md", 39 | "lib/**", 40 | "bin/**", 41 | "*.d.ts", 42 | "*.js" 43 | ], 44 | "scripts": { 45 | "test": "bin/create-feathers.js --help" 46 | }, 47 | "publishConfig": { 48 | "access": "public" 49 | }, 50 | "dependencies": { 51 | "@feathersjs/cli": "^5.0.34" 52 | }, 53 | "gitHead": "90caf635aec850550b9d37bea2762af959d9e8d5" 54 | } 55 | -------------------------------------------------------------------------------- /packages/errors/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/errors/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/errors 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/errors.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/errors) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > Common error types for feathers apps 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/errors --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers errors API documentation](https://feathersjs.com/api/errors.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/errors/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/express/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/express/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/express 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/express.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/express) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > Feathers Express framework bindings and REST provider 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/client --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers Express API documentation](https://feathersjs.com/api/express.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/express/test/not-found-handler.test.ts: -------------------------------------------------------------------------------- 1 | import { strict as assert } from 'assert' 2 | import { NotFound } from '@feathersjs/errors' 3 | 4 | import { notFound } from '../src' 5 | 6 | const handler = notFound as any 7 | 8 | describe('not-found-handler', () => { 9 | it('returns NotFound error', (done) => { 10 | handler()( 11 | { 12 | url: 'some/where', 13 | headers: {} 14 | }, 15 | {}, 16 | function (error: any) { 17 | assert.ok(error instanceof NotFound) 18 | assert.equal(error.message, 'Page not found') 19 | assert.deepEqual(error.data, { 20 | url: 'some/where' 21 | }) 22 | done() 23 | } 24 | ) 25 | }) 26 | 27 | it('returns NotFound error with URL when verbose', (done) => { 28 | handler({ verbose: true })( 29 | { 30 | url: 'some/where', 31 | headers: {} 32 | }, 33 | {}, 34 | function (error: any) { 35 | assert.ok(error instanceof NotFound) 36 | assert.equal(error.message, 'Page not found: some/where') 37 | assert.deepEqual(error.data, { 38 | url: 'some/where' 39 | }) 40 | done() 41 | } 42 | ) 43 | }) 44 | }) 45 | -------------------------------------------------------------------------------- /packages/express/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/feathers/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/feathers/src/events.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from 'events' 2 | import { NextFunction } from '@feathersjs/hooks' 3 | import { HookContext, FeathersService } from './declarations' 4 | import { getServiceOptions, defaultEventMap } from './service' 5 | 6 | export function eventHook(context: HookContext, next: NextFunction) { 7 | const { events } = getServiceOptions((context as any).self) 8 | const defaultEvent = (defaultEventMap as any)[context.method] || null 9 | 10 | context.event = defaultEvent 11 | 12 | return next().then(() => { 13 | // Send the event only if the service does not do so already (indicated in the `events` option) 14 | // This is used for custom events and for client services receiving event from the server 15 | if (typeof context.event === 'string' && !events.includes(context.event)) { 16 | const results = Array.isArray(context.result) ? context.result : [context.result] 17 | 18 | results.forEach((element) => (context as any).self.emit(context.event, element, context)) 19 | } 20 | }) 21 | } 22 | 23 | export function eventMixin(service: FeathersService) { 24 | const isEmitter = typeof service.on === 'function' && typeof service.emit === 'function' 25 | 26 | if (!isEmitter) { 27 | Object.assign(service, EventEmitter.prototype) 28 | } 29 | 30 | return service 31 | } 32 | -------------------------------------------------------------------------------- /packages/feathers/src/index.ts: -------------------------------------------------------------------------------- 1 | import { setDebug } from '@feathersjs/commons' 2 | 3 | import version from './version' 4 | import { Feathers } from './application' 5 | import { Application } from './declarations' 6 | 7 | export function feathers() { 8 | return new Feathers() as Application 9 | } 10 | 11 | feathers.setDebug = setDebug 12 | 13 | export { version, Feathers } 14 | export * from './hooks' 15 | export * from './declarations' 16 | export * from './service' 17 | 18 | if (typeof module !== 'undefined') { 19 | module.exports = Object.assign(feathers, module.exports) 20 | } 21 | -------------------------------------------------------------------------------- /packages/feathers/src/version.ts: -------------------------------------------------------------------------------- 1 | export default 'development' 2 | -------------------------------------------------------------------------------- /packages/feathers/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/generators/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/generators 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/generators.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/cli) 5 | 6 | > Feathers core code generators used by the CLI powered by [Pinion](https://github.com/feathershq/pinion/) 7 | 8 | ## Installation 9 | 10 | ``` 11 | npm install @feathersjs/generators --save-dev 12 | ``` 13 | 14 | ## Documentation 15 | 16 | Refer to the [Feathers CLI guide](https://feathersjs.com/guides/cli/) for more details. 17 | 18 | ## License 19 | 20 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 21 | 22 | Licensed under the [MIT license](LICENSE). 23 | -------------------------------------------------------------------------------- /packages/generators/src/app/templates/app.test.tpl.ts: -------------------------------------------------------------------------------- 1 | import { toFile } from '@featherscloud/pinion' 2 | import { renderSource } from '../../commons.js' 3 | import { AppGeneratorContext } from '../index.js' 4 | 5 | const template = ({ 6 | lib 7 | }: AppGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/app.test.html 8 | import assert from 'assert' 9 | import axios from 'axios' 10 | import type { Server } from 'http' 11 | import { app } from '../${lib}/app' 12 | 13 | const port = app.get('port') 14 | const appUrl = \`http://\${app.get('host')}:\${port}\` 15 | 16 | describe('Feathers application tests', () => { 17 | let server: Server 18 | 19 | before(async () => { 20 | server = await app.listen(port) 21 | }) 22 | 23 | after(async () => { 24 | await app.teardown() 25 | }) 26 | 27 | it('starts and shows the index page', async () => { 28 | const { data } = await axios.get(appUrl) 29 | 30 | assert.ok(data.indexOf('') !== -1) 31 | }) 32 | 33 | it('shows a 404 JSON error', async () => { 34 | try { 35 | await axios.get(\`\${appUrl}/path/to/nowhere\`, { 36 | responseType: 'json' 37 | }) 38 | assert.fail('should never get here') 39 | } catch (error: any) { 40 | const { response } = error 41 | assert.strictEqual(response?.status, 404) 42 | assert.strictEqual(response?.data?.code, 404) 43 | assert.strictEqual(response?.data?.name, 'NotFound') 44 | } 45 | }) 46 | }) 47 | ` 48 | 49 | export const generate = (ctx: AppGeneratorContext) => 50 | Promise.resolve(ctx).then(renderSource(template, toFile('test', 'app.test'))) 51 | -------------------------------------------------------------------------------- /packages/generators/src/app/templates/client.test.tpl.ts: -------------------------------------------------------------------------------- 1 | import { toFile, when } from '@featherscloud/pinion' 2 | import { renderSource } from '../../commons.js' 3 | import { AppGeneratorContext } from '../index.js' 4 | 5 | const template = ({ lib }: AppGeneratorContext) => /* ts */ `import assert from 'assert' 6 | import axios from 'axios' 7 | import type { Server } from 'http' 8 | import { app } from '../${lib}/app' 9 | import { createClient } from '../${lib}/client' 10 | 11 | import rest from '@feathersjs/rest-client' 12 | 13 | const port = app.get('port') 14 | const appUrl = \`http://\${app.get('host')}:\${port}\` 15 | 16 | describe('client tests', () => { 17 | const client = createClient(rest(appUrl).axios(axios)) 18 | 19 | it('initialized the client', () => { 20 | assert.ok(client) 21 | }) 22 | }) 23 | ` 24 | 25 | export const generate = (ctx: AppGeneratorContext) => 26 | Promise.resolve(ctx).then( 27 | when((ctx) => ctx.client, renderSource(template, toFile('test', 'client.test'))) 28 | ) 29 | -------------------------------------------------------------------------------- /packages/generators/src/app/templates/index.tpl.ts: -------------------------------------------------------------------------------- 1 | import { toFile } from '@featherscloud/pinion' 2 | import { renderSource } from '../../commons.js' 3 | import { AppGeneratorContext } from '../index.js' 4 | 5 | const template = ({}: AppGeneratorContext) => /* ts */ `import { app } from './app' 6 | import { logger } from './logger' 7 | 8 | const port = app.get('port') 9 | const host = app.get('host') 10 | 11 | process.on('unhandledRejection', (reason) => 12 | logger.error('Unhandled Rejection %O', reason) 13 | ) 14 | 15 | app.listen(port).then(() => { 16 | logger.info(\`Feathers app listening on http://\${host}:\${port}\`) 17 | }) 18 | ` 19 | 20 | export const generate = (ctx: AppGeneratorContext) => 21 | Promise.resolve(ctx).then( 22 | renderSource( 23 | template, 24 | toFile(({ lib }) => lib, 'index') 25 | ) 26 | ) 27 | -------------------------------------------------------------------------------- /packages/generators/src/app/templates/prettierrc.tpl.ts: -------------------------------------------------------------------------------- 1 | import { toFile, writeJSON } from '@featherscloud/pinion' 2 | import { AppGeneratorContext } from '../index.js' 3 | import { PRETTIERRC } from '../../commons.js' 4 | 5 | export const generate = (ctx: AppGeneratorContext) => 6 | Promise.resolve(ctx).then( 7 | writeJSON( 8 | (ctx) => ({ 9 | ...PRETTIERRC, 10 | parser: ctx.language === 'ts' ? 'typescript' : 'babel' 11 | }), 12 | toFile('.prettierrc') 13 | ) 14 | ) 15 | -------------------------------------------------------------------------------- /packages/generators/src/app/templates/services.tpl.ts: -------------------------------------------------------------------------------- 1 | import { toFile } from '@featherscloud/pinion' 2 | import { renderSource } from '../../commons.js' 3 | import { AppGeneratorContext } from '../index.js' 4 | 5 | const template = 6 | ({}: AppGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/application.html#configure-functions 7 | import type { Application } from '../declarations' 8 | 9 | export const services = (app: Application) => { 10 | // All services will be registered here 11 | } 12 | ` 13 | 14 | export const generate = (ctx: AppGeneratorContext) => 15 | Promise.resolve(ctx).then( 16 | renderSource( 17 | template, 18 | toFile(({ lib }) => lib, 'services', 'index') 19 | ) 20 | ) 21 | -------------------------------------------------------------------------------- /packages/generators/src/app/templates/tsconfig.json.tpl.ts: -------------------------------------------------------------------------------- 1 | import { toFile, when, writeJSON } from '@featherscloud/pinion' 2 | import { AppGeneratorContext } from '../index.js' 3 | 4 | export const generate = (ctx: AppGeneratorContext) => 5 | Promise.resolve(ctx).then( 6 | when( 7 | (ctx) => ctx.language === 'ts', 8 | writeJSON( 9 | ({ lib }) => ({ 10 | 'ts-node': { 11 | files: true 12 | }, 13 | compilerOptions: { 14 | target: 'es2020', 15 | module: 'commonjs', 16 | outDir: './lib', 17 | rootDir: `./${lib}`, 18 | declaration: true, 19 | strict: true, 20 | esModuleInterop: true, 21 | sourceMap: true 22 | }, 23 | include: [lib], 24 | exclude: ['test'] 25 | }), 26 | toFile('tsconfig.json') 27 | ) 28 | ) 29 | ) 30 | -------------------------------------------------------------------------------- /packages/generators/src/app/templates/validators.tpl.ts: -------------------------------------------------------------------------------- 1 | import { toFile } from '@featherscloud/pinion' 2 | import { renderSource } from '../../commons.js' 3 | import { AppGeneratorContext } from '../index.js' 4 | 5 | const validatorTemplate = /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/validators.html 6 | import { Ajv, addFormats } from '@feathersjs/schema' 7 | import type { FormatsPluginOptions } from '@feathersjs/schema' 8 | 9 | const formats: FormatsPluginOptions = [ 10 | 'date-time', 11 | 'time', 12 | 'date', 13 | 'email', 14 | 'hostname', 15 | 'ipv4', 16 | 'ipv6', 17 | 'uri', 18 | 'uri-reference', 19 | 'uuid', 20 | 'uri-template', 21 | 'json-pointer', 22 | 'relative-json-pointer', 23 | 'regex' 24 | ] 25 | 26 | export const dataValidator: Ajv = addFormats(new Ajv({}), formats) 27 | 28 | export const queryValidator: Ajv = addFormats(new Ajv({ 29 | coerceTypes: true 30 | }), formats) 31 | ` 32 | 33 | export const generate = (ctx: AppGeneratorContext) => 34 | Promise.resolve(ctx).then( 35 | renderSource( 36 | validatorTemplate, 37 | toFile(({ lib }) => lib, 'validators') 38 | ) 39 | ) 40 | -------------------------------------------------------------------------------- /packages/generators/src/authentication/templates/declarations.tpl.ts: -------------------------------------------------------------------------------- 1 | import { inject, before, toFile, when, append } from '@featherscloud/pinion' 2 | import { AuthenticationGeneratorContext } from '../index.js' 3 | 4 | const importTemplate = ({ 5 | upperName, 6 | folder, 7 | fileName 8 | }: AuthenticationGeneratorContext) => /* ts */ `import { ${upperName} } from './services/${folder.join( 9 | '/' 10 | )}/${fileName}' 11 | ` 12 | 13 | const paramsTemplate = ({ 14 | entity, 15 | upperName 16 | }: AuthenticationGeneratorContext) => /* ts */ `// Add the ${entity} as an optional property to all params 17 | declare module '@feathersjs/feathers' { 18 | interface Params { 19 | ${entity}?: ${upperName} 20 | } 21 | } 22 | ` 23 | 24 | const toDeclarationFile = toFile(({ lib }) => lib, 'declarations.ts') 25 | 26 | export const generate = (ctx: AuthenticationGeneratorContext) => 27 | Promise.resolve(ctx) 28 | .then( 29 | when( 30 | (ctx) => ctx.language === 'ts', 31 | inject( 32 | importTemplate, 33 | before(/export \{ NextFunction \}|export type \{ NextFunction \}/), 34 | toDeclarationFile 35 | ) 36 | ) 37 | ) 38 | .then(when((ctx) => ctx.language === 'ts', inject(paramsTemplate, append(), toDeclarationFile))) 39 | -------------------------------------------------------------------------------- /packages/generators/src/hook/index.ts: -------------------------------------------------------------------------------- 1 | import { dirname } from 'path' 2 | import { fileURLToPath } from 'url' 3 | import { prompt, runGenerators } from '@featherscloud/pinion' 4 | import _ from 'lodash' 5 | import { checkPreconditions, FeathersBaseContext, initializeBaseContext } from '../commons.js' 6 | 7 | // Set __dirname in es module 8 | const __dirname = dirname(fileURLToPath(import.meta.url)) 9 | 10 | export interface HookGeneratorContext extends FeathersBaseContext { 11 | name: string 12 | camelName: string 13 | kebabName: string 14 | type: 'regular' | 'around' 15 | } 16 | 17 | export const generate = (ctx: HookGeneratorContext) => 18 | Promise.resolve(ctx) 19 | .then(initializeBaseContext()) 20 | .then(checkPreconditions()) 21 | .then( 22 | prompt(({ type, name }) => [ 23 | { 24 | type: 'input', 25 | name: 'name', 26 | message: 'What is the name of the hook?', 27 | when: !name 28 | }, 29 | { 30 | name: 'type', 31 | type: 'list', 32 | when: !type, 33 | message: 'What kind of hook is it?', 34 | choices: [ 35 | { value: 'around', name: 'Around' }, 36 | { value: 'regular', name: 'Before, After or Error' } 37 | ] 38 | } 39 | ]) 40 | ) 41 | .then((ctx) => { 42 | const { name } = ctx 43 | const kebabName = _.kebabCase(name) 44 | const camelName = _.camelCase(name) 45 | 46 | return { 47 | ...ctx, 48 | kebabName, 49 | camelName 50 | } 51 | }) 52 | .then(runGenerators(__dirname, 'templates')) 53 | -------------------------------------------------------------------------------- /packages/generators/src/hook/templates/hook.tpl.ts: -------------------------------------------------------------------------------- 1 | import { toFile } from '@featherscloud/pinion' 2 | import { HookGeneratorContext } from '../index.js' 3 | import { renderSource } from '../../commons.js' 4 | 5 | const aroundTemplate = ({ 6 | camelName, 7 | name 8 | }: HookGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/hook.html 9 | import type { HookContext, NextFunction } from '../declarations' 10 | 11 | export const ${camelName} = async (context: HookContext, next: NextFunction) => { 12 | console.log(\`Running hook ${name} on \${context.path}\.\${context.method}\`) 13 | await next() 14 | } 15 | ` 16 | 17 | const regularTemplate = ({ 18 | camelName, 19 | name 20 | }: HookGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/hook.html 21 | import type { HookContext } from '../declarations' 22 | 23 | export const ${camelName} = async (context: HookContext) => { 24 | console.log(\`Running hook ${name} on \${context.path}\.\${context.method}\`) 25 | }` 26 | 27 | export const generate = (ctx: HookGeneratorContext) => 28 | Promise.resolve(ctx).then( 29 | renderSource( 30 | (ctx) => (ctx.type === 'around' ? aroundTemplate(ctx) : regularTemplate(ctx)), 31 | toFile(({ lib, kebabName }) => [lib, 'hooks', kebabName]) 32 | ) 33 | ) 34 | -------------------------------------------------------------------------------- /packages/generators/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@featherscloud/pinion' 2 | 3 | export * from './commons.js' 4 | export * as app from './app/index.js' 5 | export * as authentication from './authentication/index.js' 6 | export * as connection from './connection/index.js' 7 | export * as hook from './hook/index.js' 8 | export * as service from './service/index.js' 9 | -------------------------------------------------------------------------------- /packages/generators/src/service/templates/client.tpl.ts: -------------------------------------------------------------------------------- 1 | import { toFile, after, before, when } from '@featherscloud/pinion' 2 | import { fileExists, injectSource } from '../../commons.js' 3 | import { ServiceGeneratorContext } from '../index.js' 4 | 5 | const importTemplate = ({ upperName, folder, fileName, camelName }: ServiceGeneratorContext) => /* ts */ ` 6 | import { ${camelName}Client } from './services/${folder.join('/')}/${fileName}.shared' 7 | export type { 8 | ${upperName}, 9 | ${upperName}Data, 10 | ${upperName}Query, 11 | ${upperName}Patch 12 | } from './services/${folder.join('/')}/${fileName}.shared' 13 | ` 14 | 15 | const registrationTemplate = ({ camelName }: ServiceGeneratorContext) => 16 | ` client.configure(${camelName}Client)` 17 | 18 | const toClientFile = toFile(({ lib }) => [lib, 'client']) 19 | 20 | export const generate = async (ctx: ServiceGeneratorContext) => 21 | Promise.resolve(ctx).then( 22 | when( 23 | ({ lib, language }) => fileExists(lib, `client.${language}`), 24 | injectSource(registrationTemplate, before('return client'), toClientFile), 25 | injectSource( 26 | importTemplate, 27 | after(({ language }) => 28 | language === 'ts' ? 'import type { AuthenticationClientOptions }' : 'import authenticationClient' 29 | ), 30 | toClientFile 31 | ) 32 | ) 33 | ) 34 | -------------------------------------------------------------------------------- /packages/generators/src/service/templates/test.tpl.ts: -------------------------------------------------------------------------------- 1 | import { toFile } from '@featherscloud/pinion' 2 | import { renderSource } from '../../commons.js' 3 | import { ServiceGeneratorContext } from '../index.js' 4 | 5 | const template = ({ 6 | relative, 7 | lib, 8 | path 9 | }: ServiceGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/service.test.html 10 | import assert from 'assert' 11 | import { app } from '../${relative}/${lib}/app' 12 | 13 | describe('${path} service', () => { 14 | it('registered the service', () => { 15 | const service = app.service('${path}') 16 | 17 | assert.ok(service, 'Registered the service') 18 | }) 19 | }) 20 | ` 21 | 22 | export const generate = (ctx: ServiceGeneratorContext) => 23 | Promise.resolve(ctx).then( 24 | renderSource( 25 | template, 26 | toFile(({ test, folder, fileName }) => [ 27 | test, 28 | 'services', 29 | ...folder, 30 | `${fileName}.test` 31 | ]) 32 | ) 33 | ) 34 | -------------------------------------------------------------------------------- /packages/generators/test/build/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feathersjs/feathers/7f38ebf629175a6b685d5b15c075fbb2856ceef8/packages/generators/test/build/.gitkeep -------------------------------------------------------------------------------- /packages/generators/test/commons.test.ts: -------------------------------------------------------------------------------- 1 | import { strictEqual } from 'assert' 2 | import { getJavaScript } from '../lib/commons' 3 | 4 | describe('common tests', () => { 5 | it('getJavaScript returns transpiled JavaScript', () => { 6 | const transpiled = getJavaScript( 7 | `import bla from 'bla' 8 | import something from './file' 9 | 10 | type X = { name: string } 11 | 12 | function test (arg: X) { 13 | bla(something) 14 | } 15 | 16 | // This is a comment 17 | const otherThing: string = "Hello" 18 | ` 19 | ) 20 | 21 | strictEqual( 22 | transpiled, 23 | `import bla from 'bla'; 24 | import something from './file.js'; 25 | 26 | function test(arg) { 27 | bla(something); 28 | } 29 | 30 | // This is a comment 31 | const otherThing = "Hello"; 32 | ` 33 | ) 34 | 35 | strictEqual( 36 | getJavaScript(`import { authentication } from './authentication'`), 37 | `import { authentication } from './authentication.js'` 38 | ) 39 | }) 40 | }) 41 | -------------------------------------------------------------------------------- /packages/generators/test/utils.ts: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import pkg from '../package.json' 3 | import { DependencyVersions } from '../src/commons' 4 | import { readFileSync } from 'fs' 5 | 6 | // Set __dirname in es module 7 | const __dirname = path.dirname(new URL(import.meta.url).pathname) 8 | 9 | export function combinate>(obj: O) { 10 | let combos: { [k in keyof O]: O[k][number] }[] = [] 11 | for (const key of Object.keys(obj)) { 12 | const values = obj[key] 13 | const all: any[] = [] 14 | for (let i = 0; i < values.length; i++) { 15 | for (let j = 0; j < (combos.length || 1); j++) { 16 | const newCombo = { ...combos[j], [key]: values[i] } 17 | all.push(newCombo) 18 | } 19 | } 20 | combos = all 21 | } 22 | return combos 23 | } 24 | 25 | export const dependencyVersions = Object.keys(pkg.devDependencies as any) 26 | .filter((dep) => dep.startsWith('@feathersjs/')) 27 | .reduce((acc, dep) => { 28 | const [, name] = dep.split('/') 29 | const { version } = JSON.parse( 30 | readFileSync(path.join(__dirname, '..', '..', name, 'package.json'), 'utf8').toString() 31 | ) 32 | 33 | acc[dep] = path.join(__dirname, 'build', `feathersjs-${name}-${version}.tgz`) 34 | 35 | return acc 36 | }, {} as DependencyVersions) 37 | -------------------------------------------------------------------------------- /packages/generators/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib", 8 | "module": "ESNext", 9 | "moduleResolution": "Node" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/knex/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/knex/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/knex 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/mongodb.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/mongodb) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > Feathers SQL service adapter using KnexJS 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/knex --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers Knex adapter documentation](https://feathersjs.com/api/databases/knex.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/knex/src/declarations.ts: -------------------------------------------------------------------------------- 1 | import { Knex } from 'knex' 2 | import { AdapterServiceOptions, AdapterParams, AdapterQuery } from '@feathersjs/adapter-commons' 3 | 4 | export interface KnexAdapterOptions extends AdapterServiceOptions { 5 | Model: Knex 6 | name: string 7 | schema?: string 8 | tableOptions?: { 9 | only?: boolean 10 | } 11 | extendedOperators?: { 12 | [key: string]: string 13 | } 14 | } 15 | 16 | export interface KnexAdapterTransaction { 17 | starting: boolean 18 | parent?: KnexAdapterTransaction 19 | committed?: Promise 20 | resolve?: any 21 | trx?: Knex.Transaction 22 | id?: number 23 | promise?: Promise 24 | } 25 | 26 | export interface KnexAdapterParams extends AdapterParams> { 27 | knex?: Knex.QueryBuilder 28 | transaction?: KnexAdapterTransaction 29 | } 30 | -------------------------------------------------------------------------------- /packages/knex/test/connection.ts: -------------------------------------------------------------------------------- 1 | export default (DB: string) => { 2 | if (DB === 'mysql') { 3 | return { 4 | client: 'mysql', 5 | connection: { 6 | host: '127.0.0.1', 7 | user: 'root', 8 | password: '', 9 | database: 'feathers_knex' 10 | } 11 | } 12 | } 13 | 14 | if (DB === 'postgres') { 15 | return { 16 | client: 'postgresql', 17 | connection: { 18 | host: 'localhost', 19 | database: 'feathers', 20 | user: 'postgres', 21 | password: 'postgres' 22 | } 23 | } 24 | } 25 | 26 | return { 27 | client: 'sqlite3', 28 | connection: { 29 | filename: './db.sqlite' 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/knex/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/koa/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Feathers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/koa/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/koa 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/koa.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/koa) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > Feathers KoaJS framework bindings and REST provider 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/koa --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers Koa API documentation](https://feathersjs.com/api/koa.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/koa/src/declarations.ts: -------------------------------------------------------------------------------- 1 | import Koa, { Next } from 'koa' 2 | import { Server } from 'http' 3 | import { Application as FeathersApplication, HookContext, Params, RouteLookup } from '@feathersjs/feathers' 4 | import '@feathersjs/authentication' 5 | 6 | export type ApplicationAddons = { 7 | server: Server 8 | listen(port?: number, ...args: any[]): Promise 9 | } 10 | 11 | export type Application = Omit & 12 | FeathersApplication & 13 | ApplicationAddons 14 | 15 | export type FeathersKoaContext = Koa.Context & { 16 | app: A 17 | } 18 | 19 | export type Middleware = (context: FeathersKoaContext, next: Next) => any 20 | 21 | declare module '@feathersjs/feathers/lib/declarations' { 22 | interface ServiceOptions { 23 | koa?: { 24 | before?: Middleware[] 25 | after?: Middleware[] 26 | composed?: Middleware 27 | } 28 | } 29 | } 30 | 31 | declare module 'koa' { 32 | interface ExtendableContext { 33 | feathers?: Partial 34 | lookup?: RouteLookup 35 | hook?: HookContext 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/koa/src/handlers.ts: -------------------------------------------------------------------------------- 1 | import { FeathersError, NotFound } from '@feathersjs/errors' 2 | import { FeathersKoaContext } from './declarations' 3 | 4 | export const errorHandler = () => async (ctx: FeathersKoaContext, next: () => Promise) => { 5 | try { 6 | await next() 7 | 8 | if (ctx.body === undefined) { 9 | throw new NotFound(`Path ${ctx.path} not found`) 10 | } 11 | } catch (error: any) { 12 | ctx.response.status = error instanceof FeathersError ? error.code : 500 13 | ctx.body = 14 | typeof error.toJSON === 'function' 15 | ? error.toJSON() 16 | : { 17 | message: error.message 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/koa/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/memory/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/memory/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/memory 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/memory.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/memory) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > A Feathers service adapter for in-memory data storage that works on all platforms. 8 | 9 | ## Installation 10 | 11 | ```bash 12 | $ npm install --save @feathersjs/memory 13 | ``` 14 | 15 | ## Documentation 16 | 17 | See [FeathersJS Memory Adapter API documentation](https://feathersjs.com/api/databases/memory.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/memory/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/mongodb/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/mongodb/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/mongodb 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/mongodb.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/mongodb) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > Feathers MongoDB service adapter 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/mongodb --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers MongoDB adapter documentation](https://feathersjs.com/api/databases/mongodb.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/mongodb/src/error-handler.ts: -------------------------------------------------------------------------------- 1 | import { GeneralError } from '@feathersjs/errors' 2 | import { MongoError } from 'mongodb' 3 | 4 | export function errorHandler(error: MongoError): any { 5 | // See https://github.com/mongodb/mongo/blob/master/docs/errors.md 6 | if (error && error.name && error.name.startsWith('Mongo')) { 7 | throw new GeneralError(error, { 8 | name: error.name, 9 | code: error.code 10 | }) 11 | } 12 | 13 | throw error 14 | } 15 | -------------------------------------------------------------------------------- /packages/mongodb/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/rest-client/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/rest-client/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/rest-client 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/rest-client.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/rest-client) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > REST client services for different HTTP libraries 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/rest-client --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers REST client API documentation](https://feathersjs.com/api/client/rest.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/rest-client/src/axios.ts: -------------------------------------------------------------------------------- 1 | import { Params } from '@feathersjs/feathers' 2 | import { Base, RestClientParams } from './base' 3 | 4 | export class AxiosClient, P extends Params = RestClientParams> extends Base { 5 | request(options: any, params: RestClientParams) { 6 | const config = Object.assign( 7 | { 8 | url: options.url, 9 | method: options.method, 10 | data: options.body, 11 | headers: Object.assign( 12 | { 13 | Accept: 'application/json' 14 | }, 15 | this.options.headers, 16 | options.headers 17 | ) 18 | }, 19 | params.connection 20 | ) 21 | 22 | return this.connection 23 | .request(config) 24 | .then((res: any) => res.data) 25 | .catch((error: any) => { 26 | const response = error.response || error 27 | 28 | throw response instanceof Error ? response : response.data || response 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/rest-client/src/fetch.ts: -------------------------------------------------------------------------------- 1 | import { errors } from '@feathersjs/errors' 2 | import { Params } from '@feathersjs/feathers' 3 | import { Base, RestClientParams } from './base' 4 | 5 | export class FetchClient, P extends Params = RestClientParams> extends Base { 6 | request(options: any, params: RestClientParams) { 7 | const fetchOptions = Object.assign({}, options, params.connection) 8 | 9 | fetchOptions.headers = Object.assign( 10 | { 11 | Accept: 'application/json' 12 | }, 13 | this.options.headers, 14 | fetchOptions.headers 15 | ) 16 | 17 | if (options.body) { 18 | fetchOptions.body = JSON.stringify(options.body) 19 | } 20 | 21 | return this.connection(options.url, fetchOptions) 22 | .then(this.checkStatus) 23 | .then((response: any) => { 24 | if (response.status === 204) { 25 | return null 26 | } 27 | 28 | return response.json() 29 | }) 30 | } 31 | 32 | checkStatus(response: any) { 33 | if (response.ok) { 34 | return response 35 | } 36 | 37 | return response 38 | .json() 39 | .catch(() => { 40 | const ErrorClass = (errors as any)[response.status] || Error 41 | 42 | return new ErrorClass('JSON parsing error') 43 | }) 44 | .then((error: any) => { 45 | error.response = response 46 | throw error 47 | }) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /packages/rest-client/src/superagent.ts: -------------------------------------------------------------------------------- 1 | import { Params } from '@feathersjs/feathers' 2 | import { Base, RestClientParams } from './base' 3 | 4 | export class SuperagentClient, P extends Params = RestClientParams> extends Base< 5 | T, 6 | D, 7 | P 8 | > { 9 | request(options: any, params: RestClientParams) { 10 | const superagent = this.connection(options.method, options.url) 11 | .set(this.options.headers || {}) 12 | .set('Accept', 'application/json') 13 | .set(params.connection || {}) 14 | .set(options.headers || {}) 15 | .type(options.type || 'json') 16 | 17 | return new Promise((resolve, reject) => { 18 | superagent.set(options.headers) 19 | 20 | if (options.body) { 21 | superagent.send(options.body) 22 | } 23 | 24 | superagent.end(function (error: any, res: any) { 25 | if (error) { 26 | try { 27 | const response = error.response 28 | error = JSON.parse(error.response.text) 29 | error.response = response 30 | } catch (e: any) {} 31 | 32 | return reject(error) 33 | } 34 | 35 | resolve(res && res.body) 36 | }) 37 | }) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/rest-client/test/declarations.ts: -------------------------------------------------------------------------------- 1 | import { CustomMethod } from '@feathersjs/feathers' 2 | import { RestService } from '../src' 3 | 4 | type Data = { message: string } 5 | type Result = { 6 | data: Data 7 | provider: string 8 | type: string 9 | } 10 | 11 | export type ServiceTypes = { 12 | todos: RestService & { 13 | customMethod: CustomMethod 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/rest-client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/schema/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/schema/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/schema 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/schema.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/schema) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > A common data schema definition format 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/schema --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers schema API documentation](https://feathersjs.com/api/schema/) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/schema/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './resolve' 2 | export * from './validate' 3 | -------------------------------------------------------------------------------- /packages/schema/src/index.ts: -------------------------------------------------------------------------------- 1 | import addFormats, { FormatName, FormatOptions, FormatsPluginOptions } from 'ajv-formats' 2 | import { ResolverStatus } from './resolver' 3 | 4 | export type { FromSchema } from 'json-schema-to-ts' 5 | export { addFormats, FormatName, FormatOptions, FormatsPluginOptions } 6 | 7 | export * from './schema' 8 | export * from './resolver' 9 | export * from './hooks' 10 | export * from './json-schema' 11 | export * from './default-schemas' 12 | 13 | export * as hooks from './hooks' 14 | export * as jsonSchema from './json-schema' 15 | 16 | export type Infer = S['_type'] 17 | 18 | export type Combine = Pick, Exclude, keyof U>> & U 19 | 20 | declare module '@feathersjs/feathers/lib/declarations' { 21 | interface Params { 22 | resolve?: ResolverStatus 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/schema/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/socketio-client/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/socketio-client/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/socketio-client 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/socketio-client.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/socketio-client) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > Client for Socket.io Feathers connections 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/socketio-client --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers SocketIO API documentation](https://feathersjs.com/api/client/socketio.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/socketio-client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/socketio/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/socketio/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/socketio 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/socketio.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/socketio) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > The Feathers Socket.io real-time API provider 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/socketio --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers SocketIO API documentation](https://feathersjs.com/api/socketio.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/socketio/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/tests/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/tests/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/tests 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/tests.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/tests) 5 | 6 | > Common tests for Feathers core modules 7 | -------------------------------------------------------------------------------- /packages/tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@feathersjs/tests", 3 | "private": true, 4 | "description": "Feathers core module common tests", 5 | "version": "5.0.34", 6 | "homepage": "https://feathersjs.com", 7 | "main": "lib/", 8 | "types": "lib/", 9 | "keywords": [ 10 | "feathers" 11 | ], 12 | "license": "MIT", 13 | "funding": { 14 | "type": "github", 15 | "url": "https://github.com/sponsors/daffl" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "git://github.com/feathersjs/feathers.git", 20 | "directory": "packages/tests" 21 | }, 22 | "author": { 23 | "name": "Feathers contributors", 24 | "email": "hello@feathersjs.com", 25 | "url": "https://feathersjs.com" 26 | }, 27 | "contributors": [], 28 | "bugs": { 29 | "url": "https://github.com/feathersjs/feathers/issues" 30 | }, 31 | "engines": { 32 | "node": ">= 12" 33 | }, 34 | "scripts": { 35 | "prepublish": "npm run compile", 36 | "pack": "echo \"not necessary\"", 37 | "test": "echo \"not necessary\"", 38 | "compile": "shx rm -rf lib/ && tsc" 39 | }, 40 | "directories": { 41 | "lib": "lib" 42 | }, 43 | "publishConfig": { 44 | "access": "public" 45 | }, 46 | "dependencies": { 47 | "@types/lodash": "^4.17.16", 48 | "axios": "^1.9.0", 49 | "lodash": "^4.17.21" 50 | }, 51 | "devDependencies": { 52 | "@feathersjs/feathers": "^5.0.34", 53 | "@types/mocha": "^10.0.10", 54 | "@types/node": "^22.15.3", 55 | "mocha": "^11.2.2", 56 | "shx": "^0.4.0", 57 | "ts-node": "^10.9.2", 58 | "typescript": "^5.8.3" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /packages/tests/resources/certificate.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICmzCCAgQCCQDugFqITnU/sDANBgkqhkiG9w0BAQUFADCBkTELMAkGA1UEBhMC 3 | Q0ExEDAOBgNVBAgTB0FsYmVydGExEDAOBgNVBAcTB0NhbGdhcnkxETAPBgNVBAoT 4 | CEZlYXRoZXJzMREwDwYDVQQLEwhGZWF0aGVyczETMBEGA1UEAxMKRmVhdGhlcnNK 5 | UzEjMCEGCSqGSIb3DQEJARYUaGVsbG9AZmVhdGhlcnNqcy5jb20wHhcNMTQwMTA0 6 | MDIwNTUyWhcNMTQwMjAzMDIwNTUyWjCBkTELMAkGA1UEBhMCQ0ExEDAOBgNVBAgT 7 | B0FsYmVydGExEDAOBgNVBAcTB0NhbGdhcnkxETAPBgNVBAoTCEZlYXRoZXJzMREw 8 | DwYDVQQLEwhGZWF0aGVyczETMBEGA1UEAxMKRmVhdGhlcnNKUzEjMCEGCSqGSIb3 9 | DQEJARYUaGVsbG9AZmVhdGhlcnNqcy5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0A 10 | MIGJAoGBALixfLwrvDDYAaaU62oycz8zwUpxCguyyXyhVDN/KMmP/I+HfkbcIrqj 11 | tW0jbpRWiLhn5cw4K/cUTkfMj4AwaN5t2zq0FVFJdIddLxzuamyJLJFZfs5sPYWt 12 | X6morPcu9RM7jwb3R1V852XjVWUj8neUAu7eUzKoSQ575kHsnKrdAgMBAAEwDQYJ 13 | KoZIhvcNAQEFBQADgYEATVlxNPkSgkqBF4foUYNGnkvaiwhd88Mh/Ya3T3EnknF9 14 | Gz6KrlwWDDI8MkPmqabT2Ijg3LSec7WV+C8SETVFbWLOGV6N1ZVfodFzJ7EKMz5e 15 | VvEIKnHfHpYOEa21E5u02+OfKahtW37eTEVmvcV67vYmW4HNa5QSZ5qfrrqcUhc= 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /packages/tests/resources/certrequest.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIB0jCCATsCAQAwgZExCzAJBgNVBAYTAkNBMRAwDgYDVQQIEwdBbGJlcnRhMRAw 3 | DgYDVQQHEwdDYWxnYXJ5MREwDwYDVQQKEwhGZWF0aGVyczERMA8GA1UECxMIRmVh 4 | dGhlcnMxEzARBgNVBAMTCkZlYXRoZXJzSlMxIzAhBgkqhkiG9w0BCQEWFGhlbGxv 5 | QGZlYXRoZXJzanMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4sXy8 6 | K7ww2AGmlOtqMnM/M8FKcQoLssl8oVQzfyjJj/yPh35G3CK6o7VtI26UVoi4Z+XM 7 | OCv3FE5HzI+AMGjebds6tBVRSXSHXS8c7mpsiSyRWX7ObD2FrV+pqKz3LvUTO48G 8 | 90dVfOdl41VlI/J3lALu3lMyqEkOe+ZB7Jyq3QIDAQABoAAwDQYJKoZIhvcNAQEF 9 | BQADgYEAFN1xm2Jc5EwDsiJwjUQkVCYLfAPz8FxLx8XCY7JugPCZWxeJ3w9C3Ymz 10 | hET//7uxNg6q7EO9CI33vP5eOdI8oC8XQffh4GzCoSrmGrKpHSqVh3zN/rCoB4BY 11 | f4nJofTka5iENjMdA0R8//Wp7F1u7xhriuxaRiZoFEPaCIsrvK4= 12 | -----END CERTIFICATE REQUEST----- 13 | -------------------------------------------------------------------------------- /packages/tests/resources/privatekey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXAIBAAKBgQC4sXy8K7ww2AGmlOtqMnM/M8FKcQoLssl8oVQzfyjJj/yPh35G 3 | 3CK6o7VtI26UVoi4Z+XMOCv3FE5HzI+AMGjebds6tBVRSXSHXS8c7mpsiSyRWX7O 4 | bD2FrV+pqKz3LvUTO48G90dVfOdl41VlI/J3lALu3lMyqEkOe+ZB7Jyq3QIDAQAB 5 | AoGAYCTkzf/mY3bOxSzYr9u7ardCc8IMfLKBeMNy1avoS6UM0Jqz/acy3P3DwCCl 6 | u8qgOX68fWbwXBrR9UZjnVOWAvAgACS9bSTR4UxXuHve9YHf1s1Idm1Ck8CopiuY 7 | 0PTiuF7OJp6U7fc1RjO5F5tvSMuYbh+68Vpx9SQRfDHYqnECQQD1KnhSRDjLCfoB 8 | lLfTew99W51OTx2NPRKRXwZH/YwlgRl/cAgJhdemah/AAavB6BUdqEXdiIviEHuT 9 | UsfAXhf7AkEAwNrmEI3B4gtMRKJAsyWAKGFxDHuC9wGkhSxCVihQuxXtqEMX7Qnx 10 | ucU9bRRtUgVPcOmFEtpPsI4e0wkTMg+ZBwJAPL+ERuYuqGjVcPTXw+g3Q1mjFddW 11 | vDuI0UqZdNcnlddyaPhqlWl7sPmU2m/PjmGicdHTVfxSpPZumGenpUvrZwJAdodS 12 | 9QObEOmus1Qhfbljne3dhDV5FYTd77d3Aer/Syy8BzlNQDNnbKysBxmR4uI+o//x 13 | +NdSOQnwKfYe5RqvCwJBAMfq911uzlD8Kd9s0n+MJe8b5/duYOtgPZvaIFWOWyNm 14 | 0aJE/VovVhk2JGvIU9kxdgt9O4N0x2XukS2hq7I1Xts= 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /packages/tests/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './client' 2 | export * from './rest' 3 | export * from './fixture' 4 | -------------------------------------------------------------------------------- /packages/tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/transport-commons/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/transport-commons/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/transport-commons 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/transport-commons.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/transport-commons) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > Shared functionality for Feathers API transports like `@feathers/socketio` and `@feathersjs/primus`. Only intended to be used internally. 8 | 9 | ## License 10 | 11 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 12 | 13 | Licensed under the [MIT license](LICENSE). 14 | -------------------------------------------------------------------------------- /packages/transport-commons/client.d.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/client' 2 | -------------------------------------------------------------------------------- /packages/transport-commons/client.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/client'); -------------------------------------------------------------------------------- /packages/transport-commons/src/channels/channel/base.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from 'events' 2 | import { RealTimeConnection } from '@feathersjs/feathers' 3 | 4 | export class Channel extends EventEmitter { 5 | connections: RealTimeConnection[] 6 | data: any 7 | 8 | constructor(connections: RealTimeConnection[] = [], data: any = null) { 9 | super() 10 | 11 | this.connections = connections 12 | this.data = data 13 | } 14 | 15 | get length() { 16 | return this.connections.length 17 | } 18 | 19 | leave(...connections: RealTimeConnection[]) { 20 | connections.forEach((current) => { 21 | if (typeof current === 'function') { 22 | const callback = current as (connection: RealTimeConnection) => boolean 23 | 24 | this.leave(...this.connections.filter(callback)) 25 | } else { 26 | const index = this.connections.indexOf(current) 27 | 28 | if (index !== -1) { 29 | this.connections.splice(index, 1) 30 | } 31 | } 32 | }) 33 | 34 | if (this.length === 0) { 35 | this.emit('empty') 36 | } 37 | 38 | return this 39 | } 40 | 41 | join(...connections: RealTimeConnection[]) { 42 | connections.forEach((connection) => { 43 | if (connection && this.connections.indexOf(connection) === -1) { 44 | this.connections.push(connection) 45 | } 46 | }) 47 | 48 | return this 49 | } 50 | 51 | filter(fn: (connection: RealTimeConnection) => boolean) { 52 | return new Channel(this.connections.filter(fn), this.data) 53 | } 54 | 55 | send(data: any) { 56 | return new Channel(this.connections, data) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /packages/transport-commons/src/index.ts: -------------------------------------------------------------------------------- 1 | import { socket } from './socket' 2 | import { routing } from './routing' 3 | import { channels, Channel, CombinedChannel } from './channels' 4 | import { RealTimeConnection } from '@feathersjs/feathers' 5 | 6 | export * as http from './http' 7 | export { socket, routing, channels, Channel, CombinedChannel, RealTimeConnection } 8 | -------------------------------------------------------------------------------- /packages/transport-commons/test/channels/index.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-function */ 2 | import assert from 'assert' 3 | import { feathers } from '@feathersjs/feathers' 4 | import { channels, keys } from '../../src/channels' 5 | 6 | describe('feathers-channels', () => { 7 | it('has app.channel', () => { 8 | const app = feathers().configure(channels()) 9 | 10 | assert.strictEqual(typeof app.channel, 'function') 11 | assert.strictEqual(typeof (app as any)[keys.CHANNELS], 'object') 12 | assert.strictEqual(app.channels.length, 0) 13 | }) 14 | 15 | it('throws an error when called with nothing', () => { 16 | const app = feathers().configure(channels()) 17 | 18 | try { 19 | app.channel() 20 | assert.ok(false, 'Should never get here') 21 | } catch (e: any) { 22 | assert.strictEqual(e.message, 'app.channel needs at least one channel name') 23 | } 24 | }) 25 | 26 | it('configuring twice does nothing', () => { 27 | feathers().configure(channels()).configure(channels()) 28 | }) 29 | 30 | it('does not add things to the service if `dispatch` exists', () => { 31 | const app = feathers() 32 | .configure(channels()) 33 | .use('/test', { 34 | async setup() {}, 35 | publish() { 36 | return this 37 | } 38 | } as any) 39 | 40 | const service: any = app.service('test') 41 | 42 | assert.ok(!service[keys.PUBLISHERS]) 43 | }) 44 | }) 45 | -------------------------------------------------------------------------------- /packages/transport-commons/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/typebox/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Feathers Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/typebox/README.md: -------------------------------------------------------------------------------- 1 | # @feathersjs/typebox 2 | 3 | [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) 4 | [![Download Status](https://img.shields.io/npm/dm/@feathersjs/typebox.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/typebox) 5 | [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx) 6 | 7 | > [TypeBox](https://github.com/sinclairzx81/typebox) integration for @feathersjs/schema 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install @feathersjs/typebox --save 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Refer to the [Feathers TypeBox documentation](https://feathersjs.com/api/schema/typebox.html) for more details. 18 | 19 | ## License 20 | 21 | Copyright (c) 2024 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) 22 | 23 | Licensed under the [MIT license](LICENSE). 24 | -------------------------------------------------------------------------------- /packages/typebox/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "lib" 8 | } 9 | } 10 | --------------------------------------------------------------------------------