From 32feb46f886591cb310eb814e989eabcd32da05c Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 26 Sep 2019 19:17:01 +0300 Subject: [PATCH 01/72] Add occupation model to function as history of roles --- webapp/admin.py | 3 +- webapp/migrations/0055_auto_20190926_1850.py | 31 ++++++++++++ webapp/migrations/0056_auto_20190926_1857.py | 51 +++++++++++++++++++ webapp/migrations/0057_auto_20190926_1915.py | 18 +++++++ webapp/models.py | 52 +++++++++++++++++--- 5 files changed, 147 insertions(+), 8 deletions(-) create mode 100644 webapp/migrations/0055_auto_20190926_1850.py create mode 100644 webapp/migrations/0056_auto_20190926_1857.py create mode 100644 webapp/migrations/0057_auto_20190926_1915.py diff --git a/webapp/admin.py b/webapp/admin.py index 2059a1d..dd0c36f 100644 --- a/webapp/admin.py +++ b/webapp/admin.py @@ -1,7 +1,7 @@ """File containing webapp app admin registers.""" from django.contrib import admin -from webapp.models import Official, Role, Committee +from webapp.models import Official, Role, Committee, Occupation from webapp.models import Feed, Tag, BaseFeed, Event, Signup, SignupForm, TemplateQuestion from modeltranslation.admin import TranslationAdmin from django.contrib.auth.models import Permission @@ -17,5 +17,6 @@ admin.site.register(SignupForm, TranslationAdmin) admin.site.register(Signup, TranslationAdmin) admin.site.register(TemplateQuestion, TranslationAdmin) admin.site.register(Official) +admin.site.register(Occupation) admin.site.register(Role) admin.site.register(Committee) diff --git a/webapp/migrations/0055_auto_20190926_1850.py b/webapp/migrations/0055_auto_20190926_1850.py new file mode 100644 index 0000000..a1fb4ff --- /dev/null +++ b/webapp/migrations/0055_auto_20190926_1850.py @@ -0,0 +1,31 @@ +# Generated by Django 2.1.5 on 2019-09-26 15:50 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('webapp', '0054_auto_20190313_1642'), + ] + + operations = [ + migrations.CreateModel( + name='Occupation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('start_date', models.DateField(verbose_name='Start date')), + ('end_date', models.DateField(verbose_name='End date')), + ], + options={ + 'verbose_name': 'Occupation', + 'verbose_name_plural': 'Occupations', + }, + ), + migrations.DeleteModel( + name='official' + ) + ] diff --git a/webapp/migrations/0056_auto_20190926_1857.py b/webapp/migrations/0056_auto_20190926_1857.py new file mode 100644 index 0000000..6f99cba --- /dev/null +++ b/webapp/migrations/0056_auto_20190926_1857.py @@ -0,0 +1,51 @@ +# Generated by Django 2.1.5 on 2019-09-26 15:57 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import phonenumber_field.modelfields + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('webapp', '0055_auto_20190926_1850'), + ] + + operations = [ + migrations.CreateModel( + name='Official', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('phone_number', phonenumber_field.modelfields.PhoneNumberField(max_length=128, verbose_name='Phone number')), + ], + options={ + 'verbose_name': 'Official', + 'verbose_name_plural': 'Officials', + }, + ), + migrations.RemoveField( + model_name='role', + name='end_date', + ), + migrations.RemoveField( + model_name='role', + name='start_date', + ), + migrations.AddField( + model_name='occupation', + name='occupation', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='webapp.Role'), + ), + migrations.AddField( + model_name='official', + name='role_history', + field=models.ManyToManyField(to='webapp.Occupation'), + ), + migrations.AddField( + model_name='official', + name='user', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/webapp/migrations/0057_auto_20190926_1915.py b/webapp/migrations/0057_auto_20190926_1915.py new file mode 100644 index 0000000..ae2c01f --- /dev/null +++ b/webapp/migrations/0057_auto_20190926_1915.py @@ -0,0 +1,18 @@ +# Generated by Django 2.1.5 on 2019-09-26 16:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0056_auto_20190926_1857'), + ] + + operations = [ + migrations.AlterField( + model_name='official', + name='role_history', + field=models.ManyToManyField(blank=True, to='webapp.Occupation'), + ), + ] diff --git a/webapp/models.py b/webapp/models.py index 348d8d7..9325702 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -4,9 +4,10 @@ from django.db import models from django.utils import timezone # from datetime import timedelta from django.contrib.auth.models import User +from django.db.models.signals import post_save +from django.dispatch import receiver from webapp.utils import month_from_now from django.utils.translation import ugettext_lazy as _ -# from django.contrib.auth.models import User from auditlog.registry import auditlog from phonenumber_field.modelfields import PhoneNumberField # from django.contrib.postgres.fields import JSONField @@ -163,7 +164,7 @@ class Role(PresetRole): Model for Role. Model representing an active or historical occupation - in an official's history. + in the guild. """ class Meta: @@ -172,12 +173,32 @@ class Role(PresetRole): verbose_name = _('Role') verbose_name_plural = _('Roles') - start_date = models.DateField(_('Start date')) - end_date = models.DateField(_('End date')) committee = models.ForeignKey('Committee', related_name='roles', on_delete=models.SET_NULL, null=True) + def __str__(self): + return '{} (Hallitus: {}) ({})'.format(self.name, _("Yes") if self.is_board else _("No"), self.committee) -class Official(User): + +class Occupation(models.Model): + """ + Model for a occupation in guild. + + Model links Official into a role he/she has or has had in the guild. + """ + + class Meta: + verbose_name = _('Occupation') + verbose_name_plural = _('Occupations') + + start_date = models.DateField(_('Start date')) + end_date = models.DateField(_('End date')) + occupation = models.ForeignKey('Role', on_delete=models.SET_NULL, null=True) + + def __str__(self): + return '{}: {} - {}'.format(self.occupation.name, self.start_date, self.end_date) + + +class Official(models.Model): """Model representing a guild official.""" class Meta: @@ -186,11 +207,28 @@ class Official(User): verbose_name = _('Official') verbose_name_plural = _('Officials') + user = models.OneToOneField(User, on_delete=models.CASCADE) + phone_number = PhoneNumberField(_('Phone number')) - role = models.ManyToManyField('Role', related_name='official') + role_history = models.ManyToManyField('Occupation', blank=True) + + @property + def current_roles(self): + return self.role_history.all().filter(end_date__gte=timezone.now()).filter(start_date__lte=timezone.now()) def __str__(self): - return '{} {}'.format(self.first_name, self.last_name) + return '{} {}'.format(self.user.first_name, self.user.last_name) + + +@receiver(post_save, sender=User) +def create_user_profile(sender, instance, created, **kwargs): + if created: + Official.objects.create(user=instance) + + +@receiver(post_save, sender=User) +def save_user_profile(sender, instance, **kwargs): + instance.official.save() auditlog.register(Tag) From 22371b8f15366f8cc4aac4b94b95adcb8680ae25 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 26 Sep 2019 19:22:11 +0300 Subject: [PATCH 02/72] Locales --- locale/en/LC_MESSAGES/django.po | 87 ++++++++++++++++++-------------- locale/fi/LC_MESSAGES/django.po | 88 +++++++++++++++++++-------------- 2 files changed, 101 insertions(+), 74 deletions(-) diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po index f0ed178..81e9aa9 100644 --- a/locale/en/LC_MESSAGES/django.po +++ b/locale/en/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-09-16 19:33+0300\n" +"POT-Creation-Date: 2019-09-26 19:19+0300\n" "PO-Revision-Date: 2017-11-02 23:09+0200\n" "Last-Translator: \n" "Language-Team: \n" @@ -37,7 +37,7 @@ msgstr "Sössö articles" msgid "Today's lunch" msgstr "" -#: infoscreen/models.py:212 webapp/models.py:74 +#: infoscreen/models.py:212 webapp/models.py:75 msgid "Events" msgstr "Events" @@ -113,7 +113,7 @@ msgid "Delete" msgstr "Delete" #: infoscreen/templates/tabs/add_remove.html:23 kaehmy/models.py:56 -#: kaehmy/templates/list.html:36 webapp/models.py:125 webapp/models.py:154 +#: kaehmy/templates/list.html:36 webapp/models.py:126 webapp/models.py:155 msgid "Name" msgstr "Name" @@ -263,7 +263,7 @@ msgstr "" msgid "Category" msgstr "" -#: kaehmy/models.py:39 webapp/models.py:136 +#: kaehmy/models.py:39 webapp/models.py:137 msgid "Description" msgstr "Description" @@ -311,7 +311,7 @@ msgstr "Kaehmy application" msgid "Kaehmylomakkeet" msgstr "Kaehmy applications" -#: kaehmy/models.py:98 webapp/models.py:189 +#: kaehmy/models.py:98 webapp/models.py:212 msgid "Phone number" msgstr "" @@ -327,7 +327,7 @@ msgstr "" msgid "Custom role name" msgstr "" -#: kaehmy/models.py:104 webapp/models.py:126 +#: kaehmy/models.py:104 webapp/models.py:127 msgid "Board member" msgstr "Board member" @@ -351,7 +351,7 @@ msgstr "" msgid "Telegram channels" msgstr "" -#: kaehmy/tables.py:13 webapp/models.py:173 +#: kaehmy/tables.py:13 webapp/models.py:174 msgid "Roles" msgstr "" @@ -1111,111 +1111,127 @@ msgstr "Go" msgid "Aalto-yliopiston Sähköinsinöörikilta ry" msgstr "Aalto-yliopiston Sähköinsinöörikilta ry" -#: webapp/models.py:17 +#: webapp/models.py:18 msgid "Webapp" msgstr "Webapp" -#: webapp/models.py:28 +#: webapp/models.py:29 msgid "Tag" msgstr "Tag" -#: webapp/models.py:29 +#: webapp/models.py:30 msgid "Tags" msgstr "Tags" -#: webapp/models.py:32 +#: webapp/models.py:33 msgid "Tag: {}" msgstr "Tag: {}" -#: webapp/models.py:53 +#: webapp/models.py:54 msgid "Feed: {}" msgstr "Feed: {}" -#: webapp/models.py:56 +#: webapp/models.py:57 msgid "Feed" msgstr "" -#: webapp/models.py:57 +#: webapp/models.py:58 msgid "Feeds" msgstr "" -#: webapp/models.py:70 +#: webapp/models.py:71 msgid "Event: {}" msgstr "" -#: webapp/models.py:73 +#: webapp/models.py:74 msgid "Event" msgstr "" -#: webapp/models.py:84 +#: webapp/models.py:85 msgid "Template questions: {}" msgstr "" -#: webapp/models.py:87 +#: webapp/models.py:88 msgid "Template question" msgstr "" -#: webapp/models.py:88 +#: webapp/models.py:89 msgid "Template questions" msgstr "" -#: webapp/models.py:102 +#: webapp/models.py:103 msgid "#{} {}" msgstr "" -#: webapp/models.py:105 +#: webapp/models.py:106 msgid "Signup form" msgstr "" -#: webapp/models.py:106 +#: webapp/models.py:107 msgid "Signup forms" msgstr "" -#: webapp/models.py:115 +#: webapp/models.py:116 msgid "Sign-ups: {}" msgstr "" -#: webapp/models.py:118 +#: webapp/models.py:119 msgid "Sign-up" msgstr "" -#: webapp/models.py:119 +#: webapp/models.py:120 msgid "Sign-ups" msgstr "" -#: webapp/models.py:130 +#: webapp/models.py:131 msgid "board member" msgstr "board member" -#: webapp/models.py:148 +#: webapp/models.py:149 msgid "Committee" msgstr "" -#: webapp/models.py:149 +#: webapp/models.py:150 msgid "Committees" msgstr "" -#: webapp/models.py:152 +#: webapp/models.py:153 msgid "Committee: {}" msgstr "" -#: webapp/models.py:172 +#: webapp/models.py:173 msgid "Role" msgstr "" -#: webapp/models.py:175 +#: webapp/models.py:179 +msgid "Yes" +msgstr "" + +#: webapp/models.py:179 +msgid "No" +msgstr "" + +#: webapp/models.py:190 +msgid "Occupation" +msgstr "Occupation" + +#: webapp/models.py:191 +msgid "Occupations" +msgstr "Occupations" + +#: webapp/models.py:193 msgid "Start date" msgstr "" -#: webapp/models.py:176 +#: webapp/models.py:194 msgid "End date" msgstr "" -#: webapp/models.py:186 +#: webapp/models.py:207 msgid "Official" msgstr "" -#: webapp/models.py:187 +#: webapp/models.py:208 msgid "Officials" msgstr "" @@ -1340,6 +1356,3 @@ msgstr "Corporate" #~ msgid "Missing \"textfield\" POST request field" #~ msgstr "Missing \"textfield\" POST request field" - -#~ msgid "Options" -#~ msgstr "Options" diff --git a/locale/fi/LC_MESSAGES/django.po b/locale/fi/LC_MESSAGES/django.po index 25eee0e..7a39bc6 100644 --- a/locale/fi/LC_MESSAGES/django.po +++ b/locale/fi/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-09-16 19:33+0300\n" +"POT-Creation-Date: 2019-09-26 19:19+0300\n" "PO-Revision-Date: 2017-11-02 23:04+0200\n" "Last-Translator: \n" "Language-Team: \n" @@ -38,7 +38,7 @@ msgstr "Sössön artikkelit" msgid "Today's lunch" msgstr "Päivän lounas" -#: infoscreen/models.py:212 webapp/models.py:74 +#: infoscreen/models.py:212 webapp/models.py:75 msgid "Events" msgstr "Tapahtumat" @@ -114,7 +114,7 @@ msgid "Delete" msgstr "Poista" #: infoscreen/templates/tabs/add_remove.html:23 kaehmy/models.py:56 -#: kaehmy/templates/list.html:36 webapp/models.py:125 webapp/models.py:154 +#: kaehmy/templates/list.html:36 webapp/models.py:126 webapp/models.py:155 msgid "Name" msgstr "Nimi" @@ -264,7 +264,7 @@ msgstr "Muut" msgid "Category" msgstr "Kategoria" -#: kaehmy/models.py:39 webapp/models.py:136 +#: kaehmy/models.py:39 webapp/models.py:137 msgid "Description" msgstr "Kuvaus" @@ -312,7 +312,7 @@ msgstr "Kaehmylomake" msgid "Kaehmylomakkeet" msgstr "Kaehmylomakkeet" -#: kaehmy/models.py:98 webapp/models.py:189 +#: kaehmy/models.py:98 webapp/models.py:212 msgid "Phone number" msgstr "Puhelinnumero" @@ -328,7 +328,7 @@ msgstr "Teksti" msgid "Custom role name" msgstr "Uusi virka" -#: kaehmy/models.py:104 webapp/models.py:126 +#: kaehmy/models.py:104 webapp/models.py:127 msgid "Board member" msgstr "Hallituksen jäsen" @@ -352,7 +352,7 @@ msgstr "Telegram-kanava" msgid "Telegram channels" msgstr "Telegram-kanavat" -#: kaehmy/tables.py:13 webapp/models.py:173 +#: kaehmy/tables.py:13 webapp/models.py:174 msgid "Roles" msgstr "Roolit" @@ -767,10 +767,8 @@ msgid "" msgstr "" #: members/templates/email_application_submit.html:15 -#, fuzzy -#| msgid "Muista myös maksaa jäsenmaksusi!" msgid "Muistathan maksaa jäsenmaksun! Alla maksutiedot" -msgstr "Muista myös maksaa jäsenmaksusi!" +msgstr "Muistathan maksaa jäsenmaksun! Alla maksutiedot" #: members/templates/email_application_submit.html:17 msgid "Saaja" @@ -1101,111 +1099,127 @@ msgstr "Vaihda" msgid "Aalto-yliopiston Sähköinsinöörikilta ry" msgstr "Aalto-yliopiston Sähköinsinöörikilta ry" -#: webapp/models.py:17 +#: webapp/models.py:18 msgid "Webapp" msgstr "Nettisivut" -#: webapp/models.py:28 +#: webapp/models.py:29 msgid "Tag" msgstr "Tunniste" -#: webapp/models.py:29 +#: webapp/models.py:30 msgid "Tags" msgstr "Tunnisteet" -#: webapp/models.py:32 +#: webapp/models.py:33 msgid "Tag: {}" msgstr "Tunniste: {}" -#: webapp/models.py:53 +#: webapp/models.py:54 msgid "Feed: {}" msgstr "Uutinen: {}" -#: webapp/models.py:56 +#: webapp/models.py:57 msgid "Feed" msgstr "Uutinen" -#: webapp/models.py:57 +#: webapp/models.py:58 msgid "Feeds" msgstr "Uutiset" -#: webapp/models.py:70 +#: webapp/models.py:71 msgid "Event: {}" msgstr "Tapahtuma: {}" -#: webapp/models.py:73 +#: webapp/models.py:74 msgid "Event" msgstr "Tapahtuma" -#: webapp/models.py:84 +#: webapp/models.py:85 msgid "Template questions: {}" msgstr "Vakiokysymykset: {}" -#: webapp/models.py:87 +#: webapp/models.py:88 msgid "Template question" msgstr "Vakiokysymys" -#: webapp/models.py:88 +#: webapp/models.py:89 msgid "Template questions" msgstr "Vakiokysymykset" -#: webapp/models.py:102 +#: webapp/models.py:103 msgid "#{} {}" msgstr "" -#: webapp/models.py:105 +#: webapp/models.py:106 msgid "Signup form" msgstr "Ilmoittautumislomake" -#: webapp/models.py:106 +#: webapp/models.py:107 msgid "Signup forms" msgstr "Ilmoittautumislomakkeet" -#: webapp/models.py:115 +#: webapp/models.py:116 msgid "Sign-ups: {}" msgstr "Ilmoittautumiset: {}" -#: webapp/models.py:118 +#: webapp/models.py:119 msgid "Sign-up" msgstr "Ilmoittautuminen" -#: webapp/models.py:119 +#: webapp/models.py:120 msgid "Sign-ups" msgstr "Ilmoittautumiset" -#: webapp/models.py:130 +#: webapp/models.py:131 msgid "board member" msgstr "hallituksen jäsen" -#: webapp/models.py:148 +#: webapp/models.py:149 msgid "Committee" msgstr "Toimikunta" -#: webapp/models.py:149 +#: webapp/models.py:150 msgid "Committees" msgstr "Toimikunnat" -#: webapp/models.py:152 +#: webapp/models.py:153 msgid "Committee: {}" msgstr "Toimikunta: {}" -#: webapp/models.py:172 +#: webapp/models.py:173 msgid "Role" msgstr "Rooli" -#: webapp/models.py:175 +#: webapp/models.py:179 +msgid "Yes" +msgstr "" + +#: webapp/models.py:179 +msgid "No" +msgstr "" + +#: webapp/models.py:190 +msgid "Occupation" +msgstr "Virka" + +#: webapp/models.py:191 +msgid "Occupations" +msgstr "Virat" + +#: webapp/models.py:193 msgid "Start date" msgstr "Alkupäivämäärä" -#: webapp/models.py:176 +#: webapp/models.py:194 msgid "End date" msgstr "Loppupäivämäärä" -#: webapp/models.py:186 +#: webapp/models.py:207 msgid "Official" msgstr "Toimihenkilö" -#: webapp/models.py:187 +#: webapp/models.py:208 msgid "Officials" msgstr "Toimihenkilöt" From e365c394d86b79ac60a22ee07b978accd8b639c4 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 26 Sep 2019 20:16:24 +0300 Subject: [PATCH 03/72] Fix user creation receiver at official creation --- webapp/migrations/0058_auto_20190926_2010.py | 31 ++++++++++++++++++++ webapp/models.py | 23 +++++++++++---- webapp/serializers.py | 10 ++++++- 3 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 webapp/migrations/0058_auto_20190926_2010.py diff --git a/webapp/migrations/0058_auto_20190926_2010.py b/webapp/migrations/0058_auto_20190926_2010.py new file mode 100644 index 0000000..e7230cd --- /dev/null +++ b/webapp/migrations/0058_auto_20190926_2010.py @@ -0,0 +1,31 @@ +# Generated by Django 2.1.5 on 2019-09-26 17:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0057_auto_20190926_1915'), + ] + + operations = [ + migrations.AddField( + model_name='official', + name='email', + field=models.EmailField(default='asd@asd.fi', max_length=254, verbose_name='Email address'), + preserve_default=False, + ), + migrations.AddField( + model_name='official', + name='first_name', + field=models.CharField(default='asd', max_length=30, verbose_name='First name'), + preserve_default=False, + ), + migrations.AddField( + model_name='official', + name='last_name', + field=models.CharField(default='asd', max_length=150, verbose_name='Last name'), + preserve_default=False, + ), + ] diff --git a/webapp/models.py b/webapp/models.py index 9325702..c3fd53d 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -209,6 +209,9 @@ class Official(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) + first_name = models.CharField(_('First name'), max_length=30) + last_name = models.CharField(_('Last name'), max_length=150) + email = models.EmailField(_('Email address')) phone_number = PhoneNumberField(_('Phone number')) role_history = models.ManyToManyField('Occupation', blank=True) @@ -216,19 +219,29 @@ class Official(models.Model): def current_roles(self): return self.role_history.all().filter(end_date__gte=timezone.now()).filter(start_date__lte=timezone.now()) + @property + def roles_of_year(self, year): + return self.role_history.all().filter(end_date__gte=timezone.datetime(year, 1, 1)).filter(start_date__lte=timezone.datetime(year, 12, 31)) + def __str__(self): - return '{} {}'.format(self.user.first_name, self.user.last_name) + return '{} {}'.format(self.first_name, self.last_name) -@receiver(post_save, sender=User) +@receiver(post_save, sender=Official) def create_user_profile(sender, instance, created, **kwargs): if created: - Official.objects.create(user=instance) + instance.user.first_name = instance.first_name + instance.user.last_name = instance.last_name + instance.user.email = instance.email + instance.user.save() -@receiver(post_save, sender=User) +@receiver(post_save, sender=Official) def save_user_profile(sender, instance, **kwargs): - instance.official.save() + instance.user.first_name = instance.first_name + instance.user.last_name = instance.last_name + instance.user.email = instance.email + instance.user.save() auditlog.register(Tag) diff --git a/webapp/serializers.py b/webapp/serializers.py index b542d55..7cdee73 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -93,8 +93,16 @@ class FeedSerializer(serializers.ModelSerializer): return feed +class OccupationSerializer(serializers.ModelSerializer): + class Meta: + model = Occupation + fields = ('start_date', 'end_date') + + class ContactsSerializer(serializers.ModelSerializer): + current_roles = OccupationSerializer(many=True, read_only=True) + class Meta: model = Official - fields = ('id', 'first_name', 'last_name', 'phone_number', 'role') + fields = ('id', 'first_name', 'last_name', 'email', 'phone_number', 'current_roles') depth = 2 From 5a29c8c49d1789767f88fcd9ff877d2d62673866 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 26 Sep 2019 20:43:13 +0300 Subject: [PATCH 04/72] Set contact serializer --- webapp/migrations/0059_auto_20190926_2032.py | 23 ++++++++++++++++++++ webapp/models.py | 4 ++-- webapp/serializers.py | 18 ++++++++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 webapp/migrations/0059_auto_20190926_2032.py diff --git a/webapp/migrations/0059_auto_20190926_2032.py b/webapp/migrations/0059_auto_20190926_2032.py new file mode 100644 index 0000000..a956773 --- /dev/null +++ b/webapp/migrations/0059_auto_20190926_2032.py @@ -0,0 +1,23 @@ +# Generated by Django 2.1.5 on 2019-09-26 17:32 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0058_auto_20190926_2010'), + ] + + operations = [ + migrations.RemoveField( + model_name='occupation', + name='occupation', + ), + migrations.AddField( + model_name='occupation', + name='role', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='webapp.Role'), + ), + ] diff --git a/webapp/models.py b/webapp/models.py index c3fd53d..4e5414d 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -192,10 +192,10 @@ class Occupation(models.Model): start_date = models.DateField(_('Start date')) end_date = models.DateField(_('End date')) - occupation = models.ForeignKey('Role', on_delete=models.SET_NULL, null=True) + role = models.OneToOneField('Role', on_delete=models.SET_NULL, null=True) def __str__(self): - return '{}: {} - {}'.format(self.occupation.name, self.start_date, self.end_date) + return '{}: {} - {}'.format(self.role.name, self.start_date, self.end_date) class Official(models.Model): diff --git a/webapp/serializers.py b/webapp/serializers.py index 7cdee73..3d4a3e8 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -93,10 +93,26 @@ class FeedSerializer(serializers.ModelSerializer): return feed +class CommitteeSerializer(serializers.ModelSerializer): + class Meta: + model = Committee + fields = ['name'] + + +class RoleSerializer(serializers.ModelSerializer): + committee = CommitteeSerializer(read_only=True) + + class Meta: + model = Role + fields = ('name', 'description', 'committee') + + class OccupationSerializer(serializers.ModelSerializer): + role = RoleSerializer(read_only=True) + class Meta: model = Occupation - fields = ('start_date', 'end_date') + fields = ('role', 'start_date', 'end_date') class ContactsSerializer(serializers.ModelSerializer): From 23563651974d1080cf19698ec68ee3f19bd8164e Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 26 Sep 2019 20:52:11 +0300 Subject: [PATCH 05/72] Reconstruct migrations (squash merge request) --- webapp/migrations/0055_auto_20190926_1850.py | 31 ----------- webapp/migrations/0055_auto_20190926_2048.py | 19 +++++++ webapp/migrations/0056_auto_20190926_1857.py | 51 ----------------- webapp/migrations/0056_auto_20190926_2051.py | 58 ++++++++++++++++++++ webapp/migrations/0057_auto_20190926_1915.py | 18 ------ webapp/migrations/0058_auto_20190926_2010.py | 31 ----------- webapp/migrations/0059_auto_20190926_2032.py | 23 -------- 7 files changed, 77 insertions(+), 154 deletions(-) delete mode 100644 webapp/migrations/0055_auto_20190926_1850.py create mode 100644 webapp/migrations/0055_auto_20190926_2048.py delete mode 100644 webapp/migrations/0056_auto_20190926_1857.py create mode 100644 webapp/migrations/0056_auto_20190926_2051.py delete mode 100644 webapp/migrations/0057_auto_20190926_1915.py delete mode 100644 webapp/migrations/0058_auto_20190926_2010.py delete mode 100644 webapp/migrations/0059_auto_20190926_2032.py diff --git a/webapp/migrations/0055_auto_20190926_1850.py b/webapp/migrations/0055_auto_20190926_1850.py deleted file mode 100644 index a1fb4ff..0000000 --- a/webapp/migrations/0055_auto_20190926_1850.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 2.1.5 on 2019-09-26 15:50 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('webapp', '0054_auto_20190313_1642'), - ] - - operations = [ - migrations.CreateModel( - name='Occupation', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('start_date', models.DateField(verbose_name='Start date')), - ('end_date', models.DateField(verbose_name='End date')), - ], - options={ - 'verbose_name': 'Occupation', - 'verbose_name_plural': 'Occupations', - }, - ), - migrations.DeleteModel( - name='official' - ) - ] diff --git a/webapp/migrations/0055_auto_20190926_2048.py b/webapp/migrations/0055_auto_20190926_2048.py new file mode 100644 index 0000000..36f40e0 --- /dev/null +++ b/webapp/migrations/0055_auto_20190926_2048.py @@ -0,0 +1,19 @@ +# Generated by Django 2.1.5 on 2019-09-26 17:48 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('webapp', '0054_auto_20190313_1642'), + ] + + operations = [ + migrations.DeleteModel( + name='official' + ) + ] diff --git a/webapp/migrations/0056_auto_20190926_1857.py b/webapp/migrations/0056_auto_20190926_1857.py deleted file mode 100644 index 6f99cba..0000000 --- a/webapp/migrations/0056_auto_20190926_1857.py +++ /dev/null @@ -1,51 +0,0 @@ -# Generated by Django 2.1.5 on 2019-09-26 15:57 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion -import phonenumber_field.modelfields - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('webapp', '0055_auto_20190926_1850'), - ] - - operations = [ - migrations.CreateModel( - name='Official', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('phone_number', phonenumber_field.modelfields.PhoneNumberField(max_length=128, verbose_name='Phone number')), - ], - options={ - 'verbose_name': 'Official', - 'verbose_name_plural': 'Officials', - }, - ), - migrations.RemoveField( - model_name='role', - name='end_date', - ), - migrations.RemoveField( - model_name='role', - name='start_date', - ), - migrations.AddField( - model_name='occupation', - name='occupation', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='webapp.Role'), - ), - migrations.AddField( - model_name='official', - name='role_history', - field=models.ManyToManyField(to='webapp.Occupation'), - ), - migrations.AddField( - model_name='official', - name='user', - field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/webapp/migrations/0056_auto_20190926_2051.py b/webapp/migrations/0056_auto_20190926_2051.py new file mode 100644 index 0000000..3c9dbff --- /dev/null +++ b/webapp/migrations/0056_auto_20190926_2051.py @@ -0,0 +1,58 @@ +# Generated by Django 2.1.5 on 2019-09-26 17:51 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import phonenumber_field.modelfields + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('webapp', '0055_auto_20190926_2048'), + ] + + operations = [ + migrations.CreateModel( + name='Occupation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('start_date', models.DateField(verbose_name='Start date')), + ('end_date', models.DateField(verbose_name='End date')), + ], + options={ + 'verbose_name': 'Occupation', + 'verbose_name_plural': 'Occupations', + }, + ), + migrations.CreateModel( + name='Official', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_name', models.CharField(max_length=30, verbose_name='First name')), + ('last_name', models.CharField(max_length=150, verbose_name='Last name')), + ('email', models.EmailField(max_length=254, verbose_name='Email address')), + ('phone_number', phonenumber_field.modelfields.PhoneNumberField(max_length=128, verbose_name='Phone number')), + ('role_history', models.ManyToManyField(blank=True, to='webapp.Occupation')), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'Official', + 'verbose_name_plural': 'Officials', + }, + ), + migrations.RemoveField( + model_name='role', + name='end_date', + ), + migrations.RemoveField( + model_name='role', + name='start_date', + ), + migrations.AddField( + model_name='occupation', + name='role', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='webapp.Role'), + ), + ] diff --git a/webapp/migrations/0057_auto_20190926_1915.py b/webapp/migrations/0057_auto_20190926_1915.py deleted file mode 100644 index ae2c01f..0000000 --- a/webapp/migrations/0057_auto_20190926_1915.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.1.5 on 2019-09-26 16:15 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('webapp', '0056_auto_20190926_1857'), - ] - - operations = [ - migrations.AlterField( - model_name='official', - name='role_history', - field=models.ManyToManyField(blank=True, to='webapp.Occupation'), - ), - ] diff --git a/webapp/migrations/0058_auto_20190926_2010.py b/webapp/migrations/0058_auto_20190926_2010.py deleted file mode 100644 index e7230cd..0000000 --- a/webapp/migrations/0058_auto_20190926_2010.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 2.1.5 on 2019-09-26 17:10 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('webapp', '0057_auto_20190926_1915'), - ] - - operations = [ - migrations.AddField( - model_name='official', - name='email', - field=models.EmailField(default='asd@asd.fi', max_length=254, verbose_name='Email address'), - preserve_default=False, - ), - migrations.AddField( - model_name='official', - name='first_name', - field=models.CharField(default='asd', max_length=30, verbose_name='First name'), - preserve_default=False, - ), - migrations.AddField( - model_name='official', - name='last_name', - field=models.CharField(default='asd', max_length=150, verbose_name='Last name'), - preserve_default=False, - ), - ] diff --git a/webapp/migrations/0059_auto_20190926_2032.py b/webapp/migrations/0059_auto_20190926_2032.py deleted file mode 100644 index a956773..0000000 --- a/webapp/migrations/0059_auto_20190926_2032.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 2.1.5 on 2019-09-26 17:32 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('webapp', '0058_auto_20190926_2010'), - ] - - operations = [ - migrations.RemoveField( - model_name='occupation', - name='occupation', - ), - migrations.AddField( - model_name='occupation', - name='role', - field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='webapp.Role'), - ), - ] From fef74dd99556d4f2c7e4ad8b6c9856f4b4131785 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 26 Sep 2019 21:03:26 +0300 Subject: [PATCH 06/72] Fix brainfart --- webapp/migrations/0057_auto_20190926_2102.py | 19 +++++++++++++++++++ webapp/models.py | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 webapp/migrations/0057_auto_20190926_2102.py diff --git a/webapp/migrations/0057_auto_20190926_2102.py b/webapp/migrations/0057_auto_20190926_2102.py new file mode 100644 index 0000000..1317349 --- /dev/null +++ b/webapp/migrations/0057_auto_20190926_2102.py @@ -0,0 +1,19 @@ +# Generated by Django 2.1.5 on 2019-09-26 18:02 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0056_auto_20190926_2051'), + ] + + operations = [ + migrations.AlterField( + model_name='occupation', + name='role', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='webapp.Role'), + ), + ] diff --git a/webapp/models.py b/webapp/models.py index 4e5414d..2ecad36 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -192,7 +192,7 @@ class Occupation(models.Model): start_date = models.DateField(_('Start date')) end_date = models.DateField(_('End date')) - role = models.OneToOneField('Role', on_delete=models.SET_NULL, null=True) + role = models.ForeignKey('Role', on_delete=models.SET_NULL, null=True) def __str__(self): return '{}: {} - {}'.format(self.role.name, self.start_date, self.end_date) From 0da0a02bacc52708afbe5801261feec13520117b Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 28 Sep 2019 17:41:37 +0300 Subject: [PATCH 07/72] Get Officials by year with query param year --- webapp/models.py | 15 +++++++++++---- webapp/serializers.py | 4 ++-- webapp/views.py | 6 ++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/webapp/models.py b/webapp/models.py index 2ecad36..875c855 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -194,6 +194,12 @@ class Occupation(models.Model): end_date = models.DateField(_('End date')) role = models.ForeignKey('Role', on_delete=models.SET_NULL, null=True) + @staticmethod + def occupations_by_year(year): + return Occupation.objects.filter( + end_date__gte=timezone.datetime(year, 1, 1)).filter( + start_date__lte=timezone.datetime(year, 12, 31)) + def __str__(self): return '{}: {} - {}'.format(self.role.name, self.start_date, self.end_date) @@ -217,11 +223,12 @@ class Official(models.Model): @property def current_roles(self): - return self.role_history.all().filter(end_date__gte=timezone.now()).filter(start_date__lte=timezone.now()) + return self.role_history.all().filter(end_date__gte=timezone.now()) - @property - def roles_of_year(self, year): - return self.role_history.all().filter(end_date__gte=timezone.datetime(year, 1, 1)).filter(start_date__lte=timezone.datetime(year, 12, 31)) + @staticmethod + def official_by_year(year): + return Official.objects.filter( + role_history__in=Occupation.occupations_by_year(year)).distinct() def __str__(self): return '{} {}'.format(self.first_name, self.last_name) diff --git a/webapp/serializers.py b/webapp/serializers.py index 3d4a3e8..bd3ad13 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -116,9 +116,9 @@ class OccupationSerializer(serializers.ModelSerializer): class ContactsSerializer(serializers.ModelSerializer): - current_roles = OccupationSerializer(many=True, read_only=True) + role_history = OccupationSerializer(many=True, read_only=True) class Meta: model = Official - fields = ('id', 'first_name', 'last_name', 'email', 'phone_number', 'current_roles') + fields = ('id', 'first_name', 'last_name', 'email', 'phone_number', 'role_history') depth = 2 diff --git a/webapp/views.py b/webapp/views.py index 8eeaf00..1aeab93 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -112,6 +112,12 @@ class ContactsViewSet(viewsets.ReadOnlyModelViewSet): serializer_class = ContactsSerializer permission_classes = [IsAuthenticatedOrReadOnly] + def get_queryset(self): + year = self.request.query_params.get('year') + if not year: + return Official.official_by_year(timezone.now().year) + return Official.official_by_year(int(year)) + class TagsViewSet(viewsets.ReadOnlyModelViewSet): queryset = Tag.objects.all() From b58dbde83c26b3b13d470f811cf31355ba56a9c6 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 28 Sep 2019 19:52:14 +0300 Subject: [PATCH 08/72] Minor cleanup --- webapp/models.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/webapp/models.py b/webapp/models.py index 875c855..52c141a 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -235,16 +235,7 @@ class Official(models.Model): @receiver(post_save, sender=Official) -def create_user_profile(sender, instance, created, **kwargs): - if created: - instance.user.first_name = instance.first_name - instance.user.last_name = instance.last_name - instance.user.email = instance.email - instance.user.save() - - -@receiver(post_save, sender=Official) -def save_user_profile(sender, instance, **kwargs): +def save_user_official(sender, instance, **kwargs): instance.user.first_name = instance.first_name instance.user.last_name = instance.last_name instance.user.email = instance.email From 562738f945e2cb18830303b57fbe1a3abb1d291a Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Wed, 9 Oct 2019 23:49:57 +0300 Subject: [PATCH 09/72] Use env variables for settings.py variables --- .env.sample | 8 ++ .gitignore | 2 +- sikweb/.ci-settings.py | 14 ---- sikweb/settings-sample.py | 75 ------------------- .../{settings-sample-prod.py => settings.py} | 22 +++--- 5 files changed, 20 insertions(+), 101 deletions(-) create mode 100644 .env.sample delete mode 100644 sikweb/.ci-settings.py delete mode 100644 sikweb/settings-sample.py rename sikweb/{settings-sample-prod.py => settings.py} (63%) diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..5be805f --- /dev/null +++ b/.env.sample @@ -0,0 +1,8 @@ +HOST=localhost +SECRET_KEY=7p$85^4ibb^p4-=vs44b7!y0e-zemugze18@a#30&71=a8)dp( +TG_BOT_TOKEN= +EMAIL_HOST= +EMAIL_PASSWD= +DB_USER=postgres +DB_PASSWD=postgres +DB_PORT=5432 \ No newline at end of file diff --git a/.gitignore b/.gitignore index b264155..aa9f6d1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ *.swp -sikweb/settings.py +.env *~ *.pyc *.sqlite3 diff --git a/sikweb/.ci-settings.py b/sikweb/.ci-settings.py deleted file mode 100644 index 043f3ce..0000000 --- a/sikweb/.ci-settings.py +++ /dev/null @@ -1,14 +0,0 @@ -"""File containing CI settings.""" - -from sikweb.default_settings import * - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'ci', - 'USER': 'postgres', - 'PASSWORD': 'postgres', - 'HOST': 'postgres', - 'PORT': '5432', - }, -} diff --git a/sikweb/settings-sample.py b/sikweb/settings-sample.py deleted file mode 100644 index b92133c..0000000 --- a/sikweb/settings-sample.py +++ /dev/null @@ -1,75 +0,0 @@ - -""" -Django settings for sikweb project. - -Generated by 'django-admin startproject' using Django 1.9. - -For more information on this file, see -https://docs.djangoproject.com/en/1.9/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/1.9/ref/settings/ -""" - -from sikweb.base import * - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -# ALLOWED_HOSTS = ["*"] -URL = "sika.sik.party" - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = '7p$85^4ibb^p4-=vs44b7!y0e-zemugze18@a#30&71=a8)dp(' - -# MQTT settings -MQTT_SETTINGS = { - 'HOST': 'mqtt.sik.party', - 'PORT': 1883, - 'TOPICS': { - 'BREW_TIME': 'sik/kiltahuone/kahvivaaka/brewtime', - 'WEIGHT': 'sik/kiltahuone/kahvivaaka/weight', - 'BREWING': 'sik/kiltahuone/kahvivaaka/brewing', - 'CUPS': 'sik/kiltahuone/kahvivaaka/cups', - } -} - -# ReCaptcha -# http://www.yaconiello.com/blog/integrating-google-recaptcha-to-django/ -GOOGLE_RECAPTCHA_SITE_KEY = "YOUR-PUBLIC-KEY" -GOOGLE_RECAPTCHA_SECRET_KEY = "YOUR-PRIVATE-KEY" - -# Email settings (more settings in base.py) -EMAIL_HOST_USER = '@gmail.com' -EMAIL_HOST_PASSWORD = '' -DEFAULT_EMAIL_FROM = 'SIK Viestintä ' -ENABLE_AUTOMATIC_EMAILS = False - -# Token for Telegram bot -TELEGRAM_BOT_TOKEN = "" - -# Database settings -# Only uncomment if default settings in base.py are not ok - -# DATABASES = { -# 'default': { -# 'ENGINE': 'django.db.backends.postgresql_psycopg2', -# 'NAME': 'sik', -# 'USER': 'sik', -# 'PASSWORD': 'password123', -# 'HOST': 'localhost', -# 'PORT': '5432', -# 'TEST': { -# 'NAME': 'sik_test', -# }, -# }, -# } -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': 'mydatabase', - 'TEST': { - 'NAME': 'sik_test', - }, - } -} diff --git a/sikweb/settings-sample-prod.py b/sikweb/settings.py similarity index 63% rename from sikweb/settings-sample-prod.py rename to sikweb/settings.py index bb05654..7333fe2 100644 --- a/sikweb/settings-sample-prod.py +++ b/sikweb/settings.py @@ -14,27 +14,27 @@ https://docs.djangoproject.com/en/1.9/ref/settings/ from sikweb.base import * # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = False +DEBUG = os.getenv('DEBUG', False) == 'True' -ALLOWED_HOSTS = ["sika.sik.party"] -URL = "sika.sik.party" +URL = os.getenv("HOST", "sika.sik.party") +ALLOWED_HOSTS = [URL] # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.getenv('SECRET_KEY', '') # ReCaptcha # http://www.yaconiello.com/blog/integrating-google-recaptcha-to-django/ -GOOGLE_RECAPTCHA_SITE_KEY = "YOUR-PUBLIC-KEY" -GOOGLE_RECAPTCHA_SECRET_KEY = "YOUR-PRIVATE-KEY" +GOOGLE_RECAPTCHA_SITE_KEY = os.getenv("GOOGLE_RECAPTCHA_SITE_KEY", "YOUR-PUBLIC-KEY") +GOOGLE_RECAPTCHA_SECRET_KEY = os.getenv("GOOGLE_RECAPTCHA_SECRET_KEY", "YOUR-PRIVATE-KEY") # Email settings (more settings in base.py) -EMAIL_HOST_USER = 'sikviestinta@gmail.com' +EMAIL_HOST_USER = os.getenv('EMAIL_HOST', 'sikviestinta@gmail.com') EMAIL_HOST_PASSWORD = os.getenv('EMAIL_PASSWD', '') DEFAULT_EMAIL_FROM = 'SIK Viestintä ' ENABLE_AUTOMATIC_EMAILS = True # Token for Telegram bot -TELEGRAM_BOT_TOKEN = os.getenv('TG_BOT_TOKEN') +TELEGRAM_BOT_TOKEN = os.getenv('TG_BOT_TOKEN', '') # Database settings # Only uncomment if default settings in base.py are not ok @@ -42,10 +42,10 @@ TELEGRAM_BOT_TOKEN = os.getenv('TG_BOT_TOKEN') DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': os.getenv('DB_USER', ''), - 'USER': os.getenv('DB_USER', ''), - 'PASSWORD': os.getenv('DB_PASSWD', ''), - 'HOST': os.getenv('DB_HOST', '127.0.0.1'), + 'NAME': os.getenv('DB_USER', 'postgres'), + 'USER': os.getenv('DB_USER', 'postgres'), + 'PASSWORD': os.getenv('DB_PASSWD', 'postgres'), + 'HOST': os.getenv('DB_HOST', 'localhost'), 'PORT': os.getenv('DB_PORT', 5432), } } From 4e216891e6d111933b2f1bba56dbefc069a52c49 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Wed, 9 Oct 2019 23:51:36 +0300 Subject: [PATCH 10/72] Remove copy from Dockerfile.prod --- Dockerfile.prod | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile.prod b/Dockerfile.prod index 060f380..d8299d5 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -5,7 +5,6 @@ WORKDIR /app COPY requirements.txt ./ COPY requirements.production.txt ./ COPY . ./ -COPY sikweb/settings-sample-prod.py sikweb/settings.py # uWSGI, gunicorn etc. RUN apk add --no-cache --virtual .build-deps python3-dev build-base linux-headers pcre-dev openssl \ From 192be6e28b7f4a7ac096385b119693268e291ade Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 00:33:39 +0300 Subject: [PATCH 11/72] Remove copy cmds from CI --- .gitlab-ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 58d85e1..2ff9c3f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,8 +17,6 @@ test: script: - python -V - pip install -r requirements.txt - - cp sikweb/settings-sample.py sikweb/default_settings.py - - cp sikweb/.ci-settings.py sikweb/settings.py - python manage.py migrate --noinput - python manage.py createdefaultadmin - python manage.py test From 7457b8a24d49374b13bc13f6cd3b36a2b36bead9 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 00:56:44 +0300 Subject: [PATCH 12/72] Add env var for unit tests --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 03fa62d..c51bb41 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,6 +14,7 @@ test: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres DATABASE_URL: "postgresql://postgres:postgres@postgres:5432/$POSTGRES_DB" + DB_HOST: postgres script: - python -V - pip install -r requirements.txt From d7f57c5b3a5eb5c17149b11618dff5a92aa96f3a Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 18:02:06 +0300 Subject: [PATCH 13/72] Clean webapp urls --- webapp/urls.py | 54 +------------------------------------------------- 1 file changed, 1 insertion(+), 53 deletions(-) diff --git a/webapp/urls.py b/webapp/urls.py index f3bfa44..353b0ad 100644 --- a/webapp/urls.py +++ b/webapp/urls.py @@ -3,22 +3,8 @@ from django.conf.urls import url, include from rest_framework import routers from rest_framework_jwt.views import obtain_jwt_token, verify_jwt_token - -# from rest_framework.urlpatterns import format_suffix_patterns -# from django.conf import settings -# from django.utils.translation import ugettext_lazy as _ - -# from webapp.views import main_index -# from webapp.views import login_view -# from webapp.views import logout_view from webapp.views import about_view -# from webapp.views import guild_view -# from webapp.views import freshmen_view -# from webapp.views import jobs_view -# from webapp.views import event_calendar_view -# from webapp.views import international_view -# from webapp.views import sosso_view -# from webapp.views import contact_view + from webapp.views import EventViewSet, SignupFormViewSet, SignupViewSet,\ FeedViewSet, ContactsViewSet, SavedQuestionsViewSet, RootView, TagsViewSet @@ -41,44 +27,6 @@ urlpatterns = [ url(r'^api/', include(router.urls)), url(r'^api/api-token-auth/', obtain_jwt_token), url(r'^api/api-token-verify/', verify_jwt_token), - - # login stuff - # url(r'^login$', login_view), - # url(r'^logout$', logout_view), - # git revision url(r'^about', about_view), ] -# urlpatterns = [ -# # main -# url(r'^$', main_index), -# url(r'^api/events/$', EventList.as_view(), name='event-list'), -# url(r'^api/events/(?P[0-9]+)/$', EventDetail.as_view(), name='event-detail'), -# url(r'^api/signup/$', SignupFormList.as_view(), name='signupform-list'), -# url(r'^api/signup/(?P[0-9]+)/$', SignupFormDetail.as_view(), name='signup-detail'), - -# url(r'^api/signup/create$', SignupFormCreate.as_view(), name='signupform-create'), - -# # url(r'^signupform/$', SignupFormList.as_view(), name='signupform-list'), -# # url(r'^signupform/(?P[0-9]+)/$', SignupFormDetail.as_view(), name='signupform-detail'), - -# # login stuff -# url(r'^login$', login_view), -# url(r'^logout$', logout_view), - -# # pages -# url(r'^guild', guild_view), -# url(r'^freshmen', freshmen_view), -# url(r'^event_calendar', event_calendar_view), -# url(r'^international', international_view), -# url(r'^sosso', sosso_view), -# url(r'^contact', contact_view), - -# # corporate -# url(r'^jobs', jobs_view), -# ] - - -# if settings.DEBUG: -# from django.contrib.staticfiles.urls import staticfiles_urlpatterns -# urlpatterns += staticfiles_urlpatterns() From d0d63a6e29e80b39c8328c32c601749625a52f0d Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 18:13:01 +0300 Subject: [PATCH 14/72] Add translations --- locale/en/LC_MESSAGES/django.mo | Bin 16042 -> 16111 bytes locale/en/LC_MESSAGES/django.po | 29 +++++++++++++----------- locale/fi/LC_MESSAGES/django.mo | Bin 16647 -> 15540 bytes locale/fi/LC_MESSAGES/django.po | 38 ++++++++++++++++++++++---------- 4 files changed, 42 insertions(+), 25 deletions(-) diff --git a/locale/en/LC_MESSAGES/django.mo b/locale/en/LC_MESSAGES/django.mo index ce8fde80325bd50d5bb4fda27513239a94593ec9..2324f4f31c5aa496b671c23658d20d637a714d6c 100644 GIT binary patch delta 3198 zcmX}t32anF9LMq5LQApiwgt*ni?2{=3+33Nr5u6?a%)iTE3lS@E?p?J4N$eNMi7GG z&=+Vpf&voc60n>SNe~Po8Z^YCNK`Q4O2kkQ4aMsB$D7#n?Pq4*o9jRSeY>mbkE;Er z<6G4bt;X@R3L4`<@z_>OHqg7MVP;UoAhj>1criMi=s`$$ZqJ|0srYU@>)NZrL8 z+=PDoJl(`hO9~fgXpGmfDgKU)@Gsk5kHe^&M~z8<;n*BUV=FAeWPI7W0>kX(0(-<{?8P+^hMEau6dN68%lTk-f zVO@sW&<0dQK0=Lm95e6~GEU4~rl2#wi8}MUsGa|f1i>VB^v)^=CsOZ*D{&cWM`>AJ zMB1Su(H*ss0&I-WqZTj*weT6Jg+Zk(QUcU?^e@zEW!hzTYpTiui#29_dRtmH6EXHGyy9w9}mA(B@D<6e% zI0v34;6`&?%vMR(NDb#YJ%RVg$_hz`BuqrjWEJF4Cvl?$U$JDr9)ni5oG z%5D1+e7GUh0@oK1fBo9+r9mtD0w2C=Q3KSWe(mm~21@SbovDKgZAUD^QMSGxM^LXt zg*dCw8#fmpzN)bm?c=aDMhl6*8kW$Y9dAU1bi4H+Dk7&a4ZlJy@Cqu_53I?(y&ZKx zMWO(;fkC!?Bx;=LsCkM}kuQr;PzV=dCtPkH*oQ-?AH&6H`gl94L`CE^R4854PBz&4 zAEOp<1U2DlRH(nkEWC{Bm(bTU=BJ<)wM1oidu)qOqjF+0I`}%K;}+Df-KVyG(bn&w z#%a;d8#n`%bXllKbVeOvzI6~1ftVR=`HJFE+Fc;4vZ((x>BbeD=3+iIb+Y}U%O{nbMh6>>U)C=SUs^dww)}QU) zPiZX|8D`G7{y=)_R7x*$z0Y-sYmM7Gu*~<9doqyio9x~Q^z|tP2%2nT-~@j za&6|C=+-6|`PR8lrDQ9;{{K5qX$IF6w=!jb&$!1@ro?|qeYe{-wcK~fU70#GeggGr zZf$CJ-*~ra^S(Y)^KA3anz)7SF1CqQgq(`f$lOp_q&QR(nNu2xM#D}{v76AYn=iMf zS$acUO;Y>qaWw~=f14x)dvp!g29^OIpvA&q~NU=%I1bDBBk@3@WSxC$h_Ik ztkNh;d!zs32fnn6& z#57!kUfi2t0;V5@!!-29v)BiJ!d}>6+dJ`j>RlLunS+dp!F=qGr5J_ttaW(JW6Wxd zpnb_;_kJVhQ-24wkgo>^+zF4_4yREQv||=_q9TtR;`WQPCL#Z31Rv2j2^By&YQkFU zTd0+;!%%ESWv0cp9|%y;ghx@S{}#!vxriF@Zybn0es_RDsEiFm4OEDFej+}JFX6|y z9JA5O{%C8*pfbDxwN;yuWSYPy6qLd?jKj0G-i3;|2P3f;qstgnMv_o_osJ6d8Pt}{ zw$`E+v<8)tZK&~fVJa{h+M;gMbG=fH;ryB~498R)fq9sQ^D#hQv!23IJcz*<$K4Q2M4jGYsK|3M z2*=`Zd=~v4V`{L6`X(AXaYMR0VHLA!oYyf7SD`ZdE^47$Mv#9^;LyOo+0BO@_`!Dg z8I_rK)Jkul0_nzZ^klea#f$2fh{`~gt(RCQTj!(BR0Brf)(rBWL!pHR{>^zlGVuW_ zh3Qlj;7HWzF2M+#V%y76{iiyvMEFD zSraPK9oD0$LwFgLiGNVv63<9Cz-ZJ2Lr{UHqE2}c($!2x1>S@T_Yj#DFGVMj;vBKt;X-bvpN0526m`5sb!m)Wm<;`aRTH2rqC~IsmmbDX7e3 z+4iycctNNDrxlQY{o1`kgCcqdb;=#o0Q*rXYeNlm2DPUhsMKD?N(>$4)~j(M^=+t3 zcB01ZLcN;1u|N7oyT1{sqshM-#?qh_&p@qgfwdl$k<}QB>rer_MH0*kbqBt{9cVxu{>e6}H}N>tCYA zIft5{9d+nBQJMGywS_mW50MN6Ow`kEhrXy4B%rp$k5h3JR^vw0*8GdgSV)OI<*4T} zP=V*5PWdFvz?nE4*CKCUa{#OGGWztZGhvJy@l4eBbRH^&HK@b367}FJ=aM(oyOmNi z7bnTQ=6E9$qRT10%(aWFjq8k47`e_f!#N(A>Y3x*h|KeR;B(bHq1C$uyUpfzgc~<7|p94W6Y2=Th`Y z&rGLJOtI%s>vJ(DLY@2ZnVux4cl?#stc1Hk9)D}f;637d|D(|G?83~P0)I|nQC?o_ zg|x=7^zn-;7S&YME%q<3_g6GD)U5PZH2N$2b@g?b3+pSEE%MhdSyEM5RZ)}Vl;+%a NG85*sUds)O_zzU9Uta(K diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po index f0ed178..11d9b79 100644 --- a/locale/en/LC_MESSAGES/django.po +++ b/locale/en/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-09-16 19:33+0300\n" +"POT-Creation-Date: 2019-10-10 18:11+0300\n" "PO-Revision-Date: 2017-11-02 23:09+0200\n" "Last-Translator: \n" "Language-Team: \n" @@ -392,7 +392,7 @@ msgid "" " Koska lista ei ole koskaan täydellinen, voit myös ehdottaa ihan " "uutta toimenkuvaa.\n" " Jos sinulla on kysyttävää mistä tahansa virasta, kannattaa " -"konsultoida kaehmyopasta \n" +"konsultoida kaehmyopasta\n" " tai olla yhteydessä kyseistä virkaa tänä vuonna toimittavaan " "henkilöön." msgstr "" @@ -406,7 +406,7 @@ msgstr "" #: kaehmy/templates/kaehmy.html:23 msgid "" -"Muista, että kaehmyn lähettäminen on kiinnostuksen ilmaus \n" +"Muista, että kaehmyn lähettäminen on kiinnostuksen ilmaus\n" " eikä siis missään nimessä sitova ilmoittautumien mihinkään " "tehtävään!" msgstr "" @@ -418,24 +418,27 @@ msgid "Päivämääriä & deadlineja" msgstr "Dates and deadlines" #: kaehmy/templates/kaehmy.html:28 +msgid "Kiltailta" +msgstr "Guild night" + +#: kaehmy/templates/kaehmy.html:29 msgid "Hallitustyrkkypaneeli (haku hallitukseen olisi hyvä tehdä ennen tätä!)" msgstr "Board panel discussion (applications to the board before this date!)" -#: kaehmy/templates/kaehmy.html:29 +#: kaehmy/templates/kaehmy.html:30 msgid "Vaalikokous, osa 1 (puheenjohtajan valinta)" msgstr "Election meeting, part 1 (chairman election)" -#: kaehmy/templates/kaehmy.html:30 -msgid "Kiltailta" -msgstr "Guild night" - #: kaehmy/templates/kaehmy.html:31 msgid "Vaalikokous, osa 2 (hallituksen valinta)" msgstr "Election meeting, part 2 (board election)" #: kaehmy/templates/kaehmy.html:32 -msgid "Haku toimariksi olisi hyvä tehdä ennen tätä!" -msgstr "Deadline to apply as a non-board official!" +msgid "" +"Infoilta toimarihakijoille (haku toimariksi olisi hyvä tehdä ennen tätä)" +msgstr "" +"Information evening for applicants (applications to official roles before " +"this date!)" #: kaehmy/templates/kaehmy.html:33 msgid "Vaalikokous, osa 3 (toimarien valinta)" @@ -913,11 +916,11 @@ msgstr "Payments in register:" msgid "Language" msgstr "Language" -#: members/templates/settings.html:20 sikweb/base.py:255 +#: members/templates/settings.html:20 sikweb/base.py:256 msgid "Finnish" msgstr "Finnish" -#: members/templates/settings.html:21 sikweb/base.py:256 +#: members/templates/settings.html:21 sikweb/base.py:257 msgid "English" msgstr "English" @@ -1098,7 +1101,7 @@ msgstr "" msgid "Challenge" msgstr "Challenge" -#: ohlhafv/views.py:43 +#: ohlhafv/views.py:44 msgid "Sinut on haastettu Øhlhäfviin!" msgstr "You have been challenged at Ohlhafv!" diff --git a/locale/fi/LC_MESSAGES/django.mo b/locale/fi/LC_MESSAGES/django.mo index 118a138435a50268936aff3ca9b73dd7d176f420..66c110c982232a3b3f75bca24efba14b641503f4 100644 GIT binary patch delta 5356 zcmZA52Xt2D9mnw}2qBO`5<*BwkT-@Ab_N6*WR?~QXbA->Vb(INVO1p<)+JOL1r*va zWK<9&jsiABhHR)%&{!}MIv5cVD-xN?IC|QCf4P5qZ13UsexB#v`#$sDHy(@T2fbb3 zosX`)+;Q9^iR9C|&gBF-x4D7NI(I$BxhlMYq4;4V=R)wD`5E3v{TjB#TNsSZV*T?i zQQvEWk(i0~u^)yx=efal!x&Vbd8iv_VFWI=>uc=%YvwL&#`WV!L+&!B;cYXev2*RH z=VE&-!rHhU!*Mr8)4w}LK@FV2dic5Ba1-?f7w2EEgPM6XY6c0Y`&(iFQ|){X4yQg6 zSxmPB8I#+Oy1x=NfGVs{|L#i)P4O=33$gLeb;kQqUl@W>I2x028s3k~P%BVoeuVsU zxA@Qi!<+ak8i(pI1=W5gMq>~38dAuipd}xV9WWoYBAZYvunqOaov6J%fZEfes4c2M zt;_|~{a>KkyN0^YCHU=yq1uVZI+&Ee`fDVuIMENYPz}wu8yDG)#pWthhwD%)vlTU< zU8oKZ*!7cEuR<2pT}KV99#6R1k3bEeaU$!l2Agt1BWs6Rx=#22_C$T*F*~1!wW#N# z8YsYQ^iU7md)NZ+pjNgi`>OlWQ0;cXBte9-c?u zL|2WPQ4kM;Rw5Yn8b+ed$Dmdw9<{;&)I*qoddsp+FPDP$`UyKR13OVKLXCVcs)NI* z0hL?5(yT%~oR?7ze}if-lqXZhp$6UpwZa*wiFWhPdu|{Fb(D)5@mSQ-O+=m_Hw)G9 z3e?kGf@Y9)?Y{T!;{OQ@~8jVm!e;IBw2Y9KpMTk$UH`Ew^IXlbq>ue__p2C3cz zHRCkYOtMfb(GN9%9MsH*BirrrP)q$BY9eb;&(;RB6xH5A)RrH|F#2~@6g0DHR0F{b zU&fPGu~x4oU{v- zs1DDf8oG>Hx|^s0=~qYti9uaYMBU#4^}eTDy$7nJ0jMP(Y>q;G|M6tjUpGwSgho08 zSp-*zT9J*|0{3A6FCwq9tKHmR@&Kyd-Ri?p4d)(Mw zDJS&D<73oFqv=%*G)3)k2eTJyYX+m9k@2X8X5&w>5c9ASHL%_-{fUi2t>8pdd(%o;AiTra3t^6hJgIe>Cs)0So;<+QJj<2G=e-A@3 zq`g0(7!0GHg8H-G8P$FshU@)*l0pFIVKaOM*&cTYY0F)<^RYas8b~Ip!JeoN2io}& zsDX?_J!Dg@UWmN8ZZT?LZ=qIb4|;0weF_@UDf0~K#!s*gUPbNsSEz=+H6uFu0|=n5 zcSH@W3+ku4FZRJPs2`pUsQz}M+CA8j_g_nSloQ&klNgQ{Q8T%L8pyYHJ|xv&(pc0l zU>j7&525ZGWc88QfciL8M^D@NnHZoxA2s2PsjR;`decs9M}1*0X5(Sh7KEqK8D^nY zU_9zIn_Uk72<0RCQbwu5ejar#Uto|r! zpd(QupJ-08^V3l?o@Xva4P?F5x1ipdeW(fEM78hTwG*{6{JjamC@w@{1SX>zPPcj= z)PQqP9gMO1B-CHEnW+1hqB>fS8gL0l;uh3fwI8|9b7v@Y=foA%!_k^yYNqL^FLp;Y z+!yr}=i*B^2ek#Uyi?ly1hW-tD>6_&!8xe!O-4;J_Lz zLKjdY{|41z7{5ZAVHE2AB&)YY-PaA(!9dgia!~`!H|Lu#O8R%JDQLzesF9bVW_|*- zgr}{37PUebQ5{!X{Wj_s^53XuC#j3yaSPP_y;1FCW6fKF`u<4twAT|TXiuI&&0x7% zf-%&0n&sG-`UTVg?_oo9UHzqvLA{R2W?R$%GB6n*M7>&p6Tzk?kX^iDvl%d6kSN+P}Y%E#zn93!;Oa`tNa@(wiik{F!`629S2-GqRujn4BaX z2}iLP8SgEnu#$XE29iAT|HoWAvG{uzDk!hA`f&UQIYgczX9#QJdJ-LfAU`MXslxF* z`5oD)-yj`}YCipsX;yv`^(t%S7m{bmRdSEKMwXGoDW#lBg2RuaQ$3NAv=kl$6_*` zJVd@bzOq6-mXh^kDA93@q!S+NniuXmes?@fL2qlMR%jE2H1aXoMl#6jL`Q^A&F2t4 zM_PTHISYSd<=msz_C`|g%fmVCkk815xY=iPBh2h*CdhTl2kH} ztRTIJj;SP?JVz!G9X})^$V~DlvX1ljoM8_S{g@lnLa**iwt5416 z8+=xgN6A^znA{{fz9cPcO8jpbTtj-0!FKNN__Y6a`e%aSFXZ>+CuBL%@f1lQajJ0K z^7)_7my1`$Bn*Gs&h^KBWVY2$o1fqy(v3{FbC2V@B-84Xb}uuc{(k^V0uikM delta 6393 zcmeI!i=T~k0>|;+WDEvl#)#3lJZMnHT+qmE$X0~4B3jy|Cv!BXGtObonaRj{HZ{7i zv3qjsCZW4-Bayaf%4Jh2k;xN-Ej>A;E8k-p7nR0uAhZ=Jp>cl%S4Ij1NZ?x@Ot$VRO-+zX5WE!imn*!BMt- zI*zA43)xJw2brTefI9y;Y67P)mGMo}*2c8OEYt->cpes`E{I_U&c;r-5ZmEe)DG;j z9z*__%(MInc1P{#`KSShqWT|)&2b`nnG~i|(3V$Y9xg_$_+``%yotK-ZPdLzh`Ohr zqHfVq)XpSj`{$>k`fG+d&q4K_vSOY6Ztp1D!-otUk+7J%6tv=){h}H* zP#iV$WvDH@7kSRiT2#lcqn`GIs9SdewIfN~H`QCB`fZ2&Gx>Zh#nGr8tHY*x|G%c7 zd-8AOc`=Q6$FxN`$WMalZ|j$#RvbdDD27`3^{4^op;jJ89s{!)wdF6O7P1@ltnIVb zVMD$DKTy!UuXncJack7dI-@!mWF3Rri7BWF%tQ@*6Y_YN1*n}{gUMK9>+4Yye;zgA zt(c5&prg;0OrJz{I>rsEVGyAU-4$z<#e~NinhlO}n7k{QBP#s*3y2qu~nW$SdAN9;ENAV>7CQoyePLcB8iN8|;SW9RGJ97n!3Oizzq@ zwdFV1`a*0(eF>_+6{rF4N1eA8&p>Z8h2crYyo4{(kj^MNVHaw}@1rg}g4(iE$Ujpr z*MAoBu>tk-u@MeJEo7K=ytNe7&$Xx>tM=PHvy_6~=Lh@-^9<_5EvSd+NvsH)c|6A0+Dcs*C*cwyy{&%LJnHSnG`q}zWOrw1? zYKvXeLsp6!pc<#(ZK&&yBX`N1LJizC-@m>mHl{upwV;ux30#He>HUvT&;YBkDL#r0 zK8x+~J>)quCy`AsoeKQ+QK*SbLv>h%X*k!mFG5Y^9@I1Tkgab-e(TH@^fa^2C^W<4 zs1ED%=xai0)-zG(wZZz>6?M<^FawLMLs1i$fcid&n%H#IPxovbjLT5JJNpXRe+_tq z26g-cYAa0-|6Zk{cBCz8CEZXHDYET@QCm6+^$S>n8h8%syjyL3F=~PLpvHO3wy*8M z{yQ{0M}tBd7bqn z>c9EM{DG+ndB=E%bb{&azeee(6<>rJXt=G9Mct|^P%AA#-Rnx!_0_h%2sQClr~#g` z^%qe8$-Rm?|084^&m5zmnV-OPH0S%TSqAFFJRE?-9l8yOHfbs8eEDy zQMV%4$A1>W)|seVG8gstr&&co7j8nW=p)n$j-nnS)7Nirg4&U6ThGDP)O(>OJ`y$H zB-F%9Q0K>NeKzX6+fe;4$85$oYba=-?bhAa53FCJR(t|A^JISJwDOLqTXl}D=c9J0 z2sQ9PTfYQ5P#=wY#$uR_Gtkoow^L9@ccUh<64k-usC&Hu^~?7PY6XX_C$I(e)c(Hh zu@&`Rs0oh1OdNyS*{e~nXQg#^fBXK=rJ)mFEI_>;HOQN0cA;jT!UN!7SL}+Hpl(?? z>h)WM>Ua}sz-`zZ_n{W}73yL99<`J8i~axR(~H^v0vZO=pf9GO?%j2$mCi$5c$aN| z2sOY4)Cyn4QTP^Ki8%xPpX#}&9efPc-+I(eZL{u2U4PW0(2l|h)D~q8^8b77f?DYq z?2NNe57$b}!Us_k-i*3sJ5aZ9FKXontVi$+>d6=Imoe&i&?oVSiD%0{^D3pA$Tg&# zyg_uVB;CjhM1jzklBGK)8mpo1`Ctna9yoEm>-&1;&3?tjgF8$FooI)-+Og52= z$(!-9>7Bg4QCdbmCnHE1`Q@>Z%Aak+ZNK>9Ey@dQeLU_XwWNydCp=V!?M@tP_;kq* zziQ^;?PRrnnsodn@#%j|x8*464c3OwCv(ZyQ{gxEiNtTn} zktIY&jAWB6RXC3O{Oa@GcvXw+@#}2cB{+oq$=3H;KgLm{AE~r$LEJ)$Z2dXBz?Q{K z;?;cF;`RnjLlsUe5}fLm2Sd?d{PThi@y!KQHQ%+VO7cRHa3D}t<~o&;V9W`YO?89O znCpas!EiVdja7uAfoL#sbx^IG8I8J5AWUOrMI;<{^HQB(93ynK&WMDaN|);^+_H*5 zFcx!zVJ8|0)vj_%-LkS^tRmXo3B+O^4Vqf8G!Ulu+I5w|@=)ZO|LApiBpPy^vc${+ zK_^lca6)Qw!%nPrRaFTK2!;dUTz?T$t7_Lpoj_?xgkfDLSjuS?6_gVrF-}FLdwKxR z&V5)U>O_O#3he|_4^>60Vsu?uyNU@;Wnj(Ir6-og6j_;@>x5j^pBRH(j8>GfkP_GF z?>eRBfhhwz=5takI5|HOD-D$AhuqSsRgr0KG;dnTl#azAH=ue64KcTWzFX}4Y9HAz zmdRwQN@D>Q7>zOkW)<+KqFrKX%qmQ~eTWIC)a?3~`u+I8W)`0^f;Yj(7|B`Ln4 y*TkBqoHh*_7xd{~SmYG;>D#ks%{yJ{8vgeqQnR_>lm9;+{|k>t&GH^+rv3yKxuZS+ diff --git a/locale/fi/LC_MESSAGES/django.po b/locale/fi/LC_MESSAGES/django.po index 25eee0e..97ff0ef 100644 --- a/locale/fi/LC_MESSAGES/django.po +++ b/locale/fi/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-09-16 19:33+0300\n" +"POT-Creation-Date: 2019-10-10 18:11+0300\n" "PO-Revision-Date: 2017-11-02 23:04+0200\n" "Last-Translator: \n" "Language-Team: \n" @@ -386,6 +386,17 @@ msgid "Copyright Aalto-yliopiston Sähköinsinöörikilta ry" msgstr "Copyright Aalto-yliopiston Sähköinsinöörikilta ry" #: kaehmy/templates/kaehmy.html:16 +#, fuzzy +#| msgid "" +#| "Kaehmykoneella voit ilmaista kiinnostuksesi toimia killassa ensi vuonna.\n" +#| " Listassa on vastuualueittain sekä hallitus- että " +#| "toimihenkilövirkoja.\n" +#| " Koska lista ei ole koskaan täydellinen, voit myös ehdottaa " +#| "ihan uutta toimenkuvaa.\n" +#| " Jos sinulla on kysyttävää mistä tahansa virasta, kannattaa " +#| "konsultoida kaehmyopasta \n" +#| " tai olla yhteydessä kyseistä virkaa tänä vuonna toimittavaan " +#| "henkilöön." msgid "" "Kaehmykoneella voit ilmaista kiinnostuksesi toimia killassa ensi vuonna.\n" " Listassa on vastuualueittain sekä hallitus- että " @@ -393,7 +404,7 @@ msgid "" " Koska lista ei ole koskaan täydellinen, voit myös ehdottaa ihan " "uutta toimenkuvaa.\n" " Jos sinulla on kysyttävää mistä tahansa virasta, kannattaa " -"konsultoida kaehmyopasta \n" +"konsultoida kaehmyopasta\n" " tai olla yhteydessä kyseistä virkaa tänä vuonna toimittavaan " "henkilöön." msgstr "" @@ -409,7 +420,7 @@ msgstr "" #: kaehmy/templates/kaehmy.html:23 msgid "" -"Muista, että kaehmyn lähettäminen on kiinnostuksen ilmaus \n" +"Muista, että kaehmyn lähettäminen on kiinnostuksen ilmaus\n" " eikä siis missään nimessä sitova ilmoittautumien mihinkään " "tehtävään!" msgstr "" @@ -422,23 +433,26 @@ msgid "Päivämääriä & deadlineja" msgstr "Päivämääriä & deadlineja" #: kaehmy/templates/kaehmy.html:28 +msgid "Kiltailta" +msgstr "Kiltailta" + +#: kaehmy/templates/kaehmy.html:29 msgid "Hallitustyrkkypaneeli (haku hallitukseen olisi hyvä tehdä ennen tätä!)" msgstr "Hallitustyrkkypaneeli (haku hallitukseen olisi hyvä tehdä ennen tätä!)" -#: kaehmy/templates/kaehmy.html:29 +#: kaehmy/templates/kaehmy.html:30 msgid "Vaalikokous, osa 1 (puheenjohtajan valinta)" msgstr "Vaalikokous, osa 1 (puheenjohtajan valinta)" -#: kaehmy/templates/kaehmy.html:30 -msgid "Kiltailta" -msgstr "Kiltailta" - #: kaehmy/templates/kaehmy.html:31 msgid "Vaalikokous, osa 2 (hallituksen valinta)" msgstr "Vaalikokous, osa 2 (hallituksen valinta)" #: kaehmy/templates/kaehmy.html:32 -msgid "Haku toimariksi olisi hyvä tehdä ennen tätä!" +#, fuzzy +#| msgid "Haku toimariksi olisi hyvä tehdä ennen tätä!" +msgid "" +"Infoilta toimarihakijoille (haku toimariksi olisi hyvä tehdä ennen tätä)" msgstr "Haku toimariksi olisi hyvä tehdä ennen tätä!" #: kaehmy/templates/kaehmy.html:33 @@ -903,11 +917,11 @@ msgstr "Maksutapahtumia:" msgid "Language" msgstr "Kieli" -#: members/templates/settings.html:20 sikweb/base.py:255 +#: members/templates/settings.html:20 sikweb/base.py:256 msgid "Finnish" msgstr "suomi" -#: members/templates/settings.html:21 sikweb/base.py:256 +#: members/templates/settings.html:21 sikweb/base.py:257 msgid "English" msgstr "englanti" @@ -1088,7 +1102,7 @@ msgstr "Haasta kaverisi mittelöön!" msgid "Challenge" msgstr "Haasta" -#: ohlhafv/views.py:43 +#: ohlhafv/views.py:44 msgid "Sinut on haastettu Øhlhäfviin!" msgstr "" From e5cc62bbbf096d31ee65a39aa49daabdf4cf65d9 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 18:37:15 +0300 Subject: [PATCH 15/72] Use OccupationSerializer for the Contacts API --- webapp/migrations/0058_auto_20191010_1837.py | 18 ++++++++++++++++++ webapp/models.py | 10 +++------- webapp/serializers.py | 19 +++++++++---------- webapp/views.py | 8 ++++---- 4 files changed, 34 insertions(+), 21 deletions(-) create mode 100644 webapp/migrations/0058_auto_20191010_1837.py diff --git a/webapp/migrations/0058_auto_20191010_1837.py b/webapp/migrations/0058_auto_20191010_1837.py new file mode 100644 index 0000000..7df01b1 --- /dev/null +++ b/webapp/migrations/0058_auto_20191010_1837.py @@ -0,0 +1,18 @@ +# Generated by Django 2.1.5 on 2019-10-10 15:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0057_auto_20190926_2102'), + ] + + operations = [ + migrations.AlterField( + model_name='official', + name='role_history', + field=models.ManyToManyField(blank=True, related_name='officials', to='webapp.Occupation'), + ), + ] diff --git a/webapp/models.py b/webapp/models.py index 52c141a..4c8d331 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -195,7 +195,7 @@ class Occupation(models.Model): role = models.ForeignKey('Role', on_delete=models.SET_NULL, null=True) @staticmethod - def occupations_by_year(year): + def by_year(year): return Occupation.objects.filter( end_date__gte=timezone.datetime(year, 1, 1)).filter( start_date__lte=timezone.datetime(year, 12, 31)) @@ -219,14 +219,10 @@ class Official(models.Model): last_name = models.CharField(_('Last name'), max_length=150) email = models.EmailField(_('Email address')) phone_number = PhoneNumberField(_('Phone number')) - role_history = models.ManyToManyField('Occupation', blank=True) - - @property - def current_roles(self): - return self.role_history.all().filter(end_date__gte=timezone.now()) + role_history = models.ManyToManyField('Occupation', 'officials', blank=True) @staticmethod - def official_by_year(year): + def by_year(year): return Official.objects.filter( role_history__in=Occupation.occupations_by_year(year)).distinct() diff --git a/webapp/serializers.py b/webapp/serializers.py index bd3ad13..03f8f1f 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -107,18 +107,17 @@ class RoleSerializer(serializers.ModelSerializer): fields = ('name', 'description', 'committee') +class ContactsSerializer(serializers.ModelSerializer): + class Meta: + model = Official + fields = ('first_name', 'last_name', 'email', 'phone_number') + depth = 2 + + class OccupationSerializer(serializers.ModelSerializer): role = RoleSerializer(read_only=True) + officials = ContactsSerializer(many=True, read_only=True) class Meta: model = Occupation - fields = ('role', 'start_date', 'end_date') - - -class ContactsSerializer(serializers.ModelSerializer): - role_history = OccupationSerializer(many=True, read_only=True) - - class Meta: - model = Official - fields = ('id', 'first_name', 'last_name', 'email', 'phone_number', 'role_history') - depth = 2 + fields = ('role', 'start_date', 'end_date', 'officials') diff --git a/webapp/views.py b/webapp/views.py index 1aeab93..e024e4c 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -108,15 +108,15 @@ class FeedViewSet(viewsets.ModelViewSet): class ContactsViewSet(viewsets.ReadOnlyModelViewSet): - queryset = Official.objects.all() - serializer_class = ContactsSerializer + queryset = Occupation.objects.all() + serializer_class = OccupationSerializer permission_classes = [IsAuthenticatedOrReadOnly] def get_queryset(self): year = self.request.query_params.get('year') if not year: - return Official.official_by_year(timezone.now().year) - return Official.official_by_year(int(year)) + return Occupation.by_year(timezone.now().year) + return Occupation.by_year(int(year)) class TagsViewSet(viewsets.ReadOnlyModelViewSet): From 86af724cccfd67e105fb18a0d6f9da45f2fe4e47 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 19:03:26 +0300 Subject: [PATCH 16/72] Add translations to API --- webapp/admin.py | 2 +- webapp/migrations/0059_auto_20191010_1900.py | 23 ++++++++++++++++++++ webapp/serializers.py | 4 ++-- webapp/translation.py | 10 +++++++-- 4 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 webapp/migrations/0059_auto_20191010_1900.py diff --git a/webapp/admin.py b/webapp/admin.py index dd0c36f..04d51cf 100644 --- a/webapp/admin.py +++ b/webapp/admin.py @@ -16,7 +16,7 @@ admin.site.register(Event, TranslationAdmin) admin.site.register(SignupForm, TranslationAdmin) admin.site.register(Signup, TranslationAdmin) admin.site.register(TemplateQuestion, TranslationAdmin) +admin.site.register(Committee, TranslationAdmin) admin.site.register(Official) admin.site.register(Occupation) admin.site.register(Role) -admin.site.register(Committee) diff --git a/webapp/migrations/0059_auto_20191010_1900.py b/webapp/migrations/0059_auto_20191010_1900.py new file mode 100644 index 0000000..8fc9972 --- /dev/null +++ b/webapp/migrations/0059_auto_20191010_1900.py @@ -0,0 +1,23 @@ +# Generated by Django 2.1.5 on 2019-10-10 16:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0058_auto_20191010_1837'), + ] + + operations = [ + migrations.AddField( + model_name='committee', + name='name_en', + field=models.CharField(max_length=255, null=True, verbose_name='Name'), + ), + migrations.AddField( + model_name='committee', + name='name_fi', + field=models.CharField(max_length=255, null=True, verbose_name='Name'), + ), + ] diff --git a/webapp/serializers.py b/webapp/serializers.py index 03f8f1f..b4db898 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -96,7 +96,7 @@ class FeedSerializer(serializers.ModelSerializer): class CommitteeSerializer(serializers.ModelSerializer): class Meta: model = Committee - fields = ['name'] + fields = ['name_fi', 'name_en'] class RoleSerializer(serializers.ModelSerializer): @@ -104,7 +104,7 @@ class RoleSerializer(serializers.ModelSerializer): class Meta: model = Role - fields = ('name', 'description', 'committee') + fields = ('name_fi', 'name_en', 'description_fi', 'description_en', 'committee') class ContactsSerializer(serializers.ModelSerializer): diff --git a/webapp/translation.py b/webapp/translation.py index 73713ca..24c4b62 100644 --- a/webapp/translation.py +++ b/webapp/translation.py @@ -1,8 +1,7 @@ """Translation classes.""" from modeltranslation.translator import register, TranslationOptions -from webapp.models import BaseFeed, Feed, Tag, Event, Signup, SignupForm, TemplateQuestion -from webapp.models import PresetRole, BaseRole +from webapp.models import * @register(BaseFeed) @@ -66,3 +65,10 @@ class PresetRoleTranslationOptions(TranslationOptions): """Class for PresetRole translation options.""" fields = ('description',) + + +@register(Committee) +class CommitteeTranslationOptions(TranslationOptions): + """Class for PresetRole translation options.""" + + fields = ('name',) From 59dcb382ceb23848cf483747a63b3ceb889d6b55 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 19:06:48 +0300 Subject: [PATCH 17/72] Add images to Officials --- webapp/migrations/0060_official_image.py | 18 ++++++++++++++++++ webapp/models.py | 1 + webapp/serializers.py | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 webapp/migrations/0060_official_image.py diff --git a/webapp/migrations/0060_official_image.py b/webapp/migrations/0060_official_image.py new file mode 100644 index 0000000..0df934f --- /dev/null +++ b/webapp/migrations/0060_official_image.py @@ -0,0 +1,18 @@ +# Generated by Django 2.1.5 on 2019-10-10 16:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0059_auto_20191010_1900'), + ] + + operations = [ + migrations.AddField( + model_name='official', + name='image', + field=models.ImageField(null=True, upload_to=''), + ), + ] diff --git a/webapp/models.py b/webapp/models.py index 4c8d331..7676bf3 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -220,6 +220,7 @@ class Official(models.Model): email = models.EmailField(_('Email address')) phone_number = PhoneNumberField(_('Phone number')) role_history = models.ManyToManyField('Occupation', 'officials', blank=True) + image = models.ImageField(null=True) @staticmethod def by_year(year): diff --git a/webapp/serializers.py b/webapp/serializers.py index b4db898..ae0b69e 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -110,7 +110,7 @@ class RoleSerializer(serializers.ModelSerializer): class ContactsSerializer(serializers.ModelSerializer): class Meta: model = Official - fields = ('first_name', 'last_name', 'email', 'phone_number') + fields = ('first_name', 'last_name', 'email', 'phone_number', 'image') depth = 2 From 971247e67c61f0f34037468002038e9e72311bc7 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 19:10:35 +0300 Subject: [PATCH 18/72] Show board status --- webapp/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/serializers.py b/webapp/serializers.py index ae0b69e..9ea9456 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -104,7 +104,7 @@ class RoleSerializer(serializers.ModelSerializer): class Meta: model = Role - fields = ('name_fi', 'name_en', 'description_fi', 'description_en', 'committee') + fields = ('name_fi', 'name_en', 'description_fi', 'description_en', 'committee', 'is_board') class ContactsSerializer(serializers.ModelSerializer): From 09e973fab1198fdeb4885974cd379cbf601149c2 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 20:48:27 +0300 Subject: [PATCH 19/72] Allow missing official image --- webapp/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/models.py b/webapp/models.py index 7676bf3..520af45 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -220,7 +220,7 @@ class Official(models.Model): email = models.EmailField(_('Email address')) phone_number = PhoneNumberField(_('Phone number')) role_history = models.ManyToManyField('Occupation', 'officials', blank=True) - image = models.ImageField(null=True) + image = models.ImageField(blank=True, null=True) @staticmethod def by_year(year): From c408a6532e5376541d605f9c3e8af1c77900e52f Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 20:48:39 +0300 Subject: [PATCH 20/72] Add committee API --- webapp/urls.py | 4 ++-- webapp/views.py | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/webapp/urls.py b/webapp/urls.py index 353b0ad..535a13d 100644 --- a/webapp/urls.py +++ b/webapp/urls.py @@ -6,8 +6,7 @@ from rest_framework_jwt.views import obtain_jwt_token, verify_jwt_token from webapp.views import about_view -from webapp.views import EventViewSet, SignupFormViewSet, SignupViewSet,\ - FeedViewSet, ContactsViewSet, SavedQuestionsViewSet, RootView, TagsViewSet +from webapp.views import * class APIRouter(routers.DefaultRouter): @@ -20,6 +19,7 @@ router.register(r'signupForm', SignupFormViewSet) router.register(r'signup', SignupViewSet) router.register(r'feed', FeedViewSet) router.register(r'contacts', ContactsViewSet) +router.register(r'committees', CommitteeViewSet) router.register(r'questions', SavedQuestionsViewSet) router.register(r'tags', TagsViewSet) diff --git a/webapp/views.py b/webapp/views.py index e024e4c..2faef8c 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -119,6 +119,12 @@ class ContactsViewSet(viewsets.ReadOnlyModelViewSet): return Occupation.by_year(int(year)) +class CommitteeViewSet(viewsets.ReadOnlyModelViewSet): + queryset = Committee.objects.all() + serializer_class = CommitteeSerializer + permission_classes = [IsAuthenticatedOrReadOnly] + + class TagsViewSet(viewsets.ReadOnlyModelViewSet): queryset = Tag.objects.all() serializer_class = TagSerializer From 96fc8a55693be11d060bb419d6d56256c1e88b04 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 3 Nov 2019 16:06:14 +0200 Subject: [PATCH 21/72] Update development docker setup --- .env.sample | 2 + Dockerfile | 25 +++++-- Dockerfile.prod | 20 ++--- docker-compose.yml | 11 ++- setup.sh | 3 +- sikweb/base.py | 37 ---------- wait-for-it.sh | 177 --------------------------------------------- 7 files changed, 39 insertions(+), 236 deletions(-) delete mode 100755 wait-for-it.sh diff --git a/.env.sample b/.env.sample index 5be805f..65ab9dd 100644 --- a/.env.sample +++ b/.env.sample @@ -1,8 +1,10 @@ HOST=localhost +DEBUG=True SECRET_KEY=7p$85^4ibb^p4-=vs44b7!y0e-zemugze18@a#30&71=a8)dp( TG_BOT_TOKEN= EMAIL_HOST= EMAIL_PASSWD= DB_USER=postgres DB_PASSWD=postgres +DB_HOST=db DB_PORT=5432 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 3123a63..1473924 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,19 @@ -FROM python:3.7 +FROM python:3.7-alpine ENV PYTHONUNBUFFERED 1 -ENV IS_DOCKER 1 -RUN mkdir /code -WORKDIR /code -ADD requirements.txt /code/ -RUN env -ADD . /code/ +ENV IS_DOCKER 0 +WORKDIR /app +COPY requirements.txt ./ +COPY requirements.production.txt ./ +COPY . ./ + +# uWSGI, gunicorn etc. +RUN apk add --no-cache python3-dev build-base linux-headers pcre-dev openssl bash \ + # PSQL + && apk add --no-cache postgresql-dev \ + # Pillow + && apk add --no-cache jpeg-dev zlib-dev \ + && pip install --upgrade pip \ + && pip install -r requirements.txt \ + && pip install -r requirements.production.txt + +RUN python manage.py collectstatic --noinput diff --git a/Dockerfile.prod b/Dockerfile.prod index d8299d5..299a4ce 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -7,19 +7,15 @@ COPY requirements.production.txt ./ COPY . ./ # uWSGI, gunicorn etc. -RUN apk add --no-cache --virtual .build-deps python3-dev build-base linux-headers pcre-dev openssl \ - # PSQL - && apk add --no-cache postgresql-dev \ - # Pillow - && apk add --no-cache jpeg-dev zlib-dev \ - && pip install --upgrade pip \ - && pip install -r requirements.txt \ - && pip install -r requirements.production.txt \ - && apk del .build-deps +RUN apk add --no-cache python3-dev build-base linux-headers pcre-dev openssl \ + # PSQL + && apk add --no-cache postgresql-dev \ + # Pillow + && apk add --no-cache jpeg-dev zlib-dev \ + && pip install --upgrade pip \ + && pip install -r requirements.txt \ + && pip install -r requirements.production.txt RUN python manage.py collectstatic --noinput -# run migrate -# python manage.py migrate --noinput - ENTRYPOINT ["sh", "-c", "./production_entrypoint.sh"] diff --git a/docker-compose.yml b/docker-compose.yml index 6a7b964..198c3eb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,12 +2,19 @@ version: '3' services: db: - image: postgres + image: postgres:12 + volumes: + - dbdata:/var/lib/postgresql/data web: build: . image: registry.gitlab.com/sahkoinsinoorikilta/vtmk/web2.0-backend:dev - command: ["bash", "-c", "cd /code && ./wait-for-it.sh db:5432 -- bash setup.sh --no-input --no-npm && python manage.py runserver 0.0.0.0:8000"] + command: ["bash", "-c", "cd /app & bash setup.sh --no-input --no-npm && gunicorn -w 4 -b 0.0.0.0:8000 sikweb.wsgi"] + env_file: + - .env.sample ports: - "8000:8000" depends_on: - db + +volumes: + dbdata: diff --git a/setup.sh b/setup.sh index 53c1a71..d2f82b6 100755 --- a/setup.sh +++ b/setup.sh @@ -3,7 +3,7 @@ echo "SIK WEB 2.0" echo "This script will set up the environment for this project." echo "=========================================================" -echo "Dependencies: python>3.5" +echo "Dependencies: python3.7" INTERACTIVE="true" USE_NPM="true" @@ -65,6 +65,7 @@ fi set -e set -x pip install -r requirements.txt +pip install -r requirements.production.txt $USE_NPM && npm install python manage.py migrate python manage.py createdefaultadmin diff --git a/sikweb/base.py b/sikweb/base.py index 7c026d7..5caee47 100644 --- a/sikweb/base.py +++ b/sikweb/base.py @@ -7,19 +7,12 @@ from django.utils.translation import ugettext_lazy as _ # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -IS_DOCKER = bool(os.getenv('IS_DOCKER', None)) - # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' -if not IS_DOCKER: - ALLOWED_HOSTS = [] -else: - ALLOWED_HOSTS = ["*"] - # Logger level LOGGERLEVEL = logging.DEBUG @@ -166,36 +159,6 @@ TEMPLATES = [ WSGI_APPLICATION = 'sikweb.wsgi.application' - -# Database -# https://docs.djangoproject.com/en/1.9/ref/settings/#databases - -if not IS_DOCKER: - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'sik', - 'USER': 'sik', - 'PASSWORD': 'password123', - 'HOST': 'localhost', - 'PORT': '5432', - 'TEST': { - 'NAME': 'sik_test', - }, - }, - } -else: - logging.info('Using docker database configuration') - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'postgres', - 'USER': 'postgres', - 'PASSWORD': 'postgres', - 'HOST': 'db', - 'PORT': '5432', - }, - } # Password validation # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators diff --git a/wait-for-it.sh b/wait-for-it.sh deleted file mode 100755 index bbe4043..0000000 --- a/wait-for-it.sh +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/env bash -# Use this script to test if a given TCP host/port are available - -cmdname=$(basename $0) - -echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } - -usage() -{ - cat << USAGE >&2 -Usage: - $cmdname host:port [-s] [-t timeout] [-- command args] - -h HOST | --host=HOST Host or IP under test - -p PORT | --port=PORT TCP port under test - Alternatively, you specify the host and port as host:port - -s | --strict Only execute subcommand if the test succeeds - -q | --quiet Don't output any status messages - -t TIMEOUT | --timeout=TIMEOUT - Timeout in seconds, zero for no timeout - -- COMMAND ARGS Execute command with args after the test finishes -USAGE - exit 1 -} - -wait_for() -{ - if [[ $TIMEOUT -gt 0 ]]; then - echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT" - else - echoerr "$cmdname: waiting for $HOST:$PORT without a timeout" - fi - start_ts=$(date +%s) - while : - do - if [[ $ISBUSY -eq 1 ]]; then - nc -z $HOST $PORT - result=$? - else - (echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1 - result=$? - fi - if [[ $result -eq 0 ]]; then - end_ts=$(date +%s) - echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds" - break - fi - sleep 1 - done - return $result -} - -wait_for_wrapper() -{ - # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 - if [[ $QUIET -eq 1 ]]; then - timeout $BUSYTIMEFLAG $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & - else - timeout $BUSYTIMEFLAG $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & - fi - PID=$! - trap "kill -INT -$PID" INT - wait $PID - RESULT=$? - if [[ $RESULT -ne 0 ]]; then - echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT" - fi - return $RESULT -} - -# process arguments -while [[ $# -gt 0 ]] -do - case "$1" in - *:* ) - hostport=(${1//:/ }) - HOST=${hostport[0]} - PORT=${hostport[1]} - shift 1 - ;; - --child) - CHILD=1 - shift 1 - ;; - -q | --quiet) - QUIET=1 - shift 1 - ;; - -s | --strict) - STRICT=1 - shift 1 - ;; - -h) - HOST="$2" - if [[ $HOST == "" ]]; then break; fi - shift 2 - ;; - --host=*) - HOST="${1#*=}" - shift 1 - ;; - -p) - PORT="$2" - if [[ $PORT == "" ]]; then break; fi - shift 2 - ;; - --port=*) - PORT="${1#*=}" - shift 1 - ;; - -t) - TIMEOUT="$2" - if [[ $TIMEOUT == "" ]]; then break; fi - shift 2 - ;; - --timeout=*) - TIMEOUT="${1#*=}" - shift 1 - ;; - --) - shift - CLI=("$@") - break - ;; - --help) - usage - ;; - *) - echoerr "Unknown argument: $1" - usage - ;; - esac -done - -if [[ "$HOST" == "" || "$PORT" == "" ]]; then - echoerr "Error: you need to provide a host and port to test." - usage -fi - -TIMEOUT=${TIMEOUT:-15} -STRICT=${STRICT:-0} -CHILD=${CHILD:-0} -QUIET=${QUIET:-0} - -# check to see if timeout is from busybox? -# check to see if timeout is from busybox? -TIMEOUT_PATH=$(realpath $(which timeout)) -if [[ $TIMEOUT_PATH =~ "busybox" ]]; then - ISBUSY=1 - BUSYTIMEFLAG="-t" -else - ISBUSY=0 - BUSYTIMEFLAG="" -fi - -if [[ $CHILD -gt 0 ]]; then - wait_for - RESULT=$? - exit $RESULT -else - if [[ $TIMEOUT -gt 0 ]]; then - wait_for_wrapper - RESULT=$? - else - wait_for - RESULT=$? - fi -fi - -if [[ $CLI != "" ]]; then - if [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; then - echoerr "$cmdname: strict mode, refusing to execute subprocess" - exit $RESULT - fi - exec "${CLI[@]}" -else - exit $RESULT -fi From fdea5858ba7284fc59eb64c216944c773655125e Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 3 Nov 2019 16:13:17 +0200 Subject: [PATCH 22/72] Remove obsolete copy from setup.sh --- setup.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/setup.sh b/setup.sh index d2f82b6..ec3fc01 100755 --- a/setup.sh +++ b/setup.sh @@ -36,14 +36,6 @@ then exit 0 fi -$INTERACTIVE && read -p "Copy settings from template? (recommended) [y/n]" -n 1 -r || REPLY="y" -echo "" - -if [[ $REPLY =~ ^[Yy]$ ]] -then - cp "$PWD/sikweb/settings-sample.py" "$PWD/sikweb/settings.py" -fi - $INTERACTIVE && read -p "Copy pre-push hook to .git/hooks? (recommended) [y/n]" -n 1 -r || REPLY="y" echo "" From b23e439eb5a9d6cf21f4cfcc7748a5f9514ab5d6 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 3 Nov 2019 16:54:57 +0200 Subject: [PATCH 23/72] Remove IS_DOCKER ENV --- Dockerfile | 1 - Dockerfile.prod | 1 - 2 files changed, 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1473924..931b522 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,5 @@ FROM python:3.7-alpine ENV PYTHONUNBUFFERED 1 -ENV IS_DOCKER 0 WORKDIR /app COPY requirements.txt ./ COPY requirements.production.txt ./ diff --git a/Dockerfile.prod b/Dockerfile.prod index 299a4ce..9452861 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -1,6 +1,5 @@ FROM python:3.7-alpine ENV PYTHONUNBUFFERED 1 -ENV IS_DOCKER 0 WORKDIR /app COPY requirements.txt ./ COPY requirements.production.txt ./ From dab6f98ec2e8147f52b891a7dc6733acf79f1e95 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 3 Nov 2019 17:01:38 +0200 Subject: [PATCH 24/72] Combine PROD and DEV images --- .gitlab-ci.yml | 16 +--------------- Dockerfile | 2 ++ Dockerfile.prod | 20 -------------------- docker-compose.yml | 2 +- 4 files changed, 4 insertions(+), 36 deletions(-) delete mode 100644 Dockerfile.prod diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c51bb41..ac47fdd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -45,20 +45,6 @@ remark: script: - npm run remark -# TODO: remove -publish_dev: - stage: publish - image: docker:stable - services: - - docker:stable-dind - only: - - develop - script: - - docker info - - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY - - docker build . -t "$IMAGE_NAME_DEV" - - docker push "$IMAGE_NAME_DEV" - publish: stage: publish image: docker:stable @@ -69,7 +55,7 @@ publish: script: - docker info - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY - - docker build . -f Dockerfile.prod -t "$IMAGE_NAME" + - docker build . -t "$IMAGE_NAME" - docker push "$IMAGE_NAME" deploy_dev: diff --git a/Dockerfile b/Dockerfile index 931b522..a82b6ad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,3 +16,5 @@ RUN apk add --no-cache python3-dev build-base linux-headers pcre-dev openssl bas && pip install -r requirements.production.txt RUN python manage.py collectstatic --noinput + +CMD ["sh", "-c", "./production_entrypoint.sh"] diff --git a/Dockerfile.prod b/Dockerfile.prod deleted file mode 100644 index 9452861..0000000 --- a/Dockerfile.prod +++ /dev/null @@ -1,20 +0,0 @@ -FROM python:3.7-alpine -ENV PYTHONUNBUFFERED 1 -WORKDIR /app -COPY requirements.txt ./ -COPY requirements.production.txt ./ -COPY . ./ - -# uWSGI, gunicorn etc. -RUN apk add --no-cache python3-dev build-base linux-headers pcre-dev openssl \ - # PSQL - && apk add --no-cache postgresql-dev \ - # Pillow - && apk add --no-cache jpeg-dev zlib-dev \ - && pip install --upgrade pip \ - && pip install -r requirements.txt \ - && pip install -r requirements.production.txt - -RUN python manage.py collectstatic --noinput - -ENTRYPOINT ["sh", "-c", "./production_entrypoint.sh"] diff --git a/docker-compose.yml b/docker-compose.yml index 198c3eb..33acf89 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,7 +7,7 @@ services: - dbdata:/var/lib/postgresql/data web: build: . - image: registry.gitlab.com/sahkoinsinoorikilta/vtmk/web2.0-backend:dev + image: registry.gitlab.com/sahkoinsinoorikilta/vtmk/web2.0-backend command: ["bash", "-c", "cd /app & bash setup.sh --no-input --no-npm && gunicorn -w 4 -b 0.0.0.0:8000 sikweb.wsgi"] env_file: - .env.sample From 2f4009d002674e89815b003912d89d55f45626bf Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 3 Nov 2019 17:06:24 +0200 Subject: [PATCH 25/72] Update dev env --- .env.dev | 10 ++++++++++ docker-compose.yml | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .env.dev diff --git a/.env.dev b/.env.dev new file mode 100644 index 0000000..a7b70f0 --- /dev/null +++ b/.env.dev @@ -0,0 +1,10 @@ +HOST=web.sik.party +DEBUG=True +SECRET_KEY=7p$85^4ibb^p4-=vs44b7!y0e-zemugze18@a#30&71=a8)dp( +TG_BOT_TOKEN= +EMAIL_HOST= +EMAIL_PASSWD= +DB_USER=postgres +DB_PASSWD=postgres +DB_HOST=db +DB_PORT=5432 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 33acf89..828dc1e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ services: image: registry.gitlab.com/sahkoinsinoorikilta/vtmk/web2.0-backend command: ["bash", "-c", "cd /app & bash setup.sh --no-input --no-npm && gunicorn -w 4 -b 0.0.0.0:8000 sikweb.wsgi"] env_file: - - .env.sample + - .env.dev ports: - "8000:8000" depends_on: From baa329ad5d840b820392a74d75f2555569231b6d Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 3 Nov 2019 17:13:08 +0200 Subject: [PATCH 26/72] Run publish on dev branch --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ac47fdd..ec29b6e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -51,6 +51,7 @@ publish: services: - docker:stable-dind only: + - develop - master script: - docker info From e9706d0e4fe73c6c566ba49e1721c96269aa07ac Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 3 Nov 2019 17:20:12 +0200 Subject: [PATCH 27/72] Copy env file to dev deployment --- .gitlab-ci.yml | 21 +-------------------- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ec29b6e..ff18c9b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -77,30 +77,11 @@ deploy_dev: - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' script: - scp docker-compose.yml $DEV_SSH_USER@$DEV_SSH_HOST:~/deployment/docker-compose.yml + - scp .env.dev $DEV_SSH_USER@$DEV_SSH_HOST:~/deployment/.env - scp .deploy_dev.sh $DEV_SSH_USER@$DEV_SSH_HOST:~/deployment/deploy_dev.sh - ssh $DEV_SSH_USER@$DEV_SSH_HOST "docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY" - ssh $DEV_SSH_USER@$DEV_SSH_HOST "bash ~/deployment/deploy_dev.sh \"$IMAGE_NAME_DEV\"" -# deploy_production: -# stage: deploy -# image: alpine:latest -# environment: -# name: production -# url: https://sika.sahkoinsinoorikilta.fi -# when: manual -# only: -# - master -# before_script: -# - pwd -# - apk add --update openssh -# - ssh -V -# - mkdir -p ~/.ssh -# - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa -# - chmod 600 ~/.ssh/id_rsa -# - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config -# script: -# - ssh $PROD_SSH_USER@$PROD_SSH_HOST "zsh ~/deploy.sh" - deploy_production: stage: deploy image: docker:stable diff --git a/docker-compose.yml b/docker-compose.yml index 828dc1e..3a662a1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ services: image: registry.gitlab.com/sahkoinsinoorikilta/vtmk/web2.0-backend command: ["bash", "-c", "cd /app & bash setup.sh --no-input --no-npm && gunicorn -w 4 -b 0.0.0.0:8000 sikweb.wsgi"] env_file: - - .env.dev + - .env ports: - "8000:8000" depends_on: From 2f0024630d8f81ff862eea611fa859f4bc4d3b33 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 3 Nov 2019 17:33:35 +0200 Subject: [PATCH 28/72] Use IMAGE_NAME instead of removed dev image --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ff18c9b..34021fb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -80,7 +80,7 @@ deploy_dev: - scp .env.dev $DEV_SSH_USER@$DEV_SSH_HOST:~/deployment/.env - scp .deploy_dev.sh $DEV_SSH_USER@$DEV_SSH_HOST:~/deployment/deploy_dev.sh - ssh $DEV_SSH_USER@$DEV_SSH_HOST "docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY" - - ssh $DEV_SSH_USER@$DEV_SSH_HOST "bash ~/deployment/deploy_dev.sh \"$IMAGE_NAME_DEV\"" + - ssh $DEV_SSH_USER@$DEV_SSH_HOST "bash ~/deployment/deploy_dev.sh \"$IMAGE_NAME\"" deploy_production: stage: deploy From a7ada33ff930d3409ecabfe97b954e18d11fae36 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 9 Nov 2019 13:41:46 +0200 Subject: [PATCH 29/72] Open port 5432 on docker-compose --- .gitlab-ci.yml | 2 +- docker-compose.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 34021fb..9230d03 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,7 +8,7 @@ test: image: python:3.7 stage: test services: - - postgres:latest + - postgres:12 variables: POSTGRES_DB: ci POSTGRES_USER: postgres diff --git a/docker-compose.yml b/docker-compose.yml index 3a662a1..b422087 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,8 @@ services: image: postgres:12 volumes: - dbdata:/var/lib/postgresql/data + ports: + - "5432:5432" web: build: . image: registry.gitlab.com/sahkoinsinoorikilta/vtmk/web2.0-backend From 8dc576983c11e0c71f944d5830edcfcfae519c11 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 9 Nov 2019 13:54:43 +0200 Subject: [PATCH 30/72] Split tests.py into multiple files --- webapp/tests/test_contact.py | 16 ++++++ webapp/tests/test_event.py | 16 ++++++ webapp/tests/test_feed.py | 68 ++++++++++++++++++++++++++ webapp/tests/test_signup.py | 16 ++++++ webapp/{tests.py => tests/test_tag.py} | 58 ---------------------- 5 files changed, 116 insertions(+), 58 deletions(-) create mode 100644 webapp/tests/test_contact.py create mode 100644 webapp/tests/test_event.py create mode 100644 webapp/tests/test_feed.py create mode 100644 webapp/tests/test_signup.py rename webapp/{tests.py => tests/test_tag.py} (56%) diff --git a/webapp/tests/test_contact.py b/webapp/tests/test_contact.py new file mode 100644 index 0000000..ad8ed59 --- /dev/null +++ b/webapp/tests/test_contact.py @@ -0,0 +1,16 @@ +from django.test import TestCase +from django.core.files import File +from django.contrib.auth.models import User +from rest_framework.test import APITestCase +from rest_framework import status +from rest_framework.test import force_authenticate +from webapp.models import Tag, Feed +from webapp.serializers import TagSerializer, FeedSerializer + +from collections import OrderedDict +from itertools import islice +import tempfile + + +class TagsTestCase(APITestCase): + pass diff --git a/webapp/tests/test_event.py b/webapp/tests/test_event.py new file mode 100644 index 0000000..ad8ed59 --- /dev/null +++ b/webapp/tests/test_event.py @@ -0,0 +1,16 @@ +from django.test import TestCase +from django.core.files import File +from django.contrib.auth.models import User +from rest_framework.test import APITestCase +from rest_framework import status +from rest_framework.test import force_authenticate +from webapp.models import Tag, Feed +from webapp.serializers import TagSerializer, FeedSerializer + +from collections import OrderedDict +from itertools import islice +import tempfile + + +class TagsTestCase(APITestCase): + pass diff --git a/webapp/tests/test_feed.py b/webapp/tests/test_feed.py new file mode 100644 index 0000000..ca55fe4 --- /dev/null +++ b/webapp/tests/test_feed.py @@ -0,0 +1,68 @@ +from django.test import TestCase +from django.core.files import File +from django.contrib.auth.models import User +from rest_framework.test import APITestCase +from rest_framework import status +from rest_framework.test import force_authenticate +from webapp.models import Tag, Feed +from webapp.serializers import TagSerializer, FeedSerializer + +from collections import OrderedDict +from itertools import islice +import tempfile + + +class FeedTestCase(APITestCase): + + def setUp(self): + self.icon = tempfile.NamedTemporaryFile(suffix=".jpg").name + Tag.objects.create(slug='testtag1', name='test1', icon=self.icon) + tag1 = Tag.objects.get(slug="testtag1") + Tag.objects.create(slug="testtag2", name='test2', icon=self.icon) + tag2 = Tag.objects.get(slug="testtag2") + self.assertEqual(Tag.objects.count(), 2) + + Feed.objects.create(title="TestFeed", visible=True, description="diidadaapa", content="lorem ipsum") + Feed.objects.get(title="TestFeed").tags.add(tag1) + Feed.objects.get(title="TestFeed").tags.add(tag2) + self.assertEqual(Feed.objects.count(), 1) + self.assertEqual(Feed.objects.all()[0].tags.count(), 2) + + username, password = 'test_admin', 'password123' + self.authClient = User.objects.create_superuser(username, 'myemail@test.com', password) + + def test_get_feed(self): + response = self.client.get('/api/feed/', format='json') + self.assertTrue(status.is_success(response.status_code)) + + feeds = Feed.objects.all() + serializer = FeedSerializer(feeds, many=True) + + # DRF extends path given by serializer with the protocol and domain for icon + # Ignore tag on serializer and response. This is tested on TagTestCase. + # Note that we assume the length here to be 1 + response.data['results'][0].pop('tags') + serializer.data[0].pop('tags') + self.assertEqual(response.data['results'], serializer.data) + + def test_post_feed(self): + Tag.objects.create(slug="test1", name="testsds") + Tag.objects.create(slug="test2", name="testsdsd") + tag1_id = Tag.objects.get(slug="test1").id + tag2_id = Tag.objects.get(slug="test2").id + + data = {'tags': [tag1_id, tag2_id], 'title': 'testtitle', 'visible': 'True', 'description': 'liirumlaarum', 'content': 'lorem ipsum'} + # Try post without authentication + response = self.client.post('/api/feed/', data, format='multipart') + self.assertTrue(status.is_client_error(response.status_code)) + self.assertEqual(Feed.objects.count(), 1) + # Authenticate + self.client.force_authenticate(user=self.authClient) + response = self.client.post('/api/feed/', data, format='multipart') + # Return success and check object was created + self.assertTrue(status.is_success(response.status_code)) + self.assertEqual(Feed.objects.count(), 2) + + created = Feed.objects.get(title="testtitle") + print(created.tags) + # self.assertEqual(created.tags.count(), 2) diff --git a/webapp/tests/test_signup.py b/webapp/tests/test_signup.py new file mode 100644 index 0000000..ad8ed59 --- /dev/null +++ b/webapp/tests/test_signup.py @@ -0,0 +1,16 @@ +from django.test import TestCase +from django.core.files import File +from django.contrib.auth.models import User +from rest_framework.test import APITestCase +from rest_framework import status +from rest_framework.test import force_authenticate +from webapp.models import Tag, Feed +from webapp.serializers import TagSerializer, FeedSerializer + +from collections import OrderedDict +from itertools import islice +import tempfile + + +class TagsTestCase(APITestCase): + pass diff --git a/webapp/tests.py b/webapp/tests/test_tag.py similarity index 56% rename from webapp/tests.py rename to webapp/tests/test_tag.py index 067ea45..755c02c 100644 --- a/webapp/tests.py +++ b/webapp/tests/test_tag.py @@ -1,5 +1,3 @@ -"""Tests for webapp.""" - from django.test import TestCase from django.core.files import File from django.contrib.auth.models import User @@ -73,59 +71,3 @@ class TagsTestCase(APITestCase): self.assertEqual(Tag.objects.count(), 1) response = self.client.get('/api/tags/15', format='json', follow=True) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - - -class FeedTestCase(APITestCase): - - def setUp(self): - self.icon = tempfile.NamedTemporaryFile(suffix=".jpg").name - Tag.objects.create(slug='testtag1', name='test1', icon=self.icon) - tag1 = Tag.objects.get(slug="testtag1") - Tag.objects.create(slug="testtag2", name='test2', icon=self.icon) - tag2 = Tag.objects.get(slug="testtag2") - self.assertEqual(Tag.objects.count(), 2) - - Feed.objects.create(title="TestFeed", visible=True, description="diidadaapa", content="lorem ipsum") - Feed.objects.get(title="TestFeed").tags.add(tag1) - Feed.objects.get(title="TestFeed").tags.add(tag2) - self.assertEqual(Feed.objects.count(), 1) - self.assertEqual(Feed.objects.all()[0].tags.count(), 2) - - username, password = 'test_admin', 'password123' - self.authClient = User.objects.create_superuser(username, 'myemail@test.com', password) - - def test_get_feed(self): - response = self.client.get('/api/feed/', format='json') - self.assertTrue(status.is_success(response.status_code)) - - feeds = Feed.objects.all() - serializer = FeedSerializer(feeds, many=True) - - # DRF extends path given by serializer with the protocol and domain for icon - # Ignore tag on serializer and response. This is tested on TagTestCase. - # Note that we assume the length here to be 1 - response.data['results'][0].pop('tags') - serializer.data[0].pop('tags') - self.assertEqual(response.data['results'], serializer.data) - - def test_post_feed(self): - Tag.objects.create(slug="test1", name="testsds") - Tag.objects.create(slug="test2", name="testsdsd") - tag1_id = Tag.objects.get(slug="test1").id - tag2_id = Tag.objects.get(slug="test2").id - - data = {'tags': [tag1_id, tag2_id], 'title': 'testtitle', 'visible': 'True', 'description': 'liirumlaarum', 'content': 'lorem ipsum'} - # Try post without authentication - response = self.client.post('/api/feed/', data, format='multipart') - self.assertTrue(status.is_client_error(response.status_code)) - self.assertEqual(Feed.objects.count(), 1) - # Authenticate - self.client.force_authenticate(user=self.authClient) - response = self.client.post('/api/feed/', data, format='multipart') - # Return success and check object was created - self.assertTrue(status.is_success(response.status_code)) - self.assertEqual(Feed.objects.count(), 2) - - created = Feed.objects.get(title="testtitle") - print(created.tags) - # self.assertEqual(created.tags.count(), 2) From 3ea513785a9fb5268ade487329f1f3a6d8b757a8 Mon Sep 17 00:00:00 2001 From: "Oksanen, Ilkka (Nokia - FI/Espoo)" Date: Sat, 9 Nov 2019 16:55:12 +0200 Subject: [PATCH 31/72] Add api with which nginx can authenticate users --- webapp/urls.py | 3 ++- webapp/views.py | 41 +++++++++++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/webapp/urls.py b/webapp/urls.py index 535a13d..b29953a 100644 --- a/webapp/urls.py +++ b/webapp/urls.py @@ -3,7 +3,7 @@ from django.conf.urls import url, include from rest_framework import routers from rest_framework_jwt.views import obtain_jwt_token, verify_jwt_token -from webapp.views import about_view +from webapp.views import about_view, nginx_jwt_resp from webapp.views import * @@ -29,4 +29,5 @@ urlpatterns = [ url(r'^api/api-token-verify/', verify_jwt_token), # git revision url(r'^about', about_view), + url(r'^jwt_nginx', nginx_jwt_resp), ] diff --git a/webapp/views.py b/webapp/views.py index 2faef8c..b6a8d89 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -1,29 +1,31 @@ """Webapp views.""" +import jwt +# import logging +# import requests +from dealer.git import git +from django.conf import settings +from django.contrib.auth import authenticate, login, logout +from django.http import HttpResponse # from django.db.models import Count -from django.shortcuts import render, redirect -from django.contrib.auth import login, logout, authenticate +from django.shortcuts import redirect, render from django.views.decorators.http import require_http_methods +from django_filters import rest_framework as filters # from django.views.decorators.csrf import ensure_csrf_cookie # from django.http import HttpResponse, HttpResponseRedirect # from django.contrib.auth.decorators import permission_required, login_required # from django.conf import settings # from django.utils import timezone -from rest_framework import viewsets, routers +from rest_framework import permissions, routers, viewsets +from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.permissions import IsAuthenticatedOrReadOnly from rest_framework.response import Response from rest_framework.reverse import reverse -from django_filters import rest_framework as filters -from rest_framework.filters import SearchFilter, OrderingFilter -from rest_framework import permissions -# import logging -# import requests -from dealer.git import git -from webapp.models import Event, SignupForm, Signup, TemplateQuestion, Feed,\ - Committee, Official, Tag -from webapp.serializers import * from members.views.utils import * +from webapp.models import (Committee, Event, Feed, Official, Signup, + SignupForm, Tag, TemplateQuestion) +from webapp.serializers import * class IsPostOrIsAuthenticated(permissions.BasePermission): @@ -207,3 +209,18 @@ def contact_view(request, *args, **kwargs): } return render(request, "contact.html", context) + + +@require_http_methods(["GET"]) +def nginx_jwt_resp(request, *args, **kwargs): + cookie = request.COOKIES.get("jwt", None) + if not cookie: + return HttpResponse("", status=401) + try: + token = jwt.decode(cookie, settings.SECRET_KEY) + except jwt.exceptions.InvalidSignatureError: + return HttpResponse("", status=403) + user = 'admin' if token.get('username', '') == 'admin' else 'moderator' + resp = HttpResponse("", status=200) + resp['X-FBrowser-User'] = user + return resp From 029089b32d60f1e6454bc9561e7d852e5d04979a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4ki?= Date: Sat, 9 Nov 2019 20:27:55 +0200 Subject: [PATCH 32/72] Added language selection to the membership application form --- members/templates/application_form_base.html | 1 + package-lock.json | 1298 +++++++++--------- package.json | 2 +- 3 files changed, 651 insertions(+), 650 deletions(-) diff --git a/members/templates/application_form_base.html b/members/templates/application_form_base.html index d8d6f76..51af6d6 100644 --- a/members/templates/application_form_base.html +++ b/members/templates/application_form_base.html @@ -35,5 +35,6 @@ {% block content %} {% endblock content %} + {% include "webapp:footer.html" %} diff --git a/package-lock.json b/package-lock.json index 7ac6d9f..c87cde5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "resolved": "http://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "requires": { - "acorn": "3.3.0" + "acorn": "^3.0.4" }, "dependencies": { "acorn": { @@ -29,8 +29,8 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" } }, "ajv-keywords": { @@ -58,8 +58,8 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "requires": { - "micromatch": "2.3.11", - "normalize-path": "2.1.1" + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" } }, "argparse": { @@ -67,7 +67,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "requires": { - "sprintf-js": "1.0.3" + "sprintf-js": "~1.0.2" } }, "arr-diff": { @@ -75,7 +75,7 @@ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "requires": { - "arr-flatten": "1.1.0" + "arr-flatten": "^1.0.1" } }, "arr-flatten": { @@ -93,7 +93,7 @@ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "requires": { - "array-uniq": "1.0.3" + "array-uniq": "^1.0.1" } }, "array-uniq": { @@ -131,9 +131,9 @@ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" } }, "bail": { @@ -151,13 +151,13 @@ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "requires": { - "cache-base": "1.0.1", - "class-utils": "0.3.6", - "component-emitter": "1.2.1", - "define-property": "1.0.0", - "isobject": "3.0.1", - "mixin-deep": "1.3.1", - "pascalcase": "0.1.1" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { "define-property": { @@ -165,7 +165,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -173,7 +173,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -181,7 +181,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -189,9 +189,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -216,7 +216,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -225,9 +225,9 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.3" + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" } }, "buffer-from": { @@ -240,15 +240,15 @@ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "requires": { - "collection-visit": "1.0.0", - "component-emitter": "1.2.1", - "get-value": "2.0.6", - "has-value": "1.0.0", - "isobject": "3.0.1", - "set-value": "2.0.0", - "to-object-path": "0.3.0", - "union-value": "1.0.0", - "unset-value": "1.0.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" }, "dependencies": { "isobject": { @@ -263,7 +263,7 @@ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "requires": { - "callsites": "0.2.0" + "callsites": "^0.2.0" } }, "callsites": { @@ -286,11 +286,11 @@ "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "character-entities": { @@ -318,15 +318,15 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "requires": { - "anymatch": "1.3.2", - "async-each": "1.0.1", - "fsevents": "1.2.4", - "glob-parent": "2.0.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "2.0.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.2.1" + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" } }, "circular-json": { @@ -339,10 +339,10 @@ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "requires": { - "arr-union": "3.1.0", - "define-property": "0.2.5", - "isobject": "3.0.1", - "static-extend": "0.1.2" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "dependencies": { "define-property": { @@ -350,7 +350,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "isobject": { @@ -365,7 +365,7 @@ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", "requires": { - "restore-cursor": "1.0.1" + "restore-cursor": "^1.0.1" } }, "cli-width": { @@ -393,8 +393,8 @@ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "requires": { - "map-visit": "1.0.0", - "object-visit": "1.0.1" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, "color-convert": { @@ -425,10 +425,10 @@ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "requires": { - "buffer-from": "1.1.1", - "inherits": "2.0.3", - "readable-stream": "2.3.6", - "typedarray": "0.0.6" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, "copy-descriptor": { @@ -446,7 +446,7 @@ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "requires": { - "es5-ext": "0.10.46" + "es5-ext": "^0.10.9" } }, "debug": { @@ -477,8 +477,8 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "requires": { - "is-descriptor": "1.0.2", - "isobject": "3.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -486,7 +486,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -494,7 +494,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -502,9 +502,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -524,13 +524,13 @@ "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.1", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.2" + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" } }, "doctrine": { @@ -538,7 +538,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "requires": { - "esutils": "2.0.2" + "esutils": "^2.0.2" } }, "error-ex": { @@ -546,7 +546,7 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "requires": { - "is-arrayish": "0.2.1" + "is-arrayish": "^0.2.1" } }, "es5-ext": { @@ -554,9 +554,9 @@ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.46.tgz", "integrity": "sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw==", "requires": { - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1", - "next-tick": "1.0.0" + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "1" } }, "es6-iterator": { @@ -564,9 +564,9 @@ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.46", - "es6-symbol": "3.1.1" + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" } }, "es6-map": { @@ -574,12 +574,12 @@ "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.46", - "es6-iterator": "2.0.3", - "es6-set": "0.1.5", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" } }, "es6-set": { @@ -587,11 +587,11 @@ "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.46", - "es6-iterator": "2.0.3", + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" + "event-emitter": "~0.3.5" } }, "es6-symbol": { @@ -599,8 +599,8 @@ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.46" + "d": "1", + "es5-ext": "~0.10.14" } }, "es6-weak-map": { @@ -608,10 +608,10 @@ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.46", - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1" + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" } }, "escape-string-regexp": { @@ -624,10 +624,10 @@ "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", "requires": { - "es6-map": "0.1.5", - "es6-weak-map": "2.0.2", - "esrecurse": "4.2.1", - "estraverse": "4.2.0" + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, "eslint": { @@ -635,41 +635,41 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", "requires": { - "babel-code-frame": "6.26.0", - "chalk": "1.1.3", - "concat-stream": "1.6.2", - "debug": "2.6.9", - "doctrine": "2.1.0", - "escope": "3.6.0", - "espree": "3.5.4", - "esquery": "1.0.1", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "glob": "7.1.3", - "globals": "9.18.0", - "ignore": "3.3.10", - "imurmurhash": "0.1.4", - "inquirer": "0.12.0", - "is-my-json-valid": "2.19.0", - "is-resolvable": "1.1.0", - "js-yaml": "3.12.0", - "json-stable-stringify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.11", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "1.2.1", - "progress": "1.1.8", - "require-uncached": "1.0.3", - "shelljs": "0.7.8", - "strip-bom": "3.0.0", - "strip-json-comments": "2.0.1", - "table": "3.8.3", - "text-table": "0.2.0", - "user-home": "2.0.0" + "babel-code-frame": "^6.16.0", + "chalk": "^1.1.3", + "concat-stream": "^1.5.2", + "debug": "^2.1.1", + "doctrine": "^2.0.0", + "escope": "^3.6.0", + "espree": "^3.4.0", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "glob": "^7.0.3", + "globals": "^9.14.0", + "ignore": "^3.2.0", + "imurmurhash": "^0.1.4", + "inquirer": "^0.12.0", + "is-my-json-valid": "^2.10.0", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.5.1", + "json-stable-stringify": "^1.0.0", + "levn": "^0.3.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.0", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.1", + "pluralize": "^1.2.1", + "progress": "^1.1.8", + "require-uncached": "^1.0.2", + "shelljs": "^0.7.5", + "strip-bom": "^3.0.0", + "strip-json-comments": "~2.0.1", + "table": "^3.7.8", + "text-table": "~0.2.0", + "user-home": "^2.0.0" } }, "espree": { @@ -677,8 +677,8 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "requires": { - "acorn": "5.7.3", - "acorn-jsx": "3.0.1" + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" } }, "esprima": { @@ -691,7 +691,7 @@ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.0.0" } }, "esrecurse": { @@ -699,7 +699,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.1.0" } }, "estraverse": { @@ -717,8 +717,8 @@ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.46" + "d": "1", + "es5-ext": "~0.10.14" } }, "exit-hook": { @@ -731,7 +731,7 @@ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "requires": { - "is-posix-bracket": "0.1.1" + "is-posix-bracket": "^0.1.0" } }, "expand-range": { @@ -739,7 +739,7 @@ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "requires": { - "fill-range": "2.2.4" + "fill-range": "^2.1.0" } }, "extend": { @@ -752,8 +752,8 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -761,7 +761,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -771,7 +771,7 @@ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "fast-levenshtein": { @@ -784,7 +784,7 @@ "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.2.tgz", "integrity": "sha512-o2eo/X2syzzERAtN5LcGbiVQ0WwZSlN3qLtadwAz3X8Bu+XWD16dja/KMsjZLiQr+BLGPDnHGkc4yUJf1Xpkpw==", "requires": { - "format": "0.2.2" + "format": "^0.2.2" } }, "figures": { @@ -792,8 +792,8 @@ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" } }, "file-entry-cache": { @@ -801,8 +801,8 @@ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "requires": { - "flat-cache": "1.3.0", - "object-assign": "4.1.1" + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" } }, "filename-regex": { @@ -815,11 +815,11 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "3.1.0", - "repeat-element": "1.1.3", - "repeat-string": "1.6.1" + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" } }, "flat-cache": { @@ -827,10 +827,10 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", "requires": { - "circular-json": "0.3.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" } }, "fn-name": { @@ -848,7 +848,7 @@ "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "requires": { - "for-in": "1.0.2" + "for-in": "^1.0.1" } }, "format": { @@ -861,7 +861,7 @@ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "requires": { - "map-cache": "0.2.2" + "map-cache": "^0.2.2" } }, "fs.realpath": { @@ -875,8 +875,8 @@ "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", "optional": true, "requires": { - "nan": "2.11.1", - "node-pre-gyp": "0.10.0" + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" }, "dependencies": { "abbrev": { @@ -1355,7 +1355,7 @@ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", "requires": { - "is-property": "1.0.2" + "is-property": "^1.0.2" } }, "generate-object-property": { @@ -1363,7 +1363,7 @@ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", "requires": { - "is-property": "1.0.2" + "is-property": "^1.0.0" } }, "get-value": { @@ -1376,12 +1376,12 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "glob-base": { @@ -1389,8 +1389,8 @@ "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" } }, "glob-parent": { @@ -1398,7 +1398,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "requires": { - "is-glob": "2.0.1" + "is-glob": "^2.0.0" } }, "globals": { @@ -1411,12 +1411,12 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.3", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "graceful-fs": { @@ -1429,7 +1429,7 @@ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "has-flag": { @@ -1442,9 +1442,9 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "requires": { - "get-value": "2.0.6", - "has-values": "1.0.0", - "isobject": "3.0.1" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" }, "dependencies": { "isobject": { @@ -1459,8 +1459,8 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { "is-number": { @@ -1468,7 +1468,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1476,7 +1476,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1486,7 +1486,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1506,8 +1506,8 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -1525,19 +1525,19 @@ "resolved": "http://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", "requires": { - "ansi-escapes": "1.4.0", - "ansi-regex": "2.1.1", - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "cli-width": "2.2.0", - "figures": "1.7.0", - "lodash": "4.17.11", - "readline2": "1.0.1", - "run-async": "0.1.0", - "rx-lite": "3.1.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "through": "2.3.8" + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" } }, "interpret": { @@ -1555,7 +1555,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-alphabetical": { @@ -1573,8 +1573,8 @@ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.2.tgz", "integrity": "sha512-pyfU/0kHdISIgslFfZN9nfY1Gk3MquQgUm1mJTjdkEPpkAKNWuBTSqFwewOpR7N351VkErCiyV71zX7mlQQqsg==", "requires": { - "is-alphabetical": "1.0.2", - "is-decimal": "1.0.2" + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" } }, "is-arrayish": { @@ -1587,7 +1587,7 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "requires": { - "binary-extensions": "1.12.0" + "binary-extensions": "^1.0.0" } }, "is-buffer": { @@ -1600,7 +1600,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-decimal": { @@ -1613,9 +1613,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "dependencies": { "kind-of": { @@ -1640,7 +1640,7 @@ "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "requires": { - "is-primitive": "2.0.0" + "is-primitive": "^2.0.0" } }, "is-extendable": { @@ -1658,7 +1658,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-glob": { @@ -1666,7 +1666,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "is-hexadecimal": { @@ -1689,11 +1689,11 @@ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz", "integrity": "sha512-mG0f/unGX1HZ5ep4uhRaPOS8EkAY8/j6mDRMJrutq4CqhoJWYp7qAlonIPy3TV7p3ju4TK9fo/PbnoksWmsp5Q==", "requires": { - "generate-function": "2.3.1", - "generate-object-property": "1.2.0", - "is-my-ip-valid": "1.0.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" } }, "is-number": { @@ -1701,7 +1701,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-object": { @@ -1719,7 +1719,7 @@ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "requires": { - "is-path-inside": "1.0.1" + "is-path-inside": "^1.0.0" } }, "is-path-inside": { @@ -1727,7 +1727,7 @@ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "requires": { - "path-is-inside": "1.0.2" + "path-is-inside": "^1.0.1" } }, "is-plain-obj": { @@ -1740,7 +1740,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" }, "dependencies": { "isobject": { @@ -1808,8 +1808,8 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", "requires": { - "argparse": "1.0.10", - "esprima": "4.0.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "json-stable-stringify": { @@ -1817,7 +1817,7 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", "requires": { - "jsonify": "0.0.0" + "jsonify": "~0.0.0" } }, "jsonify": { @@ -1835,7 +1835,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } }, "levn": { @@ -1843,8 +1843,8 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, "load-plugin": { @@ -1852,8 +1852,8 @@ "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-2.2.2.tgz", "integrity": "sha512-FYzamtURIJefQykZGtiClYuZkJBUKzmx8Tc74y8JGAulDzbzVm/C+w/MbAljHRr+REL0cRzy3WgnHE+T8gce5g==", "requires": { - "npm-prefix": "1.2.0", - "resolve-from": "4.0.0" + "npm-prefix": "^1.2.0", + "resolve-from": "^4.0.0" }, "dependencies": { "resolve-from": { @@ -1883,7 +1883,7 @@ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "requires": { - "object-visit": "1.0.1" + "object-visit": "^1.0.0" } }, "markdown-escapes": { @@ -1916,7 +1916,7 @@ "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.2.tgz", "integrity": "sha512-d2WS98JSDVbpSsBfVvD9TaDMlqPRz7ohM/11G0rp5jOBb5q96RJ6YLszQ/09AAixyzh23FeIpCGqfaamEADtWg==", "requires": { - "unist-util-visit": "1.4.0" + "unist-util-visit": "^1.1.0" } }, "mdast-util-heading-style": { @@ -1934,19 +1934,19 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" } }, "minimatch": { @@ -1954,7 +1954,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -1967,8 +1967,8 @@ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "requires": { - "for-in": "1.0.2", - "is-extendable": "1.0.1" + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -1976,7 +1976,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -2010,17 +2010,17 @@ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "fragment-cache": "0.2.1", - "is-windows": "1.0.2", - "kind-of": "6.0.2", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "arr-diff": { @@ -2055,7 +2055,7 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "requires": { - "remove-trailing-separator": "1.1.0" + "remove-trailing-separator": "^1.0.1" } }, "npm-prefix": { @@ -2063,9 +2063,9 @@ "resolved": "https://registry.npmjs.org/npm-prefix/-/npm-prefix-1.2.0.tgz", "integrity": "sha1-5hlFX3B0ulTMZtbQ033Z8b5ry8A=", "requires": { - "rc": "1.2.8", - "shellsubstitute": "1.2.0", - "untildify": "2.1.0" + "rc": "^1.1.0", + "shellsubstitute": "^1.1.0", + "untildify": "^2.1.0" } }, "number-is-nan": { @@ -2083,9 +2083,9 @@ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" }, "dependencies": { "define-property": { @@ -2093,7 +2093,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -2103,7 +2103,7 @@ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.0" }, "dependencies": { "isobject": { @@ -2118,8 +2118,8 @@ "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" } }, "object.pick": { @@ -2127,7 +2127,7 @@ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" }, "dependencies": { "isobject": { @@ -2142,7 +2142,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "onetime": { @@ -2155,12 +2155,12 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" } }, "os-homedir": { @@ -2173,12 +2173,12 @@ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.0.tgz", "integrity": "sha512-XXtDdOPLSB0sHecbEapQi6/58U/ODj/KWfIXmmMCJF/eRn8laX6LZbOyioMoETOOJoWRW8/qTSl5VQkUIfKM5g==", "requires": { - "character-entities": "1.2.2", - "character-entities-legacy": "1.1.2", - "character-reference-invalid": "1.1.2", - "is-alphanumerical": "1.0.2", - "is-decimal": "1.0.2", - "is-hexadecimal": "1.0.2" + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" } }, "parse-glob": { @@ -2186,10 +2186,10 @@ "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" } }, "parse-json": { @@ -2197,7 +2197,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "requires": { - "error-ex": "1.3.2" + "error-ex": "^1.2.0" } }, "pascalcase": { @@ -2235,7 +2235,7 @@ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "requires": { - "pinkie": "2.0.4" + "pinkie": "^2.0.0" } }, "plur": { @@ -2243,7 +2243,7 @@ "resolved": "https://registry.npmjs.org/plur/-/plur-3.0.1.tgz", "integrity": "sha512-lJl0ojUynAM1BZn58Pas2WT/TXeC1+bS+UqShl0x9+49AtOn7DixRXVzaC8qrDOIxNDmepKnLuMTH7NQmkX0PA==", "requires": { - "irregular-plurals": "2.0.0" + "irregular-plurals": "^2.0.0" } }, "pluralize": { @@ -2281,9 +2281,9 @@ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz", "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==", "requires": { - "is-number": "4.0.0", - "kind-of": "6.0.2", - "math-random": "1.0.1" + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" }, "dependencies": { "is-number": { @@ -2303,10 +2303,10 @@ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "requires": { - "deep-extend": "0.6.0", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -2321,13 +2321,13 @@ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "readdirp": { @@ -2335,9 +2335,9 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "requires": { - "graceful-fs": "4.1.11", - "micromatch": "3.1.10", - "readable-stream": "2.3.6" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" }, "dependencies": { "arr-diff": { @@ -2355,16 +2355,16 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.3", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -2372,7 +2372,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2382,13 +2382,13 @@ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -2396,7 +2396,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -2404,7 +2404,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "is-accessor-descriptor": { @@ -2412,7 +2412,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -2420,7 +2420,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2430,7 +2430,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -2438,7 +2438,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2448,9 +2448,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" } }, "kind-of": { @@ -2465,14 +2465,14 @@ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -2480,7 +2480,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "extend-shallow": { @@ -2488,7 +2488,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2498,10 +2498,10 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { "extend-shallow": { @@ -2509,7 +2509,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2519,7 +2519,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -2527,7 +2527,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -2535,9 +2535,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "is-number": { @@ -2545,7 +2545,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -2553,7 +2553,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2573,19 +2573,19 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.13", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } } } @@ -2595,8 +2595,8 @@ "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", "mute-stream": "0.0.5" } }, @@ -2605,7 +2605,7 @@ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "requires": { - "resolve": "1.8.1" + "resolve": "^1.1.6" } }, "regex-cache": { @@ -2613,7 +2613,7 @@ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "requires": { - "is-equal-shallow": "0.1.3" + "is-equal-shallow": "^0.1.3" } }, "regex-not": { @@ -2621,8 +2621,8 @@ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "requires": { - "extend-shallow": "3.0.2", - "safe-regex": "1.1.0" + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, "remark": { @@ -2630,9 +2630,9 @@ "resolved": "https://registry.npmjs.org/remark/-/remark-8.0.0.tgz", "integrity": "sha512-K0PTsaZvJlXTl9DN6qYlvjTkqSZBFELhROZMrblm2rB+085flN84nz4g/BscKRMqDvhzlK1oQ/xnWQumdeNZYw==", "requires": { - "remark-parse": "4.0.0", - "remark-stringify": "4.0.0", - "unified": "6.2.0" + "remark-parse": "^4.0.0", + "remark-stringify": "^4.0.0", + "unified": "^6.0.0" } }, "remark-cli": { @@ -2640,9 +2640,9 @@ "resolved": "https://registry.npmjs.org/remark-cli/-/remark-cli-4.0.0.tgz", "integrity": "sha512-q5GMjGypUS4rTZb3WfMQcGpClSC38A9Ogg1h/HB2GLsqypDetmAfy0X+tuJ6JeyCPVOXXCDgsDCQq4QPqKmxBA==", "requires": { - "markdown-extensions": "1.1.1", - "remark": "8.0.0", - "unified-args": "4.0.0" + "markdown-extensions": "^1.1.0", + "remark": "^8.0.0", + "unified-args": "^4.0.0" } }, "remark-lint": { @@ -2650,7 +2650,7 @@ "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-6.0.2.tgz", "integrity": "sha512-zrIx7InZLLOUYUViT6lSa8T80pDyl3Ywvliog+4hoc7LoiJZRV74ejq+RBZK70bg/p2dU/CV6ycedgypFFePPg==", "requires": { - "remark-message-control": "4.1.0" + "remark-message-control": "^4.0.0" } }, "remark-lint-final-newline": { @@ -2658,7 +2658,7 @@ "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-1.0.2.tgz", "integrity": "sha512-hW/lbDwVKtME3jIcJWJ16wBtoJdFPWIiu0fEI93yzNTjeB1g3VSWJp66dHbtCLYwquRS5fr8UlGx7JxIu1kiuA==", "requires": { - "unified-lint-rule": "1.0.3" + "unified-lint-rule": "^1.0.0" } }, "remark-lint-hard-break-spaces": { @@ -2666,10 +2666,10 @@ "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-1.0.3.tgz", "integrity": "sha512-GiC0uXeFwef6/Pfo+EYBN0WIVlEFffh+9TdeJ4uLt89ZweaRVDPCTJQqkkuXoiXSPnZGD7cGHdkWCfXU1PaU7Q==", "requires": { - "unified-lint-rule": "1.0.3", - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.4.0" + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^1.1.1" } }, "remark-lint-list-item-bullet-indent": { @@ -2677,11 +2677,11 @@ "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-1.0.2.tgz", "integrity": "sha512-zvyQD6mJLRratZjk4Dw7D4vh73L43NXNCcap/6TxcmU9SKO7dXzoh8Ap9tyaFLic0LnHFc3Gx1pqYiPQ7PnL2g==", "requires": { - "plur": "3.0.1", - "unified-lint-rule": "1.0.3", - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.4.0" + "plur": "^3.0.0", + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^1.1.1" } }, "remark-lint-list-item-indent": { @@ -2689,11 +2689,11 @@ "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-1.0.2.tgz", "integrity": "sha512-ogCCrO8nyuM/0k1bo+O7Ww0S08XxHA9sHh5VdhLwffCTCyOPDoxL1zWCIrAgzPBFZkgjXDQHsOxeUBi5I1ZFcA==", "requires": { - "plur": "3.0.1", - "unified-lint-rule": "1.0.3", - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.4.0" + "plur": "^3.0.0", + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^1.1.1" } }, "remark-lint-no-auto-link-without-protocol": { @@ -2701,11 +2701,11 @@ "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-1.0.2.tgz", "integrity": "sha512-3GtkSxOyd6we4b8JdtJsNgt8+3UN+hpw1UiMoE9X96ahc1rqsCFm6miorNUnF/gfPQ1liHBvZUed2SIenDmpkg==", "requires": { - "mdast-util-to-string": "1.0.5", - "unified-lint-rule": "1.0.3", - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.4.0" + "mdast-util-to-string": "^1.0.2", + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^1.1.1" } }, "remark-lint-no-blockquote-without-marker": { @@ -2713,11 +2713,11 @@ "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-2.0.2.tgz", "integrity": "sha512-jkfZ4hFiviZttEo7Ac7GZWFgMQ/bdVPfSluLeuf+qwL8sQvR4ClklKJ0Xbkk3cLRjvlGsc8U8uZR8qqH5MSLoA==", "requires": { - "unified-lint-rule": "1.0.3", - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.4.0", - "vfile-location": "2.0.3" + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^1.1.1", + "vfile-location": "^2.0.1" } }, "remark-lint-no-duplicate-definitions": { @@ -2725,11 +2725,11 @@ "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-1.0.2.tgz", "integrity": "sha512-e5tSoIBChG3UCz4eJ+JPKV915iNeIeT7uKBKzXBPxnMcEgQaT3V7DBDdN8Wn1oPw9fLp/5AjDN5l9x7iddLsRw==", "requires": { - "unified-lint-rule": "1.0.3", - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-stringify-position": "1.1.2", - "unist-util-visit": "1.4.0" + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-stringify-position": "^1.1.2", + "unist-util-visit": "^1.1.1" } }, "remark-lint-no-heading-content-indent": { @@ -2737,12 +2737,12 @@ "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-1.0.2.tgz", "integrity": "sha512-g2MVmJhHbfFungca5WGWVB9bBY4YTrY6og20U+6DxkdS4ngoc8ezXUt8zV1HHEn0M/GdKr9F7fYhXcekJd/qaw==", "requires": { - "mdast-util-heading-style": "1.0.4", - "plur": "3.0.1", - "unified-lint-rule": "1.0.3", - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.4.0" + "mdast-util-heading-style": "^1.0.2", + "plur": "^3.0.0", + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^1.1.1" } }, "remark-lint-no-inline-padding": { @@ -2750,10 +2750,10 @@ "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-1.0.2.tgz", "integrity": "sha512-SHYqEH27yxzgcXSyaIzvqImvktDhXGltRSOEhAHiL2nJktuPt3nosFfGy4/oKAJMWJ2N3aMudXq/zuw1dAkQSg==", "requires": { - "mdast-util-to-string": "1.0.5", - "unified-lint-rule": "1.0.3", - "unist-util-generated": "1.1.2", - "unist-util-visit": "1.4.0" + "mdast-util-to-string": "^1.0.2", + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-visit": "^1.1.1" } }, "remark-lint-no-literal-urls": { @@ -2761,11 +2761,11 @@ "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-1.0.2.tgz", "integrity": "sha512-+mWZIJA4yAqpKIclcFP5wRy/6hxcPnfU9Xmgp4fR7OD4JQ4JHkKq9O7MUbda14PLez1aMX+Is0O0hWI7OuqsSw==", "requires": { - "mdast-util-to-string": "1.0.5", - "unified-lint-rule": "1.0.3", - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.4.0" + "mdast-util-to-string": "^1.0.2", + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^1.1.1" } }, "remark-lint-no-shortcut-reference-image": { @@ -2773,9 +2773,9 @@ "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-1.0.2.tgz", "integrity": "sha512-IVYv5pgyf70jYcrn+BNHVO37BuQJg26rFOLzi2mj+/8EdFpolJiJcTvkChJgz5yip7317DmQQSNLX6gCExuDrQ==", "requires": { - "unified-lint-rule": "1.0.3", - "unist-util-generated": "1.1.2", - "unist-util-visit": "1.4.0" + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-visit": "^1.1.1" } }, "remark-lint-no-shortcut-reference-link": { @@ -2783,9 +2783,9 @@ "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-1.0.3.tgz", "integrity": "sha512-v5mk4wYQL+YRmlOTqi8avpzhoGZg+P42dDRda2jedysDIx7TJBEXUH6oMFEbo/qV6PMmtr7fr066M3RrOrLpiQ==", "requires": { - "unified-lint-rule": "1.0.3", - "unist-util-generated": "1.1.2", - "unist-util-visit": "1.4.0" + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-visit": "^1.1.1" } }, "remark-lint-no-undefined-references": { @@ -2793,9 +2793,9 @@ "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-1.0.2.tgz", "integrity": "sha512-te5rmQvdMg2Qld09Jzh4BlpjGQhbwG0EIlYVX6aE/YnwwrIldOgqLrW8x49XTyEMNOL8j/Bjxd2FX+sRfeldRw==", "requires": { - "unified-lint-rule": "1.0.3", - "unist-util-generated": "1.1.2", - "unist-util-visit": "1.4.0" + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-visit": "^1.1.1" } }, "remark-lint-no-unused-definitions": { @@ -2803,9 +2803,9 @@ "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-1.0.2.tgz", "integrity": "sha512-Qv4J2hI2S0NJdrlFuQhBVOlGNUSBLpe+2VBm/hSJAnBE7FW2ZGkVwwrs9h7HdZ/vW3LqfBrNcTKTVw+5ZzWTiA==", "requires": { - "unified-lint-rule": "1.0.3", - "unist-util-generated": "1.1.2", - "unist-util-visit": "1.4.0" + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-visit": "^1.1.1" } }, "remark-lint-ordered-list-marker-style": { @@ -2813,10 +2813,10 @@ "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-1.0.2.tgz", "integrity": "sha512-4EHuHxZqy8IT4k+4Vc8P38I34AiZfgl07fS5/iqGhCdoSMCvvxdOuzTWTgpDFbx/W2QpHelBfJ+FtOp+E0J4Lg==", "requires": { - "unified-lint-rule": "1.0.3", - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.4.0" + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^1.1.1" } }, "remark-message-control": { @@ -2824,9 +2824,9 @@ "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-4.1.0.tgz", "integrity": "sha512-e1dszks4YKY7hLAkhS2367jBjBpAfvi+kVgSN/tOFrdp3qxITjiNR5fOFnyYF8vvorkQ9uxlKJoZUOW8T7rKDg==", "requires": { - "mdast-comment-marker": "1.0.3", - "unified-message-control": "1.0.4", - "xtend": "4.0.1" + "mdast-comment-marker": "^1.0.0", + "unified-message-control": "^1.0.0", + "xtend": "^4.0.1" } }, "remark-parse": { @@ -2834,21 +2834,21 @@ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-4.0.0.tgz", "integrity": "sha512-XZgICP2gJ1MHU7+vQaRM+VA9HEL3X253uwUM/BGgx3iv6TH2B3bF3B8q00DKcyP9YrJV+/7WOWEWBFF/u8cIsw==", "requires": { - "collapse-white-space": "1.0.4", - "is-alphabetical": "1.0.2", - "is-decimal": "1.0.2", - "is-whitespace-character": "1.0.2", - "is-word-character": "1.0.2", - "markdown-escapes": "1.0.2", - "parse-entities": "1.2.0", - "repeat-string": "1.6.1", - "state-toggle": "1.0.1", + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.0.2", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", "trim": "0.0.1", - "trim-trailing-lines": "1.1.1", - "unherit": "1.1.1", - "unist-util-remove-position": "1.1.2", - "vfile-location": "2.0.3", - "xtend": "4.0.1" + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" } }, "remark-preset-lint-recommended": { @@ -2856,22 +2856,22 @@ "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-3.0.2.tgz", "integrity": "sha512-os4YNWLbkorjvDHVB4o+zCCufZLzGoD4Iwdk7SV7bSIZurUTrMp/ZrpNytyetN9ugIMXuHbWJUE+dF0ND+WorQ==", "requires": { - "remark-lint": "6.0.2", - "remark-lint-final-newline": "1.0.2", - "remark-lint-hard-break-spaces": "1.0.3", - "remark-lint-list-item-bullet-indent": "1.0.2", - "remark-lint-list-item-indent": "1.0.2", - "remark-lint-no-auto-link-without-protocol": "1.0.2", - "remark-lint-no-blockquote-without-marker": "2.0.2", - "remark-lint-no-duplicate-definitions": "1.0.2", - "remark-lint-no-heading-content-indent": "1.0.2", - "remark-lint-no-inline-padding": "1.0.2", - "remark-lint-no-literal-urls": "1.0.2", - "remark-lint-no-shortcut-reference-image": "1.0.2", - "remark-lint-no-shortcut-reference-link": "1.0.3", - "remark-lint-no-undefined-references": "1.0.2", - "remark-lint-no-unused-definitions": "1.0.2", - "remark-lint-ordered-list-marker-style": "1.0.2" + "remark-lint": "^6.0.0", + "remark-lint-final-newline": "^1.0.0", + "remark-lint-hard-break-spaces": "^1.0.0", + "remark-lint-list-item-bullet-indent": "^1.0.0", + "remark-lint-list-item-indent": "^1.0.0", + "remark-lint-no-auto-link-without-protocol": "^1.0.0", + "remark-lint-no-blockquote-without-marker": "^2.0.0", + "remark-lint-no-duplicate-definitions": "^1.0.0", + "remark-lint-no-heading-content-indent": "^1.0.0", + "remark-lint-no-inline-padding": "^1.0.0", + "remark-lint-no-literal-urls": "^1.0.0", + "remark-lint-no-shortcut-reference-image": "^1.0.0", + "remark-lint-no-shortcut-reference-link": "^1.0.0", + "remark-lint-no-undefined-references": "^1.0.0", + "remark-lint-no-unused-definitions": "^1.0.0", + "remark-lint-ordered-list-marker-style": "^1.0.0" } }, "remark-stringify": { @@ -2879,20 +2879,20 @@ "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-4.0.0.tgz", "integrity": "sha512-xLuyKTnuQer3ke9hkU38SUYLiTmS078QOnoFavztmbt/pAJtNSkNtFgR0U//uCcmG0qnyxao+PDuatQav46F1w==", "requires": { - "ccount": "1.0.3", - "is-alphanumeric": "1.0.0", - "is-decimal": "1.0.2", - "is-whitespace-character": "1.0.2", - "longest-streak": "2.0.2", - "markdown-escapes": "1.0.2", - "markdown-table": "1.1.2", - "mdast-util-compact": "1.0.2", - "parse-entities": "1.2.0", - "repeat-string": "1.6.1", - "state-toggle": "1.0.1", - "stringify-entities": "1.3.2", - "unherit": "1.1.1", - "xtend": "4.0.1" + "ccount": "^1.0.0", + "is-alphanumeric": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "longest-streak": "^2.0.1", + "markdown-escapes": "^1.0.0", + "markdown-table": "^1.1.0", + "mdast-util-compact": "^1.0.0", + "parse-entities": "^1.0.2", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "stringify-entities": "^1.0.1", + "unherit": "^1.0.4", + "xtend": "^4.0.1" } }, "remove-trailing-separator": { @@ -2920,8 +2920,8 @@ "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" } }, "resolve": { @@ -2929,7 +2929,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", "requires": { - "path-parse": "1.0.6" + "path-parse": "^1.0.5" } }, "resolve-from": { @@ -2947,8 +2947,8 @@ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" } }, "ret": { @@ -2961,7 +2961,7 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "requires": { - "glob": "7.1.3" + "glob": "^7.0.5" } }, "run-async": { @@ -2969,7 +2969,7 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", "requires": { - "once": "1.4.0" + "once": "^1.3.0" } }, "rx-lite": { @@ -2987,7 +2987,7 @@ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "requires": { - "ret": "0.1.15" + "ret": "~0.1.10" } }, "set-value": { @@ -2995,10 +2995,10 @@ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "split-string": "3.1.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -3006,7 +3006,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -3016,9 +3016,9 @@ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", "requires": { - "glob": "7.1.3", - "interpret": "1.1.0", - "rechoir": "0.6.2" + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" } }, "shellsubstitute": { @@ -3041,14 +3041,14 @@ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "requires": { - "base": "0.11.2", - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "map-cache": "0.2.2", - "source-map": "0.5.7", - "source-map-resolve": "0.5.2", - "use": "3.1.1" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" }, "dependencies": { "define-property": { @@ -3056,7 +3056,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -3064,7 +3064,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -3074,9 +3074,9 @@ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "requires": { - "define-property": "1.0.0", - "isobject": "3.0.1", - "snapdragon-util": "3.0.1" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" }, "dependencies": { "define-property": { @@ -3084,7 +3084,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -3092,7 +3092,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -3100,7 +3100,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -3108,9 +3108,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -3130,7 +3130,7 @@ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.2.0" } }, "source-map": { @@ -3143,11 +3143,11 @@ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "requires": { - "atob": "2.1.2", - "decode-uri-component": "0.2.0", - "resolve-url": "0.2.1", - "source-map-url": "0.4.0", - "urix": "0.1.0" + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, "source-map-url": { @@ -3160,7 +3160,7 @@ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "requires": { - "extend-shallow": "3.0.2" + "extend-shallow": "^3.0.0" } }, "sprintf-js": { @@ -3178,8 +3178,8 @@ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "requires": { - "define-property": "0.2.5", - "object-copy": "0.1.0" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, "dependencies": { "define-property": { @@ -3187,7 +3187,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -3197,9 +3197,9 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -3207,7 +3207,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "~5.1.0" } }, "stringify-entities": { @@ -3215,10 +3215,10 @@ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", "requires": { - "character-entities-html4": "1.1.2", - "character-entities-legacy": "1.1.2", - "is-alphanumerical": "1.0.2", - "is-hexadecimal": "1.0.2" + "character-entities-html4": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-hexadecimal": "^1.0.0" } }, "strip-ansi": { @@ -3226,7 +3226,7 @@ "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-bom": { @@ -3249,12 +3249,12 @@ "resolved": "http://registry.npmjs.org/table/-/table-3.8.3.tgz", "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", "requires": { - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", - "lodash": "4.17.11", + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", "slice-ansi": "0.0.4", - "string-width": "2.1.1" + "string-width": "^2.0.0" }, "dependencies": { "ansi-regex": { @@ -3272,8 +3272,8 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" } }, "strip-ansi": { @@ -3281,7 +3281,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } } } @@ -3301,7 +3301,7 @@ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "to-regex": { @@ -3309,10 +3309,10 @@ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "requires": { - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "regex-not": "1.0.2", - "safe-regex": "1.1.0" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" } }, "to-regex-range": { @@ -3320,8 +3320,8 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "requires": { - "is-number": "3.0.0", - "repeat-string": "1.6.1" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" }, "dependencies": { "is-number": { @@ -3329,7 +3329,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } } } @@ -3339,9 +3339,9 @@ "resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-2.2.0.tgz", "integrity": "sha512-saGC8/lWdGrEoBMLUtgzhRHWAkQMP8gdldA3MOAUhBwTGEb1RSMVcflHGSx4ZJsdEZ9o1qDBCPp47LCPrbZWow==", "requires": { - "is-buffer": "1.1.6", - "vfile": "2.3.0", - "x-is-function": "1.0.4" + "is-buffer": "^1.1.4", + "vfile": "^2.0.0", + "x-is-function": "^1.0.4" } }, "trim": { @@ -3364,7 +3364,7 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "requires": { - "prelude-ls": "1.1.2" + "prelude-ls": "~1.1.2" } }, "typedarray": { @@ -3377,8 +3377,8 @@ "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.1.tgz", "integrity": "sha512-+XZuV691Cn4zHsK0vkKYwBEwB74T3IZIcxrgn2E4rKwTfFyI1zCh7X7grwh9Re08fdPlarIdyWgI8aVB3F5A5g==", "requires": { - "inherits": "2.0.3", - "xtend": "4.0.1" + "inherits": "^2.0.1", + "xtend": "^4.0.1" } }, "unified": { @@ -3386,12 +3386,12 @@ "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz", "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==", "requires": { - "bail": "1.0.3", - "extend": "3.0.2", - "is-plain-obj": "1.1.0", - "trough": "1.0.3", - "vfile": "2.3.0", - "x-is-string": "0.1.0" + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^1.1.0", + "trough": "^1.0.0", + "vfile": "^2.0.0", + "x-is-string": "^0.1.0" } }, "unified-args": { @@ -3399,12 +3399,12 @@ "resolved": "https://registry.npmjs.org/unified-args/-/unified-args-4.0.0.tgz", "integrity": "sha1-jZubitNHvrN/QwVipixNNhtCIg8=", "requires": { - "camelcase": "4.1.0", - "chalk": "2.4.1", - "chokidar": "1.7.0", - "minimist": "1.2.0", - "text-table": "0.2.0", - "unified-engine": "4.0.1" + "camelcase": "^4.0.0", + "chalk": "^2.0.0", + "chokidar": "^1.5.1", + "minimist": "^1.2.0", + "text-table": "^0.2.0", + "unified-engine": "^4.0.0" }, "dependencies": { "ansi-styles": { @@ -3412,7 +3412,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { - "color-convert": "1.9.3" + "color-convert": "^1.9.0" } }, "chalk": { @@ -3420,9 +3420,9 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "minimist": { @@ -3435,7 +3435,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } } } @@ -3445,25 +3445,25 @@ "resolved": "https://registry.npmjs.org/unified-engine/-/unified-engine-4.0.1.tgz", "integrity": "sha1-lpKql/1cTsNoiXeeElFL746GP8M=", "requires": { - "concat-stream": "1.6.2", - "debug": "2.6.9", - "fault": "1.0.2", - "fn-name": "2.0.1", - "glob": "7.1.3", - "ignore": "3.3.10", - "is-empty": "1.2.0", - "is-hidden": "1.1.1", - "is-object": "1.0.1", - "js-yaml": "3.12.0", - "load-plugin": "2.2.2", - "parse-json": "2.2.0", - "to-vfile": "2.2.0", - "trough": "1.0.3", - "vfile-reporter": "4.0.0", - "vfile-statistics": "1.1.1", - "x-is-function": "1.0.4", - "x-is-string": "0.1.0", - "xtend": "4.0.1" + "concat-stream": "^1.5.1", + "debug": "^2.2.0", + "fault": "^1.0.0", + "fn-name": "^2.0.1", + "glob": "^7.0.3", + "ignore": "^3.2.0", + "is-empty": "^1.0.0", + "is-hidden": "^1.0.1", + "is-object": "^1.0.1", + "js-yaml": "^3.6.1", + "load-plugin": "^2.0.0", + "parse-json": "^2.2.0", + "to-vfile": "^2.0.0", + "trough": "^1.0.0", + "vfile-reporter": "^4.0.0", + "vfile-statistics": "^1.1.0", + "x-is-function": "^1.0.4", + "x-is-string": "^0.1.0", + "xtend": "^4.0.1" } }, "unified-lint-rule": { @@ -3471,7 +3471,7 @@ "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-1.0.3.tgz", "integrity": "sha512-6z+HH3mtlFdj/w3MaQpObrZAd9KRiro370GxBFh13qkV8LYR21lLozA4iQiZPhe7KuX/lHewoGOEgQ4AWrAR3Q==", "requires": { - "wrapped": "1.0.1" + "wrapped": "^1.0.1" } }, "unified-message-control": { @@ -3480,8 +3480,8 @@ "integrity": "sha512-e1dEtN4Z/TvLn/qHm+xeZpzqhJTtfZusFErk336kkZVpqrJYiV9ptxq+SbRPFMlN0OkjDYHmVJ929KYjsMTo3g==", "requires": { "trim": "0.0.1", - "unist-util-visit": "1.4.0", - "vfile-location": "2.0.3" + "unist-util-visit": "^1.0.0", + "vfile-location": "^2.0.0" } }, "union-value": { @@ -3489,10 +3489,10 @@ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "requires": { - "arr-union": "3.1.0", - "get-value": "2.0.6", - "is-extendable": "0.1.1", - "set-value": "0.4.3" + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" }, "dependencies": { "extend-shallow": { @@ -3500,7 +3500,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "set-value": { @@ -3508,10 +3508,10 @@ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" } } } @@ -3536,7 +3536,7 @@ "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.2.tgz", "integrity": "sha512-XxoNOBvq1WXRKXxgnSYbtCF76TJrRoe5++pD4cCBsssSiWSnPEktyFrFLE8LTk3JW5mt9hB0Sk5zn4x/JeWY7Q==", "requires": { - "unist-util-visit": "1.4.0" + "unist-util-visit": "^1.1.0" } }, "unist-util-stringify-position": { @@ -3549,7 +3549,7 @@ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.0.tgz", "integrity": "sha512-FiGu34ziNsZA3ZUteZxSFaczIjGmksfSgdKqBfOejrrfzyUy5b7YrlzT1Bcvi+djkYDituJDy2XB7tGTeBieKw==", "requires": { - "unist-util-visit-parents": "2.0.1" + "unist-util-visit-parents": "^2.0.0" } }, "unist-util-visit-parents": { @@ -3557,7 +3557,7 @@ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.0.1.tgz", "integrity": "sha512-6B0UTiMfdWql4cQ03gDTCSns+64Zkfo2OCbK31Ov0uMizEz+CJeAp0cgZVb5Fhmcd7Bct2iRNywejT0orpbqUA==", "requires": { - "unist-util-is": "2.1.2" + "unist-util-is": "^2.1.2" } }, "unset-value": { @@ -3565,8 +3565,8 @@ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "requires": { - "has-value": "0.3.1", - "isobject": "3.0.1" + "has-value": "^0.3.1", + "isobject": "^3.0.0" }, "dependencies": { "has-value": { @@ -3574,9 +3574,9 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "requires": { - "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" }, "dependencies": { "isobject": { @@ -3606,7 +3606,7 @@ "resolved": "https://registry.npmjs.org/untildify/-/untildify-2.1.0.tgz", "integrity": "sha1-F+soB5h/dpUunASF/DEdBqgmouA=", "requires": { - "os-homedir": "1.0.2" + "os-homedir": "^1.0.0" } }, "urix": { @@ -3624,7 +3624,7 @@ "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", "requires": { - "os-homedir": "1.0.2" + "os-homedir": "^1.0.0" } }, "util-deprecate": { @@ -3637,10 +3637,10 @@ "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", "requires": { - "is-buffer": "1.1.6", + "is-buffer": "^1.1.4", "replace-ext": "1.0.0", - "unist-util-stringify-position": "1.1.2", - "vfile-message": "1.0.1" + "unist-util-stringify-position": "^1.0.0", + "vfile-message": "^1.0.0" } }, "vfile-location": { @@ -3653,7 +3653,7 @@ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.0.1.tgz", "integrity": "sha512-vSGCkhNvJzO6VcWC6AlJW4NtYOVtS+RgCaqFIYUjoGIlHnFL+i0LbtYvonDWOMcB97uTPT4PRsyYY7REWC9vug==", "requires": { - "unist-util-stringify-position": "1.1.2" + "unist-util-stringify-position": "^1.1.1" } }, "vfile-reporter": { @@ -3661,11 +3661,11 @@ "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-4.0.0.tgz", "integrity": "sha1-6m8K4TQvSEFXOYXgX5QXNvJ96do=", "requires": { - "repeat-string": "1.6.1", - "string-width": "1.0.2", - "supports-color": "4.5.0", - "unist-util-stringify-position": "1.1.2", - "vfile-statistics": "1.1.1" + "repeat-string": "^1.5.0", + "string-width": "^1.0.0", + "supports-color": "^4.1.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-statistics": "^1.1.0" }, "dependencies": { "has-flag": { @@ -3678,7 +3678,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "requires": { - "has-flag": "2.0.0" + "has-flag": "^2.0.0" } } } @@ -3699,7 +3699,7 @@ "integrity": "sha1-x4PZ2Aeyc+mwHoUWgKk4yHyQckI=", "requires": { "co": "3.1.0", - "sliced": "1.0.1" + "sliced": "^1.0.1" }, "dependencies": { "co": { @@ -3719,7 +3719,7 @@ "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "requires": { - "mkdirp": "0.5.1" + "mkdirp": "^0.5.1" } }, "x-is-function": { diff --git a/package.json b/package.json index ddb3578..f1cffea 100644 --- a/package.json +++ b/package.json @@ -23,4 +23,4 @@ "remark-preset-lint-recommended" ] } -} \ No newline at end of file +} From 72b2a18c63d7968050450ea59e2e8c80d9f7f2d8 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 9 Nov 2019 21:09:25 +0200 Subject: [PATCH 33/72] Webapp test changes, GET for Event API --- webapp/serializers.py | 16 +++--- webapp/tests/test_contact.py | 2 +- webapp/tests/test_event.py | 108 ++++++++++++++++++++++++++++++++--- webapp/tests/test_feed.py | 9 +-- webapp/tests/test_signup.py | 2 +- webapp/tests/test_tag.py | 25 ++++---- webapp/views.py | 3 +- 7 files changed, 125 insertions(+), 40 deletions(-) diff --git a/webapp/serializers.py b/webapp/serializers.py index 9ea9456..048fa22 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -2,13 +2,13 @@ from rest_framework import serializers from webapp.models import * -class SignupFormSerializer(serializers.HyperlinkedModelSerializer): +class SignupFormSerializer(serializers.ModelSerializer): class Meta: model = SignupForm - fields = ('id', 'title', 'start_time', 'end_time', 'questions') + fields = ('id', 'title_fi', 'title_en', 'start_time', 'end_time', 'questions') -class EventSerializer(serializers.HyperlinkedModelSerializer): +class EventSerializer(serializers.ModelSerializer): signupForm = SignupFormSerializer(many=True, read_only=True, required=False) signup_id = serializers.PrimaryKeyRelatedField( many=True, @@ -23,8 +23,8 @@ class EventSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Event - fields = ('id', 'tag_id', 'tags', 'visible', 'title', 'description', - 'content', 'start_time', 'end_time', 'location', 'signup_id', 'signupForm') + fields = ('id', 'tag_id', 'tags', 'visible', 'title_fi', 'title_en', 'description_fi', 'description_en', + 'content_fi', 'content_en', 'start_time', 'end_time', 'location', 'signup_id', 'signupForm') depth = 1 def create(self, validated_data): @@ -68,7 +68,7 @@ class SavedQuestionsSerializer(serializers.ModelSerializer): class TagSerializer(serializers.ModelSerializer): class Meta: model = Tag - fields = ('id', 'slug', 'name', 'icon') + fields = ('id', 'slug', 'name_fi', 'name_en', 'icon') class FeedSerializer(serializers.ModelSerializer): @@ -80,8 +80,8 @@ class FeedSerializer(serializers.ModelSerializer): class Meta: model = Feed - fields = ('id', 'tags', 'tag_id', 'visible', 'title', 'description', - 'content', 'publish_time', 'autohide', 'autohide_enabled') + fields = ('id', 'tags', 'tag_id', 'visible', 'title_fi', 'title_en', 'description_fi', 'description_en', + 'content_fi', 'content_en', 'publish_time', 'autohide', 'autohide_enabled') depth = 1 def create(self, validated_data): diff --git a/webapp/tests/test_contact.py b/webapp/tests/test_contact.py index ad8ed59..4606335 100644 --- a/webapp/tests/test_contact.py +++ b/webapp/tests/test_contact.py @@ -12,5 +12,5 @@ from itertools import islice import tempfile -class TagsTestCase(APITestCase): +class ContactsTestCase(APITestCase): pass diff --git a/webapp/tests/test_event.py b/webapp/tests/test_event.py index ad8ed59..36e374f 100644 --- a/webapp/tests/test_event.py +++ b/webapp/tests/test_event.py @@ -1,16 +1,106 @@ from django.test import TestCase -from django.core.files import File +from django.utils import timezone from django.contrib.auth.models import User -from rest_framework.test import APITestCase +from rest_framework.test import APITestCase, APIRequestFactory, force_authenticate from rest_framework import status -from rest_framework.test import force_authenticate -from webapp.models import Tag, Feed -from webapp.serializers import TagSerializer, FeedSerializer +from webapp.models import Tag, Event +from webapp.serializers import EventSerializer -from collections import OrderedDict -from itertools import islice import tempfile -class TagsTestCase(APITestCase): - pass +class EventTestCase(APITestCase): + + def setUp(self): + self.icon = tempfile.NamedTemporaryFile(suffix=".jpg").name + Tag.objects.create(slug='testtag1', name='test1', icon=self.icon) + tag1 = Tag.objects.get(slug="testtag1") + Tag.objects.create(slug="testtag2", name='test2', icon=self.icon) + tag2 = Tag.objects.get(slug="testtag2") + self.assertEqual(Tag.objects.count(), 2) + + # Visible and relevant + Event.objects.create( + title="TestEvent1", + visible=True, + description="diidadaapa", + content="lorem ipsum", + start_time=timezone.datetime(2019, 11, 9, 12, 0, 0), + end_time=timezone.datetime(2020, 11, 9, 13, 0, 0), + location="Testimaa" + ) + # Invisible but relevant + Event.objects.create( + title="TestEvent2", + visible=False, + description="diidadaapa", + content="lorem ipsum", + start_time=timezone.datetime(2018, 12, 9, 12, 0, 0), + end_time=timezone.datetime(2020, 12, 9, 13, 0, 0), + location="Testimaan kerhohuone" + ) + # Visible but unrelevant + Event.objects.create( + title="TestEvent3", + visible=True, + description="diidadaapa", + content="lorem ipsum", + start_time=timezone.datetime(2018, 12, 9, 12, 0, 0), + end_time=timezone.datetime(2018, 12, 9, 13, 0, 0), + location="Testimaan kerhohuone" + ) + # Visible and relevant + Event.objects.create( + title="TestEvent4", + visible=True, + description="diidadaapa", + content="lorem ipsum", + start_time=timezone.datetime(2018, 12, 9, 12, 0, 0), + end_time=timezone.datetime(2020, 12, 9, 13, 0, 0), + location="Testimaan kerhohuone" + ) + Event.objects.get(title="TestEvent1").tags.add(tag1) + Event.objects.get(title="TestEvent2").tags.add(tag2) + self.assertEqual(Event.objects.count(), 4) + + username, password = 'test_admin', 'password123' + self.authClient = User.objects.create_superuser(username, 'myemail@test.com', password) + self.testEventId = Event.objects.get(title="TestEvent1").id + + def test_get_events(self): + # Get from API + response = self.client.get("/api/events/", format="json") + # Response 200 + self.assertTrue(status.is_success(response.status_code)) + # Response should not have old events + self.assertEqual(len(response.data["results"]), 2) + # Check that serialized data is equal to received response + expected_events = EventSerializer( + Event.objects.filter(title__in=("TestEvent1", "TestEvent4")).order_by("start_time"), + many=True, + context={ + "request": APIRequestFactory().get(r"http://testserver/api/events/") + } + ) + self.assertEqual(response.data["results"], expected_events.data) + + def test_get_single_event(self): + response = self.client.get(f"/api/events/{self.testEventId}/", format="json") + result = response.data + # Remove tags because of API call having also domain name added to icon URL + result.pop("tags") + serialized = EventSerializer(Event.objects.get(title="TestEvent1")).data + serialized.pop("tags") + self.assertEqual( + result, + serialized + ) + + def test_post_event(self): + pass + + def test_update_event(self): + pass + + def test_delete_event(self): + pass diff --git a/webapp/tests/test_feed.py b/webapp/tests/test_feed.py index ca55fe4..2a73d79 100644 --- a/webapp/tests/test_feed.py +++ b/webapp/tests/test_feed.py @@ -1,14 +1,11 @@ from django.test import TestCase -from django.core.files import File from django.contrib.auth.models import User from rest_framework.test import APITestCase from rest_framework import status from rest_framework.test import force_authenticate from webapp.models import Tag, Feed -from webapp.serializers import TagSerializer, FeedSerializer +from webapp.serializers import FeedSerializer -from collections import OrderedDict -from itertools import islice import tempfile @@ -51,7 +48,7 @@ class FeedTestCase(APITestCase): tag1_id = Tag.objects.get(slug="test1").id tag2_id = Tag.objects.get(slug="test2").id - data = {'tags': [tag1_id, tag2_id], 'title': 'testtitle', 'visible': 'True', 'description': 'liirumlaarum', 'content': 'lorem ipsum'} + data = {'tags': [tag1_id, tag2_id], 'title_fi': 'testtitle', 'title_en': 'testtitle', 'visible': 'True', 'description_fi': 'liirumlaarum', 'description_en': 'liirumlaarum', 'content_fi': 'lorem ipsum', 'content_en': 'lorem ipsum'} # Try post without authentication response = self.client.post('/api/feed/', data, format='multipart') self.assertTrue(status.is_client_error(response.status_code)) @@ -63,6 +60,6 @@ class FeedTestCase(APITestCase): self.assertTrue(status.is_success(response.status_code)) self.assertEqual(Feed.objects.count(), 2) - created = Feed.objects.get(title="testtitle") + created = Feed.objects.get(title_fi="testtitle") print(created.tags) # self.assertEqual(created.tags.count(), 2) diff --git a/webapp/tests/test_signup.py b/webapp/tests/test_signup.py index ad8ed59..82f671a 100644 --- a/webapp/tests/test_signup.py +++ b/webapp/tests/test_signup.py @@ -12,5 +12,5 @@ from itertools import islice import tempfile -class TagsTestCase(APITestCase): +class SignupTestCase(APITestCase): pass diff --git a/webapp/tests/test_tag.py b/webapp/tests/test_tag.py index 755c02c..d8e2a4a 100644 --- a/webapp/tests/test_tag.py +++ b/webapp/tests/test_tag.py @@ -1,11 +1,8 @@ from django.test import TestCase -from django.core.files import File -from django.contrib.auth.models import User -from rest_framework.test import APITestCase from rest_framework import status -from rest_framework.test import force_authenticate -from webapp.models import Tag, Feed -from webapp.serializers import TagSerializer, FeedSerializer +from rest_framework.test import APITestCase +from webapp.models import Tag +from webapp.serializers import TagSerializer from collections import OrderedDict from itertools import islice @@ -16,7 +13,7 @@ class TagsTestCase(APITestCase): def setUp(self): self.icon = tempfile.NamedTemporaryFile(suffix=".jpg").name - Tag.objects.create(slug='Party', name='Bileet', icon=self.icon) + Tag.objects.create(slug='Party', name_fi='Bileet', name_en="Partytime", icon=self.icon) def test_get_single_tag(self): self.assertEqual(Tag.objects.count(), 1) @@ -26,7 +23,7 @@ class TagsTestCase(APITestCase): # We dont care about icon, so response is sliced sliced_response = OrderedDict(islice(response.data['results'][0].items(), 3)) tag1 = Tag.objects.get(slug="Party") - self.assertEqual(sliced_response, {'id': tag1.id, 'slug': 'Party', 'name': 'Bileet'}) + self.assertEqual(sliced_response, {'id': tag1.id, 'slug': 'Party', 'name_fi': 'Bileet'}) def test_get_single_tag_serializer(self): response = self.client.get('/api/tags/', format='json') @@ -43,8 +40,8 @@ class TagsTestCase(APITestCase): def test_get_multiple_tags(self): self.assertEqual(Tag.objects.count(), 1) - Tag.objects.create(slug='Freshmen', name='Fuksit', icon=self.icon) - Tag.objects.create(slug='International', name='Ulkkarit', icon=self.icon) + Tag.objects.create(slug='Freshmen', name_fi='Fuksit', icon=self.icon) + Tag.objects.create(slug='International', name_fi='Ulkkarit', icon=self.icon) self.assertEqual(Tag.objects.count(), 3) response = self.client.get('/api/tags/', format='json') @@ -53,17 +50,17 @@ class TagsTestCase(APITestCase): # We dont care about icon, so response is sliced tag1 = Tag.objects.get(slug="Party") sliced_response = OrderedDict(islice(response.data['results'][0].items(), 3)) - self.assertEqual(sliced_response, {'id': tag1.id, 'slug': 'Party', 'name': 'Bileet'}) + self.assertEqual(sliced_response, {'id': tag1.id, 'slug': 'Party', 'name_fi': 'Bileet'}) sliced_response = OrderedDict(islice(response.data['results'][1].items(), 3)) tag2 = Tag.objects.get(slug="Freshmen") - self.assertEqual(sliced_response, {'id': tag2.id, 'slug': 'Freshmen', 'name': 'Fuksit'}) + self.assertEqual(sliced_response, {'id': tag2.id, 'slug': 'Freshmen', 'name_fi': 'Fuksit'}) sliced_response = OrderedDict(islice(response.data['results'][2].items(), 3)) tag3 = Tag.objects.get(slug="International") - self.assertEqual(sliced_response, {'id': tag3.id, 'slug': 'International', 'name': 'Ulkkarit'}) + self.assertEqual(sliced_response, {'id': tag3.id, 'slug': 'International', 'name_fi': 'Ulkkarit'}) def test_create_tag(self): self.assertEqual(Tag.objects.count(), 1) - response = self.client.post('/api/tags/', {'slug': 'Test', 'name': 'Testinimi', 'icon': self.icon}, format='multipart') + response = self.client.post('/api/tags/', {'slug': 'Test', 'name_fi': 'Testinimi', 'icon': self.icon}, format='multipart') self.assertFalse(status.is_success(response.status_code)) self.assertEqual(Tag.objects.count(), 1) diff --git a/webapp/views.py b/webapp/views.py index 2faef8c..ae8c0d9 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -41,6 +41,7 @@ class RootView(routers.APIRootView): class EventViewSet(viewsets.ModelViewSet): queryset = Event.objects.all() + ordering = ["start_time"] serializer_class = EventSerializer permission_classes = [IsAuthenticatedOrReadOnly] filter_backends = (filters.DjangoFilterBackend, SearchFilter, OrderingFilter) @@ -52,7 +53,7 @@ class EventViewSet(viewsets.ModelViewSet): if since: return Event.objects.filter(visible=True, end_time__gt=since).order_by('start_time') - return Event.objects.filter(visible=True).order_by('start_time') + return Event.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time') class SignupFormViewSet(viewsets.ModelViewSet): From 04e91a0e8df1d85a803bb279753a7a39601c7c25 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 9 Nov 2019 21:14:02 +0200 Subject: [PATCH 34/72] Check npm packages are OK --- package-lock.json | 3147 ++++++++++++--------------------------------- package.json | 4 +- 2 files changed, 825 insertions(+), 2326 deletions(-) diff --git a/package-lock.json b/package-lock.json index c87cde5..036d73d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,11 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/unist": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", + "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" + }, "acorn": { "version": "5.7.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", @@ -11,7 +16,7 @@ }, "acorn-jsx": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "requires": { "acorn": "^3.0.4" @@ -19,7 +24,7 @@ "dependencies": { "acorn": { "version": "3.3.0", - "resolved": "http://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" } } @@ -31,6 +36,13 @@ "requires": { "co": "^4.6.0", "json-stable-stringify": "^1.0.1" + }, + "dependencies": { + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + } } }, "ajv-keywords": { @@ -44,22 +56,25 @@ "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" }, "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } }, "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, "argparse": { @@ -70,62 +85,6 @@ "sprintf-js": "~1.0.2" } }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" - }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -134,82 +93,59 @@ "chalk": "^1.1.3", "esutils": "^2.0.2", "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } } }, "bail": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.3.tgz", - "integrity": "sha512-1X8CnjFVQ+a+KW36uBNMTU5s8+v5FzeqrP7hTG5aTb4aPreSbZJlhwPon9VKMuEVgV++JM+SQrALY3kr7eswdg==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.4.tgz", + "integrity": "sha512-S8vuDB4w6YpRhICUDET3guPlQpaJl7od94tpZ0Fvnyp+MKW/HyDTcRDck+29C9g+d/qQHnddRH3+94kZdrW0Ww==" }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - } - } - }, "binary-extensions": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", - "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==" }, "brace-expansion": { "version": "1.1.11", @@ -221,13 +157,11 @@ } }, "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "fill-range": "^7.0.1" } }, "buffer-from": { @@ -235,29 +169,6 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, "caller-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", @@ -272,61 +183,58 @@ "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "ccount": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.3.tgz", - "integrity": "sha512-Jt9tIBkRc9POUof7QA/VwWd+58fKkEEfI+/t1/eOlxKM7ZhrczNzMFefge7Ai+39y1pR/pP6cI19guHy3FSLmw==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.4.tgz", + "integrity": "sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w==" }, "chalk": { - "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "character-entities": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.2.tgz", - "integrity": "sha512-sMoHX6/nBiy3KKfC78dnEalnpn0Az0oSNvqUWYTtYrhRI5iUIYsROU48G+E+kMFQzqXaJ8kHJZ85n7y6/PHgwQ==" + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.3.tgz", + "integrity": "sha512-yB4oYSAa9yLcGyTbB4ItFwHw43QHdH129IJ5R+WvxOkWlyFnR5FAaBNnUq4mcxsTVZGh28bHoeTHMKXH1wZf3w==" }, "character-entities-html4": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.2.tgz", - "integrity": "sha512-sIrXwyna2+5b0eB9W149izTPJk/KkJTg6mEzDGibwBUkyH1SbDa+nf515Ppdi3MaH35lW0JFJDWeq9Luzes1Iw==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.3.tgz", + "integrity": "sha512-SwnyZ7jQBCRHELk9zf2CN5AnGEc2nA+uKMZLHvcqhpPprjkYhiLn0DywMHgN5ttFZuITMATbh68M6VIVKwJbcg==" }, "character-entities-legacy": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.2.tgz", - "integrity": "sha512-9NB2VbXtXYWdXzqrvAHykE/f0QJxzaKIpZ5QzNZrrgQ7Iyxr2vnfS8fCBNVW9nUEZE0lo57nxKRqnzY/dKrwlA==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.3.tgz", + "integrity": "sha512-YAxUpPoPwxYFsslbdKkhrGnXAtXoHNgYjlBM3WMXkWGTl5RsY3QmOyhwAgL8Nxm9l5LBThXGawxKPn68y6/fww==" }, "character-reference-invalid": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.2.tgz", - "integrity": "sha512-7I/xceXfKyUJmSAn/jw8ve/9DyOP7XxufNYLI9Px7CmsKgEUaZLUTax6nZxGQtaoiZCjpu6cHPj20xC/vqRReQ==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.3.tgz", + "integrity": "sha512-VOq6PRzQBam/8Jm6XBGk2fNEnHXAdGd6go0rtd4weAGECBamHDwwCQSOT12TACIYUZegUXnV6xBXqUssijtxIg==" }, "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" } }, "circular-json": { @@ -334,32 +242,6 @@ "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==" }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, "cli-cursor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", @@ -374,9 +256,9 @@ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" }, "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", + "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=" }, "code-point-at": { "version": "1.1.0", @@ -384,18 +266,9 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "collapse-white-space": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.4.tgz", - "integrity": "sha512-YfQ1tAUZm561vpYD+5eyWN8+UsceQbSrqqlc/6zDY2gtAE+uZLSdkkovhnGpmCThsvKBFakq4EdY/FF93E8XIw==" - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.5.tgz", + "integrity": "sha512-703bOOmytCYAX9cXYqoikYIx6twmFCXsnzRQheBcTG3nzKYBR4P/+wkYeH+Mvj7qUz8zZDtdyzbxfnEi/kYzRQ==" }, "color-convert": { "version": "1.9.3", @@ -410,58 +283,44 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", - "readable-stream": "^2.2.2", + "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", "requires": { - "es5-ext": "^0.10.9" + "es5-ext": "^0.10.50", + "type": "^1.0.1" } }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -472,67 +331,6 @@ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - } - } - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - } - }, "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -541,6 +339,11 @@ "esutils": "^2.0.2" } }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -550,13 +353,13 @@ } }, "es5-ext": { - "version": "0.10.46", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.46.tgz", - "integrity": "sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw==", + "version": "0.10.52", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.52.tgz", + "integrity": "sha512-bWCbE9fbpYQY4CU6hJbJ1vSz70EClMlDgJ7BmwI+zEJhxrwjesZRPglGJlsZhu0334U3hI+gaspwksH9IGD6ag==", "requires": { "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "1" + "es6-symbol": "~3.1.2", + "next-tick": "~1.0.0" } }, "es6-iterator": { @@ -592,25 +395,36 @@ "es6-iterator": "~2.0.1", "es6-symbol": "3.1.1", "event-emitter": "~0.3.5" + }, + "dependencies": { + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + } } }, "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", "requires": { - "d": "1", - "es5-ext": "~0.10.14" + "d": "^1.0.1", + "ext": "^1.1.2" } }, "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", "requires": { "d": "1", - "es5-ext": "^0.10.14", - "es6-iterator": "^2.0.1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.1" } }, @@ -670,6 +484,94 @@ "table": "^3.7.8", "text-table": "~0.2.0", "user-home": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } } }, "espree": { @@ -703,14 +605,14 @@ } }, "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" }, "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, "event-emitter": { "version": "0.3.5", @@ -726,20 +628,19 @@ "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=" }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "ext": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.2.0.tgz", + "integrity": "sha512-0ccUQK/9e3NreLFg6K6np8aPyRgwycx+oFGtfx1dSp7Wj00Ozw9r05FgBRlzjf2XBM7LAzwgLyDscRrtSU91hA==", "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "requires": { - "fill-range": "^2.1.0" + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", + "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==" + } } }, "extend": { @@ -747,53 +648,25 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "requires": { - "is-extglob": "^1.0.0" - } - }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "fault": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.2.tgz", - "integrity": "sha512-o2eo/X2syzzERAtN5LcGbiVQ0WwZSlN3qLtadwAz3X8Bu+XWD16dja/KMsjZLiQr+BLGPDnHGkc4yUJf1Xpkpw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.3.tgz", + "integrity": "sha512-sfFuP4X0hzrbGKjAUNXYvNqsZ5F6ohx/dZ9I0KQud/aiZNwg263r5L9yGB0clvXHCkzXh5W3t7RSHchggYIFmA==", "requires": { "format": "^0.2.2" } }, "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", + "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" + "escape-string-regexp": "^1.0.5" } }, "file-entry-cache": { @@ -805,31 +678,22 @@ "object-assign": "^4.0.1" } }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" - }, "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "to-regex-range": "^5.0.1" } }, "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", "requires": { "circular-json": "^0.3.1", - "del": "^2.0.2", "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", "write": "^0.2.1" } }, @@ -838,517 +702,21 @@ "resolved": "https://registry.npmjs.org/fn-name/-/fn-name-2.0.1.tgz", "integrity": "sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc=" }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "requires": { - "for-in": "^1.0.1" - } - }, "format": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=" }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "requires": { - "map-cache": "^0.2.2" - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.5.1", - "bundled": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.21", - "bundled": true, - "optional": true, - "requires": { - "safer-buffer": "^2.1.0" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "optional": true - }, - "minipass": { - "version": "2.2.4", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.1.0", - "bundled": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "needle": { - "version": "2.2.0", - "bundled": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.0", - "bundled": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.3", - "bundled": true, - "optional": true - }, - "npm-packlist": { - "version": "1.1.10", - "bundled": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "rc": { - "version": "1.2.7", - "bundled": true, - "optional": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "optional": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "optional": true - }, - "semver": { - "version": "5.5.0", - "bundled": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "tar": { - "version": "4.4.1", - "bundled": true, - "optional": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "optional": true, - "requires": { - "string-width": "^1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "yallist": { - "version": "3.0.2", - "bundled": true, - "optional": true - } - } + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "optional": true }, "generate-function": { "version": "2.3.1", @@ -1366,15 +734,10 @@ "is-property": "^1.0.0" } }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" - }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1384,21 +747,12 @@ "path-is-absolute": "^1.0.0" } }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "requires": { - "is-glob": "^2.0.0" + "is-glob": "^4.0.1" } }, "globals": { @@ -1406,23 +760,10 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" }, "has-ansi": { "version": "2.0.0", @@ -1430,6 +771,13 @@ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "requires": { "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } } }, "has-flag": { @@ -1437,60 +785,6 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "ignore": { "version": "3.3.10", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", @@ -1511,9 +805,9 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.5", @@ -1522,7 +816,7 @@ }, "inquirer": { "version": "0.12.0", - "resolved": "http://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", "requires": { "ansi-escapes": "^1.1.0", @@ -1538,30 +832,86 @@ "string-width": "^1.0.1", "strip-ansi": "^3.0.0", "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } } }, "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==" }, "irregular-plurals": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz", "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==" }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - } - }, "is-alphabetical": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.2.tgz", - "integrity": "sha512-V0xN4BYezDHcBSKb1QHUFMlR4as/XEuCZBzMJUU4n7+Cbt33SmUnSol+pnXFvLxSHNq2CemUXNdaXV6Flg7+xg==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.3.tgz", + "integrity": "sha512-eEMa6MKpHFzw38eKm56iNNi6GJ7lf6aLLio7Kr23sJPAECscgRtZvOBYybejWDQ2bM949Y++61PY+udzj5QMLA==" }, "is-alphanumeric": { "version": "1.0.0", @@ -1569,9 +919,9 @@ "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=" }, "is-alphanumerical": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.2.tgz", - "integrity": "sha512-pyfU/0kHdISIgslFfZN9nfY1Gk3MquQgUm1mJTjdkEPpkAKNWuBTSqFwewOpR7N351VkErCiyV71zX7mlQQqsg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.3.tgz", + "integrity": "sha512-A1IGAPO5AW9vSh7omxIlOGwIqEvpW/TA+DksVOPM5ODuxKlZS09+TEM1E3275lJqO2oJ38vDpeAL3DCIiHE6eA==", "requires": { "is-alphabetical": "^1.0.0", "is-decimal": "^1.0.0" @@ -1583,101 +933,55 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "requires": { - "binary-extensions": "^1.0.0" + "binary-extensions": "^2.0.0" } }, "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - } + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" }, "is-decimal": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.2.tgz", - "integrity": "sha512-TRzl7mOCchnhchN+f3ICUCzYvL9ul7R+TYOsZ8xia++knyZAJfv/uA1FvQXsAnYIl1T3B2X5E/J7Wb1QXiIBXg==" - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "is-dotfile": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.3.tgz", + "integrity": "sha512-bvLSwoDg2q6Gf+E2LEPiklHZxxiSi3XAh4Mav65mKqTfCO1HM3uBs24TjEH8iJX3bbDdLXKJXBTmGzuTUuAEjQ==" }, "is-empty": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-empty/-/is-empty-1.2.0.tgz", "integrity": "sha1-3pu1snhzigWgsJpX4ftNSjQan2s=" }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "^2.1.1" } }, "is-hexadecimal": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.2.tgz", - "integrity": "sha512-but/G3sapV3MNyqiDBLrOi4x8uCIw0RY3o/Vb5GT0sMFHrVV7731wFSVy41T5FO1og7G0gXLJh0MkgPRouko/A==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.3.tgz", + "integrity": "sha512-zxQ9//Q3D/34poZf8fiy3m3XVpbQc7ren15iKqrTtLPwkPD/t3Scy9Imp63FujULGxuK0ZlCwoo5xNpktFgbOA==" }, "is-hidden": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-hidden/-/is-hidden-1.1.1.tgz", - "integrity": "sha512-175UKecS8+U4hh2PSY0j4xnm2GKYzvSKnbh+naC93JjuBA7LgIo6YxlbcsSo6seFBdQO3RuIcH980yvqqD/2cA==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-hidden/-/is-hidden-1.1.2.tgz", + "integrity": "sha512-kytBeNVW2QTIqZdJBDKIjP+EkUTzDT07rsc111w/gxqR6wK3ODkOswcpxgED6HU6t7fEhOxqojVZ2a2kU9rj+A==" }, "is-my-ip-valid": { "version": "1.0.0", @@ -1685,9 +989,9 @@ "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==" }, "is-my-json-valid": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz", - "integrity": "sha512-mG0f/unGX1HZ5ep4uhRaPOS8EkAY8/j6mDRMJrutq4CqhoJWYp7qAlonIPy3TV7p3ju4TK9fo/PbnoksWmsp5Q==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.0.tgz", + "integrity": "sha512-XTHBZSIIxNsIsZXg7XB5l8z/OBFosl1Wao4tXLpeC7eKU4Vm/kdop2azkPqULwnfGQjmeDIyey9g7afMMtdWAA==", "requires": { "generate-function": "^2.0.0", "generate-object-property": "^1.1.0", @@ -1697,68 +1001,19 @@ } }, "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "requires": { - "kind-of": "^3.0.2" - } + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "is-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "requires": { - "path-is-inside": "^1.0.1" - } - }, "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" - }, - "is-primitive": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.0.0.tgz", + "integrity": "sha512-EYisGhpgSCwspmIuRHGjROWTon2Xp8Z7U03Wubk/bTL5TTRC5R1rGVgyjzBrk9+ULdH6cRD06KRcw/xfqhVYKQ==" }, "is-property": { "version": "1.0.2", @@ -1771,47 +1026,39 @@ "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" }, "is-whitespace-character": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.2.tgz", - "integrity": "sha512-SzM+T5GKUCtLhlHFKt2SDAX2RFzfS6joT91F2/WSi9LxgFdsnhfPK/UIA+JhRR2xuyLdrCys2PiFDrtn1fU5hQ==" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.3.tgz", + "integrity": "sha512-SNPgMLz9JzPccD3nPctcj8sZlX9DAMJSKH8bP7Z6bohCwuNgX8xbWr1eTAYXX9Vpi/aSn8Y1akL9WgM3t43YNQ==" }, "is-word-character": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.2.tgz", - "integrity": "sha512-T3FlsX8rCHAH8e7RE7PfOPZVFQlcV3XRF9eOOBQ1uf70OxO7CjjSOjeImMPCADBdYWcStAbVbYvJ1m2D3tb+EA==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.3.tgz", + "integrity": "sha512-0wfcrFgOOOBdgRNT9H33xe6Zi6yhX/uoc4U8NBZGeQQB0ctU1dnlNTyL9JM2646bHDTpsDm1Brb3VPoCIMrd/A==" }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" }, "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" } }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, "json-stable-stringify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", @@ -1820,6 +1067,21 @@ "jsonify": "~0.0.0" } }, + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "requires": { + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", @@ -1830,14 +1092,6 @@ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=" }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -1848,48 +1102,35 @@ } }, "load-plugin": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-2.2.2.tgz", - "integrity": "sha512-FYzamtURIJefQykZGtiClYuZkJBUKzmx8Tc74y8JGAulDzbzVm/C+w/MbAljHRr+REL0cRzy3WgnHE+T8gce5g==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-2.3.1.tgz", + "integrity": "sha512-dYB1lbwqHgPTrruy9glukCu8Ya9vzj6TMfouCtj2H/GuJ+8syioisgKTBPxnCi6m8K8jINKfTOxOHngFkUYqHw==", "requires": { "npm-prefix": "^1.2.0", - "resolve-from": "^4.0.0" + "resolve-from": "^5.0.0" }, "dependencies": { "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" } } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "longest-streak": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.2.tgz", - "integrity": "sha512-TmYTeEYxiAmSVdpbnQDXGtvYOIRsCMg89CVZzwzc2o7GFL1CjoiRPjH5ec0NFAVlAx3fVof9dX/t6KKRAo2OWA==" - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "requires": { - "object-visit": "^1.0.0" - } + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.3.tgz", + "integrity": "sha512-9lz5IVdpwsKLMzQi0MQ+oD9EA0mIGcWYP7jXMTZVXP8D42PwuAk+M/HBFYQoxt1G5OR8m7aSIgb1UymfWGBWEw==" }, "markdown-escapes": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.2.tgz", - "integrity": "sha512-lbRZ2mE3Q9RtLjxZBZ9+IMl68DKIXaVAhwvwn9pmjnPLS0h/6kyBMgNhqi1xFJ/2yv6cSyv0jbiZavZv93JkkA==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.3.tgz", + "integrity": "sha512-XUi5HJhhV5R74k8/0H2oCbCiYf/u4cO/rX8tnGkRvrqhsr5BRNU6Mg0yt/8UIx1iIS8220BNJsDb7XnILhLepw==" }, "markdown-extensions": { "version": "1.1.1", @@ -1897,57 +1138,32 @@ "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==" }, "markdown-table": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.2.tgz", - "integrity": "sha512-NcWuJFHDA8V3wkDgR/j4+gZx+YQwstPgfQDV8ndUeWWzta3dnDTBxpVzqS9lkmJAuV5YX35lmyojl6HO5JXAgw==" - }, - "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==" }, "mdast-comment-marker": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/mdast-comment-marker/-/mdast-comment-marker-1.0.3.tgz", - "integrity": "sha512-FZXxBBYeJ/R6k9zgyVGygHWka6FDJdzSbP6kcvB+L4Yqz62po57rZlnA2I14LIKsb3XPEky4vgP0Y83tZXTw7Q==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/mdast-comment-marker/-/mdast-comment-marker-1.1.1.tgz", + "integrity": "sha512-TWZDaUtPLwKX1pzDIY48MkSUQRDwX/HqbTB4m3iYdL/zosi/Z6Xqfdv0C0hNVKvzrPjZENrpWDt4p4odeVO0Iw==" }, "mdast-util-compact": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.2.tgz", - "integrity": "sha512-d2WS98JSDVbpSsBfVvD9TaDMlqPRz7ohM/11G0rp5jOBb5q96RJ6YLszQ/09AAixyzh23FeIpCGqfaamEADtWg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.3.tgz", + "integrity": "sha512-nRiU5GpNy62rZppDKbLwhhtw5DXoFMqw9UNZFmlPsNaQCZ//WLjGKUwWMdJrUH+Se7UvtO2gXtAMe0g/N+eI5w==", "requires": { "unist-util-visit": "^1.1.0" } }, "mdast-util-heading-style": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-1.0.4.tgz", - "integrity": "sha512-n4fUvwpR5Uj1Ti658KxYDq9gR0UF3FK1UVTVig12imrSOssQU2OpUysje8nps5Cb85b6eau5akpWW7Zkxtv1XA==" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-1.0.5.tgz", + "integrity": "sha512-8zQkb3IUwiwOdUw6jIhnwM6DPyib+mgzQuHAe7j2Hy1rIarU4VUxe472bp9oktqULW3xqZE+Kz6OD4Gi7IA3vw==" }, "mdast-util-to-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.0.5.tgz", - "integrity": "sha512-2qLt/DEOo5F6nc2VFScQiHPzQ0XXcabquRJxKMhKte8nt42o08HUxNDPk7tt0YPxnWjAT11I1SYi0X0iPnfI5A==" - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.0.6.tgz", + "integrity": "sha512-868pp48gUPmZIhfKrLbaDneuzGiw3OTDjHc5M1kAepR2CWBJ+HpEsm252K4aXdiP5coVZaJPOqGtVU6Po8xnXg==" }, "minimatch": { "version": "3.0.4", @@ -1959,87 +1175,27 @@ }, "minimist": { "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, - "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, "mkdirp": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "mute-stream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=" }, - "nan": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", - "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - } - } - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -2051,12 +1207,9 @@ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "npm-prefix": { "version": "1.2.0", @@ -2078,65 +1231,6 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2147,20 +1241,20 @@ }, "onetime": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" }, "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "requires": { "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", + "fast-levenshtein": "~2.0.6", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", - "wordwrap": "~1.0.0" + "word-wrap": "~1.2.3" } }, "os-homedir": { @@ -2169,9 +1263,9 @@ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "parse-entities": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.0.tgz", - "integrity": "sha512-XXtDdOPLSB0sHecbEapQi6/58U/ODj/KWfIXmmMCJF/eRn8laX6LZbOyioMoETOOJoWRW8/qTSl5VQkUIfKM5g==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", + "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", "requires": { "character-entities": "^1.0.0", "character-entities-legacy": "^1.0.0", @@ -2181,30 +1275,15 @@ "is-hexadecimal": "^1.0.0" } }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "requires": { - "error-ex": "^1.2.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" } }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -2220,28 +1299,15 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } + "picomatch": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz", + "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==" }, "plur": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/plur/-/plur-3.0.1.tgz", - "integrity": "sha512-lJl0ojUynAM1BZn58Pas2WT/TXeC1+bS+UqShl0x9+49AtOn7DixRXVzaC8qrDOIxNDmepKnLuMTH7NQmkX0PA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz", + "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==", "requires": { "irregular-plurals": "^2.0.0" } @@ -2251,53 +1317,21 @@ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=" }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" - }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" - }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "progress": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=" }, - "randomatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz", - "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==", - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - } - } - }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -2313,281 +1347,30 @@ "version": "1.2.0", "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" } } }, "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } + "picomatch": "^2.0.4" } }, "readline2": { @@ -2598,6 +1381,16 @@ "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", "mute-stream": "0.0.5" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + } } }, "rechoir": { @@ -2608,63 +1401,46 @@ "resolve": "^1.1.6" } }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, "remark": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/remark/-/remark-8.0.0.tgz", - "integrity": "sha512-K0PTsaZvJlXTl9DN6qYlvjTkqSZBFELhROZMrblm2rB+085flN84nz4g/BscKRMqDvhzlK1oQ/xnWQumdeNZYw==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/remark/-/remark-11.0.1.tgz", + "integrity": "sha512-Fl2AvN+yU6sOBAjUz3xNC5iEvLkXV8PZicLOOLifjU8uKGusNvhHfGRCfETsqyvRHZ24JXqEyDY4hRLhoUd30A==", "requires": { - "remark-parse": "^4.0.0", - "remark-stringify": "^4.0.0", - "unified": "^6.0.0" + "remark-parse": "^7.0.0", + "remark-stringify": "^7.0.0", + "unified": "^8.2.0" } }, "remark-cli": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-cli/-/remark-cli-4.0.0.tgz", - "integrity": "sha512-q5GMjGypUS4rTZb3WfMQcGpClSC38A9Ogg1h/HB2GLsqypDetmAfy0X+tuJ6JeyCPVOXXCDgsDCQq4QPqKmxBA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/remark-cli/-/remark-cli-7.0.0.tgz", + "integrity": "sha512-gYomWviFnZsiRimG+Jdb4LQ9c8uSOcGmPTmzlvxImt0gvzabqlp1kaqndxTx4kYLsWGqwhQRO+M9iyqHDkoDlA==", "requires": { "markdown-extensions": "^1.1.0", - "remark": "^8.0.0", - "unified-args": "^4.0.0" + "remark": "^11.0.0", + "unified-args": "^7.0.0" } }, "remark-lint": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-6.0.2.tgz", - "integrity": "sha512-zrIx7InZLLOUYUViT6lSa8T80pDyl3Ywvliog+4hoc7LoiJZRV74ejq+RBZK70bg/p2dU/CV6ycedgypFFePPg==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-6.0.5.tgz", + "integrity": "sha512-o1I3ddm+KNsTxk60wWGI+p2yU1jB1gcm8jo2Sy6VhJ4ab2TrQIp1oQbp5xeLoFXYSh/NAqCpKjHkCM/BYpkFdQ==", "requires": { "remark-message-control": "^4.0.0" } }, "remark-lint-final-newline": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-1.0.2.tgz", - "integrity": "sha512-hW/lbDwVKtME3jIcJWJ16wBtoJdFPWIiu0fEI93yzNTjeB1g3VSWJp66dHbtCLYwquRS5fr8UlGx7JxIu1kiuA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-1.0.3.tgz", + "integrity": "sha512-ETAadktv75EwUS3XDhyZUVstXKxfPAEn7SmfN9kZ4+Jb4qo4hHE9gtTOzhE6HxLUxxl9BBhpC5mMO3JcL8UZ5A==", "requires": { "unified-lint-rule": "^1.0.0" } }, "remark-lint-hard-break-spaces": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-1.0.3.tgz", - "integrity": "sha512-GiC0uXeFwef6/Pfo+EYBN0WIVlEFffh+9TdeJ4uLt89ZweaRVDPCTJQqkkuXoiXSPnZGD7cGHdkWCfXU1PaU7Q==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-1.0.4.tgz", + "integrity": "sha512-YM82UpgliZCZhGNmFxEe7ArfhqR5CplFf2bc0k0+8w3rKWKx7EJcGMar2NK410tIi40gGeWtH/pIEypPJFCCiA==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", @@ -2673,9 +1449,9 @@ } }, "remark-lint-list-item-bullet-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-1.0.2.tgz", - "integrity": "sha512-zvyQD6mJLRratZjk4Dw7D4vh73L43NXNCcap/6TxcmU9SKO7dXzoh8Ap9tyaFLic0LnHFc3Gx1pqYiPQ7PnL2g==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-1.0.3.tgz", + "integrity": "sha512-iVxQbrgzLpMHG3C6o6wRta/+Bc96etOiBYJnh2zm/aWz6DJ7cGLDykngblP/C4he7LYSeWOD/8Y57HbXZwM2Og==", "requires": { "plur": "^3.0.0", "unified-lint-rule": "^1.0.0", @@ -2685,9 +1461,9 @@ } }, "remark-lint-list-item-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-1.0.2.tgz", - "integrity": "sha512-ogCCrO8nyuM/0k1bo+O7Ww0S08XxHA9sHh5VdhLwffCTCyOPDoxL1zWCIrAgzPBFZkgjXDQHsOxeUBi5I1ZFcA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-1.0.4.tgz", + "integrity": "sha512-Sv0gVH6qP1/nFpbJuyyguB9sAD2o42StD2WbEZeUcEexXwRO4u/YaX0Pm5pMtCiEHyN+qyL6ShKBQMtgol9BeA==", "requires": { "plur": "^3.0.0", "unified-lint-rule": "^1.0.0", @@ -2697,9 +1473,9 @@ } }, "remark-lint-no-auto-link-without-protocol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-1.0.2.tgz", - "integrity": "sha512-3GtkSxOyd6we4b8JdtJsNgt8+3UN+hpw1UiMoE9X96ahc1rqsCFm6miorNUnF/gfPQ1liHBvZUed2SIenDmpkg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-1.0.3.tgz", + "integrity": "sha512-k+hg2mXnO4Q9WV+UShPLen5oThvFxcRVWkx2hviVd/nu3eiszBKH3o38csBwjeJoMG3l2ZhdUW8dlOBhq8670Q==", "requires": { "mdast-util-to-string": "^1.0.2", "unified-lint-rule": "^1.0.0", @@ -2709,9 +1485,9 @@ } }, "remark-lint-no-blockquote-without-marker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-2.0.2.tgz", - "integrity": "sha512-jkfZ4hFiviZttEo7Ac7GZWFgMQ/bdVPfSluLeuf+qwL8sQvR4ClklKJ0Xbkk3cLRjvlGsc8U8uZR8qqH5MSLoA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-2.0.3.tgz", + "integrity": "sha512-faDzKrA6aKidsRXG6gcIlCO8TexLxIxe+n9B3mdnl8mhZGgE0FfWTkIWVMj0IYps/xVsVMf45KxhXgc1wU9kwg==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", @@ -2721,21 +1497,21 @@ } }, "remark-lint-no-duplicate-definitions": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-1.0.2.tgz", - "integrity": "sha512-e5tSoIBChG3UCz4eJ+JPKV915iNeIeT7uKBKzXBPxnMcEgQaT3V7DBDdN8Wn1oPw9fLp/5AjDN5l9x7iddLsRw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-1.0.5.tgz", + "integrity": "sha512-zKXmfNUODXhJsGQdqfguMG9Nl9v1sLaDsQgMjUtmOSoQRnNud9ThQAZl62eX5jBn5HKcpOifG80tgkyBvU5eEw==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-stringify-position": "^1.1.2", - "unist-util-visit": "^1.1.1" + "unist-util-stringify-position": "^2.0.0", + "unist-util-visit": "^1.4.0" } }, "remark-lint-no-heading-content-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-1.0.2.tgz", - "integrity": "sha512-g2MVmJhHbfFungca5WGWVB9bBY4YTrY6og20U+6DxkdS4ngoc8ezXUt8zV1HHEn0M/GdKr9F7fYhXcekJd/qaw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-1.0.3.tgz", + "integrity": "sha512-7xM6X5E/dt8OXOHdejH+sfYb139a3kMr8ZSSkcp90Ab1y+ZQBNaWsR3mYh8FRKkYPTN5eyd+KjhNpLWyqqCbgg==", "requires": { "mdast-util-heading-style": "^1.0.2", "plur": "^3.0.0", @@ -2746,20 +1522,20 @@ } }, "remark-lint-no-inline-padding": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-1.0.2.tgz", - "integrity": "sha512-SHYqEH27yxzgcXSyaIzvqImvktDhXGltRSOEhAHiL2nJktuPt3nosFfGy4/oKAJMWJ2N3aMudXq/zuw1dAkQSg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-1.0.4.tgz", + "integrity": "sha512-u5rgbDkcfVv645YxxOwoGBBJbsHEwWm/XqnO8EhfKTxkfKOF4ZItG7Ajhj89EDaeXMkvCcB/avBl4bj50eJH3g==", "requires": { "mdast-util-to-string": "^1.0.2", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^1.4.0" } }, "remark-lint-no-literal-urls": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-1.0.2.tgz", - "integrity": "sha512-+mWZIJA4yAqpKIclcFP5wRy/6hxcPnfU9Xmgp4fR7OD4JQ4JHkKq9O7MUbda14PLez1aMX+Is0O0hWI7OuqsSw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-1.0.3.tgz", + "integrity": "sha512-H5quyMzl2kaewK+jYD1FI0G1SIinIsIp4DEyOUwIR+vYUoKwo0B4vvW0cmPpD1dgqqxHYx0B2B0JQQKFVWzGiw==", "requires": { "mdast-util-to-string": "^1.0.2", "unified-lint-rule": "^1.0.0", @@ -2769,9 +1545,9 @@ } }, "remark-lint-no-shortcut-reference-image": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-1.0.2.tgz", - "integrity": "sha512-IVYv5pgyf70jYcrn+BNHVO37BuQJg26rFOLzi2mj+/8EdFpolJiJcTvkChJgz5yip7317DmQQSNLX6gCExuDrQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-1.0.3.tgz", + "integrity": "sha512-CGm27X54kXp/5ehXejDTsZjqzK4uIhLGcrFzN3k/KjdwunQouEY92AARGrLSEuJ1hQx0bJsmnvr/hvQyWAfNJg==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", @@ -2779,9 +1555,9 @@ } }, "remark-lint-no-shortcut-reference-link": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-1.0.3.tgz", - "integrity": "sha512-v5mk4wYQL+YRmlOTqi8avpzhoGZg+P42dDRda2jedysDIx7TJBEXUH6oMFEbo/qV6PMmtr7fr066M3RrOrLpiQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-1.0.4.tgz", + "integrity": "sha512-FXdMJYqspZBhPlxYqfVgVluVXjxStg0RHJzqrk8G9wS8fCS62AE3reoaoiCahwoH1tfKcA+poktbKqDAmZo7Jg==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", @@ -2789,29 +1565,30 @@ } }, "remark-lint-no-undefined-references": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-1.0.2.tgz", - "integrity": "sha512-te5rmQvdMg2Qld09Jzh4BlpjGQhbwG0EIlYVX6aE/YnwwrIldOgqLrW8x49XTyEMNOL8j/Bjxd2FX+sRfeldRw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-1.1.1.tgz", + "integrity": "sha512-b1eIjWFaCu6m16Ax2uG33o1v+eRYqDTQRUqU6UeQ76JXmDmVtVO75ZuyRpqqE7VTZRW8YLVurXfJPDXfIa5Wng==", "requires": { + "collapse-white-space": "^1.0.4", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^1.4.0" } }, "remark-lint-no-unused-definitions": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-1.0.2.tgz", - "integrity": "sha512-Qv4J2hI2S0NJdrlFuQhBVOlGNUSBLpe+2VBm/hSJAnBE7FW2ZGkVwwrs9h7HdZ/vW3LqfBrNcTKTVw+5ZzWTiA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-1.0.5.tgz", + "integrity": "sha512-Bo22e0RNzc1QMW317KTuStGFDG7uTDUQhm/TrW6Qzud0WXnNnqUyvts+e7wTYoj8VnwhhjyjyoA9lKA3uXMdAQ==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^1.4.0" } }, "remark-lint-ordered-list-marker-style": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-1.0.2.tgz", - "integrity": "sha512-4EHuHxZqy8IT4k+4Vc8P38I34AiZfgl07fS5/iqGhCdoSMCvvxdOuzTWTgpDFbx/W2QpHelBfJ+FtOp+E0J4Lg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-1.0.3.tgz", + "integrity": "sha512-24TmW1eUa/2JlwprZg9jJ8LKLxNGKnlKiI5YOhN4taUp2yv8daqlV9vR54yfn/ZZQh6EQvbIX0jeVY9NYgQUtw==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", @@ -2820,9 +1597,9 @@ } }, "remark-message-control": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-4.1.0.tgz", - "integrity": "sha512-e1dszks4YKY7hLAkhS2367jBjBpAfvi+kVgSN/tOFrdp3qxITjiNR5fOFnyYF8vvorkQ9uxlKJoZUOW8T7rKDg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-4.2.0.tgz", + "integrity": "sha512-WXH2t5ljTyhsXlK1zPBLF3iPHbXl58R94phPMreS1xcHWBZJt6Oiu8RtNjy1poZFb3PqKnbYLJeR/CWcZ1bTFw==", "requires": { "mdast-comment-marker": "^1.0.0", "unified-message-control": "^1.0.0", @@ -2830,9 +1607,9 @@ } }, "remark-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-4.0.0.tgz", - "integrity": "sha512-XZgICP2gJ1MHU7+vQaRM+VA9HEL3X253uwUM/BGgx3iv6TH2B3bF3B8q00DKcyP9YrJV+/7WOWEWBFF/u8cIsw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-7.0.1.tgz", + "integrity": "sha512-WOZLa545jYXtSy+txza6ACudKWByQac4S2DmGk+tAGO/3XnVTOxwyCIxB7nTcLlk8Aayhcuf3cV1WV6U6L7/DQ==", "requires": { "collapse-white-space": "^1.0.2", "is-alphabetical": "^1.0.0", @@ -2840,7 +1617,7 @@ "is-whitespace-character": "^1.0.0", "is-word-character": "^1.0.0", "markdown-escapes": "^1.0.0", - "parse-entities": "^1.0.2", + "parse-entities": "^1.1.0", "repeat-string": "^1.5.4", "state-toggle": "^1.0.0", "trim": "0.0.1", @@ -2852,9 +1629,9 @@ } }, "remark-preset-lint-recommended": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-3.0.2.tgz", - "integrity": "sha512-os4YNWLbkorjvDHVB4o+zCCufZLzGoD4Iwdk7SV7bSIZurUTrMp/ZrpNytyetN9ugIMXuHbWJUE+dF0ND+WorQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-3.0.3.tgz", + "integrity": "sha512-5sQ34j1Irlsj6Tt4WWRylZ7UU+1jD5es/LfDZBZp/LXDwC4ldGqKpMmCCR6Z00x1jYM1phmS4M+eGqTdah0qkQ==", "requires": { "remark-lint": "^6.0.0", "remark-lint-final-newline": "^1.0.0", @@ -2875,9 +1652,9 @@ } }, "remark-stringify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-4.0.0.tgz", - "integrity": "sha512-xLuyKTnuQer3ke9hkU38SUYLiTmS078QOnoFavztmbt/pAJtNSkNtFgR0U//uCcmG0qnyxao+PDuatQav46F1w==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-7.0.3.tgz", + "integrity": "sha512-+jgmjNjm2kR7y2Ns1BATXRlFr+iQ7sDcpSgytfU77nkw7UCd5yJNArSxB3MU3Uul7HuyYNTCjetoGfy8xLia1A==", "requires": { "ccount": "^1.0.0", "is-alphanumeric": "^1.0.0", @@ -2890,21 +1667,11 @@ "parse-entities": "^1.0.2", "repeat-string": "^1.5.4", "state-toggle": "^1.0.0", - "stringify-entities": "^1.0.1", + "stringify-entities": "^2.0.0", "unherit": "^1.0.4", "xtend": "^4.0.1" } }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" - }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", @@ -2925,11 +1692,11 @@ } }, "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", "requires": { - "path-parse": "^1.0.5" + "path-parse": "^1.0.6" } }, "resolve-from": { @@ -2937,11 +1704,6 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=" }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, "restore-cursor": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", @@ -2951,17 +1713,12 @@ "onetime": "^1.0.0" } }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" - }, "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" } }, "run-async": { @@ -2978,38 +1735,9 @@ "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=" }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "requires": { - "ret": "~0.1.10" - } - }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" }, "shelljs": { "version": "0.7.8", @@ -3036,197 +1764,52 @@ "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "requires": { - "extend-shallow": "^3.0.0" - } - }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "state-toggle": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.1.tgz", - "integrity": "sha512-Qe8QntFrrpWTnHwvwj2FZTgv+PKIsp0B9VxLzLLbSpPXWOgRgc5LVj/aTiSfK1RqIeF9jeC1UeOH8Q8y60A7og==" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.2.tgz", + "integrity": "sha512-8LpelPGR0qQM4PnfLiplOQNJcIN1/r2Gy0xKB2zKnIW2YzPMt2sR4I/+gtPjhN7Svh9kw+zqEg2SFwpBO9iNiw==" }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz", + "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==", "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^5.2.0" } }, "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "~5.2.0" } }, "stringify-entities": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", - "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-2.0.0.tgz", + "integrity": "sha512-fqqhZzXyAM6pGD9lky/GOPq6V4X0SeTAFBl0iXb/BzOegl40gpf/bV3QQP7zULNYvjr6+Dx8SCaDULjVoOru0A==", "requires": { "character-entities-html4": "^1.0.0", "character-entities-legacy": "^1.0.0", "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.2", "is-hexadecimal": "^1.0.0" } }, "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^4.1.0" } }, "strip-bom": { @@ -3240,13 +1823,16 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } }, "table": { "version": "3.8.3", - "resolved": "http://registry.npmjs.org/table/-/table-3.8.3.tgz", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", "requires": { "ajv": "^4.7.0", @@ -3258,9 +1844,26 @@ }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } }, "is-fullwidth-code-point": { "version": "2.0.0", @@ -3274,15 +1877,35 @@ "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^2.0.0" } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" } } }, @@ -3293,55 +1916,24 @@ }, "through": { "version": "2.3.8", - "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - } - } + "is-number": "^7.0.0" } }, "to-vfile": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-2.2.0.tgz", - "integrity": "sha512-saGC8/lWdGrEoBMLUtgzhRHWAkQMP8gdldA3MOAUhBwTGEb1RSMVcflHGSx4ZJsdEZ9o1qDBCPp47LCPrbZWow==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-6.0.0.tgz", + "integrity": "sha512-i9fwXXSsHLu7mzgixc1WjgnqSe6pGpjnzCYoFmrASvEueLfyKf09QAe+XQYu8OAJ62aFqHpe2EKXojeRVvEzqA==", "requires": { - "is-buffer": "^1.1.4", - "vfile": "^2.0.0", - "x-is-function": "^1.0.4" + "is-buffer": "^2.0.0", + "vfile": "^4.0.0" } }, "trim": { @@ -3350,14 +1942,19 @@ "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" }, "trim-trailing-lines": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.1.tgz", - "integrity": "sha512-bWLv9BbWbbd7mlqqs2oQYnLD/U/ZqeJeJwbO0FG2zA1aTq+HTvxfHNKFa/HGCVyJpDiioUYaBhfiT6rgk+l4mg==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.2.tgz", + "integrity": "sha512-MUjYItdrqqj2zpcHFTkMa9WAv4JHTI6gnRQGPFLrt5L9a6tRMiDnIqYl8JBvu2d2Tc3lWJKQwlGCp0K8AvCM+Q==" }, "trough": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.3.tgz", - "integrity": "sha512-fwkLWH+DimvA4YCy+/nvJd61nWQQ2liO/nF/RjkTpiOGi+zxZzVkhb1mvbHIIW4b/8nDsYI8uTmAlc0nNkRMOw==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.4.tgz", + "integrity": "sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==" + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" }, "type-check": { "version": "0.3.2", @@ -3373,103 +1970,86 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "unherit": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.1.tgz", - "integrity": "sha512-+XZuV691Cn4zHsK0vkKYwBEwB74T3IZIcxrgn2E4rKwTfFyI1zCh7X7grwh9Re08fdPlarIdyWgI8aVB3F5A5g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.2.tgz", + "integrity": "sha512-W3tMnpaMG7ZY6xe/moK04U9fBhi6wEiCYHUW5Mop/wQHf12+79EQGwxYejNdhEz2mkqkBlGwm7pxmgBKMVUj0w==", "requires": { "inherits": "^2.0.1", "xtend": "^4.0.1" } }, "unified": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz", - "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==", + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/unified/-/unified-8.4.1.tgz", + "integrity": "sha512-YPj/uIIZSO7mMIZQj/5Z3hDl4lshWYRQGs5TgUCjHTVdklUWH+O94mK5Cy77SEcmEUwGhnUcudMuH/zIwporqw==", "requires": { "bail": "^1.0.0", "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", + "is-plain-obj": "^2.0.0", "trough": "^1.0.0", - "vfile": "^2.0.0", - "x-is-string": "^0.1.0" + "vfile": "^4.0.0" } }, "unified-args": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unified-args/-/unified-args-4.0.0.tgz", - "integrity": "sha1-jZubitNHvrN/QwVipixNNhtCIg8=", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/unified-args/-/unified-args-7.1.0.tgz", + "integrity": "sha512-soi9Rn7l5c1g0RfElSCHMwaxeiclSI0EsS3uZmMPUOfwMeeeZjLpNmHAowV9iSlQh59iiZhSMyQu9lB8WnIz5g==", "requires": { - "camelcase": "^4.0.0", + "camelcase": "^5.0.0", "chalk": "^2.0.0", - "chokidar": "^1.5.1", + "chokidar": "^3.0.0", + "fault": "^1.0.2", + "json5": "^2.0.0", "minimist": "^1.2.0", "text-table": "^0.2.0", - "unified-engine": "^4.0.0" + "unified-engine": "^7.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, "minimist": { "version": "1.2.0", "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } } } }, "unified-engine": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/unified-engine/-/unified-engine-4.0.1.tgz", - "integrity": "sha1-lpKql/1cTsNoiXeeElFL746GP8M=", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/unified-engine/-/unified-engine-7.0.0.tgz", + "integrity": "sha512-zH/MvcISpWg3JZtCoY/GYBw1WnVHkhnPoMBWpmuvAifCPSS9mzT9EbtimesJp6t2nnr/ojI0mg3TmkO1CjIwVA==", "requires": { - "concat-stream": "^1.5.1", - "debug": "^2.2.0", + "concat-stream": "^2.0.0", + "debug": "^4.0.0", "fault": "^1.0.0", + "figures": "^3.0.0", "fn-name": "^2.0.1", "glob": "^7.0.3", - "ignore": "^3.2.0", + "ignore": "^5.0.0", "is-empty": "^1.0.0", "is-hidden": "^1.0.1", "is-object": "^1.0.1", "js-yaml": "^3.6.1", "load-plugin": "^2.0.0", - "parse-json": "^2.2.0", - "to-vfile": "^2.0.0", + "parse-json": "^4.0.0", + "to-vfile": "^6.0.0", "trough": "^1.0.0", - "vfile-reporter": "^4.0.0", + "unist-util-inspect": "^4.1.2", + "vfile-reporter": "^6.0.0", "vfile-statistics": "^1.1.0", - "x-is-function": "^1.0.4", "x-is-string": "^0.1.0", "xtend": "^4.0.1" + }, + "dependencies": { + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==" + } } }, "unified-lint-rule": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-1.0.3.tgz", - "integrity": "sha512-6z+HH3mtlFdj/w3MaQpObrZAd9KRiro370GxBFh13qkV8LYR21lLozA4iQiZPhe7KuX/lHewoGOEgQ4AWrAR3Q==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-1.0.4.tgz", + "integrity": "sha512-q9wY6S+d38xRAuWQVOMjBQYi7zGyKkY23ciNafB8JFVmDroyKjtytXHCg94JnhBCXrNqpfojo3+8D+gmF4zxJQ==", "requires": { "wrapped": "^1.0.1" } @@ -3484,121 +2064,59 @@ "vfile-location": "^2.0.0" } }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "unist-util-generated": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.4.tgz", + "integrity": "sha512-SA7Sys3h3X4AlVnxHdvN/qYdr4R38HzihoEVY2Q2BZu8NHWDnw5OGcC/tXWjQfd4iG+M6qRFNIRGqJmp2ez4Ww==" + }, + "unist-util-inspect": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/unist-util-inspect/-/unist-util-inspect-4.1.4.tgz", + "integrity": "sha512-7xxyvKiZ1SC9vL5qrMqKub1T31gRHfau4242F69CcaOrXt//5PmRVOmDZ36UAEgiT+tZWzmQmbNZn+mVtnR9HQ==", "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "is-empty": "^1.0.0" } }, - "unist-util-generated": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.2.tgz", - "integrity": "sha512-1HcwiEO62dr0XWGT+abVK4f0aAm8Ik8N08c5nAYVmuSxfvpA9rCcNyX/le8xXj1pJK5nBrGlZefeWB6bN8Pstw==" - }, "unist-util-is": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.2.tgz", - "integrity": "sha512-YkXBK/H9raAmG7KXck+UUpnKiNmUdB+aBGrknfQ4EreE1banuzrKABx3jP6Z5Z3fMSPMQQmeXBlKpCbMwBkxVw==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" }, "unist-util-position": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.0.1.tgz", - "integrity": "sha512-05QfJDPI7PE1BIUtAxeSV+cDx21xP7+tUZgSval5CA7tr0pHBwybF7OnEa1dOFqg6BfYH/qiMUnWwWj+Frhlww==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.0.3.tgz", + "integrity": "sha512-28EpCBYFvnMeq9y/4w6pbnFmCUfzlsc41NJui5c51hOFjBA1fejcwc+5W4z2+0ECVbScG3dURS3JTVqwenzqZw==" }, "unist-util-remove-position": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.2.tgz", - "integrity": "sha512-XxoNOBvq1WXRKXxgnSYbtCF76TJrRoe5++pD4cCBsssSiWSnPEktyFrFLE8LTk3JW5mt9hB0Sk5zn4x/JeWY7Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.3.tgz", + "integrity": "sha512-CtszTlOjP2sBGYc2zcKA/CvNdTdEs3ozbiJ63IPBxh8iZg42SCCb8m04f8z2+V1aSk5a7BxbZKEdoDjadmBkWA==", "requires": { "unist-util-visit": "^1.1.0" } }, "unist-util-stringify-position": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", - "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.1.tgz", + "integrity": "sha512-Zqlf6+FRI39Bah8Q6ZnNGrEHUhwJOkHde2MHVk96lLyftfJJckaPslKgzhVcviXj8KcE9UJM9F+a4JEiBUTYgA==", + "requires": { + "@types/unist": "^2.0.2" + } }, "unist-util-visit": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.0.tgz", - "integrity": "sha512-FiGu34ziNsZA3ZUteZxSFaczIjGmksfSgdKqBfOejrrfzyUy5b7YrlzT1Bcvi+djkYDituJDy2XB7tGTeBieKw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", "requires": { "unist-util-visit-parents": "^2.0.0" } }, "unist-util-visit-parents": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.0.1.tgz", - "integrity": "sha512-6B0UTiMfdWql4cQ03gDTCSns+64Zkfo2OCbK31Ov0uMizEz+CJeAp0cgZVb5Fhmcd7Bct2iRNywejT0orpbqUA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", "requires": { - "unist-util-is": "^2.1.2" - } - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } + "unist-util-is": "^3.0.0" } }, "untildify": { @@ -3609,16 +2127,6 @@ "os-homedir": "^1.0.0" } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" - }, "user-home": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", @@ -3633,65 +2141,68 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "vfile": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", - "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.0.1.tgz", + "integrity": "sha512-lRHFCuC4SQBFr7Uq91oJDJxlnftoTLQ7eKIpMdubhYcVMho4781a8MWXLy3qZrZ0/STD1kRiKc0cQOHm4OkPeA==", "requires": { - "is-buffer": "^1.1.4", + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" } }, "vfile-location": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.3.tgz", - "integrity": "sha512-zM5/l4lfw1CBoPx3Jimxoc5RNDAHHpk6AM6LM0pTIkm5SUSsx8ZekZ0PVdf0WEZ7kjlhSt7ZlqbRL6Cd6dBs6A==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.5.tgz", + "integrity": "sha512-Pa1ey0OzYBkLPxPZI3d9E+S4BmvfVwNAAXrrqGbwTVXWaX2p9kM1zZ+n35UtVM06shmWKH4RPRN8KI80qE3wNQ==" }, "vfile-message": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.0.1.tgz", - "integrity": "sha512-vSGCkhNvJzO6VcWC6AlJW4NtYOVtS+RgCaqFIYUjoGIlHnFL+i0LbtYvonDWOMcB97uTPT4PRsyYY7REWC9vug==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.1.tgz", + "integrity": "sha512-KtasSV+uVU7RWhUn4Lw+wW1Zl/nW8JWx7JCPps10Y9JRRIDeDXf8wfBLoOSsJLyo27DqMyAi54C6Jf/d6Kr2Bw==", "requires": { - "unist-util-stringify-position": "^1.1.1" + "@types/unist": "^2.0.2", + "unist-util-stringify-position": "^2.0.0" } }, "vfile-reporter": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-4.0.0.tgz", - "integrity": "sha1-6m8K4TQvSEFXOYXgX5QXNvJ96do=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-6.0.0.tgz", + "integrity": "sha512-8Is0XxFxWJUhPJdOg3CyZTqd3ICCWg6r304PuBl818ZG91h4FMS3Q+lrOPS+cs5/DZK3H0+AkJdH0J8JEwKtDA==", "requires": { "repeat-string": "^1.5.0", - "string-width": "^1.0.0", - "supports-color": "^4.1.0", - "unist-util-stringify-position": "^1.0.0", + "string-width": "^4.0.0", + "supports-color": "^6.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-sort": "^2.1.2", "vfile-statistics": "^1.1.0" }, "dependencies": { - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" - }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "requires": { - "has-flag": "^2.0.0" + "has-flag": "^3.0.0" } } } }, - "vfile-statistics": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.1.tgz", - "integrity": "sha512-dxUM6IYvGChHuwMT3dseyU5BHprNRXzAV0OHx1A769lVGsTiT50kU7BbpRFV+IE6oWmU+PwHdsTKfXhnDIRIgQ==" + "vfile-sort": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-2.2.1.tgz", + "integrity": "sha512-5dt7xEhC44h0uRQKhbM2JAe0z/naHphIZlMOygtMBM9Nn0pZdaX5fshhwWit9wvsuP8t/wp43nTDRRErO1WK8g==" }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + "vfile-statistics": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.3.tgz", + "integrity": "sha512-CstaK/ebTz1W3Qp41Bt9Lj/2DmumFsCwC2sKahDNSPh0mPh7/UyMLCoU8ZBX34CRU0d61B4W41yIFsV0NKMZeA==" + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" }, "wrapped": { "version": "1.0.1", @@ -3700,13 +2211,6 @@ "requires": { "co": "3.1.0", "sliced": "^1.0.1" - }, - "dependencies": { - "co": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", - "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=" - } } }, "wrappy": { @@ -3722,20 +2226,15 @@ "mkdirp": "^0.5.1" } }, - "x-is-function": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/x-is-function/-/x-is-function-1.0.4.tgz", - "integrity": "sha1-XSlNw9Joy90GJYDgxd93o5HR+h4=" - }, "x-is-string": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=" }, "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" } } } diff --git a/package.json b/package.json index f1cffea..2ba05be 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,8 @@ "license": "ISC", "dependencies": { "eslint": "3.19.0", - "remark-cli": "^4.0.0", - "remark-preset-lint-recommended": "^3.0.1" + "remark-cli": "7.0.0", + "remark-preset-lint-recommended": "3.0.3" }, "remarkConfig": { "plugins": [ From 81a16680e49910e8f795b3d6313a2c73c87b87dc Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 9 Nov 2019 21:15:24 +0200 Subject: [PATCH 35/72] Ignore all .coverage files --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index aa9f6d1..68bbb03 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,7 @@ members/logs/* logs/ /media/ node_modules/ -/.coverage +.coverage db.sqlite3 requirements_henu.txt /collected_static/ From 31ebace4cd49d421eddbc81577c724bbec32b0b4 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 9 Nov 2019 21:43:46 +0200 Subject: [PATCH 36/72] Use context and other test fixes --- webapp/tests/test_event.py | 15 ++++--- webapp/tests/test_feed.py | 16 +++---- webapp/tests/test_tag.py | 91 ++++++++++++++++++++------------------ 3 files changed, 64 insertions(+), 58 deletions(-) diff --git a/webapp/tests/test_event.py b/webapp/tests/test_event.py index 36e374f..e09d2c3 100644 --- a/webapp/tests/test_event.py +++ b/webapp/tests/test_event.py @@ -1,8 +1,9 @@ from django.test import TestCase -from django.utils import timezone from django.contrib.auth.models import User -from rest_framework.test import APITestCase, APIRequestFactory, force_authenticate +from django.utils import timezone from rest_framework import status +from rest_framework.test import APITestCase, APIRequestFactory, force_authenticate + from webapp.models import Tag, Event from webapp.serializers import EventSerializer @@ -87,10 +88,12 @@ class EventTestCase(APITestCase): def test_get_single_event(self): response = self.client.get(f"/api/events/{self.testEventId}/", format="json") result = response.data - # Remove tags because of API call having also domain name added to icon URL - result.pop("tags") - serialized = EventSerializer(Event.objects.get(title="TestEvent1")).data - serialized.pop("tags") + serialized = EventSerializer( + Event.objects.get(title="TestEvent1"), + context={ + "request": APIRequestFactory().get(r"http://testserver/api/events/") + } + ).data self.assertEqual( result, serialized diff --git a/webapp/tests/test_feed.py b/webapp/tests/test_feed.py index 2a73d79..3710f07 100644 --- a/webapp/tests/test_feed.py +++ b/webapp/tests/test_feed.py @@ -1,8 +1,8 @@ from django.test import TestCase from django.contrib.auth.models import User -from rest_framework.test import APITestCase from rest_framework import status -from rest_framework.test import force_authenticate +from rest_framework.test import APITestCase, APIRequestFactory, force_authenticate + from webapp.models import Tag, Feed from webapp.serializers import FeedSerializer @@ -33,13 +33,11 @@ class FeedTestCase(APITestCase): self.assertTrue(status.is_success(response.status_code)) feeds = Feed.objects.all() - serializer = FeedSerializer(feeds, many=True) - - # DRF extends path given by serializer with the protocol and domain for icon - # Ignore tag on serializer and response. This is tested on TagTestCase. - # Note that we assume the length here to be 1 - response.data['results'][0].pop('tags') - serializer.data[0].pop('tags') + serializer = FeedSerializer( + feeds, many=True, + context={ + "request": APIRequestFactory().get(r"http://testserver/api/events/") + }) self.assertEqual(response.data['results'], serializer.data) def test_post_feed(self): diff --git a/webapp/tests/test_tag.py b/webapp/tests/test_tag.py index d8e2a4a..69f1165 100644 --- a/webapp/tests/test_tag.py +++ b/webapp/tests/test_tag.py @@ -1,6 +1,8 @@ from django.test import TestCase +from django.contrib.auth.models import User from rest_framework import status -from rest_framework.test import APITestCase +from rest_framework.test import APITestCase, APIRequestFactory, force_authenticate + from webapp.models import Tag from webapp.serializers import TagSerializer @@ -13,58 +15,61 @@ class TagsTestCase(APITestCase): def setUp(self): self.icon = tempfile.NamedTemporaryFile(suffix=".jpg").name - Tag.objects.create(slug='Party', name_fi='Bileet', name_en="Partytime", icon=self.icon) + self.tag_id = Tag.objects.create(slug='Party', name_fi='Bileet', name_en="Partytime", icon=self.icon).id + Tag.objects.create(slug='OFF', name_fi='Virallinen', name_en="Official", icon=self.icon) + self.assertEqual(Tag.objects.count(), 2) + + username, password = 'test_admin', 'password123' + self.authClient = User.objects.create_superuser(username, 'myemail@test.com', password) def test_get_single_tag(self): - self.assertEqual(Tag.objects.count(), 1) - response = self.client.get('/api/tags/', format='json') - self.assertTrue(status.is_success(response.status_code)) + response = self.client.get(f"/api/tags/{self.tag_id}/", format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) - # We dont care about icon, so response is sliced - sliced_response = OrderedDict(islice(response.data['results'][0].items(), 3)) - tag1 = Tag.objects.get(slug="Party") - self.assertEqual(sliced_response, {'id': tag1.id, 'slug': 'Party', 'name_fi': 'Bileet'}) - - def test_get_single_tag_serializer(self): - response = self.client.get('/api/tags/', format='json') - self.assertTrue(status.is_success(response.status_code)) - - tags = Tag.objects.all() - serializer = TagSerializer(tags, many=True) - # Icon on serializer is returned without protocol and domain - # Assert these individually - resp_icon = response.data['results'][0].pop('icon') - serial_icon = serializer.data[0].pop('icon') - self.assertEqual(response.data['results'], serializer.data) - self.assertEqual(resp_icon, "http://testserver" + serial_icon) + tags = Tag.objects.get(id=self.tag_id) + serializer = TagSerializer( + tags, context={ + "request": APIRequestFactory().get(r"http://testserver/api/events/") + }) + self.assertEqual(response.data, serializer.data) def test_get_multiple_tags(self): - self.assertEqual(Tag.objects.count(), 1) Tag.objects.create(slug='Freshmen', name_fi='Fuksit', icon=self.icon) Tag.objects.create(slug='International', name_fi='Ulkkarit', icon=self.icon) - self.assertEqual(Tag.objects.count(), 3) + self.assertEqual(Tag.objects.count(), 4) response = self.client.get('/api/tags/', format='json') - self.assertTrue(status.is_success(response.status_code)) + self.assertEqual(response.status_code, status.HTTP_200_OK) - # We dont care about icon, so response is sliced - tag1 = Tag.objects.get(slug="Party") - sliced_response = OrderedDict(islice(response.data['results'][0].items(), 3)) - self.assertEqual(sliced_response, {'id': tag1.id, 'slug': 'Party', 'name_fi': 'Bileet'}) - sliced_response = OrderedDict(islice(response.data['results'][1].items(), 3)) - tag2 = Tag.objects.get(slug="Freshmen") - self.assertEqual(sliced_response, {'id': tag2.id, 'slug': 'Freshmen', 'name_fi': 'Fuksit'}) - sliced_response = OrderedDict(islice(response.data['results'][2].items(), 3)) - tag3 = Tag.objects.get(slug="International") - self.assertEqual(sliced_response, {'id': tag3.id, 'slug': 'International', 'name_fi': 'Ulkkarit'}) + expected = TagSerializer( + Tag.objects.all(), many=True, + context={ + "request": APIRequestFactory().get(r"http://testserver/api/events/") + }).data - def test_create_tag(self): - self.assertEqual(Tag.objects.count(), 1) - response = self.client.post('/api/tags/', {'slug': 'Test', 'name_fi': 'Testinimi', 'icon': self.icon}, format='multipart') - self.assertFalse(status.is_success(response.status_code)) - self.assertEqual(Tag.objects.count(), 1) + self.assertEqual( + response.data['results'], + expected + ) - def test_invalid_tag(self): - self.assertEqual(Tag.objects.count(), 1) - response = self.client.get('/api/tags/15', format='json', follow=True) + def test_get_invalid_tag(self): + response = self.client.get('/api/tags/15/', format='json', follow=True) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + + # READ ONLY API! + def test_create_tag(self): + # Authenticate + self.client.force_authenticate(user=self.authClient) + response = self.client.post( + "/api/tags/", + { + "slug": "Test", + "name": "Testinimi", + "name_fi": "Testinimi", + "name_en": "Test name", + "icon": self.icon + }, + format='json' + ) + self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) + self.assertEqual(Tag.objects.count(), 2) From 80c8d9bc903d55b2d569b922a0c8ef27428179d6 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 9 Nov 2019 21:57:55 +0200 Subject: [PATCH 37/72] Fix inconsistency --- webapp/tests/test_event.py | 18 ++++++++++-------- webapp/tests/test_tag.py | 37 ++++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/webapp/tests/test_event.py b/webapp/tests/test_event.py index e09d2c3..9aa4ee6 100644 --- a/webapp/tests/test_event.py +++ b/webapp/tests/test_event.py @@ -72,8 +72,8 @@ class EventTestCase(APITestCase): # Get from API response = self.client.get("/api/events/", format="json") # Response 200 - self.assertTrue(status.is_success(response.status_code)) - # Response should not have old events + self.assertTrue(response.status_code, status.HTTP_200_OK) + # Response should not have old events and invisible self.assertEqual(len(response.data["results"]), 2) # Check that serialized data is equal to received response expected_events = EventSerializer( @@ -87,17 +87,19 @@ class EventTestCase(APITestCase): def test_get_single_event(self): response = self.client.get(f"/api/events/{self.testEventId}/", format="json") - result = response.data - serialized = EventSerializer( + self.assertEqual(response.status_code, status.HTTP_200_OK) + + serializer = EventSerializer( Event.objects.get(title="TestEvent1"), context={ "request": APIRequestFactory().get(r"http://testserver/api/events/") } - ).data - self.assertEqual( - result, - serialized ) + self.assertEqual(response.data, serializer.data) + + def test_get_invalid_event(self): + response = self.client.get("/api/events/15/", format="json") + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_post_event(self): pass diff --git a/webapp/tests/test_tag.py b/webapp/tests/test_tag.py index 69f1165..838ad5c 100644 --- a/webapp/tests/test_tag.py +++ b/webapp/tests/test_tag.py @@ -22,24 +22,9 @@ class TagsTestCase(APITestCase): username, password = 'test_admin', 'password123' self.authClient = User.objects.create_superuser(username, 'myemail@test.com', password) - def test_get_single_tag(self): - response = self.client.get(f"/api/tags/{self.tag_id}/", format='json') - self.assertEqual(response.status_code, status.HTTP_200_OK) - - tags = Tag.objects.get(id=self.tag_id) - serializer = TagSerializer( - tags, context={ - "request": APIRequestFactory().get(r"http://testserver/api/events/") - }) - self.assertEqual(response.data, serializer.data) - def test_get_multiple_tags(self): Tag.objects.create(slug='Freshmen', name_fi='Fuksit', icon=self.icon) Tag.objects.create(slug='International', name_fi='Ulkkarit', icon=self.icon) - self.assertEqual(Tag.objects.count(), 4) - - response = self.client.get('/api/tags/', format='json') - self.assertEqual(response.status_code, status.HTTP_200_OK) expected = TagSerializer( Tag.objects.all(), many=True, @@ -47,16 +32,31 @@ class TagsTestCase(APITestCase): "request": APIRequestFactory().get(r"http://testserver/api/events/") }).data + response = self.client.get('/api/tags/', format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data['results']), 4) + self.assertEqual( response.data['results'], expected ) + def test_get_single_tag(self): + response = self.client.get(f"/api/tags/{self.tag_id}/", format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + serializer = TagSerializer( + Tag.objects.get(id=self.tag_id), + context={ + "request": APIRequestFactory().get(r"http://testserver/api/events/") + }) + self.assertEqual(response.data, serializer.data) + def test_get_invalid_tag(self): - response = self.client.get('/api/tags/15/', format='json', follow=True) + response = self.client.get('/api/tags/15/', format='json') self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - # READ ONLY API! + # READ ONLY API! Modify result code and count def test_create_tag(self): # Authenticate self.client.force_authenticate(user=self.authClient) @@ -71,5 +71,8 @@ class TagsTestCase(APITestCase): }, format='json' ) + + # Method Not allowed! self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) + # Not created self.assertEqual(Tag.objects.count(), 2) From fe48a2a336df00fe3e6a3f94d8f2086af287030f Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 9 Nov 2019 22:18:19 +0200 Subject: [PATCH 38/72] Event POST test --- webapp/tests/test_event.py | 99 +++++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 18 deletions(-) diff --git a/webapp/tests/test_event.py b/webapp/tests/test_event.py index 9aa4ee6..76a02be 100644 --- a/webapp/tests/test_event.py +++ b/webapp/tests/test_event.py @@ -19,54 +19,67 @@ class EventTestCase(APITestCase): Tag.objects.create(slug="testtag2", name='test2', icon=self.icon) tag2 = Tag.objects.get(slug="testtag2") self.assertEqual(Tag.objects.count(), 2) + self.testTagId = Tag.objects.get(slug="testtag1").id # Visible and relevant Event.objects.create( - title="TestEvent1", + title_fi="Testitapahtuma1", + title_en="TestEvent1", visible=True, - description="diidadaapa", - content="lorem ipsum", + description_fi="diidadaapa", + description_en="diidadaapa EN", + content_fi="lorem ipsum", + content_en="lorem ipsum EN", start_time=timezone.datetime(2019, 11, 9, 12, 0, 0), end_time=timezone.datetime(2020, 11, 9, 13, 0, 0), location="Testimaa" ) # Invisible but relevant Event.objects.create( - title="TestEvent2", + title_fi="Testitapahtuma1", + title_en="TestEvent2", visible=False, - description="diidadaapa", - content="lorem ipsum", + description_fi="diidadaapa", + description_en="diidadaapa EN", + content_fi="lorem ipsum", + content_en="lorem ipsum EN", start_time=timezone.datetime(2018, 12, 9, 12, 0, 0), end_time=timezone.datetime(2020, 12, 9, 13, 0, 0), location="Testimaan kerhohuone" ) # Visible but unrelevant Event.objects.create( - title="TestEvent3", + title_fi="Testitapahtuma3", + title_en="TestEvent3", visible=True, - description="diidadaapa", - content="lorem ipsum", + description_fi="diidadaapa", + description_en="diidadaapa EN", + content_fi="lorem ipsum", + content_en="lorem ipsum EN", start_time=timezone.datetime(2018, 12, 9, 12, 0, 0), end_time=timezone.datetime(2018, 12, 9, 13, 0, 0), location="Testimaan kerhohuone" ) # Visible and relevant Event.objects.create( - title="TestEvent4", + title_fi="Testitapahtuma4", + title_en="TestEvent4", visible=True, - description="diidadaapa", - content="lorem ipsum", + description_fi="diidadaapa", + description_en="diidadaapa EN", + content_fi="lorem ipsum", + content_en="lorem ipsum EN", start_time=timezone.datetime(2018, 12, 9, 12, 0, 0), end_time=timezone.datetime(2020, 12, 9, 13, 0, 0), location="Testimaan kerhohuone" ) - Event.objects.get(title="TestEvent1").tags.add(tag1) - Event.objects.get(title="TestEvent2").tags.add(tag2) + Event.objects.get(title_en="TestEvent1").tags.add(tag1) + Event.objects.get(title_en="TestEvent2").tags.add(tag2) + self.testEventId = Event.objects.get(title_en="TestEvent1").id self.assertEqual(Event.objects.count(), 4) username, password = 'test_admin', 'password123' self.authClient = User.objects.create_superuser(username, 'myemail@test.com', password) - self.testEventId = Event.objects.get(title="TestEvent1").id def test_get_events(self): # Get from API @@ -77,7 +90,7 @@ class EventTestCase(APITestCase): self.assertEqual(len(response.data["results"]), 2) # Check that serialized data is equal to received response expected_events = EventSerializer( - Event.objects.filter(title__in=("TestEvent1", "TestEvent4")).order_by("start_time"), + Event.objects.filter(title_en__in=("TestEvent1", "TestEvent4")).order_by("start_time"), many=True, context={ "request": APIRequestFactory().get(r"http://testserver/api/events/") @@ -90,7 +103,7 @@ class EventTestCase(APITestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) serializer = EventSerializer( - Event.objects.get(title="TestEvent1"), + Event.objects.get(title_en="TestEvent1"), context={ "request": APIRequestFactory().get(r"http://testserver/api/events/") } @@ -102,10 +115,60 @@ class EventTestCase(APITestCase): self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_post_event(self): - pass + # Authenticate + self.client.force_authenticate(user=self.authClient) + response = self.client.post( + "/api/events/", + { + "tags": [self.testTagId], + "tag_id": [self.testTagId], + "visible": True, + "title": "POST Testi", + # "title_fi": "POST Testi", + # "title_en": "POST Test", + "description": "ABC", + # "description_fi": "ABC", + # "description_en": "CBA", + "content": "Benis", + # "content_fi": "Benis", + # "content_en": "Bensels :DDD", + "start_time": timezone.now(), + "end_time": timezone.now(), + "signup_id": [] + }, + format='json' + ) + + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(Event.objects.count(), 5) + + def test_post_event_unauth(self): + response = self.client.post( + "/api/events/", + { + "tags": "Test", + "visible": "Testinimi", + "title_fi": "Testinimi", + "title_en": "Test name", + "description_fi": self.icon, + "description_en": self.icon, + "content_fi": self.icon, + "content_en": self.icon, + }, + format='json' + ) + + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + self.assertEqual(Event.objects.count(), 4) def test_update_event(self): pass + def test_update_event_unauth(self): + pass + def test_delete_event(self): pass + + def test_delete_event_unauth(self): + pass From ff98f700f993dcb0372d11e6b4892a4089c5d450 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 9 Nov 2019 22:19:06 +0200 Subject: [PATCH 39/72] Event POST unauthorized test --- webapp/tests/test_event.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/webapp/tests/test_event.py b/webapp/tests/test_event.py index 76a02be..89a0f39 100644 --- a/webapp/tests/test_event.py +++ b/webapp/tests/test_event.py @@ -146,14 +146,21 @@ class EventTestCase(APITestCase): response = self.client.post( "/api/events/", { - "tags": "Test", - "visible": "Testinimi", - "title_fi": "Testinimi", - "title_en": "Test name", - "description_fi": self.icon, - "description_en": self.icon, - "content_fi": self.icon, - "content_en": self.icon, + "tags": [self.testTagId], + "tag_id": [self.testTagId], + "visible": True, + "title": "POST Testi", + # "title_fi": "POST Testi", + # "title_en": "POST Test", + "description": "ABC", + # "description_fi": "ABC", + # "description_en": "CBA", + "content": "Benis", + # "content_fi": "Benis", + # "content_en": "Bensels :DDD", + "start_time": timezone.now(), + "end_time": timezone.now(), + "signup_id": [] }, format='json' ) From b2e2ff6699217833dae6b3e6983d12babefdc843 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 9 Nov 2019 22:35:47 +0200 Subject: [PATCH 40/72] Tag test fixture --- webapp/tests/tag_fixture.py | 15 +++++++++++ webapp/tests/test_event.py | 15 ++++------- webapp/tests/test_feed.py | 54 ++++++++++++++++++------------------- webapp/tests/test_tag.py | 15 ++++++----- 4 files changed, 56 insertions(+), 43 deletions(-) create mode 100644 webapp/tests/tag_fixture.py diff --git a/webapp/tests/tag_fixture.py b/webapp/tests/tag_fixture.py new file mode 100644 index 0000000..3b0cff5 --- /dev/null +++ b/webapp/tests/tag_fixture.py @@ -0,0 +1,15 @@ +from webapp.models import Tag +import tempfile + + +def createTagIcon(): + return tempfile.NamedTemporaryFile(suffix=".jpg").name + + +def tagBuilder(slug="Tag1", icon=createTagIcon()): + return Tag.objects.create( + slug=slug, + name_fi=slug + " name_fi", + name_en=slug + " name_en", + icon=icon + ) diff --git a/webapp/tests/test_event.py b/webapp/tests/test_event.py index 89a0f39..40d05ec 100644 --- a/webapp/tests/test_event.py +++ b/webapp/tests/test_event.py @@ -4,22 +4,17 @@ from django.utils import timezone from rest_framework import status from rest_framework.test import APITestCase, APIRequestFactory, force_authenticate -from webapp.models import Tag, Event +from webapp.models import Event from webapp.serializers import EventSerializer - -import tempfile +from webapp.tests.tag_fixture import tagBuilder, createTagIcon class EventTestCase(APITestCase): def setUp(self): - self.icon = tempfile.NamedTemporaryFile(suffix=".jpg").name - Tag.objects.create(slug='testtag1', name='test1', icon=self.icon) - tag1 = Tag.objects.get(slug="testtag1") - Tag.objects.create(slug="testtag2", name='test2', icon=self.icon) - tag2 = Tag.objects.get(slug="testtag2") - self.assertEqual(Tag.objects.count(), 2) - self.testTagId = Tag.objects.get(slug="testtag1").id + tag1 = tagBuilder() + tag2 = tagBuilder("testtag2") + self.testTagId = tag1.id # Visible and relevant Event.objects.create( diff --git a/webapp/tests/test_feed.py b/webapp/tests/test_feed.py index 3710f07..1892d93 100644 --- a/webapp/tests/test_feed.py +++ b/webapp/tests/test_feed.py @@ -3,33 +3,28 @@ from django.contrib.auth.models import User from rest_framework import status from rest_framework.test import APITestCase, APIRequestFactory, force_authenticate -from webapp.models import Tag, Feed +from webapp.models import Feed from webapp.serializers import FeedSerializer - -import tempfile +from webapp.tests.tag_fixture import tagBuilder class FeedTestCase(APITestCase): def setUp(self): - self.icon = tempfile.NamedTemporaryFile(suffix=".jpg").name - Tag.objects.create(slug='testtag1', name='test1', icon=self.icon) - tag1 = Tag.objects.get(slug="testtag1") - Tag.objects.create(slug="testtag2", name='test2', icon=self.icon) - tag2 = Tag.objects.get(slug="testtag2") - self.assertEqual(Tag.objects.count(), 2) + tag1 = tagBuilder() + tag2 = tagBuilder("testtag2") - Feed.objects.create(title="TestFeed", visible=True, description="diidadaapa", content="lorem ipsum") - Feed.objects.get(title="TestFeed").tags.add(tag1) - Feed.objects.get(title="TestFeed").tags.add(tag2) + feed = Feed.objects.create(title="TestFeed", visible=True, description="diidadaapa", content="lorem ipsum") + feed.tags.add(tag1) + feed.tags.add(tag2) self.assertEqual(Feed.objects.count(), 1) self.assertEqual(Feed.objects.all()[0].tags.count(), 2) - username, password = 'test_admin', 'password123' - self.authClient = User.objects.create_superuser(username, 'myemail@test.com', password) + username, password = "test_admin", "password123" + self.authClient = User.objects.create_superuser(username, "myemail@test.com", password) def test_get_feed(self): - response = self.client.get('/api/feed/', format='json') + response = self.client.get("/api/feed/", format="json") self.assertTrue(status.is_success(response.status_code)) feeds = Feed.objects.all() @@ -38,26 +33,31 @@ class FeedTestCase(APITestCase): context={ "request": APIRequestFactory().get(r"http://testserver/api/events/") }) - self.assertEqual(response.data['results'], serializer.data) + self.assertEqual(response.data["results"], serializer.data) def test_post_feed(self): - Tag.objects.create(slug="test1", name="testsds") - Tag.objects.create(slug="test2", name="testsdsd") - tag1_id = Tag.objects.get(slug="test1").id - tag2_id = Tag.objects.get(slug="test2").id + tag1_id = tagBuilder("test1").id + tag2_id = tagBuilder("test2").id - data = {'tags': [tag1_id, tag2_id], 'title_fi': 'testtitle', 'title_en': 'testtitle', 'visible': 'True', 'description_fi': 'liirumlaarum', 'description_en': 'liirumlaarum', 'content_fi': 'lorem ipsum', 'content_en': 'lorem ipsum'} + data = { + "tag_id": [tag1_id, tag2_id], + "title_fi": "testtitle", + "title_en": "testtitle", + "visible": "True", + "description_fi": "liirumlaarum", "description_en": "liirumlaarum", + "content_fi": "lorem ipsum", + "content_en": "lorem ipsum" + } # Try post without authentication - response = self.client.post('/api/feed/', data, format='multipart') - self.assertTrue(status.is_client_error(response.status_code)) + response = self.client.post("/api/feed/", data, format="multipart") + self.assertTrue(response.status_code, status.HTTP_401_UNAUTHORIZED) self.assertEqual(Feed.objects.count(), 1) # Authenticate self.client.force_authenticate(user=self.authClient) - response = self.client.post('/api/feed/', data, format='multipart') + response = self.client.post("/api/feed/", data, format="multipart") # Return success and check object was created - self.assertTrue(status.is_success(response.status_code)) + self.assertTrue(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Feed.objects.count(), 2) created = Feed.objects.get(title_fi="testtitle") - print(created.tags) - # self.assertEqual(created.tags.count(), 2) + self.assertEqual(created.tags.count(), 2) diff --git a/webapp/tests/test_tag.py b/webapp/tests/test_tag.py index 838ad5c..a292bc3 100644 --- a/webapp/tests/test_tag.py +++ b/webapp/tests/test_tag.py @@ -8,23 +8,26 @@ from webapp.serializers import TagSerializer from collections import OrderedDict from itertools import islice -import tempfile + +from webapp.tests.tag_fixture import tagBuilder, createTagIcon class TagsTestCase(APITestCase): def setUp(self): - self.icon = tempfile.NamedTemporaryFile(suffix=".jpg").name - self.tag_id = Tag.objects.create(slug='Party', name_fi='Bileet', name_en="Partytime", icon=self.icon).id - Tag.objects.create(slug='OFF', name_fi='Virallinen', name_en="Official", icon=self.icon) + self.icon = createTagIcon() + tag = tagBuilder("Party", icon=self.icon) + self.tag_id = tag.id + + tagBuilder("Off") self.assertEqual(Tag.objects.count(), 2) username, password = 'test_admin', 'password123' self.authClient = User.objects.create_superuser(username, 'myemail@test.com', password) def test_get_multiple_tags(self): - Tag.objects.create(slug='Freshmen', name_fi='Fuksit', icon=self.icon) - Tag.objects.create(slug='International', name_fi='Ulkkarit', icon=self.icon) + tagBuilder("Fuksi") + tagBuilder("Inter") expected = TagSerializer( Tag.objects.all(), many=True, From 8c4b997f0fae9f82b4872a1551bb63adf9810b13 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 9 Nov 2019 23:13:56 +0200 Subject: [PATCH 41/72] Event test fixture --- webapp/tests/event_fixture.py | 37 ++++++++++++ webapp/tests/test_event.py | 110 ++++++++-------------------------- 2 files changed, 62 insertions(+), 85 deletions(-) create mode 100644 webapp/tests/event_fixture.py diff --git a/webapp/tests/event_fixture.py b/webapp/tests/event_fixture.py new file mode 100644 index 0000000..6a54476 --- /dev/null +++ b/webapp/tests/event_fixture.py @@ -0,0 +1,37 @@ +from django.utils import timezone +from webapp.models import Event + + +def createEventObject(name="Testitapahtuma1", visible=True, start_time=timezone.now(), end_time=timezone.now(), tag_id=[], signup_id=[]): + return Event.objects.create( + title_fi=name, + title_en=f"title_en {name}", + visible=visible, + description_fi=f"desc_fi {name}", + description_en=f"desc_en {name}", + content_fi=f"content_fi {name}", + content_en=f"content_en {name}", + start_time=start_time, + end_time=end_time, + location=f"loc {name}" + ) + + +def createEventJSON(name="POST1", visible=True, start_time=timezone.now(), end_time=timezone.now(), tag_id=[], signup_id=[]): + return { + "tags": tag_id, + "tag_id": tag_id, + "visible": visible, + "title": f"title_fi {name}", + # "title_fi": f"title_fi {name}",, + # "title_en": f"title_en {name}",, + "description": f"desc_fi {name}", + # "description_fi": f"desc_fi {name}", + # "description_en": f"desc_en {name}", + "content": f"content_fi {name}", + # "content_fi": f"content_fi {name}", + # "content_en": f"content_en {name}", + "start_time": start_time, + "end_time": end_time, + "signup_id": signup_id + } diff --git a/webapp/tests/test_event.py b/webapp/tests/test_event.py index 40d05ec..ccb23eb 100644 --- a/webapp/tests/test_event.py +++ b/webapp/tests/test_event.py @@ -7,6 +7,7 @@ from rest_framework.test import APITestCase, APIRequestFactory, force_authentica from webapp.models import Event from webapp.serializers import EventSerializer from webapp.tests.tag_fixture import tagBuilder, createTagIcon +from webapp.tests.event_fixture import createEventObject, createEventJSON class EventTestCase(APITestCase): @@ -17,64 +18,35 @@ class EventTestCase(APITestCase): self.testTagId = tag1.id # Visible and relevant - Event.objects.create( - title_fi="Testitapahtuma1", - title_en="TestEvent1", - visible=True, - description_fi="diidadaapa", - description_en="diidadaapa EN", - content_fi="lorem ipsum", - content_en="lorem ipsum EN", + test1 = createEventObject( + "Testitapahtuma1", start_time=timezone.datetime(2019, 11, 9, 12, 0, 0), - end_time=timezone.datetime(2020, 11, 9, 13, 0, 0), - location="Testimaa" - ) + end_time=timezone.datetime(2020, 11, 9, 13, 0, 0)) # Invisible but relevant - Event.objects.create( - title_fi="Testitapahtuma1", - title_en="TestEvent2", + createEventObject( + "Testitapahtuma2", visible=False, - description_fi="diidadaapa", - description_en="diidadaapa EN", - content_fi="lorem ipsum", - content_en="lorem ipsum EN", - start_time=timezone.datetime(2018, 12, 9, 12, 0, 0), - end_time=timezone.datetime(2020, 12, 9, 13, 0, 0), - location="Testimaan kerhohuone" - ) + start_time=timezone.datetime(2018, 11, 9, 12, 0, 0), + end_time=timezone.datetime(2020, 11, 9, 13, 0, 0)) # Visible but unrelevant - Event.objects.create( - title_fi="Testitapahtuma3", - title_en="TestEvent3", + test2 = createEventObject( + "Testitapahtuma3", visible=True, - description_fi="diidadaapa", - description_en="diidadaapa EN", - content_fi="lorem ipsum", - content_en="lorem ipsum EN", start_time=timezone.datetime(2018, 12, 9, 12, 0, 0), - end_time=timezone.datetime(2018, 12, 9, 13, 0, 0), - location="Testimaan kerhohuone" - ) + end_time=timezone.datetime(2018, 12, 9, 13, 0, 0)) # Visible and relevant - Event.objects.create( - title_fi="Testitapahtuma4", - title_en="TestEvent4", + createEventObject( + "Testitapahtuma4", visible=True, - description_fi="diidadaapa", - description_en="diidadaapa EN", - content_fi="lorem ipsum", - content_en="lorem ipsum EN", start_time=timezone.datetime(2018, 12, 9, 12, 0, 0), - end_time=timezone.datetime(2020, 12, 9, 13, 0, 0), - location="Testimaan kerhohuone" - ) - Event.objects.get(title_en="TestEvent1").tags.add(tag1) - Event.objects.get(title_en="TestEvent2").tags.add(tag2) - self.testEventId = Event.objects.get(title_en="TestEvent1").id + end_time=timezone.datetime(2020, 12, 9, 13, 0, 0)) + test1.tags.add(tag1) + test2.tags.add(tag2) + self.testEventId = test1.id self.assertEqual(Event.objects.count(), 4) - username, password = 'test_admin', 'password123' - self.authClient = User.objects.create_superuser(username, 'myemail@test.com', password) + username, password = "test_admin", "password123" + self.authClient = User.objects.create_superuser(username, "myemail@test.com", password) def test_get_events(self): # Get from API @@ -85,7 +57,7 @@ class EventTestCase(APITestCase): self.assertEqual(len(response.data["results"]), 2) # Check that serialized data is equal to received response expected_events = EventSerializer( - Event.objects.filter(title_en__in=("TestEvent1", "TestEvent4")).order_by("start_time"), + Event.objects.filter(title_fi__in=("Testitapahtuma1", "Testitapahtuma4")).order_by("start_time"), many=True, context={ "request": APIRequestFactory().get(r"http://testserver/api/events/") @@ -98,7 +70,7 @@ class EventTestCase(APITestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) serializer = EventSerializer( - Event.objects.get(title_en="TestEvent1"), + Event.objects.get(title_fi="Testitapahtuma1"), context={ "request": APIRequestFactory().get(r"http://testserver/api/events/") } @@ -114,24 +86,8 @@ class EventTestCase(APITestCase): self.client.force_authenticate(user=self.authClient) response = self.client.post( "/api/events/", - { - "tags": [self.testTagId], - "tag_id": [self.testTagId], - "visible": True, - "title": "POST Testi", - # "title_fi": "POST Testi", - # "title_en": "POST Test", - "description": "ABC", - # "description_fi": "ABC", - # "description_en": "CBA", - "content": "Benis", - # "content_fi": "Benis", - # "content_en": "Bensels :DDD", - "start_time": timezone.now(), - "end_time": timezone.now(), - "signup_id": [] - }, - format='json' + createEventJSON(tag_id=[self.testTagId]), + format="json" ) self.assertEqual(response.status_code, status.HTTP_201_CREATED) @@ -140,24 +96,8 @@ class EventTestCase(APITestCase): def test_post_event_unauth(self): response = self.client.post( "/api/events/", - { - "tags": [self.testTagId], - "tag_id": [self.testTagId], - "visible": True, - "title": "POST Testi", - # "title_fi": "POST Testi", - # "title_en": "POST Test", - "description": "ABC", - # "description_fi": "ABC", - # "description_en": "CBA", - "content": "Benis", - # "content_fi": "Benis", - # "content_en": "Bensels :DDD", - "start_time": timezone.now(), - "end_time": timezone.now(), - "signup_id": [] - }, - format='json' + createEventJSON(tag_id=[self.testTagId]), + format="json" ) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) From 59f47dec2601ab2c5d620dd35a3bb3832f7b95c7 Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Sat, 9 Nov 2019 23:51:04 +0200 Subject: [PATCH 42/72] Update signup serializer for use with form ids --- webapp/serializers.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/webapp/serializers.py b/webapp/serializers.py index 9ea9456..2250a8d 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -49,9 +49,15 @@ class EventSerializer(serializers.HyperlinkedModelSerializer): class SignupSerializer(serializers.ModelSerializer): + signupForm = SignupFormSerializer(read_only=True, required=False) + signupForm_id = serializers.PrimaryKeyRelatedField( + source="signupForm", + queryset=SignupForm.objects.all() + ) + class Meta: model = Signup - fields = ('id', 'signupForm', 'answer') + fields = ('id', 'signupForm', 'signupForm_id', 'answer') extra_kwargs = { 'url': { 'view_name': 'signup-detail', From 00de36ca446e6b1c4733975661eb1d30f2a0290a Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 9 Nov 2019 23:58:21 +0200 Subject: [PATCH 43/72] Event CRUD tests --- webapp/tests/event_fixture.py | 18 ++++++------- webapp/tests/test_event.py | 48 +++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/webapp/tests/event_fixture.py b/webapp/tests/event_fixture.py index 6a54476..ac5b138 100644 --- a/webapp/tests/event_fixture.py +++ b/webapp/tests/event_fixture.py @@ -22,16 +22,14 @@ def createEventJSON(name="POST1", visible=True, start_time=timezone.now(), end_t "tags": tag_id, "tag_id": tag_id, "visible": visible, - "title": f"title_fi {name}", - # "title_fi": f"title_fi {name}",, - # "title_en": f"title_en {name}",, - "description": f"desc_fi {name}", - # "description_fi": f"desc_fi {name}", - # "description_en": f"desc_en {name}", - "content": f"content_fi {name}", - # "content_fi": f"content_fi {name}", - # "content_en": f"content_en {name}", + "title_fi": f"title_fi {name}", + "title_en": f"title_en {name}", + "description_fi": f"desc_fi {name}", + "description_en": f"desc_en {name}", + "content_fi": f"content_fi {name}", + "content_en": f"content_en {name}", "start_time": start_time, "end_time": end_time, - "signup_id": signup_id + "signup_id": signup_id, + "location": f"loc {name}" } diff --git a/webapp/tests/test_event.py b/webapp/tests/test_event.py index ccb23eb..d51763a 100644 --- a/webapp/tests/test_event.py +++ b/webapp/tests/test_event.py @@ -13,10 +13,6 @@ from webapp.tests.event_fixture import createEventObject, createEventJSON class EventTestCase(APITestCase): def setUp(self): - tag1 = tagBuilder() - tag2 = tagBuilder("testtag2") - self.testTagId = tag1.id - # Visible and relevant test1 = createEventObject( "Testitapahtuma1", @@ -40,6 +36,11 @@ class EventTestCase(APITestCase): visible=True, start_time=timezone.datetime(2018, 12, 9, 12, 0, 0), end_time=timezone.datetime(2020, 12, 9, 13, 0, 0)) + + # Add some tags + tag1 = tagBuilder() + tag2 = tagBuilder("testtag2") + self.testTagId = tag1.id test1.tags.add(tag1) test2.tags.add(tag2) self.testEventId = test1.id @@ -78,7 +79,7 @@ class EventTestCase(APITestCase): self.assertEqual(response.data, serializer.data) def test_get_invalid_event(self): - response = self.client.get("/api/events/15/", format="json") + response = self.client.get("/api/events/200/", format="json") self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_post_event(self): @@ -104,13 +105,40 @@ class EventTestCase(APITestCase): self.assertEqual(Event.objects.count(), 4) def test_update_event(self): - pass + # Authenticate + self.client.force_authenticate(user=self.authClient) + event = Event.objects.get(id=self.testEventId) + new = createEventJSON(name="Update1") + response = self.client.put( + f"/api/events/{self.testEventId}/", + new, + format="json" + ) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + event = Event.objects.get(id=self.testEventId) + self.assertEqual(event.title_fi, "title_fi Update1") + self.assertEqual(Event.objects.count(), 4) def test_update_event_unauth(self): - pass + response = self.client.put( + f"/api/events/{self.testEventId}/", + createEventJSON(name="Update1"), + format="json" + ) + + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + event = Event.objects.get(id=self.testEventId) + self.assertEqual(event.title_fi, "Testitapahtuma1") + self.assertEqual(Event.objects.count(), 4) def test_delete_event(self): - pass + response = self.client.delete(f"/api/events/{self.testEventId}/",) + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + self.assertEqual(Event.objects.count(), 4) - def test_delete_event_unauth(self): - pass + # Authenticate + self.client.force_authenticate(user=self.authClient) + response = self.client.delete(f"/api/events/{self.testEventId}/") + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + self.assertEqual(Event.objects.count(), 3) From f4b55b7863118d16f63365c91a8546e2a8503310 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 01:20:14 +0200 Subject: [PATCH 44/72] Use month_from_now utility function in tests --- webapp/tests/event_fixture.py | 5 +++-- webapp/tests/test_event.py | 10 +++------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/webapp/tests/event_fixture.py b/webapp/tests/event_fixture.py index ac5b138..e3aa8cc 100644 --- a/webapp/tests/event_fixture.py +++ b/webapp/tests/event_fixture.py @@ -1,8 +1,9 @@ from django.utils import timezone from webapp.models import Event +from webapp.utils import month_from_now -def createEventObject(name="Testitapahtuma1", visible=True, start_time=timezone.now(), end_time=timezone.now(), tag_id=[], signup_id=[]): +def createEventObject(name="Testitapahtuma1", visible=True, start_time=timezone.now(), end_time=month_from_now(), tag_id=[], signup_id=[]): return Event.objects.create( title_fi=name, title_en=f"title_en {name}", @@ -17,7 +18,7 @@ def createEventObject(name="Testitapahtuma1", visible=True, start_time=timezone. ) -def createEventJSON(name="POST1", visible=True, start_time=timezone.now(), end_time=timezone.now(), tag_id=[], signup_id=[]): +def createEventJSON(name="POST1", visible=True, start_time=timezone.now(), end_time=month_from_now(), tag_id=[], signup_id=[]): return { "tags": tag_id, "tag_id": tag_id, diff --git a/webapp/tests/test_event.py b/webapp/tests/test_event.py index d51763a..a64aa91 100644 --- a/webapp/tests/test_event.py +++ b/webapp/tests/test_event.py @@ -16,14 +16,12 @@ class EventTestCase(APITestCase): # Visible and relevant test1 = createEventObject( "Testitapahtuma1", - start_time=timezone.datetime(2019, 11, 9, 12, 0, 0), - end_time=timezone.datetime(2020, 11, 9, 13, 0, 0)) + start_time=timezone.datetime(2019, 11, 9, 12, 0, 0)) # Invisible but relevant createEventObject( "Testitapahtuma2", visible=False, - start_time=timezone.datetime(2018, 11, 9, 12, 0, 0), - end_time=timezone.datetime(2020, 11, 9, 13, 0, 0)) + start_time=timezone.datetime(2018, 11, 9, 12, 0, 0)) # Visible but unrelevant test2 = createEventObject( "Testitapahtuma3", @@ -34,9 +32,7 @@ class EventTestCase(APITestCase): createEventObject( "Testitapahtuma4", visible=True, - start_time=timezone.datetime(2018, 12, 9, 12, 0, 0), - end_time=timezone.datetime(2020, 12, 9, 13, 0, 0)) - + start_time=timezone.datetime(2018, 12, 9, 12, 0, 0)) # Add some tags tag1 = tagBuilder() tag2 = tagBuilder("testtag2") From 0f50daf2891fbfc81be701c696fd9cc2d7f97f30 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 01:20:31 +0200 Subject: [PATCH 45/72] Singup get tests --- webapp/tests/test_signup.py | 90 +++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 9 deletions(-) diff --git a/webapp/tests/test_signup.py b/webapp/tests/test_signup.py index 82f671a..f1ab80d 100644 --- a/webapp/tests/test_signup.py +++ b/webapp/tests/test_signup.py @@ -1,16 +1,88 @@ from django.test import TestCase -from django.core.files import File from django.contrib.auth.models import User -from rest_framework.test import APITestCase +from django.utils import timezone from rest_framework import status -from rest_framework.test import force_authenticate -from webapp.models import Tag, Feed -from webapp.serializers import TagSerializer, FeedSerializer +from rest_framework.test import APITestCase, APIRequestFactory, force_authenticate -from collections import OrderedDict -from itertools import islice -import tempfile +from webapp.models import Signup, SignupForm +from webapp.serializers import SignupSerializer, SignupFormSerializer +from webapp.tests.event_fixture import createEventObject, createEventJSON +from webapp.utils import month_from_now +import json + +URL = "/api/signup/" + +ALL_QUESTION_TYPES = json.dumps([ + +]) + + +def createSignupForm(name="Form1", start_time=timezone.now(), end_time=month_from_now(), questions=ALL_QUESTION_TYPES, visible=True): + return SignupForm.objects.create( + title=name, + start_time=start_time, + end_time=end_time, + questions=questions, + visible=visible + ) + + +def createSignup(form, answer): + return Signup.objects.create( + signupForm=form, + answer=answer + ) class SignupTestCase(APITestCase): - pass + + def setUp(self): + self.signupForm = createSignupForm() + self.event = createEventObject(signup_id=self.signupForm.id) + + self.signup1 = createSignup(self.signupForm, json.dumps([])) + self.signup2 = createSignup(self.signupForm, json.dumps([])) + + username, password = "test_admin", "password123" + self.authClient = User.objects.create_superuser(username, "myemail@test.com", password) + + def test_get_signups(self): + expected = SignupSerializer( + self.signupForm.signup_set.all(), + many=True + ) + + print(expected.data) + + # Unauthorized + response = self.client.get(URL, format="json") + self.assertTrue(response.status_code, status.HTTP_401_UNAUTHORIZED) + # Authenticate + self.client.force_authenticate(user=self.authClient) + response = self.client.get(URL, format="json") + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data["results"], expected.data) + + def test_get_single_signup(self): + id = self.signup1.id + expected = SignupSerializer( + Signup.objects.get(id=id) + ) + + # Unauthorized + response = self.client.get(f"{URL}{id}/", format="json") + self.assertTrue(response.status_code, status.HTTP_401_UNAUTHORIZED) + # Authenticate + self.client.force_authenticate(user=self.authClient) + response = self.client.get(f"{URL}{id}/", format="json") + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data, expected.data) + + def test_create_signup(self): + pass + + def test_update_signup(self): + pass + + def test_delete_signup(self): + pass From edb6d73c063b16b2a297cdf7c32dd91c2eb0d46c Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 01:36:08 +0200 Subject: [PATCH 46/72] Add signup create test skeleton --- webapp/tests/test_signup.py | 40 ++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/webapp/tests/test_signup.py b/webapp/tests/test_signup.py index f1ab80d..5a8fcf4 100644 --- a/webapp/tests/test_signup.py +++ b/webapp/tests/test_signup.py @@ -27,21 +27,29 @@ def createSignupForm(name="Form1", start_time=timezone.now(), end_time=month_fro ) -def createSignup(form, answer): +def createSignupObject(form, answer): return Signup.objects.create( signupForm=form, answer=answer ) +def createSignupJSON(form_id, answer): + return { + "signupForm": form_id, + "answer": answer + } + + class SignupTestCase(APITestCase): def setUp(self): self.signupForm = createSignupForm() - self.event = createEventObject(signup_id=self.signupForm.id) + self.hiddenForm = createSignupForm(visible=False) + # self.event = createEventObject(signup_id=self.signupForm.id) - self.signup1 = createSignup(self.signupForm, json.dumps([])) - self.signup2 = createSignup(self.signupForm, json.dumps([])) + self.signup1 = createSignupObject(self.signupForm, json.dumps([])) + self.signup2 = createSignupObject(self.signupForm, json.dumps([])) username, password = "test_admin", "password123" self.authClient = User.objects.create_superuser(username, "myemail@test.com", password) @@ -52,8 +60,6 @@ class SignupTestCase(APITestCase): many=True ) - print(expected.data) - # Unauthorized response = self.client.get(URL, format="json") self.assertTrue(response.status_code, status.HTTP_401_UNAUTHORIZED) @@ -79,10 +85,30 @@ class SignupTestCase(APITestCase): self.assertEqual(response.data, expected.data) def test_create_signup(self): - pass + new = createSignupJSON(self.signup1.id, "[]") + response = self.client.post(URL, format="json") + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(Signup.objects.count(), 3) + + def test_create_signup_404_or_hidden(self): + new = createSignupJSON(3001, "[]") + response = self.client.post(URL, format="json") + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + self.assertEqual(Signup.objects.count(), 2) + + new = createSignupJSON(self.hiddenForm, "[]") + response = self.client.post(URL, format="json") + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + self.assertEqual(Signup.objects.count(), 2) def test_update_signup(self): pass + def test_update_signup_token(self): + pass + def test_delete_signup(self): pass + + def test_delete_signup_token(self): + pass From a7728e50ddd96138f4ac5f3d2424323690596604 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 01:39:01 +0200 Subject: [PATCH 47/72] Skeleton clean and small comment --- webapp/tests/test_signup.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/webapp/tests/test_signup.py b/webapp/tests/test_signup.py index 5a8fcf4..79b8c5a 100644 --- a/webapp/tests/test_signup.py +++ b/webapp/tests/test_signup.py @@ -101,14 +101,11 @@ class SignupTestCase(APITestCase): self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual(Signup.objects.count(), 2) - def test_update_signup(self): - pass + # Update and Delete are available for super admin (Django Admin) + # and to the user that signed up (uid token) def test_update_signup_token(self): pass - def test_delete_signup(self): - pass - def test_delete_signup_token(self): pass From 01161db33bddb7b1d855187ad4f8795b124f4aa5 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 01:58:15 +0200 Subject: [PATCH 48/72] Test since query parameter --- webapp/tests/test_event.py | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/webapp/tests/test_event.py b/webapp/tests/test_event.py index a64aa91..1827b02 100644 --- a/webapp/tests/test_event.py +++ b/webapp/tests/test_event.py @@ -9,6 +9,8 @@ from webapp.serializers import EventSerializer from webapp.tests.tag_fixture import tagBuilder, createTagIcon from webapp.tests.event_fixture import createEventObject, createEventJSON +URL = "/api/events/" + class EventTestCase(APITestCase): @@ -45,9 +47,9 @@ class EventTestCase(APITestCase): username, password = "test_admin", "password123" self.authClient = User.objects.create_superuser(username, "myemail@test.com", password) - def test_get_events(self): + def test_get_current_events(self): # Get from API - response = self.client.get("/api/events/", format="json") + response = self.client.get(URL, format="json") # Response 200 self.assertTrue(response.status_code, status.HTTP_200_OK) # Response should not have old events and invisible @@ -62,8 +64,22 @@ class EventTestCase(APITestCase): ) self.assertEqual(response.data["results"], expected_events.data) + def test_get_events_since(self): + response = self.client.get(f"{URL}?since=2018-01-01", format="json") + self.assertTrue(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["results"]), 3) + + expected_events = EventSerializer( + Event.objects.filter(title_fi__in=("Testitapahtuma1", "Testitapahtuma3", "Testitapahtuma4")).order_by("start_time"), + many=True, + context={ + "request": APIRequestFactory().get(r"http://testserver/api/events/") + } + ) + self.assertEqual(response.data["results"], expected_events.data) + def test_get_single_event(self): - response = self.client.get(f"/api/events/{self.testEventId}/", format="json") + response = self.client.get(f"{URL}{self.testEventId}/", format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) serializer = EventSerializer( @@ -75,14 +91,14 @@ class EventTestCase(APITestCase): self.assertEqual(response.data, serializer.data) def test_get_invalid_event(self): - response = self.client.get("/api/events/200/", format="json") + response = self.client.get("{URL}200/", format="json") self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_post_event(self): # Authenticate self.client.force_authenticate(user=self.authClient) response = self.client.post( - "/api/events/", + URL, createEventJSON(tag_id=[self.testTagId]), format="json" ) @@ -92,7 +108,7 @@ class EventTestCase(APITestCase): def test_post_event_unauth(self): response = self.client.post( - "/api/events/", + URL, createEventJSON(tag_id=[self.testTagId]), format="json" ) @@ -106,7 +122,7 @@ class EventTestCase(APITestCase): event = Event.objects.get(id=self.testEventId) new = createEventJSON(name="Update1") response = self.client.put( - f"/api/events/{self.testEventId}/", + f"{URL}{self.testEventId}/", new, format="json" ) @@ -118,7 +134,7 @@ class EventTestCase(APITestCase): def test_update_event_unauth(self): response = self.client.put( - f"/api/events/{self.testEventId}/", + f"{URL}{self.testEventId}/", createEventJSON(name="Update1"), format="json" ) @@ -129,12 +145,12 @@ class EventTestCase(APITestCase): self.assertEqual(Event.objects.count(), 4) def test_delete_event(self): - response = self.client.delete(f"/api/events/{self.testEventId}/",) + response = self.client.delete(f"{URL}{self.testEventId}/",) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) self.assertEqual(Event.objects.count(), 4) # Authenticate self.client.force_authenticate(user=self.authClient) - response = self.client.delete(f"/api/events/{self.testEventId}/") + response = self.client.delete(f"{URL}{self.testEventId}/") self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(Event.objects.count(), 3) From ff9cad1f475df9b4e35d7025703267d32fd035ab Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 01:58:32 +0200 Subject: [PATCH 49/72] Minor clean up --- webapp/tests/test_tag.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/webapp/tests/test_tag.py b/webapp/tests/test_tag.py index a292bc3..406ea2a 100644 --- a/webapp/tests/test_tag.py +++ b/webapp/tests/test_tag.py @@ -6,8 +6,6 @@ from rest_framework.test import APITestCase, APIRequestFactory, force_authentica from webapp.models import Tag from webapp.serializers import TagSerializer -from collections import OrderedDict -from itertools import islice from webapp.tests.tag_fixture import tagBuilder, createTagIcon From 4859daf0b35b8c3329a95b333c9921c54189a699 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 02:00:45 +0200 Subject: [PATCH 50/72] Clean old codebase from views.py --- webapp/views.py | 56 ------------------------------------------------- 1 file changed, 56 deletions(-) diff --git a/webapp/views.py b/webapp/views.py index ae8c0d9..57e1d68 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -132,14 +132,6 @@ class TagsViewSet(viewsets.ReadOnlyModelViewSet): permission_classes = [IsAuthenticatedOrReadOnly] -# -- OLD CODEBASE -- # - -@require_http_methods(["GET"]) -def main_index(request, *args, **kwargs): - """Render main page.""" - return render(request, "index.html", {}) - - @require_http_methods(["GET"]) def about_view(request, *args, **kwargs): """Render about page.""" @@ -160,51 +152,3 @@ def about_view(request, *args, **kwargs): 'tag': latest_tag } return render(request, "about.html", context) - - -@require_http_methods(["GET"]) -def guild_view(request, *args, **kwargs): - """Render "Guild" page.""" - return render(request, "guild.html", {}) - - -@require_http_methods(["GET"]) -def freshmen_view(request, *args, **kwargs): - """Render "Freshmen" page.""" - return render(request, "freshmen.html", {}) - - -@require_http_methods(["GET"]) -def jobs_view(request, *args, **kwargs): - """Render "Jobs" page.""" - return render(request, "jobs.html", {}) - - -@require_http_methods(["GET"]) -def event_calendar_view(request, *args, **kwargs): - """Render "Event calendar" page.""" - return render(request, "event_calendar.html", {}) - - -@require_http_methods(["GET"]) -def international_view(request, *args, **kwargs): - """Render "International" page.""" - return render(request, "international.html", {}) - - -@require_http_methods(["GET"]) -def sosso_view(request, *args, **kwargs): - """Render "Sössö" page.""" - return render(request, "sosso.html", {}) - - -@require_http_methods(["GET"]) -def contact_view(request, *args, **kwargs): - """Render "Contact" page.""" - committees = Committee.objects.order_by('name') - - context = { - "committees": committees - } - - return render(request, "contact.html", context) From 86ae2197f3f2febceca5575e1cbea593970d936e Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 03:03:48 +0200 Subject: [PATCH 51/72] Contact API tests --- webapp/tests/test_contact.py | 98 ++++++++++++++++++++++++++++++++---- 1 file changed, 89 insertions(+), 9 deletions(-) diff --git a/webapp/tests/test_contact.py b/webapp/tests/test_contact.py index 4606335..747fbf7 100644 --- a/webapp/tests/test_contact.py +++ b/webapp/tests/test_contact.py @@ -1,16 +1,96 @@ from django.test import TestCase -from django.core.files import File from django.contrib.auth.models import User -from rest_framework.test import APITestCase +from django.utils import timezone from rest_framework import status -from rest_framework.test import force_authenticate -from webapp.models import Tag, Feed -from webapp.serializers import TagSerializer, FeedSerializer +from rest_framework.test import APITestCase -from collections import OrderedDict -from itertools import islice -import tempfile +from webapp.models import Official, Role, Occupation, Committee +from webapp.serializers import OccupationSerializer + + +URL = "/api/contacts/" +COMMITTEE = Committee.objects.create( + name_fi="Viestintä", + name_en="Communications" +) + + +def createRoleBoard(): + return Role.objects.create( + name_fi="Metsuri", + name_en="The lumberjack", + is_board=True, + description_fi="Toimikunta PJ", + description_en="Committee Chair" + ) + + +def createRoleNoBoard(): + return Role.objects.create( + name_fi="Toimari", + name_en="Official", + is_board=False, + description_fi="Toimikunta jäbä", + description_en="Committee dude(tte)", + committee=COMMITTEE + ) + + +def createOccupation(year, role=createRoleNoBoard(), dummydata=1): + occupation = Occupation.objects.create( + start_date=timezone.datetime(year, 1, 1), + end_date=timezone.datetime(year, 12, 31), + role=role + ) + + occupation.officials.add( + createPerson(dummydata) + ) + + return occupation + + +def createPerson(name): + return Official.objects.create( + user=User.objects.create_user(f"testi{name}", "test@test.tld", "password123"), + first_name=f"first{name}", + last_name=f"last{name}", + email="test@test.tld", + phone_number="+358501234567", + image="" + ) class ContactsTestCase(APITestCase): - pass + + def setUp(self): + createOccupation(timezone.now().year, role=createRoleBoard(), dummydata=1) + createOccupation(timezone.now().year, dummydata=2) + createOccupation(1970, role=createRoleBoard(), dummydata=3) + createOccupation(1970, dummydata=4) + + def test_get(self): + response = self.client.get(f"{URL}", format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + serializer = OccupationSerializer( + Occupation.by_year(2019), + many=True + ) + self.assertEqual(response.data["results"], serializer.data) + + def test_get_by_year(self): + response = self.client.get(f"{URL}?year=1970", format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + serializer = OccupationSerializer( + Occupation.by_year(1970), + many=True + ) + + self.assertEqual(response.data["results"], serializer.data) + + def test_by_year_empty(self): + response = self.client.get(f"{URL}?year=1971") + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data["results"], []) From 1778a0509cb87d25e9c1eb6dae8215b574acdc1e Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 03:04:05 +0200 Subject: [PATCH 52/72] Minor fixes --- webapp/tests/test_event.py | 2 +- webapp/views.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/webapp/tests/test_event.py b/webapp/tests/test_event.py index 1827b02..095a6e5 100644 --- a/webapp/tests/test_event.py +++ b/webapp/tests/test_event.py @@ -91,7 +91,7 @@ class EventTestCase(APITestCase): self.assertEqual(response.data, serializer.data) def test_get_invalid_event(self): - response = self.client.get("{URL}200/", format="json") + response = self.client.get(f"{URL}200/", format="json") self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_post_event(self): diff --git a/webapp/views.py b/webapp/views.py index 57e1d68..4eb06c2 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -143,8 +143,8 @@ def about_view(request, *args, **kwargs): latest_commit = repo.git("rev-parse HEAD").decode('utf-8') latest_date = repo.git("show -s --format=%ci " + latest_commit).decode('utf-8') latest_tag = repo.git("describe --tags " + repo.git("rev-list --tags --max-count=1").decode('utf-8')).decode('utf-8') - except Exception: - pass + except Exception as e: + print(f"Git failed:\n{e}") context = { 'commit': latest_commit, From 8afeec21ccf4d729bb6d82fdd2905207fedcc8bc Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 03:04:40 +0200 Subject: [PATCH 53/72] Settings add localhost to allowed --- sikweb/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sikweb/settings.py b/sikweb/settings.py index 7333fe2..7f8fd21 100644 --- a/sikweb/settings.py +++ b/sikweb/settings.py @@ -17,7 +17,7 @@ from sikweb.base import * DEBUG = os.getenv('DEBUG', False) == 'True' URL = os.getenv("HOST", "sika.sik.party") -ALLOWED_HOSTS = [URL] +ALLOWED_HOSTS = ["localhost", "127.0.0.1", URL] # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.getenv('SECRET_KEY', '') From 2c72e01353ccd807d1b9c0042ffc4531f218c69c Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 18:11:32 +0200 Subject: [PATCH 54/72] Clean webapp views imports --- webapp/views.py | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/webapp/views.py b/webapp/views.py index b6a8d89..75b6923 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -1,31 +1,24 @@ """Webapp views.""" import jwt -# import logging -# import requests +from django.utils import timezone from dealer.git import git from django.conf import settings -from django.contrib.auth import authenticate, login, logout +from django.contrib.auth import authenticate from django.http import HttpResponse -# from django.db.models import Count from django.shortcuts import redirect, render from django.views.decorators.http import require_http_methods from django_filters import rest_framework as filters -# from django.views.decorators.csrf import ensure_csrf_cookie -# from django.http import HttpResponse, HttpResponseRedirect -# from django.contrib.auth.decorators import permission_required, login_required -# from django.conf import settings -# from django.utils import timezone from rest_framework import permissions, routers, viewsets from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.permissions import IsAuthenticatedOrReadOnly from rest_framework.response import Response from rest_framework.reverse import reverse -from members.views.utils import * -from webapp.models import (Committee, Event, Feed, Official, Signup, - SignupForm, Tag, TemplateQuestion) -from webapp.serializers import * +from webapp.models import Event, SignupForm, Signup, TemplateQuestion, Feed, Committee, Occupation, Tag +from webapp.serializers import (EventSerializer, SignupFormSerializer, SignupSerializer, + SavedQuestionsSerializer, FeedSerializer, CommitteeSerializer, + OccupationSerializer, TagSerializer) class IsPostOrIsAuthenticated(permissions.BasePermission): From 3d755bca8c3992b4c3dc82c3dcd3678b49c957ca Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 19:19:08 +0200 Subject: [PATCH 55/72] Remove translations from SignupFormSerializer --- webapp/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/serializers.py b/webapp/serializers.py index 7fc0e9d..036afa0 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -5,7 +5,7 @@ from webapp.models import * class SignupFormSerializer(serializers.ModelSerializer): class Meta: model = SignupForm - fields = ('id', 'title_fi', 'title_en', 'start_time', 'end_time', 'questions') + fields = ('id', 'title', 'start_time', 'end_time', 'questions') class EventSerializer(serializers.ModelSerializer): From 5fba7d624937763e4a686619a01834909ea8e936 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 19:24:18 +0200 Subject: [PATCH 56/72] Use JSONFields --- webapp/migrations/0061_auto_20191110_1923.py | 29 ++++++++++++++++++++ webapp/models.py | 11 ++------ 2 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 webapp/migrations/0061_auto_20191110_1923.py diff --git a/webapp/migrations/0061_auto_20191110_1923.py b/webapp/migrations/0061_auto_20191110_1923.py new file mode 100644 index 0000000..9c22578 --- /dev/null +++ b/webapp/migrations/0061_auto_20191110_1923.py @@ -0,0 +1,29 @@ +# Generated by Django 2.1.5 on 2019-11-10 17:23 + +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0060_official_image'), + ] + + operations = [ + migrations.AlterField( + model_name='official', + name='image', + field=models.ImageField(blank=True, null=True, upload_to=''), + ), + migrations.AlterField( + model_name='signupform', + name='questions', + field=django.contrib.postgres.fields.jsonb.JSONField(), + ), + migrations.AlterField( + model_name='templatequestion', + name='question', + field=django.contrib.postgres.fields.jsonb.JSONField(), + ), + ] diff --git a/webapp/models.py b/webapp/models.py index 520af45..16a4e63 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -2,7 +2,6 @@ from django.db import models from django.utils import timezone -# from datetime import timedelta from django.contrib.auth.models import User from django.db.models.signals import post_save from django.dispatch import receiver @@ -10,9 +9,7 @@ from webapp.utils import month_from_now from django.utils.translation import ugettext_lazy as _ from auditlog.registry import auditlog from phonenumber_field.modelfields import PhoneNumberField -# from django.contrib.postgres.fields import JSONField - -# import logging +from django.contrib.postgres.fields import JSONField VERBOSE_NAME = _('Webapp') @@ -77,9 +74,8 @@ class Event(BaseFeed): class TemplateQuestion(models.Model): """Stores template questions for signup forms as JSONB""" - # question = JSONField() name = models.CharField(max_length=255) - question = models.CharField(max_length=255) + question = JSONField() def __str__(self): return _('Template questions: {}').format(self.name) @@ -95,8 +91,7 @@ class SignupForm(models.Model): title = models.CharField(max_length=255) start_time = models.DateTimeField(default=timezone.now) end_time = models.DateTimeField(default=timezone.now) - # question = JSONField() - questions = models.TextField(default="[]") + questions = JSONField() visible = models.BooleanField(default=True) def __str__(self): From 8f0c9feecf1615cdb06dab4516617d1c8df613ce Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 20:00:03 +0200 Subject: [PATCH 57/72] Remove json dumps --- webapp/tests/test_signup.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/webapp/tests/test_signup.py b/webapp/tests/test_signup.py index 79b8c5a..cf822d4 100644 --- a/webapp/tests/test_signup.py +++ b/webapp/tests/test_signup.py @@ -2,19 +2,18 @@ from django.test import TestCase from django.contrib.auth.models import User from django.utils import timezone from rest_framework import status -from rest_framework.test import APITestCase, APIRequestFactory, force_authenticate +from rest_framework.test import APITestCase, force_authenticate from webapp.models import Signup, SignupForm from webapp.serializers import SignupSerializer, SignupFormSerializer -from webapp.tests.event_fixture import createEventObject, createEventJSON +from webapp.tests.event_fixture import createEventObject from webapp.utils import month_from_now -import json URL = "/api/signup/" -ALL_QUESTION_TYPES = json.dumps([ +ALL_QUESTION_TYPES = [ -]) +] def createSignupForm(name="Form1", start_time=timezone.now(), end_time=month_from_now(), questions=ALL_QUESTION_TYPES, visible=True): @@ -48,8 +47,8 @@ class SignupTestCase(APITestCase): self.hiddenForm = createSignupForm(visible=False) # self.event = createEventObject(signup_id=self.signupForm.id) - self.signup1 = createSignupObject(self.signupForm, json.dumps([])) - self.signup2 = createSignupObject(self.signupForm, json.dumps([])) + self.signup1 = createSignupObject(self.signupForm, []) + self.signup2 = createSignupObject(self.signupForm, []) username, password = "test_admin", "password123" self.authClient = User.objects.create_superuser(username, "myemail@test.com", password) @@ -85,19 +84,19 @@ class SignupTestCase(APITestCase): self.assertEqual(response.data, expected.data) def test_create_signup(self): - new = createSignupJSON(self.signup1.id, "[]") - response = self.client.post(URL, format="json") + new = createSignupJSON(self.signup1.id, []) + response = self.client.post(URL, new, format="json") self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Signup.objects.count(), 3) def test_create_signup_404_or_hidden(self): - new = createSignupJSON(3001, "[]") - response = self.client.post(URL, format="json") + new = createSignupJSON(3001, []) + response = self.client.post(URL, new, format="json") self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual(Signup.objects.count(), 2) - new = createSignupJSON(self.hiddenForm, "[]") - response = self.client.post(URL, format="json") + new = createSignupJSON(self.hiddenForm, []) + response = self.client.post(URL, new, format="json") self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual(Signup.objects.count(), 2) From a9d6bf50d68e1ca698f0f1ecbbb30d45e5a08194 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 20:00:13 +0200 Subject: [PATCH 58/72] TemplateQuestion Tests --- webapp/tests/test_templateQuestions.py | 81 ++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 webapp/tests/test_templateQuestions.py diff --git a/webapp/tests/test_templateQuestions.py b/webapp/tests/test_templateQuestions.py new file mode 100644 index 0000000..8cfa4fd --- /dev/null +++ b/webapp/tests/test_templateQuestions.py @@ -0,0 +1,81 @@ +from django.test import TestCase +from django.contrib.auth.models import User +from rest_framework import status +from rest_framework.test import APITestCase, force_authenticate + +from webapp.models import TemplateQuestion +from webapp.serializers import SavedQuestionsSerializer + +ALL_QUESTION_TYPES = [ + +] + + +class TemplateQuestionCase(APITestCase): + def setUp(self): + self.questions = [ + TemplateQuestion.objects.create( + name="Testi1", + question=ALL_QUESTION_TYPES + ), + TemplateQuestion.objects.create( + name="Testi2", + question=ALL_QUESTION_TYPES + ) + ] + + username, password = "test_admin", "password123" + self.authClient = User.objects.create_superuser(username, "myemail@test.com", password) + + def test_get(self): + response = self.client.get("/api/questions/", format="json") + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data["results"], SavedQuestionsSerializer(self.questions, many=True).data) + response = self.client.get(f"/api/questions/{self.questions[0].id}/", format="json") + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data, SavedQuestionsSerializer(self.questions[0]).data) + + def test_post(self): + new = { + "name": "testi3", + "questions": [] + } + response = self.client.post("/api/questions/", new, format="json") + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + self.assertEqual(TemplateQuestion.objects.count(), 2) + + # Authenticate + self.client.force_authenticate(user=self.authClient) + response = self.client.post("/api/questions/", new, format="json") + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(TemplateQuestion.objects.count(), 3) + + def test_update(self): + new = { + "name": "uusi testi2", + "questions": [] + } + response = self.client.put(f"/api/questions/{self.questions[0].id}/", new, format="json") + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + self.assertEqual(TemplateQuestion.objects.count(), 2) + + # Authenticate + self.client.force_authenticate(user=self.authClient) + response = self.client.put(f"/api/questions/{self.questions[0].id}/", new, format="json") + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(TemplateQuestion.objects.count(), 2) + self.assertEqual( + TemplateQuestion.objects.get(id=self.questions[0].id).name, + "uusi testi2" + ) + + def test_delete(self): + response = self.client.delete(f"/api/questions/{self.questions[0].id}/", format="json") + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + self.assertEqual(TemplateQuestion.objects.count(), 2) + + # Authenticate + self.client.force_authenticate(user=self.authClient) + response = self.client.delete(f"/api/questions/{self.questions[0].id}/", format="json") + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + self.assertEqual(TemplateQuestion.objects.count(), 1) From 8c4f6e886cbb6021fd50e0dad2e33ae4278cb472 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 20:11:08 +0200 Subject: [PATCH 59/72] New signup fixture --- webapp/tests/signup_fixture.py | 31 +++++++++++++++++++++++ webapp/tests/test_event.py | 9 ++++--- webapp/tests/test_signup.py | 34 ++------------------------ webapp/tests/test_templateQuestions.py | 5 +--- 4 files changed, 40 insertions(+), 39 deletions(-) create mode 100644 webapp/tests/signup_fixture.py diff --git a/webapp/tests/signup_fixture.py b/webapp/tests/signup_fixture.py new file mode 100644 index 0000000..b55a43c --- /dev/null +++ b/webapp/tests/signup_fixture.py @@ -0,0 +1,31 @@ +from webapp.models import Signup, SignupForm +from django.utils import timezone +from webapp.utils import month_from_now + +ALL_QUESTION_TYPES = [ + +] + + +def createSignupForm(name="Form1", start_time=timezone.now(), end_time=month_from_now(), questions=ALL_QUESTION_TYPES, visible=True): + return SignupForm.objects.create( + title=name, + start_time=start_time, + end_time=end_time, + questions=questions, + visible=visible + ) + + +def createSignupObject(form, answer): + return Signup.objects.create( + signupForm=form, + answer=answer + ) + + +def createSignupJSON(form_id, answer): + return { + "signupForm": form_id, + "answer": answer + } diff --git a/webapp/tests/test_event.py b/webapp/tests/test_event.py index 095a6e5..4ecc175 100644 --- a/webapp/tests/test_event.py +++ b/webapp/tests/test_event.py @@ -8,6 +8,7 @@ from webapp.models import Event from webapp.serializers import EventSerializer from webapp.tests.tag_fixture import tagBuilder, createTagIcon from webapp.tests.event_fixture import createEventObject, createEventJSON +from webapp.tests.signup_fixture import createSignupForm URL = "/api/events/" @@ -44,6 +45,8 @@ class EventTestCase(APITestCase): self.testEventId = test1.id self.assertEqual(Event.objects.count(), 4) + self.signupFormId = createSignupForm().id + username, password = "test_admin", "password123" self.authClient = User.objects.create_superuser(username, "myemail@test.com", password) @@ -99,7 +102,7 @@ class EventTestCase(APITestCase): self.client.force_authenticate(user=self.authClient) response = self.client.post( URL, - createEventJSON(tag_id=[self.testTagId]), + createEventJSON(tag_id=[self.testTagId], signup_id=[self.signupFormId]), format="json" ) @@ -109,7 +112,7 @@ class EventTestCase(APITestCase): def test_post_event_unauth(self): response = self.client.post( URL, - createEventJSON(tag_id=[self.testTagId]), + createEventJSON(tag_id=[self.testTagId], signup_id=[self.signupFormId]), format="json" ) @@ -120,7 +123,7 @@ class EventTestCase(APITestCase): # Authenticate self.client.force_authenticate(user=self.authClient) event = Event.objects.get(id=self.testEventId) - new = createEventJSON(name="Update1") + new = createEventJSON(name="Update1", signup_id=[self.signupFormId]) response = self.client.put( f"{URL}{self.testEventId}/", new, diff --git a/webapp/tests/test_signup.py b/webapp/tests/test_signup.py index cf822d4..73e8d19 100644 --- a/webapp/tests/test_signup.py +++ b/webapp/tests/test_signup.py @@ -1,51 +1,21 @@ from django.test import TestCase from django.contrib.auth.models import User -from django.utils import timezone from rest_framework import status from rest_framework.test import APITestCase, force_authenticate -from webapp.models import Signup, SignupForm from webapp.serializers import SignupSerializer, SignupFormSerializer +from webapp.models import Signup from webapp.tests.event_fixture import createEventObject -from webapp.utils import month_from_now +from webapp.tests.signup_fixture import createSignupForm, createSignupObject, createSignupJSON, ALL_QUESTION_TYPES URL = "/api/signup/" -ALL_QUESTION_TYPES = [ - -] - - -def createSignupForm(name="Form1", start_time=timezone.now(), end_time=month_from_now(), questions=ALL_QUESTION_TYPES, visible=True): - return SignupForm.objects.create( - title=name, - start_time=start_time, - end_time=end_time, - questions=questions, - visible=visible - ) - - -def createSignupObject(form, answer): - return Signup.objects.create( - signupForm=form, - answer=answer - ) - - -def createSignupJSON(form_id, answer): - return { - "signupForm": form_id, - "answer": answer - } - class SignupTestCase(APITestCase): def setUp(self): self.signupForm = createSignupForm() self.hiddenForm = createSignupForm(visible=False) - # self.event = createEventObject(signup_id=self.signupForm.id) self.signup1 = createSignupObject(self.signupForm, []) self.signup2 = createSignupObject(self.signupForm, []) diff --git a/webapp/tests/test_templateQuestions.py b/webapp/tests/test_templateQuestions.py index 8cfa4fd..28eea70 100644 --- a/webapp/tests/test_templateQuestions.py +++ b/webapp/tests/test_templateQuestions.py @@ -5,10 +5,7 @@ from rest_framework.test import APITestCase, force_authenticate from webapp.models import TemplateQuestion from webapp.serializers import SavedQuestionsSerializer - -ALL_QUESTION_TYPES = [ - -] +from webapp.tests.signup_fixture import ALL_QUESTION_TYPES class TemplateQuestionCase(APITestCase): From 52a646fe04df867b218b91620f04cf296b6479b1 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 20:25:21 +0200 Subject: [PATCH 60/72] Revert "Use JSONFields" This reverts commit 5fba7d624937763e4a686619a01834909ea8e936. --- webapp/migrations/0061_auto_20191110_1923.py | 29 -------------------- webapp/models.py | 11 ++++++-- 2 files changed, 8 insertions(+), 32 deletions(-) delete mode 100644 webapp/migrations/0061_auto_20191110_1923.py diff --git a/webapp/migrations/0061_auto_20191110_1923.py b/webapp/migrations/0061_auto_20191110_1923.py deleted file mode 100644 index 9c22578..0000000 --- a/webapp/migrations/0061_auto_20191110_1923.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 2.1.5 on 2019-11-10 17:23 - -import django.contrib.postgres.fields.jsonb -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('webapp', '0060_official_image'), - ] - - operations = [ - migrations.AlterField( - model_name='official', - name='image', - field=models.ImageField(blank=True, null=True, upload_to=''), - ), - migrations.AlterField( - model_name='signupform', - name='questions', - field=django.contrib.postgres.fields.jsonb.JSONField(), - ), - migrations.AlterField( - model_name='templatequestion', - name='question', - field=django.contrib.postgres.fields.jsonb.JSONField(), - ), - ] diff --git a/webapp/models.py b/webapp/models.py index 16a4e63..520af45 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -2,6 +2,7 @@ from django.db import models from django.utils import timezone +# from datetime import timedelta from django.contrib.auth.models import User from django.db.models.signals import post_save from django.dispatch import receiver @@ -9,7 +10,9 @@ from webapp.utils import month_from_now from django.utils.translation import ugettext_lazy as _ from auditlog.registry import auditlog from phonenumber_field.modelfields import PhoneNumberField -from django.contrib.postgres.fields import JSONField +# from django.contrib.postgres.fields import JSONField + +# import logging VERBOSE_NAME = _('Webapp') @@ -74,8 +77,9 @@ class Event(BaseFeed): class TemplateQuestion(models.Model): """Stores template questions for signup forms as JSONB""" + # question = JSONField() name = models.CharField(max_length=255) - question = JSONField() + question = models.CharField(max_length=255) def __str__(self): return _('Template questions: {}').format(self.name) @@ -91,7 +95,8 @@ class SignupForm(models.Model): title = models.CharField(max_length=255) start_time = models.DateTimeField(default=timezone.now) end_time = models.DateTimeField(default=timezone.now) - questions = JSONField() + # question = JSONField() + questions = models.TextField(default="[]") visible = models.BooleanField(default=True) def __str__(self): From 1ce3c28e945682e4500d858eb0abe37640ffeb98 Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Sun, 10 Nov 2019 20:26:28 +0200 Subject: [PATCH 61/72] Use JSONField for signup and signupform models --- webapp/migrations/0061_auto_20191110_2024.py | 29 ++++++++++++++++++++ webapp/models.py | 7 ++--- 2 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 webapp/migrations/0061_auto_20191110_2024.py diff --git a/webapp/migrations/0061_auto_20191110_2024.py b/webapp/migrations/0061_auto_20191110_2024.py new file mode 100644 index 0000000..aebdfe1 --- /dev/null +++ b/webapp/migrations/0061_auto_20191110_2024.py @@ -0,0 +1,29 @@ +# Generated by Django 2.1.5 on 2019-11-10 18:24 + +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0060_official_image'), + ] + + operations = [ + migrations.AlterField( + model_name='official', + name='image', + field=models.ImageField(blank=True, null=True, upload_to=''), + ), + migrations.AlterField( + model_name='signup', + name='answer', + field=django.contrib.postgres.fields.jsonb.JSONField(), + ), + migrations.AlterField( + model_name='signupform', + name='questions', + field=django.contrib.postgres.fields.jsonb.JSONField(), + ), + ] diff --git a/webapp/models.py b/webapp/models.py index 520af45..7e23446 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -10,7 +10,7 @@ from webapp.utils import month_from_now from django.utils.translation import ugettext_lazy as _ from auditlog.registry import auditlog from phonenumber_field.modelfields import PhoneNumberField -# from django.contrib.postgres.fields import JSONField +from django.contrib.postgres.fields import JSONField # import logging @@ -95,8 +95,7 @@ class SignupForm(models.Model): title = models.CharField(max_length=255) start_time = models.DateTimeField(default=timezone.now) end_time = models.DateTimeField(default=timezone.now) - # question = JSONField() - questions = models.TextField(default="[]") + questions = JSONField() visible = models.BooleanField(default=True) def __str__(self): @@ -110,7 +109,7 @@ class SignupForm(models.Model): class Signup(models.Model): signupForm = models.ForeignKey('SignupForm', on_delete=models.CASCADE) time = models.DateTimeField(default=timezone.now) - answer = models.CharField(max_length=255) + answer = JSONField() def __str__(self): return _('Sign-ups: {}').format(self.signupForm) From eb63c9fc1c2fc5feb4761d1ca8f19d73a31e1705 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 20:30:42 +0200 Subject: [PATCH 62/72] Fix signup JSON form ID --- webapp/tests/signup_fixture.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/tests/signup_fixture.py b/webapp/tests/signup_fixture.py index b55a43c..dc3078c 100644 --- a/webapp/tests/signup_fixture.py +++ b/webapp/tests/signup_fixture.py @@ -26,6 +26,6 @@ def createSignupObject(form, answer): def createSignupJSON(form_id, answer): return { - "signupForm": form_id, + "signupForm_id": form_id, "answer": answer } From 08ec9bb9cc944f34c1aa8ad698bebad3b1168bdf Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 20:46:16 +0200 Subject: [PATCH 63/72] Use json.loads for create and update of JSONField data --- webapp/serializers.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/webapp/serializers.py b/webapp/serializers.py index 2250a8d..353b6c9 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -1,5 +1,6 @@ from rest_framework import serializers from webapp.models import * +import json class SignupFormSerializer(serializers.HyperlinkedModelSerializer): @@ -7,6 +8,14 @@ class SignupFormSerializer(serializers.HyperlinkedModelSerializer): model = SignupForm fields = ('id', 'title', 'start_time', 'end_time', 'questions') + def create(self, validated_data): + validated_data["questions"] = json.loads(validated_data["questions"]) + return super().create(validated_data) + + def update(self, instance, validated_data): + validated_data["questions"] = json.loads(validated_data["questions"]) + return super().update(instance, validated_data) + class EventSerializer(serializers.HyperlinkedModelSerializer): signupForm = SignupFormSerializer(many=True, read_only=True, required=False) @@ -64,6 +73,14 @@ class SignupSerializer(serializers.ModelSerializer): } } + def create(self, validated_data): + validated_data["answer"] = json.loads(validated_data["answer"]) + return super().create(validated_data) + + def update(self, instance, validated_data): + validated_data["answer"] = json.loads(validated_data["answer"]) + return super().update(instance, validated_data) + class SavedQuestionsSerializer(serializers.ModelSerializer): class Meta: From f64cec7d2ed8c3680a7361922497f9410be3737a Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sun, 10 Nov 2019 21:34:10 +0200 Subject: [PATCH 64/72] Fix Infernal Server Error on SignupForms --- webapp/migrations/0062_auto_20191110_2117.py | 19 +++++++++++++++++ webapp/models.py | 3 +-- webapp/serializers.py | 22 +++++--------------- webapp/views.py | 7 ++++--- 4 files changed, 29 insertions(+), 22 deletions(-) create mode 100644 webapp/migrations/0062_auto_20191110_2117.py diff --git a/webapp/migrations/0062_auto_20191110_2117.py b/webapp/migrations/0062_auto_20191110_2117.py new file mode 100644 index 0000000..671ed04 --- /dev/null +++ b/webapp/migrations/0062_auto_20191110_2117.py @@ -0,0 +1,19 @@ +# Generated by Django 2.1.5 on 2019-11-10 19:17 + +import django.contrib.postgres.fields.jsonb +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0061_auto_20191110_2024'), + ] + + operations = [ + migrations.AlterField( + model_name='templatequestion', + name='question', + field=django.contrib.postgres.fields.jsonb.JSONField(), + ), + ] diff --git a/webapp/models.py b/webapp/models.py index 7e23446..c84bdd4 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -77,9 +77,8 @@ class Event(BaseFeed): class TemplateQuestion(models.Model): """Stores template questions for signup forms as JSONB""" - # question = JSONField() name = models.CharField(max_length=255) - question = models.CharField(max_length=255) + question = JSONField() def __str__(self): return _('Template questions: {}').format(self.name) diff --git a/webapp/serializers.py b/webapp/serializers.py index 353b6c9..e226812 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -1,21 +1,14 @@ from rest_framework import serializers from webapp.models import * -import json class SignupFormSerializer(serializers.HyperlinkedModelSerializer): + questions = serializers.JSONField(binary=True) + class Meta: model = SignupForm fields = ('id', 'title', 'start_time', 'end_time', 'questions') - def create(self, validated_data): - validated_data["questions"] = json.loads(validated_data["questions"]) - return super().create(validated_data) - - def update(self, instance, validated_data): - validated_data["questions"] = json.loads(validated_data["questions"]) - return super().update(instance, validated_data) - class EventSerializer(serializers.HyperlinkedModelSerializer): signupForm = SignupFormSerializer(many=True, read_only=True, required=False) @@ -63,6 +56,7 @@ class SignupSerializer(serializers.ModelSerializer): source="signupForm", queryset=SignupForm.objects.all() ) + answer = serializers.JSONField(binary=True) class Meta: model = Signup @@ -73,16 +67,10 @@ class SignupSerializer(serializers.ModelSerializer): } } - def create(self, validated_data): - validated_data["answer"] = json.loads(validated_data["answer"]) - return super().create(validated_data) - - def update(self, instance, validated_data): - validated_data["answer"] = json.loads(validated_data["answer"]) - return super().update(instance, validated_data) - class SavedQuestionsSerializer(serializers.ModelSerializer): + question = serializers.JSONField(binary=True) + class Meta: model = TemplateQuestion fields = ('id', 'name', 'question') diff --git a/webapp/views.py b/webapp/views.py index 75b6923..5824512 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -54,9 +54,10 @@ class SignupFormViewSet(viewsets.ModelViewSet): queryset = SignupForm.objects.all() serializer_class = SignupFormSerializer permission_classes = [IsAuthenticatedOrReadOnly] - filter_backends = (filters.DjangoFilterBackend, SearchFilter, OrderingFilter) - filter_fields = '__all__' - search_fields = '__all__' + # Throws errors with JSONFIeld. Modify __all__ to not use JSONField if filters are enadbled + # filter_backends = (filters.DjangoFilterBackend, SearchFilter, OrderingFilter) + # filter_fields = '__all__' + # search_fields = '__all__' def get_queryset(self): return SignupForm.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time') From f7cf54cab248f6e48e8283eb54e9f163efff0eff Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Mon, 11 Nov 2019 00:18:48 +0200 Subject: [PATCH 65/72] Fix webapp tests --- webapp/tests/signup_fixture.py | 10 +++++++-- webapp/tests/test_feed.py | 7 ++++--- webapp/tests/test_signup.py | 29 ++++++++++++++++++-------- webapp/tests/test_templateQuestions.py | 6 ++++-- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/webapp/tests/signup_fixture.py b/webapp/tests/signup_fixture.py index 48cb756..a036274 100644 --- a/webapp/tests/signup_fixture.py +++ b/webapp/tests/signup_fixture.py @@ -2,10 +2,16 @@ from webapp.models import Signup, SignupForm from django.utils import timezone from webapp.utils import month_from_now +import json + ALL_QUESTION_TYPES = [ - {"id": "j5CeRZDvl", "name": "Asd", "type": "text", "options": []}, {"id": "RHJhSoaLD", "name": "Asd2", "type": "radiobutton", "options": ["Yes", "no", "maybe"]}, {"id": "i10d426d5", "name": "Asd3", "type": "checkbox", "options": ["A", "B", "C"]} + {"id": "j5CeRZDvl", "name": "Asd", "type": "text", "options": []}, + {"id": "RHJhSoaLD", "name": "Asd2", "type": "radiobutton", "options": ["Yes", "no", "maybe"]}, + {"id": "i10d426d5", "name": "Asd3", "type": "checkbox", "options": ["A", "B", "C"]} ] +ALL_QUESTION_TYPES_ANSWER = {"j5CeRZDvl": "Testi", "RHJhSoaLD": "maybe", "i10d426d5": ["B"]} + def createSignupForm(name="Form1", start_time=timezone.now(), end_time=month_from_now(), questions=ALL_QUESTION_TYPES, visible=True): return SignupForm.objects.create( @@ -27,5 +33,5 @@ def createSignupObject(form, answer): def createSignupJSON(form_id, answer): return { "signupForm_id": form_id, - "answer": answer + "answer": json.dumps(answer) } diff --git a/webapp/tests/test_feed.py b/webapp/tests/test_feed.py index 1892d93..6da4a77 100644 --- a/webapp/tests/test_feed.py +++ b/webapp/tests/test_feed.py @@ -44,17 +44,18 @@ class FeedTestCase(APITestCase): "title_fi": "testtitle", "title_en": "testtitle", "visible": "True", - "description_fi": "liirumlaarum", "description_en": "liirumlaarum", + "description_fi": "liirumlaarum", + "description_en": "liirumlaarum", "content_fi": "lorem ipsum", "content_en": "lorem ipsum" } # Try post without authentication - response = self.client.post("/api/feed/", data, format="multipart") + response = self.client.post("/api/feed/", data, format="json") self.assertTrue(response.status_code, status.HTTP_401_UNAUTHORIZED) self.assertEqual(Feed.objects.count(), 1) # Authenticate self.client.force_authenticate(user=self.authClient) - response = self.client.post("/api/feed/", data, format="multipart") + response = self.client.post("/api/feed/", data, format="json") # Return success and check object was created self.assertTrue(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Feed.objects.count(), 2) diff --git a/webapp/tests/test_signup.py b/webapp/tests/test_signup.py index 73e8d19..9d13ef7 100644 --- a/webapp/tests/test_signup.py +++ b/webapp/tests/test_signup.py @@ -1,4 +1,5 @@ from django.test import TestCase +from unittest import skip from django.contrib.auth.models import User from rest_framework import status from rest_framework.test import APITestCase, force_authenticate @@ -6,7 +7,8 @@ from rest_framework.test import APITestCase, force_authenticate from webapp.serializers import SignupSerializer, SignupFormSerializer from webapp.models import Signup from webapp.tests.event_fixture import createEventObject -from webapp.tests.signup_fixture import createSignupForm, createSignupObject, createSignupJSON, ALL_QUESTION_TYPES +from webapp.tests.signup_fixture import createSignupForm, createSignupObject, createSignupJSON, ALL_QUESTION_TYPES, ALL_QUESTION_TYPES_ANSWER + URL = "/api/signup/" @@ -17,7 +19,7 @@ class SignupTestCase(APITestCase): self.signupForm = createSignupForm() self.hiddenForm = createSignupForm(visible=False) - self.signup1 = createSignupObject(self.signupForm, []) + self.signup1 = createSignupObject(self.signupForm, ALL_QUESTION_TYPES) self.signup2 = createSignupObject(self.signupForm, []) username, password = "test_admin", "password123" @@ -54,27 +56,36 @@ class SignupTestCase(APITestCase): self.assertEqual(response.data, expected.data) def test_create_signup(self): - new = createSignupJSON(self.signup1.id, []) + new = createSignupJSON(self.signupForm.id, ALL_QUESTION_TYPES_ANSWER) response = self.client.post(URL, new, format="json") + print(response.data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Signup.objects.count(), 3) def test_create_signup_404_or_hidden(self): - new = createSignupJSON(3001, []) + new = createSignupJSON(3001, ALL_QUESTION_TYPES_ANSWER) response = self.client.post(URL, new, format="json") + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertEqual(response.data["signupForm_id"][0].code, "does_not_exist") + self.assertEqual(Signup.objects.count(), 2) + + new = createSignupJSON(self.hiddenForm.id, ALL_QUESTION_TYPES_ANSWER) + response = self.client.post(URL, new, format="json") + print(response.data) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual(Signup.objects.count(), 2) - new = createSignupJSON(self.hiddenForm, []) - response = self.client.post(URL, new, format="json") - self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - self.assertEqual(Signup.objects.count(), 2) + @skip("NotImplemented") + def test_create_malformed_answer(self): + response = self.client.post(URL, createSignupJSON(self.signupForm.id, []), format="json") + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) # Update and Delete are available for super admin (Django Admin) # and to the user that signed up (uid token) - + @skip("NotImplemented") def test_update_signup_token(self): pass + @skip("NotImplemented") def test_delete_signup_token(self): pass diff --git a/webapp/tests/test_templateQuestions.py b/webapp/tests/test_templateQuestions.py index 28eea70..05f1a8a 100644 --- a/webapp/tests/test_templateQuestions.py +++ b/webapp/tests/test_templateQuestions.py @@ -6,6 +6,7 @@ from rest_framework.test import APITestCase, force_authenticate from webapp.models import TemplateQuestion from webapp.serializers import SavedQuestionsSerializer from webapp.tests.signup_fixture import ALL_QUESTION_TYPES +import json class TemplateQuestionCase(APITestCase): @@ -35,7 +36,7 @@ class TemplateQuestionCase(APITestCase): def test_post(self): new = { "name": "testi3", - "questions": [] + "question": json.dumps(ALL_QUESTION_TYPES) } response = self.client.post("/api/questions/", new, format="json") self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) @@ -50,7 +51,7 @@ class TemplateQuestionCase(APITestCase): def test_update(self): new = { "name": "uusi testi2", - "questions": [] + "question": json.dumps({}) } response = self.client.put(f"/api/questions/{self.questions[0].id}/", new, format="json") self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) @@ -59,6 +60,7 @@ class TemplateQuestionCase(APITestCase): # Authenticate self.client.force_authenticate(user=self.authClient) response = self.client.put(f"/api/questions/{self.questions[0].id}/", new, format="json") + self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(TemplateQuestion.objects.count(), 2) self.assertEqual( From f422e31a42d1da4a3ca3f1582ce3e88c8680e5d2 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Mon, 11 Nov 2019 00:44:35 +0200 Subject: [PATCH 66/72] Add some code to GET all objects as admin --- webapp/tests/test_signup.py | 8 +++++--- webapp/views.py | 26 +++++++++++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/webapp/tests/test_signup.py b/webapp/tests/test_signup.py index 9d13ef7..66b0427 100644 --- a/webapp/tests/test_signup.py +++ b/webapp/tests/test_signup.py @@ -66,15 +66,17 @@ class SignupTestCase(APITestCase): new = createSignupJSON(3001, ALL_QUESTION_TYPES_ANSWER) response = self.client.post(URL, new, format="json") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - self.assertEqual(response.data["signupForm_id"][0].code, "does_not_exist") self.assertEqual(Signup.objects.count(), 2) new = createSignupJSON(self.hiddenForm.id, ALL_QUESTION_TYPES_ANSWER) response = self.client.post(URL, new, format="json") - print(response.data) - self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(Signup.objects.count(), 2) + @skip("NotImplemented") + def test_get_hidden_forms_admin(self): + pass + @skip("NotImplemented") def test_create_malformed_answer(self): response = self.client.post(URL, createSignupJSON(self.signupForm.id, []), format="json") diff --git a/webapp/views.py b/webapp/views.py index d6b3922..94249d4 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -5,7 +5,7 @@ from django.utils import timezone from dealer.git import git from django.conf import settings from django.contrib.auth import authenticate -from django.http import HttpResponse +from django.http import HttpResponseBadRequest from django.shortcuts import redirect, render from django.views.decorators.http import require_http_methods from django_filters import rest_framework as filters @@ -45,9 +45,10 @@ class EventViewSet(viewsets.ModelViewSet): def get_queryset(self): since = self.request.query_params.get('since', None) + if self.request.user.is_authenticated: + return Event.objects.all() if since: return Event.objects.filter(visible=True, end_time__gt=since).order_by('start_time') - return Event.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time') @@ -61,6 +62,8 @@ class SignupFormViewSet(viewsets.ModelViewSet): # search_fields = '__all__' def get_queryset(self): + if self.request.user.is_authenticated: + return SignupForm.objects.all().order_by('start_time') return SignupForm.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time') @@ -72,8 +75,18 @@ class SignupViewSet(viewsets.ModelViewSet): # filter_fields = '__all__' # search_fields = '__all__' - # def get_queryset(self): - # return Signup.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time') + def create(self, request, *args, **kwargs): + try: + form = SignupForm.objects.get(id=request.data["signupForm_id"]) + if (form.visible): + return super().create(request, *args, **kwargs) + except: + return HttpResponseBadRequest() + else: + return HttpResponseBadRequest() + + def update(self, request, *args, **kwargs): + return super().update(request, *args, **kwargs) class SavedQuestionsViewSet(viewsets.ModelViewSet): @@ -91,7 +104,10 @@ class FeedViewSet(viewsets.ModelViewSet): search_fields = '__all__' def get_queryset(self): - objs = Feed.objects.filter(visible=True).order_by('publish_time') + if self.request.user.is_authenticated: + objs = Feed.objects.all().order_by('publish_time') + else: + objs = Feed.objects.filter(visible=True).order_by('publish_time') result_ids = [] for obj in objs: From 373db50995f9f417a272645aa6597d2c8ce43df5 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Mon, 11 Nov 2019 00:47:22 +0200 Subject: [PATCH 67/72] Minor fix to GET as admin --- webapp/views.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/webapp/views.py b/webapp/views.py index 94249d4..4f3f055 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -44,9 +44,10 @@ class EventViewSet(viewsets.ModelViewSet): search_fields = '__all__' def get_queryset(self): - since = self.request.query_params.get('since', None) if self.request.user.is_authenticated: return Event.objects.all() + + since = self.request.query_params.get('since', None) if since: return Event.objects.filter(visible=True, end_time__gt=since).order_by('start_time') return Event.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time') @@ -105,7 +106,7 @@ class FeedViewSet(viewsets.ModelViewSet): def get_queryset(self): if self.request.user.is_authenticated: - objs = Feed.objects.all().order_by('publish_time') + return Feed.objects.all().order_by('publish_time') else: objs = Feed.objects.filter(visible=True).order_by('publish_time') From c5df450a96aeef7666bc5db14e7ae9d8176a99ed Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Mon, 11 Nov 2019 00:56:39 +0200 Subject: [PATCH 68/72] Minor import bug fix --- webapp/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/views.py b/webapp/views.py index 4f3f055..b07bd1b 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -5,7 +5,7 @@ from django.utils import timezone from dealer.git import git from django.conf import settings from django.contrib.auth import authenticate -from django.http import HttpResponseBadRequest +from django.http import HttpResponseBadRequest, HttpResponse from django.shortcuts import redirect, render from django.views.decorators.http import require_http_methods from django_filters import rest_framework as filters From 368b28d2416bc750b7de0906b5e77f7b98805a1b Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Mon, 11 Nov 2019 22:59:11 +0200 Subject: [PATCH 69/72] Debug mode ALLOWED_HOSTS wildcard --- sikweb/settings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sikweb/settings.py b/sikweb/settings.py index 7f8fd21..8e3d1a2 100644 --- a/sikweb/settings.py +++ b/sikweb/settings.py @@ -18,6 +18,7 @@ DEBUG = os.getenv('DEBUG', False) == 'True' URL = os.getenv("HOST", "sika.sik.party") ALLOWED_HOSTS = ["localhost", "127.0.0.1", URL] +if DEBUG: ALLOWED_HOSTS = ["*"] # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.getenv('SECRET_KEY', '') From c2222d44269dd3fba401a1213084d39da8145cd9 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Fri, 22 Nov 2019 18:09:53 +0200 Subject: [PATCH 70/72] Fix lint --- sikweb/settings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sikweb/settings.py b/sikweb/settings.py index 8e3d1a2..908b936 100644 --- a/sikweb/settings.py +++ b/sikweb/settings.py @@ -18,7 +18,8 @@ DEBUG = os.getenv('DEBUG', False) == 'True' URL = os.getenv("HOST", "sika.sik.party") ALLOWED_HOSTS = ["localhost", "127.0.0.1", URL] -if DEBUG: ALLOWED_HOSTS = ["*"] +if DEBUG: + ALLOWED_HOSTS = ["*"] # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.getenv('SECRET_KEY', '') From 66d9ee0a751600a2b739cb8b5a9773bf957170f0 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Tue, 17 Dec 2019 18:11:46 +0200 Subject: [PATCH 71/72] Update backend postgres --- stack-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stack-compose.yml b/stack-compose.yml index d79338b..76ea73c 100644 --- a/stack-compose.yml +++ b/stack-compose.yml @@ -1,7 +1,7 @@ version: '3.4' services: db: - image: postgres:10 + image: postgres:12 deploy: replicas: 1 restart_policy: From 242199399b3b9aeda9fe2d476cb3c06a990989a8 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Tue, 17 Dec 2019 18:28:37 +0200 Subject: [PATCH 72/72] Use stop-first for PG update_config --- stack-compose.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/stack-compose.yml b/stack-compose.yml index 76ea73c..023d0b9 100644 --- a/stack-compose.yml +++ b/stack-compose.yml @@ -6,8 +6,6 @@ services: replicas: 1 restart_policy: condition: on-failure - update_config: - order: start-first environment: - POSTGRES_USER_FILE=/run/secrets/DJANGO_DB_USER