feat: Passwordless cross-device authentication

- Arkitektur: docs/auth/passwordless-architecture.md
- Backend: iom/quixzoom-auth-service/ (FastAPI + Redis)
- Webb: quixzoom-market-pages/se/login/ (QR-kod + polling)
- App: iom/quixzoom-app/src/features/auth/ (push + deep links)

Flöde: QR-kod → app-godkännande → webb-inloggad
This commit is contained in:
Bernt
2026-07-07 07:11:50 +00:00
parent 4aa984ad74
commit 6989a98d75
61843 changed files with 5491611 additions and 872231 deletions
+3
View File
@@ -0,0 +1,3 @@
{
"editor.formatOnSave": false
}
+190
View File
@@ -0,0 +1,190 @@
# History
## 1.13.2 / 2022-01-29
- [fix] `drives` singular form
- [feat] allow `inflect` to use floats
- [chore] upgrade packages
## 1.13.1 / 2021-05-21
- [fix] use correct version for `inflector.version`
- [build] reduce npm bundle size by excluding more files
- [build] use terser to create a minified file
## 1.13.0 / 2021-05-01
- [update packages] mocha->8.3.2, should->13.2.3
- [bug fix] `grammar` plural form
- [bug fix] `bonus` plural form
- [bug fix] `octopus` plural form
- [bug fix] `virus` plural form
- [info] add LICENSE file
- [info] additional maintainer @p-kuen. @ben-lin thanks for your trust!
## 1.12.0 / 2017-01-27
- [update packages] mocha->3.2.0, should->11.2.0
- [bug fix] `minus` plural & singular form
- [bug fix] `save` plural & singular form
## 1.11.0 / 2016-04-20
- [update packages] mocha->3.0.2, should->11.1.0
- [bug fix] `inflection.transform` in ES6
## 1.10.0 / 2016-04-20
- [update packages] should->8.3.1
- [bug fix] `campus` plural & singular form
## 1.9.0 / 2016-04-06
- [update packages] mocha->2.4.5, should->8.3.0
- [bug fix] `genus` plural & singular form
## 1.8.0 / 2015-11-22
- [update packages] mocha->2.3.4, should->7.1.1
- [bug fix] `criterion` plural & singular form
## 1.7.2 / 2015-10-11
- [update packages] mocha->2.3.3, should->7.1.0
## 1.7.1 / 2015-03-25
- [bug fix] `woman` plural & singular form
## 1.7.0 / 2015-03-25
- [bug fix] `canvas` plural & singular form
- [update packages] mocha->2.2.1, should->5.2.0
## 1.6.0 / 2014-12-06
- [bug fix] Special rules for index, vertex, and matrix masked by general rule x
- [update packages] mocha->2.1.0, should->4.6.5
## 1.5.3 / 2014-12-06
- [bug fix] Remove invalid uncountable words
## 1.5.2 / 2014-11-14
- [bug fix] `business` & `access` plural form
## 1.5.1 / 2014-09-23
- [bug fix] Fix `whereas` plural & singular form
## 1.5.0 / 2014-09-23
- [refactor] Add more rules and uncountable nouns
## 1.4.2 / 2014-09-05
- [bug fix] Fix wrong implementation of `goose`, `tooth` & `foot`
## 1.4.1 / 2014-08-31
- [bug fix] Fix `goose`, `tooth` & `foot` plural & singular form
## 1.4.0 / 2014-08-23
- [new feature] Adds support for an `inflect` method that will choose to pluralize or singularize a noun based on an integer value
## 1.3.8 / 2014-07-03
- [others] Syntax tuning
## 1.3.7 / 2014-06-25
- [refactor] Adopt UMD import to work in a variety of different situations
- [update packages] should->4.0.4
## 1.3.6 / 2014-06-07
- [bug fix] Rearrange rules. `movies`->`movy`
## 1.3.5 / 2014-02-12
- Unable to publsih v1.3.4 therefore jump to v1.3.5
## 1.3.4 / 2014-02-12
- [update packages] should->3.1.2
- [refactor] Use `mocha` instead of hard coding tests
## 1.3.3 / 2014-01-22
- [update packages] should->3.0.1
- Added brower.json
## 1.3.2 / 2013-12-12
- [update packages] node.flow->1.2.3
## 1.3.1 / 2013-12-12
- [refactor] Support `Requirejs`
## 1.3.0 / 2013-12-11
- [refactor] Move `var` out of loops
- [refactor] Change the way `camelize` acts to mimic 100% `Rails ActiveSupport Inflector camelize`
## 1.2.7 / 2013-12-11
- [new feature] Added transform, thnaks to `luk3thomas`
- [update packages] should->v2.1.1
## 1.2.6 / 2013-05-24
- [bug fix] Use instance instead of `this`
## 1.2.5 / 2013-01-09
- [refactor] Allow all caps strings to be returned from underscore
## 1.2.4 / 2013-01-06
- [bug fix] window obj does not have `call` method
## 1.2.3 / 2012-08-02
- [bug fix] Singularize `status` produces `statu`
- [update packages] should->v1.1.0
## 1.2.2 / 2012-07-23
- [update packages] node.flow->v1.1.3 & should->v1.0.0
## 1.2.1 / 2012-06-22
- [bug fix] Singularize `address` produces `addres`
## 1.2.0 / 2012-04-10
- [new feature] Browser support
- [update packages] node.flow->v1.1.1
## 1.1.1 / 2012-02-13
- [update packages] node.flow->v1.1.0
## 1.1.0 / 2012-02-13
- [update packages] node.flow->v1.0.0
- [refactor] Read version number from package.json
## 1.0.0 / 2012-02-08
- Remove make file
- Add pluralize rules
- Add pluralize tests
- [refactor] Use object.jey instead of for in
## 0.0.1 / 2012-01-16
- Initial release
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 dreamerslab
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+505
View File
@@ -0,0 +1,505 @@
# inflection
A port of inflection-js to node.js module
<a href="https://www.npmjs.com/package/inflection"><img src="https://img.shields.io/npm/v/inflection" alt="NPM Version" /></a>
## Description
[inflection-js](http://code.google.com/p/inflection-js/) is a port of the functionality from Ruby on Rails' Active Support Inflection classes into Javascript. `inflection` is a port of `inflection-js` to node.js npm package. Instead of [extending JavaScript native](http://wonko.com/post/extending-javascript-natives) String object like `inflection-js` does, `inflection` separate the methods to a independent package to avoid unexpected behaviors.
Note: This library uses [Wiktionary](http://en.wiktionary.org) as its reference.
## Requires
Checkout `package.json` for dependencies.
## Angular Support
Checkout [ngInflection](https://github.com/konsumer/ngInflection) from [konsumer](https://github.com/konsumer)
## Meteor Support
Checkout [Meteor Inflector](https://github.com/katrotz/meteor-inflector) from [Veaceslav Cotruta](https://github.com/katrotz)
## Installation
Install inflection through npm
npm install inflection
## API
- inflection.indexOf( arr, item, from_index, compare_func );
- inflection.pluralize( str, plural );
- inflection.singularize( str, singular );
- inflection.inflect( str, count, singular, plural );
- inflection.camelize( str, low_first_letter );
- inflection.underscore( str, all_upper_case );
- inflection.humanize( str, low_first_letter );
- inflection.capitalize( str );
- inflection.dasherize( str );
- inflection.titleize( str );
- inflection.demodulize( str );
- inflection.tableize( str );
- inflection.classify( str );
- inflection.foreign_key( str, drop_id_ubar );
- inflection.ordinalize( str );
- inflection.transform( str, arr );
## Usage
> Require the module before using
var inflection = require( 'inflection' );
### inflection.indexOf( arr, item, from_index, compare_func );
This lets us detect if an Array contains a given element.
#### Arguments
> arr
type: Array
desc: The subject array.
> item
type: Object
desc: Object to locate in the Array.
> from_index
type: Number
desc: Starts checking from this position in the Array.(optional)
> compare_func
type: Function
desc: Function used to compare Array item vs passed item.(optional)
#### Example code
var inflection = require( 'inflection' );
inflection.indexOf([ 'hi','there' ], 'guys' ); // === -1
inflection.indexOf([ 'hi','there' ], 'hi' ); // === 0
### inflection.pluralize( str, plural );
This function adds pluralization support to every String object.
#### Arguments
> str
type: String
desc: The subject string.
> plural
type: String
desc: Overrides normal output with said String.(optional)
#### Example code
var inflection = require( 'inflection' );
inflection.pluralize( 'person' ); // === 'people'
inflection.pluralize( 'octopus' ); // === "octopi"
inflection.pluralize( 'Hat' ); // === 'Hats'
inflection.pluralize( 'person', 'guys' ); // === 'guys'
### inflection.singularize( str, singular );
This function adds singularization support to every String object.
#### Arguments
> str
type: String
desc: The subject string.
> singular
type: String
desc: Overrides normal output with said String.(optional)
#### Example code
var inflection = require( 'inflection' );
inflection.singularize( 'people' ); // === 'person'
inflection.singularize( 'octopi' ); // === "octopus"
inflection.singularize( 'Hats' ); // === 'Hat'
inflection.singularize( 'guys', 'person' ); // === 'person'
### inflection.inflect( str, count, singular, plural );
This function will pluralize or singularlize a String appropriately based on an integer value.
#### Arguments
> str
type: String
desc: The subject string.
> count
type: Number
desc: The number to base pluralization off of.
> singular
type: String
desc: Overrides normal output with said String.(optional)
> plural
type: String
desc: Overrides normal output with said String.(optional)
#### Example code
var inflection = require( 'inflection' );
inflection.inflect( 'people', 1 ); // === 'person'
inflection.inflect( 'octopi', 1 ); // === 'octopus'
inflection.inflect( 'Hats', 1 ); // === 'Hat'
inflection.inflect( 'guys', 1 , 'person' ); // === 'person'
inflection.inflect( 'person', 2 ); // === 'people'
inflection.inflect( 'octopus', 2 ); // === 'octopi'
inflection.inflect( 'Hat', 2 ); // === 'Hats'
inflection.inflect( 'person', 2, null, 'guys' ); // === 'guys'
### inflection.camelize( str, low_first_letter );
This function transforms String object from underscore to camelcase.
#### Arguments
> str
type: String
desc: The subject string.
> low_first_letter
type: Boolean
desc: Default is to capitalize the first letter of the results. Passing true will lowercase it. (optional)
#### Example code
var inflection = require( 'inflection' );
inflection.camelize( 'message_properties' ); // === 'MessageProperties'
inflection.camelize( 'message_properties', true ); // === 'messageProperties'
### inflection.underscore( str, all_upper_case );
This function transforms String object from camelcase to underscore.
#### Arguments
> str
type: String
desc: The subject string.
> all_upper_case
type: Boolean
desc: Default is to lowercase and add underscore prefix
#### Example code
var inflection = require( 'inflection' );
inflection.underscore( 'MessageProperties' ); // === 'message_properties'
inflection.underscore( 'messageProperties' ); // === 'message_properties'
inflection.underscore( 'MP' ); // === 'm_p'
inflection.underscore( 'MP', true ); // === 'MP'
### inflection.humanize( str, low_first_letter );
This function adds humanize support to every String object.
#### Arguments
> str
type: String
desc: The subject string.
> low_first_letter
type: Boolean
desc: Default is to capitalize the first letter of the results. Passing true will lowercase it. (optional)
#### Example code
var inflection = require( 'inflection' );
inflection.humanize( 'message_properties' ); // === 'Message properties'
inflection.humanize( 'message_properties', true ); // === 'message properties'
### inflection.capitalize( str );
This function adds capitalization support to every String object.
#### Arguments
> str
type: String
desc: The subject string.
#### Example code
var inflection = require( 'inflection' );
inflection.capitalize( 'message_properties' ); // === 'Message_properties'
inflection.capitalize( 'message properties', true ); // === 'Message properties'
### inflection.dasherize( str );
This function replaces underscores with dashes in the string.
#### Arguments
> str
type: String
desc: The subject string.
#### Example code
var inflection = require( 'inflection' );
inflection.dasherize( 'message_properties' ); // === 'message-properties'
inflection.dasherize( 'Message Properties' ); // === 'Message-Properties'
### inflection.titleize( str );
This function adds titleize support to every String object.
#### Arguments
> str
type: String
desc: The subject string.
#### Example code
var inflection = require( 'inflection' );
inflection.titleize( 'message_properties' ); // === 'Message Properties'
inflection.titleize( 'message properties to keep' ); // === 'Message Properties to Keep'
### inflection.demodulize( str );
This function adds demodulize support to every String object.
#### Arguments
> str
type: String
desc: The subject string.
#### Example code
var inflection = require( 'inflection' );
inflection.demodulize( 'Message::Bus::Properties' ); // === 'Properties'
### inflection.tableize( str );
This function adds tableize support to every String object.
#### Arguments
> str
type: String
desc: The subject string.
#### Example code
var inflection = require( 'inflection' );
inflection.tableize( 'MessageBusProperty' ); // === 'message_bus_properties'
### inflection.classify( str );
This function adds classification support to every String object.
#### Arguments
> str
type: String
desc: The subject string.
#### Example code
var inflection = require( 'inflection' );
inflection.classify( 'message_bus_properties' ); // === 'MessageBusProperty'
### inflection.foreign_key( str, drop_id_ubar );
This function adds foreign key support to every String object.
#### Arguments
> str
type: String
desc: The subject string.
> low_first_letter
type: Boolean
desc: Default is to seperate id with an underbar at the end of the class name, you can pass true to skip it.(optional)
#### Example code
var inflection = require( 'inflection' );
inflection.foreign_key( 'MessageBusProperty' ); // === 'message_bus_property_id'
inflection.foreign_key( 'MessageBusProperty', true ); // === 'message_bus_propertyid'
### inflection.ordinalize( str );
This function adds ordinalize support to every String object.
#### Arguments
> str
type: String
desc: The subject string.
#### Example code
var inflection = require( 'inflection' );
inflection.ordinalize( 'the 1 pitch' ); // === 'the 1st pitch'
### inflection.transform( str, arr );
This function performs multiple inflection methods on a string.
#### Arguments
> str
type: String
desc: The subject string.
> arr
type: Array
desc: An array of inflection methods.
#### Example code
var inflection = require( 'inflection' );
inflection.transform( 'all job', [ 'pluralize', 'capitalize', 'dasherize' ]); // === 'All-jobs'
## Credit
- Ryan Schuft <ryan.schuft@gmail.com>
- Lance Pollard <lancejpollard@gmail.com> (Browser support)
- Dane O'Connor <dane.oconnor@gmail.com>
- brandondewitt
- luk3thomas
- Marcel Klehr
- Raymond Feng
- Kane Cohen <kanecohen@gmail.com>
- Gianni Chiappetta <gianni@runlevel6.org>
- Eric Brody
- overlookmotel
- Patrick Mowrer
- Greger Olsson
- Jason Crawford <jason@jasoncrawford.org>
- Ray Myers <ray.myers@gmail.com>
## License
(The MIT License)
Copyright (c) 2011 dreamerslab &lt;ben@dreamerslab.com&gt;
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+1095
View File
@@ -0,0 +1,1095 @@
/*!
* inflection
* Copyright(c) 2011 Ben Lin <ben@dreamerslab.com>
* MIT Licensed
*
* @fileoverview
* A port of inflection-js to node.js module.
*/
( function ( root, factory ){
if( typeof define === 'function' && define.amd ){
define([], factory );
}else if( typeof exports === 'object' ){
module.exports = factory();
}else{
root.inflection = factory();
}
}( this, function (){
/**
* @description This is a list of nouns that use the same form for both singular and plural.
* This list should remain entirely in lower case to correctly match Strings.
* @private
*/
var uncountable_words = [
// 'access',
'accommodation',
'adulthood',
'advertising',
'advice',
'aggression',
'aid',
'air',
'aircraft',
'alcohol',
'anger',
'applause',
'arithmetic',
// 'art',
'assistance',
'athletics',
// 'attention',
'bacon',
'baggage',
// 'ballet',
// 'beauty',
'beef',
// 'beer',
// 'behavior',
'biology',
// 'billiards',
'blood',
'botany',
// 'bowels',
'bread',
// 'business',
'butter',
'carbon',
'cardboard',
'cash',
'chalk',
'chaos',
'chess',
'crossroads',
'countryside',
// 'damage',
'dancing',
// 'danger',
'deer',
// 'delight',
// 'dessert',
'dignity',
'dirt',
// 'distribution',
'dust',
'economics',
'education',
'electricity',
// 'employment',
// 'energy',
'engineering',
'enjoyment',
// 'entertainment',
'envy',
'equipment',
'ethics',
'evidence',
'evolution',
// 'failure',
// 'faith',
'fame',
'fiction',
// 'fish',
'flour',
'flu',
'food',
// 'freedom',
// 'fruit',
'fuel',
'fun',
// 'funeral',
'furniture',
'gallows',
'garbage',
'garlic',
// 'gas',
'genetics',
// 'glass',
'gold',
'golf',
'gossip',
// 'grass',
'gratitude',
'grief',
// 'ground',
'guilt',
'gymnastics',
// 'hair',
'happiness',
'hardware',
'harm',
'hate',
'hatred',
'health',
'heat',
// 'height',
'help',
'homework',
'honesty',
'honey',
'hospitality',
'housework',
'humour',
'hunger',
'hydrogen',
'ice',
'importance',
'inflation',
'information',
// 'injustice',
'innocence',
// 'intelligence',
'iron',
'irony',
'jam',
// 'jealousy',
// 'jelly',
'jewelry',
// 'joy',
'judo',
// 'juice',
// 'justice',
'karate',
// 'kindness',
'knowledge',
// 'labour',
'lack',
// 'land',
'laughter',
'lava',
'leather',
'leisure',
'lightning',
'linguine',
'linguini',
'linguistics',
'literature',
'litter',
'livestock',
'logic',
'loneliness',
// 'love',
'luck',
'luggage',
'macaroni',
'machinery',
'magic',
// 'mail',
'management',
'mankind',
'marble',
'mathematics',
'mayonnaise',
'measles',
// 'meat',
// 'metal',
'methane',
'milk',
'minus',
'money',
// 'moose',
'mud',
'music',
'mumps',
'nature',
'news',
'nitrogen',
'nonsense',
'nurture',
'nutrition',
'obedience',
'obesity',
// 'oil',
'oxygen',
// 'paper',
// 'passion',
'pasta',
'patience',
// 'permission',
'physics',
'poetry',
'pollution',
'poverty',
// 'power',
'pride',
// 'production',
// 'progress',
// 'pronunciation',
'psychology',
'publicity',
'punctuation',
// 'quality',
// 'quantity',
'quartz',
'racism',
// 'rain',
// 'recreation',
'relaxation',
'reliability',
'research',
'respect',
'revenge',
'rice',
'rubbish',
'rum',
'safety',
// 'salad',
// 'salt',
// 'sand',
// 'satire',
'scenery',
'seafood',
'seaside',
'series',
'shame',
'sheep',
'shopping',
// 'silence',
'sleep',
// 'slang'
'smoke',
'smoking',
'snow',
'soap',
'software',
'soil',
// 'sorrow',
// 'soup',
'spaghetti',
// 'speed',
'species',
// 'spelling',
// 'sport',
'steam',
// 'strength',
'stuff',
'stupidity',
// 'success',
// 'sugar',
'sunshine',
'symmetry',
// 'tea',
'tennis',
'thirst',
'thunder',
'timber',
// 'time',
// 'toast',
// 'tolerance',
// 'trade',
'traffic',
'transportation',
// 'travel',
'trust',
// 'understanding',
'underwear',
'unemployment',
'unity',
// 'usage',
'validity',
'veal',
'vegetation',
'vegetarianism',
'vengeance',
'violence',
// 'vision',
'vitality',
'warmth',
// 'water',
'wealth',
'weather',
// 'weight',
'welfare',
'wheat',
// 'whiskey',
// 'width',
'wildlife',
// 'wine',
'wisdom',
// 'wood',
// 'wool',
// 'work',
// 'yeast',
'yoga',
'zinc',
'zoology'
];
/**
* @description These rules translate from the singular form of a noun to its plural form.
* @private
*/
var regex = {
plural : {
men : new RegExp( '^(m|wom)en$' , 'gi' ),
people : new RegExp( '(pe)ople$' , 'gi' ),
children : new RegExp( '(child)ren$' , 'gi' ),
tia : new RegExp( '([ti])a$' , 'gi' ),
analyses : new RegExp( '((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$','gi' ),
databases : new RegExp( '(database)s$' , 'gi' ),
drives : new RegExp( '(drive)s$' , 'gi' ),
hives : new RegExp( '(hi|ti)ves$' , 'gi' ),
curves : new RegExp( '(curve)s$' , 'gi' ),
lrves : new RegExp( '([lr])ves$' , 'gi' ),
aves : new RegExp( '([a])ves$' , 'gi' ),
foves : new RegExp( '([^fo])ves$' , 'gi' ),
movies : new RegExp( '(m)ovies$' , 'gi' ),
aeiouyies : new RegExp( '([^aeiouy]|qu)ies$' , 'gi' ),
series : new RegExp( '(s)eries$' , 'gi' ),
xes : new RegExp( '(x|ch|ss|sh)es$' , 'gi' ),
mice : new RegExp( '([m|l])ice$' , 'gi' ),
buses : new RegExp( '(bus)es$' , 'gi' ),
oes : new RegExp( '(o)es$' , 'gi' ),
shoes : new RegExp( '(shoe)s$' , 'gi' ),
crises : new RegExp( '(cris|ax|test)es$' , 'gi' ),
octopuses : new RegExp( '(octop|vir)uses$' , 'gi' ),
aliases : new RegExp( '(alias|canvas|status|campus)es$', 'gi' ),
summonses : new RegExp( '^(summons|bonus)es$' , 'gi' ),
oxen : new RegExp( '^(ox)en' , 'gi' ),
matrices : new RegExp( '(matr)ices$' , 'gi' ),
vertices : new RegExp( '(vert|ind)ices$' , 'gi' ),
feet : new RegExp( '^feet$' , 'gi' ),
teeth : new RegExp( '^teeth$' , 'gi' ),
geese : new RegExp( '^geese$' , 'gi' ),
quizzes : new RegExp( '(quiz)zes$' , 'gi' ),
whereases : new RegExp( '^(whereas)es$' , 'gi' ),
criteria : new RegExp( '^(criteri)a$' , 'gi' ),
genera : new RegExp( '^genera$' , 'gi' ),
ss : new RegExp( 'ss$' , 'gi' ),
s : new RegExp( 's$' , 'gi' )
},
singular : {
man : new RegExp( '^(m|wom)an$' , 'gi' ),
person : new RegExp( '(pe)rson$' , 'gi' ),
child : new RegExp( '(child)$' , 'gi' ),
drive : new RegExp( '(drive)$' , 'gi' ),
ox : new RegExp( '^(ox)$' , 'gi' ),
axis : new RegExp( '(ax|test)is$' , 'gi' ),
octopus : new RegExp( '(octop|vir)us$' , 'gi' ),
alias : new RegExp( '(alias|status|canvas|campus)$', 'gi' ),
summons : new RegExp( '^(summons|bonus)$' , 'gi' ),
bus : new RegExp( '(bu)s$' , 'gi' ),
buffalo : new RegExp( '(buffal|tomat|potat)o$' , 'gi' ),
tium : new RegExp( '([ti])um$' , 'gi' ),
sis : new RegExp( 'sis$' , 'gi' ),
ffe : new RegExp( '(?:([^f])fe|([lr])f)$' , 'gi' ),
hive : new RegExp( '(hi|ti)ve$' , 'gi' ),
aeiouyy : new RegExp( '([^aeiouy]|qu)y$' , 'gi' ),
x : new RegExp( '(x|ch|ss|sh)$' , 'gi' ),
matrix : new RegExp( '(matr)ix$' , 'gi' ),
vertex : new RegExp( '(vert|ind)ex$' , 'gi' ),
mouse : new RegExp( '([m|l])ouse$' , 'gi' ),
foot : new RegExp( '^foot$' , 'gi' ),
tooth : new RegExp( '^tooth$' , 'gi' ),
goose : new RegExp( '^goose$' , 'gi' ),
quiz : new RegExp( '(quiz)$' , 'gi' ),
whereas : new RegExp( '^(whereas)$' , 'gi' ),
criterion : new RegExp( '^(criteri)on$' , 'gi' ),
genus : new RegExp( '^genus$' , 'gi' ),
s : new RegExp( 's$' , 'gi' ),
common : new RegExp( '$' , 'gi' )
}
};
var plural_rules = [
// do not replace if its already a plural word
[ regex.plural.men ],
[ regex.plural.people ],
[ regex.plural.children ],
[ regex.plural.tia ],
[ regex.plural.analyses ],
[ regex.plural.databases ],
[ regex.plural.drives ],
[ regex.plural.hives ],
[ regex.plural.curves ],
[ regex.plural.lrves ],
[ regex.plural.foves ],
[ regex.plural.aeiouyies ],
[ regex.plural.series ],
[ regex.plural.movies ],
[ regex.plural.xes ],
[ regex.plural.mice ],
[ regex.plural.buses ],
[ regex.plural.oes ],
[ regex.plural.shoes ],
[ regex.plural.crises ],
[ regex.plural.octopuses ],
[ regex.plural.aliases ],
[ regex.plural.summonses ],
[ regex.plural.oxen ],
[ regex.plural.matrices ],
[ regex.plural.feet ],
[ regex.plural.teeth ],
[ regex.plural.geese ],
[ regex.plural.quizzes ],
[ regex.plural.whereases ],
[ regex.plural.criteria ],
[ regex.plural.genera ],
// original rule
[ regex.singular.man , '$1en' ],
[ regex.singular.person , '$1ople' ],
[ regex.singular.child , '$1ren' ],
[ regex.singular.drive , '$1s' ],
[ regex.singular.ox , '$1en' ],
[ regex.singular.axis , '$1es' ],
[ regex.singular.octopus , '$1uses' ],
[ regex.singular.alias , '$1es' ],
[ regex.singular.summons , '$1es' ],
[ regex.singular.bus , '$1ses' ],
[ regex.singular.buffalo , '$1oes' ],
[ regex.singular.tium , '$1a' ],
[ regex.singular.sis , 'ses' ],
[ regex.singular.ffe , '$1$2ves' ],
[ regex.singular.hive , '$1ves' ],
[ regex.singular.aeiouyy , '$1ies' ],
[ regex.singular.matrix , '$1ices' ],
[ regex.singular.vertex , '$1ices' ],
[ regex.singular.x , '$1es' ],
[ regex.singular.mouse , '$1ice' ],
[ regex.singular.foot , 'feet' ],
[ regex.singular.tooth , 'teeth' ],
[ regex.singular.goose , 'geese' ],
[ regex.singular.quiz , '$1zes' ],
[ regex.singular.whereas , '$1es' ],
[ regex.singular.criterion, '$1a' ],
[ regex.singular.genus , 'genera' ],
[ regex.singular.s , 's' ],
[ regex.singular.common, 's' ]
];
/**
* @description These rules translate from the plural form of a noun to its singular form.
* @private
*/
var singular_rules = [
// do not replace if its already a singular word
[ regex.singular.man ],
[ regex.singular.person ],
[ regex.singular.child ],
[ regex.singular.drive ],
[ regex.singular.ox ],
[ regex.singular.axis ],
[ regex.singular.octopus ],
[ regex.singular.alias ],
[ regex.singular.summons ],
[ regex.singular.bus ],
[ regex.singular.buffalo ],
[ regex.singular.tium ],
[ regex.singular.sis ],
[ regex.singular.ffe ],
[ regex.singular.hive ],
[ regex.singular.aeiouyy ],
[ regex.singular.x ],
[ regex.singular.matrix ],
[ regex.singular.mouse ],
[ regex.singular.foot ],
[ regex.singular.tooth ],
[ regex.singular.goose ],
[ regex.singular.quiz ],
[ regex.singular.whereas ],
[ regex.singular.criterion ],
[ regex.singular.genus ],
// original rule
[ regex.plural.men , '$1an' ],
[ regex.plural.people , '$1rson' ],
[ regex.plural.children , '$1' ],
[ regex.plural.databases, '$1'],
[ regex.plural.drives , '$1'],
[ regex.plural.genera , 'genus'],
[ regex.plural.criteria , '$1on'],
[ regex.plural.tia , '$1um' ],
[ regex.plural.analyses , '$1$2sis' ],
[ regex.plural.hives , '$1ve' ],
[ regex.plural.curves , '$1' ],
[ regex.plural.lrves , '$1f' ],
[ regex.plural.aves , '$1ve' ],
[ regex.plural.foves , '$1fe' ],
[ regex.plural.movies , '$1ovie' ],
[ regex.plural.aeiouyies, '$1y' ],
[ regex.plural.series , '$1eries' ],
[ regex.plural.xes , '$1' ],
[ regex.plural.mice , '$1ouse' ],
[ regex.plural.buses , '$1' ],
[ regex.plural.oes , '$1' ],
[ regex.plural.shoes , '$1' ],
[ regex.plural.crises , '$1is' ],
[ regex.plural.octopuses, '$1us' ],
[ regex.plural.aliases , '$1' ],
[ regex.plural.summonses, '$1' ],
[ regex.plural.oxen , '$1' ],
[ regex.plural.matrices , '$1ix' ],
[ regex.plural.vertices , '$1ex' ],
[ regex.plural.feet , 'foot' ],
[ regex.plural.teeth , 'tooth' ],
[ regex.plural.geese , 'goose' ],
[ regex.plural.quizzes , '$1' ],
[ regex.plural.whereases, '$1' ],
[ regex.plural.ss, 'ss' ],
[ regex.plural.s , '' ]
];
/**
* @description This is a list of words that should not be capitalized for title case.
* @private
*/
var non_titlecased_words = [
'and', 'or', 'nor', 'a', 'an', 'the', 'so', 'but', 'to', 'of', 'at','by',
'from', 'into', 'on', 'onto', 'off', 'out', 'in', 'over', 'with', 'for'
];
/**
* @description These are regular expressions used for converting between String formats.
* @private
*/
var id_suffix = new RegExp( '(_ids|_id)$', 'g' );
var underbar = new RegExp( '_', 'g' );
var space_or_underbar = new RegExp( '[\ _]', 'g' );
var uppercase = new RegExp( '([A-Z])', 'g' );
var underbar_prefix = new RegExp( '^_' );
var inflector = {
/**
* A helper method that applies rules based replacement to a String.
* @private
* @function
* @param {String} str String to modify and return based on the passed rules.
* @param {Array: [RegExp, String]} rules Regexp to match paired with String to use for replacement
* @param {Array: [String]} skip Strings to skip if they match
* @param {String} override String to return as though this method succeeded (used to conform to APIs)
* @returns {String} Return passed String modified by passed rules.
* @example
*
* this._apply_rules( 'cows', singular_rules ); // === 'cow'
*/
_apply_rules : function ( str, rules, skip, override ){
if( override ){
str = override;
}else{
var ignore = ( inflector.indexOf( skip, str.toLowerCase()) > -1 );
if( !ignore ){
var i = 0;
var j = rules.length;
for( ; i < j; i++ ){
if( str.match( rules[ i ][ 0 ])){
if( rules[ i ][ 1 ] !== undefined ){
str = str.replace( rules[ i ][ 0 ], rules[ i ][ 1 ]);
}
break;
}
}
}
}
return str;
},
/**
* This lets us detect if an Array contains a given element.
* @public
* @function
* @param {Array} arr The subject array.
* @param {Object} item Object to locate in the Array.
* @param {Number} from_index Starts checking from this position in the Array.(optional)
* @param {Function} compare_func Function used to compare Array item vs passed item.(optional)
* @returns {Number} Return index position in the Array of the passed item.
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.indexOf([ 'hi','there' ], 'guys' ); // === -1
* inflection.indexOf([ 'hi','there' ], 'hi' ); // === 0
*/
indexOf : function ( arr, item, from_index, compare_func ){
if( !from_index ){
from_index = -1;
}
var index = -1;
var i = from_index;
var j = arr.length;
for( ; i < j; i++ ){
if( arr[ i ] === item || compare_func && compare_func( arr[ i ], item )){
index = i;
break;
}
}
return index;
},
/**
* This function adds pluralization support to every String object.
* @public
* @function
* @param {String} str The subject string.
* @param {String} plural Overrides normal output with said String.(optional)
* @returns {String} Singular English language nouns are returned in plural form.
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.pluralize( 'person' ); // === 'people'
* inflection.pluralize( 'octopus' ); // === 'octopuses'
* inflection.pluralize( 'Hat' ); // === 'Hats'
* inflection.pluralize( 'person', 'guys' ); // === 'guys'
*/
pluralize : function ( str, plural ){
return inflector._apply_rules( str, plural_rules, uncountable_words, plural );
},
/**
* This function adds singularization support to every String object.
* @public
* @function
* @param {String} str The subject string.
* @param {String} singular Overrides normal output with said String.(optional)
* @returns {String} Plural English language nouns are returned in singular form.
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.singularize( 'people' ); // === 'person'
* inflection.singularize( 'octopuses' ); // === 'octopus'
* inflection.singularize( 'Hats' ); // === 'Hat'
* inflection.singularize( 'guys', 'person' ); // === 'person'
*/
singularize : function ( str, singular ){
return inflector._apply_rules( str, singular_rules, uncountable_words, singular );
},
/**
* This function will pluralize or singularlize a String appropriately based on a number value
* @public
* @function
* @param {String} str The subject string.
* @param {Number} count The number to base pluralization off of.
* @param {String} singular Overrides normal output with said String.(optional)
* @param {String} plural Overrides normal output with said String.(optional)
* @returns {String} English language nouns are returned in the plural or singular form based on the count.
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.inflect( 'people' 1 ); // === 'person'
* inflection.inflect( 'octopuses' 1 ); // === 'octopus'
* inflection.inflect( 'Hats' 1 ); // === 'Hat'
* inflection.inflect( 'guys', 1 , 'person' ); // === 'person'
* inflection.inflect( 'inches', 1.5 ); // === 'inches'
* inflection.inflect( 'person', 2 ); // === 'people'
* inflection.inflect( 'octopus', 2 ); // === 'octopuses'
* inflection.inflect( 'Hat', 2 ); // === 'Hats'
* inflection.inflect( 'person', 2, null, 'guys' ); // === 'guys'
*/
inflect : function ( str, count, singular, plural ){
count = parseFloat( count, 10 );
if( isNaN( count )) return str;
if( count === 1 ){
return inflector._apply_rules( str, singular_rules, uncountable_words, singular );
}else{
return inflector._apply_rules( str, plural_rules, uncountable_words, plural );
}
},
/**
* This function adds camelization support to every String object.
* @public
* @function
* @param {String} str The subject string.
* @param {Boolean} low_first_letter Default is to capitalize the first letter of the results.(optional)
* Passing true will lowercase it.
* @returns {String} Lower case underscored words will be returned in camel case.
* additionally '/' is translated to '::'
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.camelize( 'message_properties' ); // === 'MessageProperties'
* inflection.camelize( 'message_properties', true ); // === 'messageProperties'
*/
camelize : function ( str, low_first_letter ){
var str_path = str.split( '/' );
var i = 0;
var j = str_path.length;
var str_arr, init_x, k, l, first;
for( ; i < j; i++ ){
str_arr = str_path[ i ].split( '_' );
k = 0;
l = str_arr.length;
for( ; k < l; k++ ){
if( k !== 0 ){
str_arr[ k ] = str_arr[ k ].toLowerCase();
}
first = str_arr[ k ].charAt( 0 );
first = low_first_letter && i === 0 && k === 0
? first.toLowerCase() : first.toUpperCase();
str_arr[ k ] = first + str_arr[ k ].substring( 1 );
}
str_path[ i ] = str_arr.join( '' );
}
return str_path.join( '::' );
},
/**
* This function adds underscore support to every String object.
* @public
* @function
* @param {String} str The subject string.
* @param {Boolean} all_upper_case Default is to lowercase and add underscore prefix.(optional)
* Passing true will return as entered.
* @returns {String} Camel cased words are returned as lower cased and underscored.
* additionally '::' is translated to '/'.
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.underscore( 'MessageProperties' ); // === 'message_properties'
* inflection.underscore( 'messageProperties' ); // === 'message_properties'
* inflection.underscore( 'MP', true ); // === 'MP'
*/
underscore : function ( str, all_upper_case ){
if( all_upper_case && str === str.toUpperCase()) return str;
var str_path = str.split( '::' );
var i = 0;
var j = str_path.length;
for( ; i < j; i++ ){
str_path[ i ] = str_path[ i ].replace( uppercase, '_$1' );
str_path[ i ] = str_path[ i ].replace( underbar_prefix, '' );
}
return str_path.join( '/' ).toLowerCase();
},
/**
* This function adds humanize support to every String object.
* @public
* @function
* @param {String} str The subject string.
* @param {Boolean} low_first_letter Default is to capitalize the first letter of the results.(optional)
* Passing true will lowercase it.
* @returns {String} Lower case underscored words will be returned in humanized form.
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.humanize( 'message_properties' ); // === 'Message properties'
* inflection.humanize( 'message_properties', true ); // === 'message properties'
*/
humanize : function ( str, low_first_letter ){
str = str.toLowerCase();
str = str.replace( id_suffix, '' );
str = str.replace( underbar, ' ' );
if( !low_first_letter ){
str = inflector.capitalize( str );
}
return str;
},
/**
* This function adds capitalization support to every String object.
* @public
* @function
* @param {String} str The subject string.
* @returns {String} All characters will be lower case and the first will be upper.
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.capitalize( 'message_properties' ); // === 'Message_properties'
* inflection.capitalize( 'message properties', true ); // === 'Message properties'
*/
capitalize : function ( str ){
str = str.toLowerCase();
return str.substring( 0, 1 ).toUpperCase() + str.substring( 1 );
},
/**
* This function replaces underscores with dashes in the string.
* @public
* @function
* @param {String} str The subject string.
* @returns {String} Replaces all spaces or underscores with dashes.
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.dasherize( 'message_properties' ); // === 'message-properties'
* inflection.dasherize( 'Message Properties' ); // === 'Message-Properties'
*/
dasherize : function ( str ){
return str.replace( space_or_underbar, '-' );
},
/**
* This function adds titleize support to every String object.
* @public
* @function
* @param {String} str The subject string.
* @returns {String} Capitalizes words as you would for a book title.
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.titleize( 'message_properties' ); // === 'Message Properties'
* inflection.titleize( 'message properties to keep' ); // === 'Message Properties to Keep'
*/
titleize : function ( str ){
str = str.toLowerCase().replace( underbar, ' ' );
var str_arr = str.split( ' ' );
var i = 0;
var j = str_arr.length;
var d, k, l;
for( ; i < j; i++ ){
d = str_arr[ i ].split( '-' );
k = 0;
l = d.length;
for( ; k < l; k++){
if( inflector.indexOf( non_titlecased_words, d[ k ].toLowerCase()) < 0 ){
d[ k ] = inflector.capitalize( d[ k ]);
}
}
str_arr[ i ] = d.join( '-' );
}
str = str_arr.join( ' ' );
str = str.substring( 0, 1 ).toUpperCase() + str.substring( 1 );
return str;
},
/**
* This function adds demodulize support to every String object.
* @public
* @function
* @param {String} str The subject string.
* @returns {String} Removes module names leaving only class names.(Ruby style)
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.demodulize( 'Message::Bus::Properties' ); // === 'Properties'
*/
demodulize : function ( str ){
var str_arr = str.split( '::' );
return str_arr[ str_arr.length - 1 ];
},
/**
* This function adds tableize support to every String object.
* @public
* @function
* @param {String} str The subject string.
* @returns {String} Return camel cased words into their underscored plural form.
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.tableize( 'MessageBusProperty' ); // === 'message_bus_properties'
*/
tableize : function ( str ){
str = inflector.underscore( str );
str = inflector.pluralize( str );
return str;
},
/**
* This function adds classification support to every String object.
* @public
* @function
* @param {String} str The subject string.
* @returns {String} Underscored plural nouns become the camel cased singular form.
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.classify( 'message_bus_properties' ); // === 'MessageBusProperty'
*/
classify : function ( str ){
str = inflector.camelize( str );
str = inflector.singularize( str );
return str;
},
/**
* This function adds foreign key support to every String object.
* @public
* @function
* @param {String} str The subject string.
* @param {Boolean} drop_id_ubar Default is to seperate id with an underbar at the end of the class name,
you can pass true to skip it.(optional)
* @returns {String} Underscored plural nouns become the camel cased singular form.
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.foreign_key( 'MessageBusProperty' ); // === 'message_bus_property_id'
* inflection.foreign_key( 'MessageBusProperty', true ); // === 'message_bus_propertyid'
*/
foreign_key : function ( str, drop_id_ubar ){
str = inflector.demodulize( str );
str = inflector.underscore( str ) + (( drop_id_ubar ) ? ( '' ) : ( '_' )) + 'id';
return str;
},
/**
* This function adds ordinalize support to every String object.
* @public
* @function
* @param {String} str The subject string.
* @returns {String} Return all found numbers their sequence like '22nd'.
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.ordinalize( 'the 1 pitch' ); // === 'the 1st pitch'
*/
ordinalize : function ( str ){
var str_arr = str.split( ' ' );
var i = 0;
var j = str_arr.length;
for( ; i < j; i++ ){
var k = parseInt( str_arr[ i ], 10 );
if( !isNaN( k )){
var ltd = str_arr[ i ].substring( str_arr[ i ].length - 2 );
var ld = str_arr[ i ].substring( str_arr[ i ].length - 1 );
var suf = 'th';
if( ltd != '11' && ltd != '12' && ltd != '13' ){
if( ld === '1' ){
suf = 'st';
}else if( ld === '2' ){
suf = 'nd';
}else if( ld === '3' ){
suf = 'rd';
}
}
str_arr[ i ] += suf;
}
}
return str_arr.join( ' ' );
},
/**
* This function performs multiple inflection methods on a string
* @public
* @function
* @param {String} str The subject string.
* @param {Array} arr An array of inflection methods.
* @returns {String}
* @example
*
* var inflection = require( 'inflection' );
*
* inflection.transform( 'all job', [ 'pluralize', 'capitalize', 'dasherize' ]); // === 'All-jobs'
*/
transform : function ( str, arr ){
var i = 0;
var j = arr.length;
for( ;i < j; i++ ){
var method = arr[ i ];
if( inflector.hasOwnProperty( method )){
str = inflector[ method ]( str );
}
}
return str;
}
};
/**
* @public
*/
inflector.version = '1.13.1';
return inflector;
}));
+111
View File
@@ -0,0 +1,111 @@
{
"name": "inflection",
"version": "1.13.4",
"description": "A port of inflection-js to node.js module",
"keywords": [
"inflection",
"inflections",
"inflection-js",
"pluralize",
"singularize",
"camelize",
"underscore",
"humanize",
"capitalize",
"dasherize",
"titleize",
"demodulize",
"tableize",
"classify",
"foreign_key",
"ordinalize"
],
"author": "dreamerslab <ben@dreamerslab.com>",
"contributors": [
{
"name": "Ryan Schuft",
"email": "ryan.schuft@gmail.com"
},
{
"name": "Ben Lin",
"email": "ben@dreamerslab.com"
},
{
"name": "Lance Pollard",
"email": "lancejpollard@gmail.com"
},
{
"name": "Dane O'Connor",
"email": "dane.oconnor@gmail.com"
},
{
"name": "David Miró",
"email": "lite.3engine@gmail.com"
},
{
"name": "brandondewitt"
},
{
"name": "luk3thomas"
},
{
"name": "Marcel Klehr"
},
{
"name": "Raymond Feng"
},
{
"name": "Kane Cohen",
"email": "kanecohen@gmail.com"
},
{
"name": "Gianni Chiappetta",
"email": "gianni@runlevel6.org"
},
{
"name": "Eric Brody"
},
{
"name": "overlookmotel"
},
{
"name": "Patrick Mowrer"
},
{
"name": "Greger Olsson"
},
{
"name": "Jason Crawford",
"email": "jason@jasoncrawford.org"
},
{
"name": "Ray Myers",
"email": "ray.myers@gmail.com"
},
{
"name": "Dillon Shook",
"email": "dshook@alumni.nmt.edu"
},
{
"name": "Patrick Kuen",
"email": "p.kuen@cloudacy.com"
}
],
"devDependencies": {
"terser": "^5.15.0",
"vitest": "^0.23.4"
},
"main": "./lib/inflection.js",
"repository": {
"type": "git",
"url": "https://github.com/dreamerslab/node.inflection.git"
},
"engines": [
"node >= 0.4.0"
],
"license": "MIT",
"scripts": {
"test": "vitest",
"minify": "terser lib/inflection.js -o inflection.min.js -c -m"
}
}
+7
View File
@@ -0,0 +1,7 @@
/// <reference types="vitest" />
import { defineConfig } from 'vite'
export default defineConfig({
test: {
},
})