diff --git a/.gitignore b/.gitignore index b8cf6b3..3e94738 100644 --- a/.gitignore +++ b/.gitignore @@ -197,3 +197,4 @@ $RECYCLE.BIN/ .idea/ *.iml .mason/ +mason-lock.json \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 463eba8..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,126 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "wyatt_clean_code", - "cwd": "apps/wyatt_clean_code", - "request": "launch", - "type": "dart" - }, - { - "name": "wyatt_clean_code (profile mode)", - "cwd": "apps/wyatt_clean_code", - "request": "launch", - "type": "dart", - "flutterMode": "profile" - }, - { - "name": "wyatt_clean_code (release mode)", - "cwd": "apps/wyatt_clean_code", - "request": "launch", - "type": "dart", - "flutterMode": "release" - }, - { - "name": "brick_generator", - "cwd": "tools/brick_generator", - "request": "launch", - "type": "dart" - }, - { - "name": "__brick__", - "cwd": "bricks/core_app_brick/__brick__", - "request": "launch", - "type": "dart" - }, - { - "name": "__brick__ (profile mode)", - "cwd": "bricks/core_app_brick/__brick__", - "request": "launch", - "type": "dart", - "flutterMode": "profile" - }, - { - "name": "__brick__ (release mode)", - "cwd": "bricks/core_app_brick/__brick__", - "request": "launch", - "type": "dart", - "flutterMode": "release" - }, - { - "name": "__brick__", - "cwd": "bricks/wyatt_clean_code/__brick__", - "request": "launch", - "type": "dart" - }, - { - "name": "__brick__ (profile mode)", - "cwd": "bricks/wyatt_clean_code/__brick__", - "request": "launch", - "type": "dart", - "flutterMode": "profile" - }, - { - "name": "__brick__ (release mode)", - "cwd": "bricks/wyatt_clean_code/__brick__", - "request": "launch", - "type": "dart", - "flutterMode": "release" - }, - { - "name": "hooks", - "cwd": "bricks/wyatt_clean_code/hooks", - "request": "launch", - "type": "dart" - }, - { - "name": "__brick__", - "cwd": "bricks/wyatt_package/__brick__", - "request": "launch", - "type": "dart" - }, - { - "name": "__brick__ (profile mode)", - "cwd": "bricks/wyatt_package/__brick__", - "request": "launch", - "type": "dart", - "flutterMode": "profile" - }, - { - "name": "__brick__ (release mode)", - "cwd": "bricks/wyatt_package/__brick__", - "request": "launch", - "type": "dart", - "flutterMode": "release" - }, - { - "name": "hooks", - "cwd": "bricks/wyatt_package/hooks", - "request": "launch", - "type": "dart" - }, - { - "name": "example", - "cwd": "bricks/wyatt_package/__brick__/example", - "request": "launch", - "type": "dart" - }, - { - "name": "example (profile mode)", - "cwd": "bricks/wyatt_package/__brick__/example", - "request": "launch", - "type": "dart", - "flutterMode": "profile" - }, - { - "name": "example (release mode)", - "cwd": "bricks/wyatt_package/__brick__/example", - "request": "launch", - "type": "dart", - "flutterMode": "release" - } - ] -} \ No newline at end of file diff --git a/README.md b/README.md index 8605d14..b307755 100644 --- a/README.md +++ b/README.md @@ -53,10 +53,22 @@ mason init ## Create a Brick +- Create a **Brickgen** project in `apps/`. + ```sh -mason new -o ./bricks +mason make wyatt_brick_template -o apps/new_brick ``` +- Create/Modify your compilable code in `apps/new_brick/new_brick`. +- Customize the `brickgen.yaml` config file. +- Generate the brick using `brickgen` cli tool. + +```sh +dart ./tools/brick_generator/bin/brickgen.dart ./apps/new_brick/ ./bricks/ +``` + +> More infos about generator in `./tools/brick_generator`. + ## Use Please add your bricks in `./bricks`. (See `Create a Brick` section) diff --git a/apps/wyatt_app_template/brickgen.yaml b/apps/wyatt_app_template/brickgen.yaml new file mode 100644 index 0000000..00b0e3a --- /dev/null +++ b/apps/wyatt_app_template/brickgen.yaml @@ -0,0 +1,69 @@ +# Copyright (C) 2023 WYATT GROUP +# Please see the AUTHORS file for details. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +name: wyatt_app_template +description: New app template for Wyatt Studio projects. + +version: 0.1.0 + +vars: + display_name: + compilable: Display Name + type: string + description: The display name + default: Display Name + prompt: "What is the display name?" + formats: + - title_case + + project_name: + compilable: starting_template + type: string + description: The project name + default: starting_template + prompt: "What is the project name?" + formats: + - snake_case + + bundle_id: + compilable: io.wyattapp.start + type: string + description: The bundle id used in Android and iOS + default: io.wyattapp.start + prompt: "What is the bundle id?" + formats: + - dot_case + + description: + compilable: A short project description + type: string + description: A short project description + default: An app by Wyatt Studio. + prompt: "What is the project description?" + formats: + - sentence_case + +brickgen: + path_to_brickify: starting_template + hooks: true + ignore: + - .env + - package-lock.json + - .dart_tool/ + - .idea/ + - build/ + - node_modules/ + - ios/.symlinks/ diff --git a/apps/wyatt_app_template/hooks/post_gen.dart b/apps/wyatt_app_template/hooks/post_gen.dart new file mode 100644 index 0000000..398a858 --- /dev/null +++ b/apps/wyatt_app_template/hooks/post_gen.dart @@ -0,0 +1,39 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:mason/mason.dart'; + +void removeGitKeepFiles(String targetPath) { + if (!FileSystemEntity.isDirectorySync(targetPath)) { + throw ArgumentError('Target must be a directory', 'targetPath'); + } + + Directory(targetPath) + .listSync(recursive: true) + .whereType() + .forEach((file) { + if (file.path.contains('.gitkeep')) { + file.deleteSync(recursive: true); + } + }); +} + +Future run(HookContext context) async { + final workingDirectory = Directory.current.path; + removeGitKeepFiles(workingDirectory); +} diff --git a/apps/wyatt_app_template/hooks/pubspec.yaml b/apps/wyatt_app_template/hooks/pubspec.yaml new file mode 100644 index 0000000..454f6df --- /dev/null +++ b/apps/wyatt_app_template/hooks/pubspec.yaml @@ -0,0 +1,7 @@ +name: hooks + +environment: + sdk: ">=2.18.0 <3.0.0" + +dependencies: + mason: any \ No newline at end of file diff --git a/apps/wyatt_app_template/starting_template/.env.example b/apps/wyatt_app_template/starting_template/.env.example new file mode 100644 index 0000000..e69de29 diff --git a/apps/wyatt_app_template/starting_template/.gitignore b/apps/wyatt_app_template/starting_template/.gitignore new file mode 100644 index 0000000..9e1210f --- /dev/null +++ b/apps/wyatt_app_template/starting_template/.gitignore @@ -0,0 +1,54 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ +*.env.* +!*.env.example + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release +.mason/ + +.env +!.env.example +node_modules/ \ No newline at end of file diff --git a/apps/wyatt_app_template/starting_template/.metadata b/apps/wyatt_app_template/starting_template/.metadata new file mode 100644 index 0000000..32d8944 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 135454af32477f815a7525073027a3ff9eff1bfd + channel: stable + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + - platform: web + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/apps/wyatt_app_template/starting_template/.vscode/launch.json b/apps/wyatt_app_template/starting_template/.vscode/launch.json new file mode 100644 index 0000000..3e84edd --- /dev/null +++ b/apps/wyatt_app_template/starting_template/.vscode/launch.json @@ -0,0 +1,77 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch development/debug:mocks", + "request": "launch", + "type": "dart", + "program": "lib/main_development.dart", + "args": [ + "--dart-define=dev_mode=mock", + "--target", + "lib/main_development.dart" + ], + "flutterMode": "debug" + }, + { + "name": "Launch development/debug:emulator", + "request": "launch", + "type": "dart", + "program": "lib/main_development.dart", + "args": [ + "--dart-define=dev_mode=emulator", + "--target", + "lib/main_development.dart" + ], + "flutterMode": "debug" + }, + { + "name": "Launch development/debug:real", + "request": "launch", + "type": "dart", + "program": "lib/main_development.dart", + "args": [ + "--dart-define=dev_mode=real", + "--target", + "lib/main_development.dart" + ], + "flutterMode": "debug" + }, + { + "name": "Launch staging/debug", + "request": "launch", + "type": "dart", + "program": "lib/main_staging.dart", + "args": [ + "--target", + "lib/main_staging.dart" + ], + "flutterMode": "debug" + }, + { + "name": "Launch production/debug", + "request": "launch", + "type": "dart", + "program": "lib/main_production.dart", + "args": [ + "--target", + "lib/main_production.dart" + ], + "flutterMode": "debug" + }, + { + "name": "Launch production/release", + "request": "launch", + "type": "dart", + "program": "lib/main_production.dart", + "args": [ + "--target", + "lib/main_production.dart" + ], + "flutterMode": "release" + }, + ] +} \ No newline at end of file diff --git a/apps/wyatt_app_template/starting_template/.vscode/settings.json b/apps/wyatt_app_template/starting_template/.vscode/settings.json new file mode 100644 index 0000000..364ffbc --- /dev/null +++ b/apps/wyatt_app_template/starting_template/.vscode/settings.json @@ -0,0 +1,15 @@ +{ + "bloc.newCubitTemplate.type": "equatable", + "psi-header.config": { + "blankLinesAfter": 0, + "forceToTop": true, + }, + "psi-header.templates": [ + { + "language": "*", + "template": [ + "Display Name Copyright (c) <>" + ] + } + ], +} \ No newline at end of file diff --git a/apps/wyatt_app_template/starting_template/README.md b/apps/wyatt_app_template/starting_template/README.md new file mode 100644 index 0000000..971d825 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/README.md @@ -0,0 +1,59 @@ +# Display Name + +A short project description + +## Requirements + +* Flutter +* Taskfile +* Trapeze (with `npm install` thanks to `package.json`) + +### Configuration + +Create `.env` file with + +```sh +cp .env.example .env +``` + +### Taskfile + +Available tasks: + +| Command | Description | Aliases | +|----|-----|-----| +| `clean` | Cleans the environment.| `cl` | +| `format` |Formats the code.| `fmt` | +| `help` |Help dialog.| `h, default` | +| `lint` |Lints the code.| `l` | +| `start-emulators` | Start needed emulators.| `emu` | +| `build:android` | Building Android APK| `build:a` | +| `build:ios` | Building iOS IPA| `build:i` | +| `gen:build` | Running build runner| `gen:b` | +| `gen:build-delete` |Running build runner with deletion of conflicting outputs| `gen:d` | +| `gen:clean` | Cleaning build runner| `gen:c` | +| `gen:intl` |Generating internationalization file| `gen:i` | +| `gen:trapeze` | Running Trapeze config| `gen:t` | +| `gen:watch` | Running build runner in watch mode| `gen:w` | +| `pub:get` | Getting latest dependencies| `pub:g` | +| `pub:outdated` |Checking for outdated dependencies| `pub:o` | +| `pub:upgrade` | Upgrading dependencies| `pub:u` | +| `pub:upgrade-major` | Upgrading dependencies| `pub:um` | +| `pub:validate` |Running dependency validator| `pub:v` | +| `run:dev` | Run app in development environment| `run:d` | +| `run:emu` | Run app in development with emulated environment| `run:e` | +| `run:logs` |Show log output for running Flutter apps| `run:l` | +| `run:mock` |Run app in development environment with mocks| `run:m` | +| `run:prod` |Run app in production environment| `run:p` | +| `run:release` | Run app in production environment and in release mode| `run:r` | +| `run:staging` | Run app in staging environment| `run:s` | + +### Flavors + +| Flavor | Details | +|-------|--------| +| Development | Use `--dart-define="dev_mode="` to choose between `mock` , `emulator` and `real` | +| Staging | With a green banner. Only `real` mode available (remote data sources) | +| Production | Only `real` mode available (remote data sources) | + +> In `lib/core/flavors/flavor.dart` you can customize flavors. diff --git a/apps/wyatt_app_template/starting_template/Taskfile.yml b/apps/wyatt_app_template/starting_template/Taskfile.yml new file mode 100644 index 0000000..43888b9 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/Taskfile.yml @@ -0,0 +1,51 @@ +version: 3 + +vars: + RED: '\033[0;31m' + GREEN: '\033[0;32m' + COLOROFF: '\033[0m' + PREFIX: "⏳" + +includes: + gen: ./automation/generator.yml + pub: ./automation/pub.yml + run: ./automation/run.yml + build: ./automation/build.yml + +silent: true + +tasks: + help: + desc: Help dialog. + aliases: [h, default] + cmds: + - task --summary --list-all + + clean: + desc: Cleans the environment. + aliases: [cl] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Cleaning the project...{{.COLOROFF}}" + - flutter clean + + format: + desc: Formats the code. + aliases: [fmt] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Formatting the code...{{.COLOROFF}}" + - flutter format --fix + - dart fix --apply + + lint: + desc: Lints the code. + aliases: [l] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Verifying code...{{.COLOROFF}}" + - dart analyze . || (echo "Error in project"; exit 1) + + start-emulators: + desc: Start needed emulators. + aliases: [emu] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Start Firebase emulators...{{.COLOROFF}}" + - firebase emulators:start --only auth,functions,firestore,storage --import=./functions/saved-data --export-on-exit=./functions/saved-data diff --git a/apps/wyatt_app_template/starting_template/analysis_options.yaml b/apps/wyatt_app_template/starting_template/analysis_options.yaml new file mode 100644 index 0000000..6b75b4c --- /dev/null +++ b/apps/wyatt_app_template/starting_template/analysis_options.yaml @@ -0,0 +1,27 @@ +include: package:wyatt_analysis/analysis_options.flutter.yaml + +analyzer: + plugins: + - dart_code_metrics + +dart_code_metrics: + anti-patterns: + - long-method + - long-parameter-list + metrics: + cyclomatic-complexity: 20 + maximum-nesting-level: 5 + number-of-parameters: 4 + source-lines-of-code: 50 + metrics-exclude: + - test/** + rules: + - newline-before-return + - no-boolean-literal-compare + - no-empty-block + - prefer-trailing-comma + - prefer-conditional-expressions + - no-equal-then-else + - avoid-border-all + - prefer-const-border-radius + - prefer-using-list-view diff --git a/apps/wyatt_feature_brick/android/.gitignore b/apps/wyatt_app_template/starting_template/android/.gitignore similarity index 100% rename from apps/wyatt_feature_brick/android/.gitignore rename to apps/wyatt_app_template/starting_template/android/.gitignore diff --git a/apps/wyatt_feature_brick/android/app/build.gradle b/apps/wyatt_app_template/starting_template/android/app/build.gradle similarity index 97% rename from apps/wyatt_feature_brick/android/app/build.gradle rename to apps/wyatt_app_template/starting_template/android/app/build.gradle index 9a12ea4..a391659 100644 --- a/apps/wyatt_feature_brick/android/app/build.gradle +++ b/apps/wyatt_app_template/starting_template/android/app/build.gradle @@ -44,7 +44,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.wyatt_feature_brick" + applicationId "io.wyattapp.start" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. minSdkVersion flutter.minSdkVersion diff --git a/apps/wyatt_feature_brick/android/app/src/profile/AndroidManifest.xml b/apps/wyatt_app_template/starting_template/android/app/src/debug/AndroidManifest.xml similarity index 88% rename from apps/wyatt_feature_brick/android/app/src/profile/AndroidManifest.xml rename to apps/wyatt_app_template/starting_template/android/app/src/debug/AndroidManifest.xml index 4de5ed0..90c5a3d 100644 --- a/apps/wyatt_feature_brick/android/app/src/profile/AndroidManifest.xml +++ b/apps/wyatt_app_template/starting_template/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="io.wyattapp.start"> - + - - + + - + diff --git a/apps/wyatt_feature_brick/android/app/src/main/kotlin/com/example/wyatt_feature_brick/MainActivity.kt b/apps/wyatt_app_template/starting_template/android/app/src/main/kotlin/io/wyattapp/start/MainActivity.kt similarity index 70% rename from apps/wyatt_feature_brick/android/app/src/main/kotlin/com/example/wyatt_feature_brick/MainActivity.kt rename to apps/wyatt_app_template/starting_template/android/app/src/main/kotlin/io/wyattapp/start/MainActivity.kt index c68250d..894a9e7 100644 --- a/apps/wyatt_feature_brick/android/app/src/main/kotlin/com/example/wyatt_feature_brick/MainActivity.kt +++ b/apps/wyatt_app_template/starting_template/android/app/src/main/kotlin/io/wyattapp/start/MainActivity.kt @@ -1,4 +1,4 @@ -package com.example.wyatt_feature_brick +package io.wyattapp.start import io.flutter.embedding.android.FlutterActivity diff --git a/apps/wyatt_feature_brick/android/app/src/main/res/drawable-v21/launch_background.xml b/apps/wyatt_app_template/starting_template/android/app/src/main/res/drawable-v21/launch_background.xml similarity index 100% rename from apps/wyatt_feature_brick/android/app/src/main/res/drawable-v21/launch_background.xml rename to apps/wyatt_app_template/starting_template/android/app/src/main/res/drawable-v21/launch_background.xml diff --git a/apps/wyatt_feature_brick/android/app/src/main/res/drawable/launch_background.xml b/apps/wyatt_app_template/starting_template/android/app/src/main/res/drawable/launch_background.xml similarity index 100% rename from apps/wyatt_feature_brick/android/app/src/main/res/drawable/launch_background.xml rename to apps/wyatt_app_template/starting_template/android/app/src/main/res/drawable/launch_background.xml diff --git a/apps/wyatt_feature_brick/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/apps/wyatt_app_template/starting_template/android/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from apps/wyatt_feature_brick/android/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to apps/wyatt_app_template/starting_template/android/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/apps/wyatt_feature_brick/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/apps/wyatt_app_template/starting_template/android/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from apps/wyatt_feature_brick/android/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to apps/wyatt_app_template/starting_template/android/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/apps/wyatt_feature_brick/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/apps/wyatt_app_template/starting_template/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from apps/wyatt_feature_brick/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to apps/wyatt_app_template/starting_template/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/apps/wyatt_feature_brick/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/apps/wyatt_app_template/starting_template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from apps/wyatt_feature_brick/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to apps/wyatt_app_template/starting_template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/apps/wyatt_feature_brick/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/apps/wyatt_app_template/starting_template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from apps/wyatt_feature_brick/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to apps/wyatt_app_template/starting_template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/apps/wyatt_feature_brick/android/app/src/main/res/values-night/styles.xml b/apps/wyatt_app_template/starting_template/android/app/src/main/res/values-night/styles.xml similarity index 100% rename from apps/wyatt_feature_brick/android/app/src/main/res/values-night/styles.xml rename to apps/wyatt_app_template/starting_template/android/app/src/main/res/values-night/styles.xml diff --git a/apps/wyatt_feature_brick/android/app/src/main/res/values/styles.xml b/apps/wyatt_app_template/starting_template/android/app/src/main/res/values/styles.xml similarity index 100% rename from apps/wyatt_feature_brick/android/app/src/main/res/values/styles.xml rename to apps/wyatt_app_template/starting_template/android/app/src/main/res/values/styles.xml diff --git a/apps/wyatt_feature_brick/android/app/src/debug/AndroidManifest.xml b/apps/wyatt_app_template/starting_template/android/app/src/profile/AndroidManifest.xml similarity index 88% rename from apps/wyatt_feature_brick/android/app/src/debug/AndroidManifest.xml rename to apps/wyatt_app_template/starting_template/android/app/src/profile/AndroidManifest.xml index 4de5ed0..90c5a3d 100644 --- a/apps/wyatt_feature_brick/android/app/src/debug/AndroidManifest.xml +++ b/apps/wyatt_app_template/starting_template/android/app/src/profile/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="io.wyattapp.start"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/wyatt_app_template/starting_template/ios/Runner/Base.lproj/Main.storyboard b/apps/wyatt_app_template/starting_template/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/wyatt_app_template/starting_template/ios/Runner/Info.plist b/apps/wyatt_app_template/starting_template/ios/Runner/Info.plist new file mode 100644 index 0000000..69cdb0e --- /dev/null +++ b/apps/wyatt_app_template/starting_template/ios/Runner/Info.plist @@ -0,0 +1,51 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Display Name + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Display Name + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + + \ No newline at end of file diff --git a/apps/wyatt_app_template/starting_template/ios/Runner/Runner-Bridging-Header.h b/apps/wyatt_app_template/starting_template/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/apps/wyatt_app_template/starting_template/ios/Runner/Runner.entitlements b/apps/wyatt_app_template/starting_template/ios/Runner/Runner.entitlements new file mode 100644 index 0000000..74c85d2 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/ios/Runner/Runner.entitlements @@ -0,0 +1,8 @@ + + + + + aps-environment + development + + \ No newline at end of file diff --git a/apps/wyatt_app_template/starting_template/l10n.yaml b/apps/wyatt_app_template/starting_template/l10n.yaml new file mode 100644 index 0000000..aeed2b1 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/l10n.yaml @@ -0,0 +1,8 @@ +arb-dir: assets/l10n +template-arb-file: intl_fr.arb +output-localization-file: app_localizations.dart +output-dir: lib/gen/ +nullable-getter: false +use-deferred-loading: true +synthetic-package: false +header: "/// Display Name, localized files. Automatically generated with `task gen:intl`." \ No newline at end of file diff --git a/apps/wyatt_app_template/starting_template/lib/bootstrap.dart b/apps/wyatt_app_template/starting_template/lib/bootstrap.dart new file mode 100644 index 0000000..d709aee --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/bootstrap.dart @@ -0,0 +1,20 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:starting_template/core/dependency_injection/get_it.dart'; +import 'package:starting_template/core/flavors/flavor.dart'; +import 'package:starting_template/core/utils/app_bloc_observer.dart'; + +Future bootstrap(FutureOr Function() builder) async { + final widgetsBinding = WidgetsFlutterBinding.ensureInitialized(); + // FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding); + + Bloc.observer = AppBlocObserver(); + + debugPrint('Flavor: ${Flavor.get()}'); + + await GetItInitializer.init(); + + runApp(await builder()); +} diff --git a/apps/wyatt_app_template/starting_template/lib/core/constants/emulator.dart b/apps/wyatt_app_template/starting_template/lib/core/constants/emulator.dart new file mode 100644 index 0000000..00258ff --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/core/constants/emulator.dart @@ -0,0 +1,18 @@ +/// Firebase Emulator constants. +/// +/// If you don't use Firebase, it can be safely deleted. +abstract class Emulator { + static const String firebaseCloudFunctionEnvKey = + 'EMULATOR_FIREBASE_CLOUD_FUNCTION_PORT'; + static const String firebaseFirestoreEnvKey = + 'EMULATOR_FIREBASE_FIRESTORE_PORT'; + static const String firebaseAuthEnvKey = 'EMULATOR_FIREBASE_AUTH_PORT'; + static const String firebaseStorageEnvKey = 'EMULATOR_FIREBASE_STORAGE_PORT'; + static const String hostEnvKey = 'EMULATOR_HOST'; + + static const int defaultFirebaseCloudFunctionPort = 5001; + static const int defaultFirebaseFirestorePort = 8080; + static const int defaultFirebaseAuthPort = 9099; + static const int defaultFirebaseStoragePort = 9199; + static const defaultHost = 'localhost'; +} diff --git a/apps/wyatt_app_template/starting_template/lib/core/dependency_injection/get_it.dart b/apps/wyatt_app_template/starting_template/lib/core/dependency_injection/get_it.dart new file mode 100644 index 0000000..9541bce --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/core/dependency_injection/get_it.dart @@ -0,0 +1,40 @@ +import 'dart:async'; + +import 'package:get_it/get_it.dart'; +import 'package:starting_template/core/enums/dev_mode.dart'; +import 'package:starting_template/core/flavors/flavor.dart'; +import 'package:starting_template/data/data_sources/local/counter_data_source_impl.dart'; +import 'package:starting_template/domain/data_sources/local/counter_data_source.dart'; + +final getIt = GetIt.I; + +/// Service and Data Source locator +abstract class GetItInitializer { + static FutureOr _initCommon() async { + // Initialize common sources/services + getIt.registerLazySingleton( + CounterDataSourceImpl.new, + ); + } + + static FutureOr _initMocks() async { + // Initialize mocked sources/services. + } + + static FutureOr _initReal() async { + // Initialize real sources/services + } + + static FutureOr init() async { + await _initCommon(); + final flavor = Flavor.get(); + + if (flavor.devMode == DevMode.mock) { + await _initMocks(); + } else { + await _initReal(); + } + + await getIt.allReady(); + } +} diff --git a/apps/wyatt_app_template/starting_template/lib/core/enums/dev_mode.dart b/apps/wyatt_app_template/starting_template/lib/core/enums/dev_mode.dart new file mode 100644 index 0000000..bd4ad84 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/core/enums/dev_mode.dart @@ -0,0 +1,20 @@ +enum DevMode { + mock, + emulator, + real; + + @override + String toString() => name; + + /// Tries to parse String and returns mode. Fallback is returned if there + /// is an error during parsing. + static DevMode fromString(String? mode, {DevMode fallback = DevMode.mock}) { + for (final m in values) { + if (m.name == mode) { + return m; + } + } + + return fallback; + } +} diff --git a/apps/wyatt_app_template/starting_template/lib/core/extensions/build_context_extension.dart b/apps/wyatt_app_template/starting_template/lib/core/extensions/build_context_extension.dart new file mode 100644 index 0000000..1eabb49 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/core/extensions/build_context_extension.dart @@ -0,0 +1,6 @@ +import 'package:flutter/widgets.dart'; +import 'package:starting_template/gen/app_localizations.dart'; + +extension BuildContextExtension on BuildContext { + AppLocalizations get l10n => AppLocalizations.of(this); +} diff --git a/apps/wyatt_app_template/starting_template/lib/core/flavors/flavor.dart b/apps/wyatt_app_template/starting_template/lib/core/flavors/flavor.dart new file mode 100644 index 0000000..6041145 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/core/flavors/flavor.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; +import 'package:starting_template/core/enums/dev_mode.dart'; + +abstract class Flavor { + Flavor._({ + this.banner, + this.bannerColor = Colors.red, + this.devMode, + }) { + _instance = this; + } + + static Flavor? _instance; + + final String? banner; + final Color bannerColor; + final DevMode? devMode; + + /// Returns [Flavor] instance. + static Flavor get() { + if (_instance == null) { + throw Exception('Flavor not initialized!'); + } + + return _instance!; + } + + @override + String toString() => runtimeType.toString().replaceAll('Flavor', ''); +} + +class DevelopmentFlavor extends Flavor { + factory DevelopmentFlavor() { + const modeString = String.fromEnvironment('dev_mode', defaultValue: 'mock'); + final mode = DevMode.fromString(modeString); + + return DevelopmentFlavor._(devMode: mode); + } + DevelopmentFlavor._({ + required DevMode devMode, + }) : super._( + banner: 'Dev', + devMode: devMode, + ); +} + +class StagingFlavor extends Flavor { + StagingFlavor() + : super._( + banner: 'Staging', + bannerColor: Colors.green, + ); +} + +class ProductionFlavor extends Flavor { + ProductionFlavor() : super._(); +} diff --git a/apps/wyatt_app_template/starting_template/lib/core/routes/router.dart b/apps/wyatt_app_template/starting_template/lib/core/routes/router.dart new file mode 100644 index 0000000..b652dc6 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/core/routes/router.dart @@ -0,0 +1,65 @@ +import 'package:flutter/cupertino.dart'; +import 'package:go_router/go_router.dart'; +import 'package:starting_template/presentation/features/counter/counter.dart'; +import 'package:starting_template/presentation/features/home/home.dart'; + +abstract class AppRouter { + /// Default transition for all pages + static Page defaultTransition( + BuildContext context, + GoRouterState state, + Widget child, + ) => + CupertinoPage( + key: state.pageKey, + child: child, + ); + + /// Disable transition animation + static Page noTransition( + BuildContext context, + GoRouterState state, + Widget child, + ) => + CustomTransitionPage( + key: state.pageKey, + transitionsBuilder: (_, __, ___, child) => child, + child: child, + ); + + /// Defines public routes (no authentication needed). + /// + /// Example: + /// ```dart + /// static final publicRoutes = [ + /// '/', + /// '/sign_in', + /// '/sign_up', + /// ]; + /// ``` + static final List publicRoutes = []; + + /// Defines GoRoute routes. + static final List routes = [ + GoRoute( + path: '/', + name: Home.pageName, + pageBuilder: (context, state) => + defaultTransition(context, state, const Home()), + ), + GoRoute( + path: '/counter', + name: Counter.pageName, + pageBuilder: (context, state) => + defaultTransition(context, state, const Counter()), + ), + ]; + + /// Router + static GoRouter router = GoRouter( + initialLocation: '/', + routes: AppRouter.routes, + debugLogDiagnostics: true, + redirect: (context, state) => null, + ); +} diff --git a/apps/wyatt_app_template/starting_template/lib/core/utils/app_bloc_observer.dart b/apps/wyatt_app_template/starting_template/lib/core/utils/app_bloc_observer.dart new file mode 100644 index 0000000..92be592 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/core/utils/app_bloc_observer.dart @@ -0,0 +1,74 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +const _messageLength = 100; + +class AppBlocObserver extends BlocObserver { + AppBlocObserver({ + this.printEvent = true, + this.printError = true, + this.printTransition = false, + this.printChange = true, + this.fullPrint = false, + }); + + final bool printEvent; + final bool printError; + final bool printChange; + final bool printTransition; + final bool fullPrint; + + String sanitize(Object? object) { + final message = object.toString(); + + return fullPrint + ? message + : message.substring( + 0, + message.length < _messageLength ? message.length : _messageLength, + ); + } + + @override + void onEvent(Bloc bloc, Object? event) { + super.onEvent(bloc, event); + if (printEvent) { + debugPrint('onEvent: ${bloc.runtimeType}\n' + '> event: ${sanitize(event)}'); + } + } + + @override + void onError(BlocBase bloc, Object error, StackTrace stackTrace) { + if (printError) { + debugPrint('onError: ${bloc.runtimeType}\n' + '> error: ${sanitize(error)}\n' + '$stackTrace'); + } + super.onError(bloc, error, stackTrace); + } + + @override + void onChange(BlocBase bloc, Change change) { + super.onChange(bloc, change); + if (printChange) { + debugPrint('onChange: ${bloc.runtimeType}\n' + '> currentState: ${sanitize(change.currentState)}\n' + '> nextState: ${sanitize(change.nextState)}'); + } + } + + @override + void onTransition( + Bloc bloc, + Transition transition, + ) { + super.onTransition(bloc, transition); + if (printTransition) { + debugPrint('onTransition: ${bloc.runtimeType}\n' + '> currentState: ${sanitize(transition.currentState)}\n' + '> event: ${sanitize(transition.event)}\n' + '> nextState: ${sanitize(transition.nextState)}'); + } + } +} diff --git a/apps/wyatt_app_template/starting_template/lib/data/data_sources/local/counter_data_source_impl.dart b/apps/wyatt_app_template/starting_template/lib/data/data_sources/local/counter_data_source_impl.dart new file mode 100644 index 0000000..85cdfe0 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/data/data_sources/local/counter_data_source_impl.dart @@ -0,0 +1,59 @@ +import 'dart:convert'; + +import 'package:starting_template/data/models/integer_model.dart'; +import 'package:starting_template/domain/data_sources/local/counter_data_source.dart'; +import 'package:starting_template/domain/entities/integer.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +class CounterDataSourceImpl extends CounterDataSource { + // Simulate external data processing + String actual = '{"value": 0}'; + + @override + Future decrement(Integer value) async { + final current = + IntegerModel.fromJson(json.decode(actual) as Map); + + final newValue = current.value - value.value; + if (newValue < 0) { + throw ClientException("Counter can't be negative!"); + } + + final newInteger = IntegerModel(value: newValue); + actual = jsonEncode(newInteger.toJson()); + + return newInteger; + } + + @override + Future increment(Integer value) async { + final current = + IntegerModel.fromJson(json.decode(actual) as Map); + + final newValue = current.value + value.value; + if (newValue < 0) { + throw ClientException("Counter can't be negative!"); + } + + final newInteger = IntegerModel(value: newValue); + actual = jsonEncode(newInteger.toJson()); + + return newInteger; + } + + @override + Future getCurrent() async { + final current = + IntegerModel.fromJson(json.decode(actual) as Map); + + return current; + } + + @override + Future reset() async { + const newInteger = IntegerModel(value: 0); + actual = jsonEncode(newInteger.toJson()); + + return newInteger; + } +} diff --git a/apps/wyatt_app_template/starting_template/lib/data/data_sources/remote/.gitkeep b/apps/wyatt_app_template/starting_template/lib/data/data_sources/remote/.gitkeep new file mode 100644 index 0000000..f94cb6f --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/data/data_sources/remote/.gitkeep @@ -0,0 +1 @@ +# just to keep empty folder in brick generation \ No newline at end of file diff --git a/apps/wyatt_app_template/starting_template/lib/data/models/integer_model.dart b/apps/wyatt_app_template/starting_template/lib/data/models/integer_model.dart new file mode 100644 index 0000000..fc1cad0 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/data/models/integer_model.dart @@ -0,0 +1,15 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:starting_template/domain/entities/integer.dart'; + +part 'integer_model.freezed.dart'; +part 'integer_model.g.dart'; + +@freezed +class IntegerModel extends Integer with _$IntegerModel { + const factory IntegerModel({ + required int value, + }) = _IntegerModel; + + factory IntegerModel.fromJson(Map json) => + _$IntegerModelFromJson(json); +} diff --git a/apps/wyatt_app_template/starting_template/lib/data/models/integer_model.freezed.dart b/apps/wyatt_app_template/starting_template/lib/data/models/integer_model.freezed.dart new file mode 100644 index 0000000..bed9972 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/data/models/integer_model.freezed.dart @@ -0,0 +1,151 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'integer_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + +IntegerModel _$IntegerModelFromJson(Map json) { + return _IntegerModel.fromJson(json); +} + +/// @nodoc +mixin _$IntegerModel { + int get value => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $IntegerModelCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $IntegerModelCopyWith<$Res> { + factory $IntegerModelCopyWith( + IntegerModel value, $Res Function(IntegerModel) then) = + _$IntegerModelCopyWithImpl<$Res, IntegerModel>; + @useResult + $Res call({int value}); +} + +/// @nodoc +class _$IntegerModelCopyWithImpl<$Res, $Val extends IntegerModel> + implements $IntegerModelCopyWith<$Res> { + _$IntegerModelCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? value = null, + }) { + return _then(_value.copyWith( + value: null == value + ? _value.value + : value // ignore: cast_nullable_to_non_nullable + as int, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$_IntegerModelCopyWith<$Res> + implements $IntegerModelCopyWith<$Res> { + factory _$$_IntegerModelCopyWith( + _$_IntegerModel value, $Res Function(_$_IntegerModel) then) = + __$$_IntegerModelCopyWithImpl<$Res>; + @override + @useResult + $Res call({int value}); +} + +/// @nodoc +class __$$_IntegerModelCopyWithImpl<$Res> + extends _$IntegerModelCopyWithImpl<$Res, _$_IntegerModel> + implements _$$_IntegerModelCopyWith<$Res> { + __$$_IntegerModelCopyWithImpl( + _$_IntegerModel _value, $Res Function(_$_IntegerModel) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? value = null, + }) { + return _then(_$_IntegerModel( + value: null == value + ? _value.value + : value // ignore: cast_nullable_to_non_nullable + as int, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$_IntegerModel implements _IntegerModel { + const _$_IntegerModel({required this.value}); + + factory _$_IntegerModel.fromJson(Map json) => + _$$_IntegerModelFromJson(json); + + @override + final int value; + + @override + String toString() { + return 'IntegerModel(value: $value)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_IntegerModel && + (identical(other.value, value) || other.value == value)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash(runtimeType, value); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$_IntegerModelCopyWith<_$_IntegerModel> get copyWith => + __$$_IntegerModelCopyWithImpl<_$_IntegerModel>(this, _$identity); + + @override + Map toJson() { + return _$$_IntegerModelToJson( + this, + ); + } +} + +abstract class _IntegerModel implements IntegerModel { + const factory _IntegerModel({required final int value}) = _$_IntegerModel; + + factory _IntegerModel.fromJson(Map json) = + _$_IntegerModel.fromJson; + + @override + int get value; + @override + @JsonKey(ignore: true) + _$$_IntegerModelCopyWith<_$_IntegerModel> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/apps/wyatt_app_template/starting_template/lib/data/models/integer_model.g.dart b/apps/wyatt_app_template/starting_template/lib/data/models/integer_model.g.dart new file mode 100644 index 0000000..291e5cf --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/data/models/integer_model.g.dart @@ -0,0 +1,17 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'integer_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$_IntegerModel _$$_IntegerModelFromJson(Map json) => + _$_IntegerModel( + value: json['value'] as int, + ); + +Map _$$_IntegerModelToJson(_$_IntegerModel instance) => + { + 'value': instance.value, + }; diff --git a/apps/wyatt_app_template/starting_template/lib/data/repositories/counter_repository_impl.dart b/apps/wyatt_app_template/starting_template/lib/data/repositories/counter_repository_impl.dart new file mode 100644 index 0000000..a18a5a5 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/data/repositories/counter_repository_impl.dart @@ -0,0 +1,41 @@ +import 'package:starting_template/domain/data_sources/local/counter_data_source.dart'; +import 'package:starting_template/domain/entities/integer.dart'; +import 'package:starting_template/domain/repositories/counter_repository.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; +import 'package:wyatt_type_utils/wyatt_type_utils.dart'; + +class CounterRepositoryImpl extends CounterRepository { + CounterRepositoryImpl({ + required CounterDataSource counterDataSource, + }) : _counterDataSource = counterDataSource; + + final CounterDataSource _counterDataSource; + + @override + FutureOrResult decrement({Integer by = const Integer(1)}) => + Result.tryCatchAsync( + () async => _counterDataSource.decrement(by), + (error) => error, + ); + + @override + FutureOrResult increment({Integer by = const Integer(1)}) => + Result.tryCatchAsync( + () async => _counterDataSource.increment(by), + (error) => error, + ); + + @override + FutureOrResult getCurrent() => + Result.tryCatchAsync( + () async => _counterDataSource.getCurrent(), + (error) => error, + ); + + @override + FutureOrResult reset() => + Result.tryCatchAsync( + () async => _counterDataSource.reset(), + (error) => error, + ); +} diff --git a/apps/wyatt_app_template/starting_template/lib/domain/data_sources/local/counter_data_source.dart b/apps/wyatt_app_template/starting_template/lib/domain/data_sources/local/counter_data_source.dart new file mode 100644 index 0000000..0481ba4 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/domain/data_sources/local/counter_data_source.dart @@ -0,0 +1,9 @@ +import 'package:starting_template/domain/entities/integer.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +abstract class CounterDataSource extends BaseDataSource { + Future decrement(Integer value); + Future increment(Integer value); + Future getCurrent(); + Future reset(); +} diff --git a/apps/wyatt_app_template/starting_template/lib/domain/data_sources/remote/.gitkeep b/apps/wyatt_app_template/starting_template/lib/domain/data_sources/remote/.gitkeep new file mode 100644 index 0000000..f94cb6f --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/domain/data_sources/remote/.gitkeep @@ -0,0 +1 @@ +# just to keep empty folder in brick generation \ No newline at end of file diff --git a/apps/wyatt_app_template/starting_template/lib/domain/entities/integer.dart b/apps/wyatt_app_template/starting_template/lib/domain/entities/integer.dart new file mode 100644 index 0000000..aea24f1 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/domain/entities/integer.dart @@ -0,0 +1,11 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +class Integer extends Entity { + const Integer(this.value); + + final int value; + + @override + String toString() => 'Integer(value: $value)'; +} diff --git a/apps/wyatt_app_template/starting_template/lib/domain/repositories/counter_repository.dart b/apps/wyatt_app_template/starting_template/lib/domain/repositories/counter_repository.dart new file mode 100644 index 0000000..fb75048 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/domain/repositories/counter_repository.dart @@ -0,0 +1,9 @@ +import 'package:starting_template/domain/entities/integer.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +abstract class CounterRepository extends BaseRepository { + FutureOrResult decrement({Integer by = const Integer(1)}); + FutureOrResult increment({Integer by = const Integer(1)}); + FutureOrResult getCurrent(); + FutureOrResult reset(); +} diff --git a/apps/wyatt_app_template/starting_template/lib/domain/usecases/counter/decrement.dart b/apps/wyatt_app_template/starting_template/lib/domain/usecases/counter/decrement.dart new file mode 100644 index 0000000..d240827 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/domain/usecases/counter/decrement.dart @@ -0,0 +1,18 @@ +import 'package:starting_template/domain/entities/integer.dart'; +import 'package:starting_template/domain/repositories/counter_repository.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +class Decrement extends AsyncUseCase { + Decrement({ + required CounterRepository counterRepository, + }) : _counterRepository = counterRepository; + + final CounterRepository _counterRepository; + + @override + FutureOrResult execute(int? params) async { + final step = Integer(params ?? 1); + + return _counterRepository.decrement(by: step); + } +} diff --git a/apps/wyatt_app_template/starting_template/lib/domain/usecases/counter/get_current.dart b/apps/wyatt_app_template/starting_template/lib/domain/usecases/counter/get_current.dart new file mode 100644 index 0000000..fd05c71 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/domain/usecases/counter/get_current.dart @@ -0,0 +1,31 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:starting_template/domain/entities/integer.dart'; +import 'package:starting_template/domain/repositories/counter_repository.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +class GetCurrent extends AsyncUseCase { + GetCurrent({ + required CounterRepository counterRepository, + }) : _counterRepository = counterRepository; + + final CounterRepository _counterRepository; + + @override + FutureOrResult execute(void params) async => + _counterRepository.getCurrent(); +} diff --git a/apps/wyatt_app_template/starting_template/lib/domain/usecases/counter/increment.dart b/apps/wyatt_app_template/starting_template/lib/domain/usecases/counter/increment.dart new file mode 100644 index 0000000..2dd418a --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/domain/usecases/counter/increment.dart @@ -0,0 +1,18 @@ +import 'package:starting_template/domain/entities/integer.dart'; +import 'package:starting_template/domain/repositories/counter_repository.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +class Increment extends AsyncUseCase { + Increment({ + required CounterRepository counterRepository, + }) : _counterRepository = counterRepository; + + final CounterRepository _counterRepository; + + @override + FutureOrResult execute(int? params) async { + final step = Integer(params ?? 1); + + return _counterRepository.increment(by: step); + } +} diff --git a/apps/wyatt_app_template/starting_template/lib/domain/usecases/counter/reset.dart b/apps/wyatt_app_template/starting_template/lib/domain/usecases/counter/reset.dart new file mode 100644 index 0000000..a7d950e --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/domain/usecases/counter/reset.dart @@ -0,0 +1,31 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:starting_template/domain/entities/integer.dart'; +import 'package:starting_template/domain/repositories/counter_repository.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +class Reset extends AsyncUseCase { + Reset({ + required CounterRepository counterRepository, + }) : _counterRepository = counterRepository; + + final CounterRepository _counterRepository; + + @override + FutureOrResult execute(void params) async => + _counterRepository.reset(); +} diff --git a/apps/wyatt_app_template/starting_template/lib/gen/app_localizations.dart b/apps/wyatt_app_template/starting_template/lib/gen/app_localizations.dart new file mode 100644 index 0000000..6081a53 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/gen/app_localizations.dart @@ -0,0 +1,142 @@ +/// Display Name, localized files. Automatically generated with `task gen:intl`. +import 'dart:async'; + +import 'package:flutter/widgets.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:intl/intl.dart' as intl; + +import 'app_localizations_fr.dart' deferred as app_localizations_fr; + +/// Callers can lookup localized strings with an instance of AppLocalizations +/// returned by `AppLocalizations.of(context)`. +/// +/// Applications need to include `AppLocalizations.delegate()` in their app's +/// `localizationDelegates` list, and the locales they support in the app's +/// `supportedLocales` list. For example: +/// +/// ```dart +/// import 'gen/app_localizations.dart'; +/// +/// return MaterialApp( +/// localizationsDelegates: AppLocalizations.localizationsDelegates, +/// supportedLocales: AppLocalizations.supportedLocales, +/// home: MyApplicationHome(), +/// ); +/// ``` +/// +/// ## Update pubspec.yaml +/// +/// Please make sure to update your pubspec.yaml to include the following +/// packages: +/// +/// ```yaml +/// dependencies: +/// # Internationalization support. +/// flutter_localizations: +/// sdk: flutter +/// intl: any # Use the pinned version from flutter_localizations +/// +/// # Rest of dependencies +/// ``` +/// +/// ## iOS Applications +/// +/// iOS applications define key application metadata, including supported +/// locales, in an Info.plist file that is built into the application bundle. +/// To configure the locales supported by your app, you’ll need to edit this +/// file. +/// +/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file. +/// Then, in the Project Navigator, open the Info.plist file under the Runner +/// project’s Runner folder. +/// +/// Next, select the Information Property List item, select Add Item from the +/// Editor menu, then select Localizations from the pop-up menu. +/// +/// Select and expand the newly-created Localizations item then, for each +/// locale your application supports, add a new item and select the locale +/// you wish to add from the pop-up menu in the Value field. This list should +/// be consistent with the languages listed in the AppLocalizations.supportedLocales +/// property. +abstract class AppLocalizations { + AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString()); + + final String localeName; + + static AppLocalizations of(BuildContext context) { + return Localizations.of(context, AppLocalizations)!; + } + + static const LocalizationsDelegate delegate = _AppLocalizationsDelegate(); + + /// A list of this localizations delegate along with the default localizations + /// delegates. + /// + /// Returns a list of localizations delegates containing this delegate along with + /// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, + /// and GlobalWidgetsLocalizations.delegate. + /// + /// Additional delegates can be added by appending to this list in + /// MaterialApp. This list does not have to be used at all if a custom list + /// of delegates is preferred or required. + static const List> localizationsDelegates = >[ + delegate, + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ]; + + /// A list of this localizations delegate's supported locales. + static const List supportedLocales = [ + Locale('fr') + ]; + + /// Texte affiché dans l'AppBar de la page Compteur + /// + /// In fr, this message translates to: + /// **'Compteur'** + String get counterAppBarTitle; + + /// Message affiché sur la page compteur + /// + /// In fr, this message translates to: + /// **'Vous avez appuyé {count} fois sur le bouton !'** + String youHavePushed(int count); + + /// Texte affiché dans le bouton ammenant vers la page Compteur + /// + /// In fr, this message translates to: + /// **'Aller au Compteur'** + String get goToCounter; +} + +class _AppLocalizationsDelegate extends LocalizationsDelegate { + const _AppLocalizationsDelegate(); + + @override + Future load(Locale locale) { + return lookupAppLocalizations(locale); + } + + @override + bool isSupported(Locale locale) => ['fr'].contains(locale.languageCode); + + @override + bool shouldReload(_AppLocalizationsDelegate old) => false; +} + +Future lookupAppLocalizations(Locale locale) { + + + // Lookup logic when only language code is specified. + switch (locale.languageCode) { + case 'fr': return app_localizations_fr.loadLibrary().then((dynamic _) => app_localizations_fr.AppLocalizationsFr()); + } + + throw FlutterError( + 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.' + ); +} diff --git a/apps/wyatt_app_template/starting_template/lib/gen/app_localizations_fr.dart b/apps/wyatt_app_template/starting_template/lib/gen/app_localizations_fr.dart new file mode 100644 index 0000000..e5fa2e5 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/gen/app_localizations_fr.dart @@ -0,0 +1,19 @@ +/// Display Name, localized files. Automatically generated with `task gen:intl`. + +import 'app_localizations.dart'; + +/// The translations for French (`fr`). +class AppLocalizationsFr extends AppLocalizations { + AppLocalizationsFr([String locale = 'fr']) : super(locale); + + @override + String get counterAppBarTitle => 'Compteur'; + + @override + String youHavePushed(int count) { + return 'Vous avez appuyé $count fois sur le bouton !'; + } + + @override + String get goToCounter => 'Aller au Compteur'; +} diff --git a/apps/wyatt_app_template/starting_template/lib/gen/assets.gen.dart b/apps/wyatt_app_template/starting_template/lib/gen/assets.gen.dart new file mode 100644 index 0000000..3deea52 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/gen/assets.gen.dart @@ -0,0 +1,92 @@ +/// GENERATED CODE - DO NOT MODIFY BY HAND +/// ***************************************************** +/// FlutterGen +/// ***************************************************** + +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal + +import 'package:flutter/widgets.dart'; + +class $AssetsImagesGen { + const $AssetsImagesGen(); + + /// File path: assets/images/wyatt_logo.jpeg + AssetGenImage get wyattLogo => + const AssetGenImage('assets/images/wyatt_logo.jpeg'); + + /// List of all assets + List get values => [wyattLogo]; +} + +class Assets { + Assets._(); + + static const $AssetsImagesGen images = $AssetsImagesGen(); +} + +class AssetGenImage { + const AssetGenImage(this._assetName); + + final String _assetName; + + Image image({ + Key? key, + AssetBundle? bundle, + ImageFrameBuilder? frameBuilder, + ImageErrorWidgetBuilder? errorBuilder, + String? semanticLabel, + bool excludeFromSemantics = false, + double? scale, + double? width, + double? height, + Color? color, + Animation? opacity, + BlendMode? colorBlendMode, + BoxFit? fit, + AlignmentGeometry alignment = Alignment.center, + ImageRepeat repeat = ImageRepeat.noRepeat, + Rect? centerSlice, + bool matchTextDirection = false, + bool gaplessPlayback = false, + bool isAntiAlias = false, + String? package, + FilterQuality filterQuality = FilterQuality.low, + int? cacheWidth, + int? cacheHeight, + }) { + return Image.asset( + _assetName, + key: key, + bundle: bundle, + frameBuilder: frameBuilder, + errorBuilder: errorBuilder, + semanticLabel: semanticLabel, + excludeFromSemantics: excludeFromSemantics, + scale: scale, + width: width, + height: height, + color: color, + opacity: opacity, + colorBlendMode: colorBlendMode, + fit: fit, + alignment: alignment, + repeat: repeat, + centerSlice: centerSlice, + matchTextDirection: matchTextDirection, + gaplessPlayback: gaplessPlayback, + isAntiAlias: isAntiAlias, + package: package, + filterQuality: filterQuality, + cacheWidth: cacheWidth, + cacheHeight: cacheHeight, + ); + } + + ImageProvider provider() => AssetImage(_assetName); + + String get path => _assetName; + + String get keyName => _assetName; +} diff --git a/apps/wyatt_app_template/starting_template/lib/gen/colors.gen.dart b/apps/wyatt_app_template/starting_template/lib/gen/colors.gen.dart new file mode 100644 index 0000000..7140be2 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/gen/colors.gen.dart @@ -0,0 +1,21 @@ +/// GENERATED CODE - DO NOT MODIFY BY HAND +/// ***************************************************** +/// FlutterGen +/// ***************************************************** + +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal + +import 'package:flutter/painting.dart'; +import 'package:flutter/material.dart'; + +class ColorName { + ColorName._(); + + /// Color: #000000 + static const Color black = Color(0xFF000000); + + /// Color: #FFFFFF + static const Color white = Color(0xFFFFFFFF); +} diff --git a/apps/wyatt_app_template/starting_template/lib/main.dart b/apps/wyatt_app_template/starting_template/lib/main.dart new file mode 100644 index 0000000..e016029 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/main.dart @@ -0,0 +1,115 @@ +import 'package:flutter/material.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + // This is the theme of your application. + // + // Try running your application with "flutter run". You'll see the + // application has a blue toolbar. Then, without quitting the app, try + // changing the primarySwatch below to Colors.green and then invoke + // "hot reload" (press "r" in the console where you ran "flutter run", + // or simply save your changes to "hot reload" in a Flutter IDE). + // Notice that the counter didn't reset back to zero; the application + // is not restarted. + primarySwatch: Colors.blue, + ), + home: const MyHomePage(title: 'Flutter Demo Home Page'), + ); + } +} + +class MyHomePage extends StatefulWidget { + const MyHomePage({super.key, required this.title}); + + // This widget is the home page of your application. It is stateful, meaning + // that it has a State object (defined below) that contains fields that affect + // how it looks. + + // This class is the configuration for the state. It holds the values (in this + // case the title) provided by the parent (in this case the App widget) and + // used by the build method of the State. Fields in a Widget subclass are + // always marked "final". + + final String title; + + @override + State createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + int _counter = 0; + + void _incrementCounter() { + setState(() { + // This call to setState tells the Flutter framework that something has + // changed in this State, which causes it to rerun the build method below + // so that the display can reflect the updated values. If we changed + // _counter without calling setState(), then the build method would not be + // called again, and so nothing would appear to happen. + _counter++; + }); + } + + @override + Widget build(BuildContext context) { + // This method is rerun every time setState is called, for instance as done + // by the _incrementCounter method above. + // + // The Flutter framework has been optimized to make rerunning build methods + // fast, so that you can just rebuild anything that needs updating rather + // than having to individually change instances of widgets. + return Scaffold( + appBar: AppBar( + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text(widget.title), + ), + body: Center( + // Center is a layout widget. It takes a single child and positions it + // in the middle of the parent. + child: Column( + // Column is also a layout widget. It takes a list of children and + // arranges them vertically. By default, it sizes itself to fit its + // children horizontally, and tries to be as tall as its parent. + // + // Invoke "debug painting" (press "p" in the console, choose the + // "Toggle Debug Paint" action from the Flutter Inspector in Android + // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) + // to see the wireframe for each widget. + // + // Column has various properties to control how it sizes itself and + // how it positions its children. Here we use mainAxisAlignment to + // center the children vertically; the main axis here is the vertical + // axis because Columns are vertical (the cross axis would be + // horizontal). + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + 'You have pushed the button this many times:', + ), + Text( + '$_counter', + style: Theme.of(context).textTheme.headline4, + ), + ], + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: _incrementCounter, + tooltip: 'Increment', + child: const Icon(Icons.add), + ), // This trailing comma makes auto-formatting nicer for build methods. + ); + } +} diff --git a/apps/wyatt_app_template/starting_template/lib/main_development.dart b/apps/wyatt_app_template/starting_template/lib/main_development.dart new file mode 100644 index 0000000..96da185 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/main_development.dart @@ -0,0 +1,11 @@ +import 'package:starting_template/bootstrap.dart'; +import 'package:starting_template/core/flavors/flavor.dart'; +import 'package:starting_template/presentation/features/app/app.dart'; + +void main(List args) { + // Define environment + DevelopmentFlavor(); + + // Initialize environment and variables + bootstrap(App.new); +} diff --git a/apps/wyatt_app_template/starting_template/lib/main_production.dart b/apps/wyatt_app_template/starting_template/lib/main_production.dart new file mode 100644 index 0000000..8f861f1 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/main_production.dart @@ -0,0 +1,11 @@ +import 'package:starting_template/bootstrap.dart'; +import 'package:starting_template/core/flavors/flavor.dart'; +import 'package:starting_template/presentation/features/app/app.dart'; + +void main(List args) { + // Define environment + ProductionFlavor(); + + // Initialize environment and variables + bootstrap(App.new); +} diff --git a/apps/wyatt_app_template/starting_template/lib/main_staging.dart b/apps/wyatt_app_template/starting_template/lib/main_staging.dart new file mode 100644 index 0000000..91dff1b --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/main_staging.dart @@ -0,0 +1,11 @@ +import 'package:starting_template/bootstrap.dart'; +import 'package:starting_template/core/flavors/flavor.dart'; +import 'package:starting_template/presentation/features/app/app.dart'; + +void main(List args) { + // Define environment + StagingFlavor(); + + // Initialize environment and variables + bootstrap(App.new); +} diff --git a/apps/wyatt_app_template/starting_template/lib/presentation/features/app/app.dart b/apps/wyatt_app_template/starting_template/lib/presentation/features/app/app.dart new file mode 100644 index 0000000..8cadcfc --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/presentation/features/app/app.dart @@ -0,0 +1,63 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:starting_template/core/dependency_injection/get_it.dart'; +import 'package:starting_template/core/flavors/flavor.dart'; +import 'package:starting_template/core/routes/router.dart'; +import 'package:starting_template/data/repositories/counter_repository_impl.dart'; +import 'package:starting_template/domain/repositories/counter_repository.dart'; +import 'package:starting_template/gen/app_localizations.dart'; +import 'package:starting_template/presentation/features/counter/blocs/counter_bloc/counter_bloc.dart'; +import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; + +class App extends StatelessWidget { + const App({super.key}); + + Widget _flavorBanner(Widget child) { + final flavor = Flavor.get(); + if (flavor.banner != null && !kReleaseMode) { + return Directionality( + textDirection: TextDirection.ltr, + child: Banner( + location: BannerLocation.topEnd, + message: flavor.banner!, + color: flavor.bannerColor, + child: child, + ), + ); + } + + return child; + } + + @override + Widget build(BuildContext context) => MultiProvider( + repositoryProviders: [ + RepositoryProvider( + create: (_) => CounterRepositoryImpl(counterDataSource: getIt()), + ), + ], + blocProviders: [ + BlocProvider( + create: (_) => CounterBloc(), + ), + ], + child: _flavorBanner( + MaterialApp.router( + title: 'Display Name', + debugShowCheckedModeBanner: false, + routerDelegate: AppRouter.router.routerDelegate, + routeInformationParser: AppRouter.router.routeInformationParser, + routeInformationProvider: AppRouter.router.routeInformationProvider, + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: AppLocalizations.supportedLocales, + ), + ), + ); +} diff --git a/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_bloc/counter_bloc.dart b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_bloc/counter_bloc.dart new file mode 100644 index 0000000..cd0683d --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_bloc/counter_bloc.dart @@ -0,0 +1,27 @@ +import 'dart:async'; + +import 'package:equatable/equatable.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +part 'counter_event.dart'; +part 'counter_state.dart'; + +/// {@template counter_bloc} +/// CounterBloc description +/// {@endtemplate} +class CounterBloc extends Bloc { + /// {@macro counter_bloc} + CounterBloc() : super(const CounterInitial()) { + on(_onCustomCounterEvent); + } + + FutureOr _onCustomCounterEvent( + CustomCounterEvent event, + Emitter emit, + ) async { + // TODO(wyatt): Add custom UI logic + const _ = 1 + 1; + + return; + } +} diff --git a/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_bloc/counter_event.dart b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_bloc/counter_event.dart new file mode 100644 index 0000000..49c34d2 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_bloc/counter_event.dart @@ -0,0 +1,20 @@ +part of 'counter_bloc.dart'; + +/// {@template counter_event} +/// CounterEvent description +/// {@endtemplate} +abstract class CounterEvent extends Equatable { + /// {@macro counter_event} + const CounterEvent(); +} + +/// {@template custom_counter_event} +/// Event added when some custom logic happens +/// {@endtemplate} +class CustomCounterEvent extends CounterEvent { + /// {@macro custom_counter_event} + const CustomCounterEvent(); + + @override + List get props => []; +} diff --git a/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_bloc/counter_state.dart b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_bloc/counter_state.dart new file mode 100644 index 0000000..79dfd2f --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_bloc/counter_state.dart @@ -0,0 +1,20 @@ +part of 'counter_bloc.dart'; + +/// {@template counter_state} +/// CounterState description +/// {@endtemplate} +abstract class CounterState extends Equatable { + /// {@macro counter_state} + const CounterState(); +} + +/// {@template counter_initial} +/// The initial state of CounterState +/// {@endtemplate} +class CounterInitial extends CounterState { + /// {@macro counter_initial} + const CounterInitial(); + + @override + List get props => []; +} diff --git a/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_cubit/counter_cubit.dart b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_cubit/counter_cubit.dart new file mode 100644 index 0000000..2d00531 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_cubit/counter_cubit.dart @@ -0,0 +1,86 @@ +import 'dart:async'; + +import 'package:equatable/equatable.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:starting_template/domain/usecases/counter/decrement.dart'; +import 'package:starting_template/domain/usecases/counter/get_current.dart'; +import 'package:starting_template/domain/usecases/counter/increment.dart'; +import 'package:starting_template/domain/usecases/counter/reset.dart'; + +part 'counter_state.dart'; + +/// {@template counter_cubit} +/// CounterCubit manages UI depending on counter state. +/// {@endtemplate} +class CounterCubit extends Cubit { + /// {@macro counter_cubit} + CounterCubit({ + required Decrement decrement, + required Increment increment, + required GetCurrent getCurrent, + required Reset reset, + }) : _decrement = decrement, + _increment = increment, + _getCurrent = getCurrent, + _reset = reset, + super(const CounterState(0)); + + final Decrement _decrement; + final Increment _increment; + final GetCurrent _getCurrent; + final Reset _reset; + + /// Decrement counter. + FutureOr decrement([int by = 1]) async { + final result = await _decrement.call(by); + + result.fold( + (integer) => emit(CounterState(integer.value)), + addError, + ); + + return; + } + + /// Increment counter. + FutureOr increment([int by = 1]) async { + final result = await _increment.call(by); + + result.fold( + (integer) => emit(CounterState(integer.value)), + addError, + ); + + return; + } + + /// Get current counter state. + FutureOr getCurrent() async { + final result = await _getCurrent.call(null); + + result.fold( + (integer) => emit(CounterState(integer.value)), + addError, + ); + + return; + } + + /// Reset counter state. + FutureOr reset() async { + final result = await _reset.call(null); + + result.fold( + (integer) => emit(CounterState(integer.value)), + addError, + ); + + return; + } + + @override + void onError(Object error, StackTrace stackTrace) { + emit(state); + super.onError(error, stackTrace); + } +} diff --git a/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_cubit/counter_state.dart b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_cubit/counter_state.dart new file mode 100644 index 0000000..50132cd --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/blocs/counter_cubit/counter_state.dart @@ -0,0 +1,14 @@ +part of 'counter_cubit.dart'; + +/// {@template counter_state} +/// CounterState containing counter value +/// {@endtemplate} +class CounterState extends Equatable { + /// {@macro counter_state} + const CounterState(this.value); + + final int value; + + @override + List get props => [value]; +} diff --git a/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/counter.dart b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/counter.dart new file mode 100644 index 0000000..e110659 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/counter.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; +import 'package:starting_template/presentation/features/counter/screens/counter_provider.dart'; + +class Counter extends StatelessWidget { + const Counter({super.key}); + + static const String pageName = 'counterPage'; + + @override + Widget build(BuildContext context) => const CounterProvider(); +} diff --git a/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/screens/counter_provider.dart b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/screens/counter_provider.dart new file mode 100644 index 0000000..7917abf --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/screens/counter_provider.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; +import 'package:starting_template/core/extensions/build_context_extension.dart'; +import 'package:starting_template/domain/repositories/counter_repository.dart'; +import 'package:starting_template/domain/usecases/counter/decrement.dart'; +import 'package:starting_template/domain/usecases/counter/get_current.dart'; +import 'package:starting_template/domain/usecases/counter/increment.dart'; +import 'package:starting_template/domain/usecases/counter/reset.dart'; +import 'package:starting_template/presentation/features/counter/blocs/counter_cubit/counter_cubit.dart'; +import 'package:starting_template/presentation/features/counter/screens/widgets/counter_consumer_widget.dart'; +import 'package:starting_template/presentation/shared/layouts/wyatt_app_template_scaffold.dart'; +import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; + +/// {@template counter_provider} +/// CounterProvider provides bloc to his children. +/// {@endtemplate} +class CounterProvider extends CubitProviderScreen { + /// {@macro counter_provider} + const CounterProvider({super.key}); + + @override + CounterCubit create(BuildContext context) => CounterCubit( + decrement: Decrement( + counterRepository: repo(context), + ), + increment: Increment( + counterRepository: repo(context), + ), + getCurrent: GetCurrent( + counterRepository: repo(context), + ), + reset: Reset( + counterRepository: repo(context), + ), + ); + + @override + CounterCubit init(BuildContext context, CounterCubit bloc) => + bloc..getCurrent(); + + @override + Widget builder(BuildContext context) => WyattAppTemplateScaffold( + title: Text(context.l10n.counterAppBarTitle), + body: const CounterConsumerWidget(), + fabChildren: [ + FloatingActionButton( + heroTag: 'increment_tag', + onPressed: () => bloc(context).increment(), + child: const Icon(Icons.add), + ), + const SizedBox(height: 8), + FloatingActionButton( + heroTag: 'increment_10_tag', + onPressed: () => bloc(context).increment(10), + child: const Text('+10'), + ), + const SizedBox(height: 8), + FloatingActionButton( + heroTag: 'decrement_tag', + onPressed: () => bloc(context).decrement(), + child: const Icon(Icons.remove), + ), + const SizedBox(height: 8), + FloatingActionButton( + heroTag: 'decrement_10_tag', + onPressed: () => bloc(context).decrement(10), + child: const Text('-10'), + ), + const SizedBox(height: 8), + FloatingActionButton( + heroTag: 'reset_tag', + onPressed: () => bloc(context).reset(), + child: const Icon(Icons.refresh), + ), + ], + ); +} diff --git a/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/screens/widgets/counter_consumer_widget.dart b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/screens/widgets/counter_consumer_widget.dart new file mode 100644 index 0000000..0add799 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/screens/widgets/counter_consumer_widget.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; +import 'package:starting_template/core/extensions/build_context_extension.dart'; +import 'package:starting_template/presentation/features/counter/blocs/counter_cubit/counter_cubit.dart'; +import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; + +/// {@template counter_consumer_widget} +/// CounterConsumerWidget is a stateful widget. Aware of state changes. +/// {@endtemplate} +class CounterConsumerWidget + extends CubitConsumerScreen { + /// {@macro counter_consumer_widget} + const CounterConsumerWidget({super.key}); + + @override + Widget onBuild(BuildContext context, CounterState state) => Text( + context.l10n.youHavePushed(state.value), + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.headline3, + ); +} diff --git a/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/stateless/counter_widget.dart b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/stateless/counter_widget.dart new file mode 100644 index 0000000..32a7619 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/presentation/features/counter/stateless/counter_widget.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +/// {@template counter_widget} +/// CounterWidget is a stateless widget. (Not aware of cubit or bloc states) +/// {@endtemplate} +class CounterWidget extends StatelessWidget { + /// {@macro counter_widget} + const CounterWidget({super.key}); + + @override + Widget build(BuildContext context) => Container(); +} diff --git a/apps/wyatt_app_template/starting_template/lib/presentation/features/home/home.dart b/apps/wyatt_app_template/starting_template/lib/presentation/features/home/home.dart new file mode 100644 index 0000000..a886492 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/presentation/features/home/home.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; +import 'package:go_router/go_router.dart'; +import 'package:starting_template/core/extensions/build_context_extension.dart'; +import 'package:starting_template/gen/assets.gen.dart'; +import 'package:starting_template/presentation/features/counter/counter.dart'; +import 'package:starting_template/presentation/shared/layouts/wyatt_app_template_scaffold.dart'; + +class Home extends StatelessWidget { + const Home({super.key}); + + static const String pageName = 'homePage'; + + @override + Widget build(BuildContext context) => WyattAppTemplateScaffold( + body: Center( + child: Column( + children: [ + Assets.images.wyattLogo.image(width: 150), + const Gap(30), + ElevatedButton( + child: Text(context.l10n.goToCounter), + onPressed: () => context.pushNamed(Counter.pageName), + ), + ], + ), + ), + ); +} diff --git a/apps/wyatt_app_template/starting_template/lib/presentation/shared/layouts/wyatt_app_template_scaffold.dart b/apps/wyatt_app_template/starting_template/lib/presentation/shared/layouts/wyatt_app_template_scaffold.dart new file mode 100644 index 0000000..60e2dee --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/presentation/shared/layouts/wyatt_app_template_scaffold.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; + +class WyattAppTemplateScaffold extends StatelessWidget { + const WyattAppTemplateScaffold({ + required this.body, + super.key, + this.title, + this.fabChildren, + }); + + final Widget? title; + final Widget body; + final List? fabChildren; + + @override + Widget build(BuildContext context) => Scaffold( + appBar: AppBar(title: title), + body: body, + floatingActionButton: (fabChildren?.isNotEmpty ?? false) + ? Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, + children: fabChildren!, + ) + : null, + ); +} diff --git a/apps/wyatt_app_template/starting_template/lib/presentation/shared/widgets/.gitkeep b/apps/wyatt_app_template/starting_template/lib/presentation/shared/widgets/.gitkeep new file mode 100644 index 0000000..f94cb6f --- /dev/null +++ b/apps/wyatt_app_template/starting_template/lib/presentation/shared/widgets/.gitkeep @@ -0,0 +1 @@ +# just to keep empty folder in brick generation \ No newline at end of file diff --git a/apps/wyatt_app_template/starting_template/local_packages/README.md b/apps/wyatt_app_template/starting_template/local_packages/README.md new file mode 100644 index 0000000..1051ebd --- /dev/null +++ b/apps/wyatt_app_template/starting_template/local_packages/README.md @@ -0,0 +1,2 @@ +Here you can find local package development copies. +Clone the package you want to customize here, then add it in `pubspec_overrides.yaml`. \ No newline at end of file diff --git a/apps/wyatt_app_template/starting_template/package-lock.json b/apps/wyatt_app_template/starting_template/package-lock.json new file mode 100644 index 0000000..8d16ba5 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/package-lock.json @@ -0,0 +1,6524 @@ +{ + "name": "starting_template", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "dependencies": { + "@trapezedev/configure": "^7.0.5" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/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==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@ionic/cli-framework-output": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@ionic/cli-framework-output/-/cli-framework-output-2.2.5.tgz", + "integrity": "sha512-YeDLTnTaE6V4IDUxT8GDIep0GuRIFaR7YZDLANMuuWJZDmnTku6DP+MmQoltBeLmVvz1BAAZgk41xzxdq6H2FQ==", + "dependencies": { + "@ionic/utils-terminal": "2.3.3", + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-array": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-array/-/utils-array-2.1.5.tgz", + "integrity": "sha512-HD72a71IQVBmQckDwmA8RxNVMTbxnaLbgFOl+dO5tbvW9CkkSFCv41h6fUuNsSEVgngfkn0i98HDuZC8mk+lTA==", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-fs": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.6.tgz", + "integrity": "sha512-eikrNkK89CfGPmexjTfSWl4EYqsPSBh0Ka7by4F0PLc1hJZYtJxUZV3X4r5ecA8ikjicUmcbU7zJmAjmqutG/w==", + "dependencies": { + "@types/fs-extra": "^8.0.0", + "debug": "^4.0.0", + "fs-extra": "^9.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-fs/node_modules/@types/fs-extra": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", + "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@ionic/utils-object": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.5.tgz", + "integrity": "sha512-XnYNSwfewUqxq+yjER1hxTKggftpNjFLJH0s37jcrNDwbzmbpFTQTVAp4ikNK4rd9DOebX/jbeZb8jfD86IYxw==", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-process": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.10.tgz", + "integrity": "sha512-mZ7JEowcuGQK+SKsJXi0liYTcXd2bNMR3nE0CyTROpMECUpJeAvvaBaPGZf5ERQUPeWBVuwqAqjUmIdxhz5bxw==", + "dependencies": { + "@ionic/utils-object": "2.1.5", + "@ionic/utils-terminal": "2.3.3", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "tree-kill": "^1.2.2", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-stream": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-stream/-/utils-stream-3.1.5.tgz", + "integrity": "sha512-hkm46uHvEC05X/8PHgdJi4l4zv9VQDELZTM+Kz69odtO9zZYfnt8DkfXHJqJ+PxmtiE5mk/ehJWLnn/XAczTUw==", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-subprocess": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@ionic/utils-subprocess/-/utils-subprocess-2.1.11.tgz", + "integrity": "sha512-6zCDixNmZCbMCy5np8klSxOZF85kuDyzZSTTQKQP90ZtYNCcPYmuFSzaqDwApJT4r5L3MY3JrqK1gLkc6xiUPw==", + "dependencies": { + "@ionic/utils-array": "2.1.5", + "@ionic/utils-fs": "3.1.6", + "@ionic/utils-process": "2.1.10", + "@ionic/utils-stream": "3.1.5", + "@ionic/utils-terminal": "2.3.3", + "cross-spawn": "^7.0.3", + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-terminal": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.3.tgz", + "integrity": "sha512-RnuSfNZ5fLEyX3R5mtcMY97cGD1A0NVBbarsSQ6yMMfRJ5YHU7hHVyUfvZeClbqkBC/pAqI/rYJuXKCT9YeMCQ==", + "dependencies": { + "@types/slice-ansi": "^4.0.0", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "slice-ansi": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "tslib": "^2.0.1", + "untildify": "^4.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-terminal/node_modules/@types/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==" + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@prettier/plugin-xml": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@prettier/plugin-xml/-/plugin-xml-1.2.0.tgz", + "integrity": "sha512-bFvVAZKs59XNmntYjyefn3K4TBykS6E+d6ZW8IcylAs88ZO+TzLhp0dPpi0VKfPzq1Nb+kpDnPRTiwb4zY6NgA==", + "dependencies": { + "@xml-tools/parser": "^1.0.11", + "prettier": ">=2.3" + } + }, + "node_modules/@trapezedev/configure": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@trapezedev/configure/-/configure-7.0.5.tgz", + "integrity": "sha512-RsweaxUNf0aGzJYdaW+cMu5Pa5EetVRBUThwSdKvsZyF5fima3DMk1XUiMwVHUzRA76CHPfp54DRarzm4gVUtQ==", + "dependencies": { + "@ionic/cli-framework-output": "^2.2.2", + "@ionic/utils-fs": "^3.1.5", + "@ionic/utils-subprocess": "^2.1.8", + "@ionic/utils-terminal": "^2.3.1", + "@prettier/plugin-xml": "^1.1.0", + "@trapezedev/project": "7.0.5", + "@types/fs-extra": "^9.0.13", + "@types/jest": "^27.0.2", + "@types/lodash": "^4.14.175", + "@types/plist": "^3.0.2", + "@types/prompts": "^2.0.14", + "@types/slice-ansi": "^5.0.0", + "commander": "^8.2.0", + "conventional-changelog": "^3.1.4", + "env-paths": "^3.0.0", + "kleur": "^4.1.4", + "lodash": "^4.17.21", + "npm-watch": "^0.9.0", + "plist": "^3.0.4", + "prompts": "^2.4.2", + "replace": "^1.1.0", + "tmp": "^0.2.1", + "ts-node": "^10.2.1", + "yaml": "^1.10.2", + "yargs": "^17.2.1" + }, + "bin": { + "trapeze": "bin/trapeze" + } + }, + "node_modules/@trapezedev/gradle-parse": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@trapezedev/gradle-parse/-/gradle-parse-7.0.5.tgz", + "integrity": "sha512-j4dHM0b8/5nDi2GbuiaKUJCXP6zplIW+nO4k6m5kCBQxz1JstB5/2l86Y04ivfRe5Xg0KiSje9K8S5KA3mX5pA==" + }, + "node_modules/@trapezedev/project": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@trapezedev/project/-/project-7.0.5.tgz", + "integrity": "sha512-0NbBHHbcw8q0OKobGDtqpB9eS42gWIrpAAy6VKK2XRs8mVizMkBNxb0i1xDZ2wiLeABYoPR97suFMZwFbkYyTQ==", + "dependencies": { + "@ionic/utils-fs": "^3.1.5", + "@ionic/utils-subprocess": "^2.1.8", + "@prettier/plugin-xml": "^2.2.0", + "@trapezedev/gradle-parse": "7.0.5", + "@types/cross-spawn": "^6.0.2", + "@types/diff": "^5.0.2", + "@types/fs-extra": "^9.0.13", + "@types/ini": "^1.3.31", + "@types/jest": "^27.0.2", + "@types/lodash": "^4.14.175", + "@types/plist": "^3.0.2", + "@types/slice-ansi": "^5.0.0", + "@xmldom/xmldom": "^0.7.5", + "conventional-changelog": "^3.1.4", + "cross-fetch": "^3.1.5", + "cross-spawn": "^7.0.3", + "diff": "^5.1.0", + "env-paths": "^3.0.0", + "gradle-to-js": "^2.0.0", + "ini": "^2.0.0", + "kleur": "^4.1.5", + "lodash": "^4.17.21", + "mergexml": "^1.2.3", + "npm-watch": "^0.9.0", + "plist": "^3.0.4", + "prettier": "^2.7.1", + "prompts": "^2.4.2", + "replace": "^1.1.0", + "tempy": "^1.0.1", + "tmp": "^0.2.1", + "ts-node": "^10.2.1", + "xcode": "^3.0.1", + "xml-js": "^1.6.11", + "xpath": "^0.0.32", + "yargs": "^17.2.1" + } + }, + "node_modules/@trapezedev/project/node_modules/@prettier/plugin-xml": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@prettier/plugin-xml/-/plugin-xml-2.2.0.tgz", + "integrity": "sha512-UWRmygBsyj4bVXvDiqSccwT1kmsorcwQwaIy30yVh8T+Gspx4OlC0shX1y+ZuwXZvgnafmpRYKks0bAu9urJew==", + "dependencies": { + "@xml-tools/parser": "^1.0.11", + "prettier": ">=2.4.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "node_modules/@types/cross-spawn": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz", + "integrity": "sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/diff": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.0.2.tgz", + "integrity": "sha512-uw8eYMIReOwstQ0QKF0sICefSy8cNO/v7gOTiIy9SbwuHyEecJUm7qlgueOO5S1udZ5I/irVydHVwMchgzbKTg==" + }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ini": { + "version": "1.3.31", + "resolved": "https://registry.npmjs.org/@types/ini/-/ini-1.3.31.tgz", + "integrity": "sha512-8ecxxaG4AlVEM1k9+BsziMw8UsX0qy3jYI1ad/71RrDZ+rdL6aZB0wLfAuflQiDhkD5o4yJ0uPK3OSUic3fG0w==" + }, + "node_modules/@types/jest": { + "version": "27.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", + "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", + "dependencies": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "node_modules/@types/lodash": { + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==" + }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==" + }, + "node_modules/@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==" + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==" + }, + "node_modules/@types/plist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz", + "integrity": "sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==", + "dependencies": { + "@types/node": "*", + "xmlbuilder": ">=11.0.1" + } + }, + "node_modules/@types/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-TwNx7qsjvRIUv/BCx583tqF5IINEVjCNqg9ofKHRlSoUHE62WBHrem4B1HGXcIrG511v29d1kJ9a/t2Esz7MIg==", + "dependencies": { + "@types/node": "*", + "kleur": "^3.0.3" + } + }, + "node_modules/@types/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@types/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-Bt9wdwNObyD9EQMNN2GSeutWmpsZUC1/bip6XKawJ+cAK9Vhf2EwnSgg7G9Zd7KJv0fTvEbgHFjrHnImemyYQg==" + }, + "node_modules/@xml-tools/parser": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@xml-tools/parser/-/parser-1.0.11.tgz", + "integrity": "sha512-aKqQ077XnR+oQtHJlrAflaZaL7qZsulWc/i/ZEooar5JiWj1eLt0+Wg28cpa+XLney107wXqneC+oG1IZvxkTA==", + "dependencies": { + "chevrotain": "7.1.1" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.9.tgz", + "integrity": "sha512-yceMpm/xd4W2a85iqZyO09gTnHvXF6pyiWjD2jcOJs7hRoZtNNOO1eJlhHj1ixA+xip2hOyGn+LgcvLCMo5zXA==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/add-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==" + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/bplist-creator": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz", + "integrity": "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==", + "dependencies": { + "stream-buffers": "2.2.x" + } + }, + "node_modules/bplist-parser": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz", + "integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==", + "dependencies": { + "big-integer": "1.6.x" + }, + "engines": { + "node": ">= 5.10.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chevrotain": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-7.1.1.tgz", + "integrity": "sha512-wy3mC1x4ye+O+QkEinVJkPf5u2vsrDIYW9G7ZuwFl6v/Yu0LwUuT2POsb+NUWApebyxfkQq6+yDfRExbnI5rcw==", + "dependencies": { + "regexp-to-ast": "0.5.0" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/conventional-changelog": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz", + "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==", + "dependencies": { + "conventional-changelog-angular": "^5.0.12", + "conventional-changelog-atom": "^2.0.8", + "conventional-changelog-codemirror": "^2.0.8", + "conventional-changelog-conventionalcommits": "^4.5.0", + "conventional-changelog-core": "^4.2.1", + "conventional-changelog-ember": "^2.0.9", + "conventional-changelog-eslint": "^3.0.9", + "conventional-changelog-express": "^2.0.6", + "conventional-changelog-jquery": "^3.0.11", + "conventional-changelog-jshint": "^2.0.9", + "conventional-changelog-preset-loader": "^2.3.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-angular": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "dependencies": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-atom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", + "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-codemirror": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", + "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-conventionalcommits": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz", + "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==", + "dependencies": { + "compare-func": "^2.0.0", + "lodash": "^4.17.15", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz", + "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==", + "dependencies": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^5.0.0", + "conventional-commits-parser": "^3.2.0", + "dateformat": "^3.0.0", + "get-pkg-repo": "^4.0.0", + "git-raw-commits": "^2.0.8", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^4.1.1", + "lodash": "^4.17.15", + "normalize-package-data": "^3.0.0", + "q": "^1.5.1", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0", + "through2": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-ember": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", + "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-eslint": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", + "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-express": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", + "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-jquery": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", + "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-jshint": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", + "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", + "dependencies": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-preset-loader": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-writer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", + "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", + "dependencies": { + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-changelog-writer": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-commits-parser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", + "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "dependencies": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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==" + }, + "node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-pkg-repo": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", + "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", + "dependencies": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "through2": "^2.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "get-pkg-repo": "src/cli.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-pkg-repo/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/get-pkg-repo/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "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" + } + }, + "node_modules/get-pkg-repo/node_modules/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==" + }, + "node_modules/get-pkg-repo/node_modules/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==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/get-pkg-repo/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/get-pkg-repo/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "dependencies": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", + "dependencies": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/git-semver-tags": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", + "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", + "dependencies": { + "meow": "^8.0.0", + "semver": "^6.0.0" + }, + "bin": { + "git-semver-tags": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", + "dependencies": { + "ini": "^1.3.2" + } + }, + "node_modules/gitconfiglocal/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "node_modules/gradle-to-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gradle-to-js/-/gradle-to-js-2.0.1.tgz", + "integrity": "sha512-is3hDn9zb8XXnjbEeAEIqxTpLHUiGBqjegLmXPuyMBfKAggpadWFku4/AP8iYAGBX6qR9/5UIUIp47V0XI3aMw==", + "dependencies": { + "lodash.merge": "^4.6.2" + }, + "bin": { + "gradle-to-js": "cli.js" + } + }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "dependencies": { + "text-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/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==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + }, + "node_modules/meow/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/meow/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/mergexml": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/mergexml/-/mergexml-1.2.3.tgz", + "integrity": "sha512-sNc9qswtLUoGmN0MB3dY+MCIJqCGEZZrtYp0Z5Iwsk6ELc/V96SFIuv5Y6O6tYAsFtdpJcPFV0FgOSHSciJLbA==", + "dependencies": { + "@xmldom/xmldom": "^0.7.0", + "formidable": "^1.2.1", + "xpath": "0.0.27" + } + }, + "node_modules/mergexml/node_modules/xpath": { + "version": "0.0.27", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz", + "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==", + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nodemon": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", + "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-watch": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/npm-watch/-/npm-watch-0.9.0.tgz", + "integrity": "sha512-C5Rgh5+jvY33K1EH8Qjr1hfpH9Nhasc90QJ0W+JyKg2ogE0LOCZI4xirC8QmywW7XinyBpynwxlrN6aPfjc3Hw==", + "dependencies": { + "nodemon": "^2.0.7", + "through2": "^4.0.2" + }, + "bin": { + "npm-watch": "cli.js" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "engines": { + "node": ">=4" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-type/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/plist": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz", + "integrity": "sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA==", + "dependencies": { + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prettier": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", + "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "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==" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regexp-to-ast": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz", + "integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==" + }, + "node_modules/replace": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/replace/-/replace-1.2.2.tgz", + "integrity": "sha512-C4EDifm22XZM2b2JOYe6Mhn+lBsLBAvLbK8drfUQLTfD1KYl/n3VaW/CDju0Ny4w3xTtegBpg8YNSpFJPUDSjA==", + "dependencies": { + "chalk": "2.4.2", + "minimatch": "3.0.5", + "yargs": "^15.3.1" + }, + "bin": { + "replace": "bin/replace.js", + "search": "bin/search.js" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/replace/node_modules/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==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/replace/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/replace/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/replace/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/replace/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/replace/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/replace/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/replace/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/replace/node_modules/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/replace/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/replace/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/replace/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/replace/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/replace/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/replace/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/replace/node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/replace/node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/replace/node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/replace/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + }, + "node_modules/replace/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/replace/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/simple-plist": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.1.tgz", + "integrity": "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==", + "dependencies": { + "bplist-creator": "0.1.0", + "bplist-parser": "0.3.1", + "plist": "^3.0.5" + } + }, + "node_modules/simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dependencies": { + "semver": "~7.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==" + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/stream-buffers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==", + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/string_decoder": { + "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==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/tempy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-1.0.1.tgz", + "integrity": "sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==", + "dependencies": { + "del": "^6.0.0", + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/to-regex-range": { + "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==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/xcode": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz", + "integrity": "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==", + "dependencies": { + "simple-plist": "^1.1.0", + "uuid": "^7.0.3" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/xpath": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz", + "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==", + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.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.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "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" + } + } + } + }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==" + }, + "@ionic/cli-framework-output": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@ionic/cli-framework-output/-/cli-framework-output-2.2.5.tgz", + "integrity": "sha512-YeDLTnTaE6V4IDUxT8GDIep0GuRIFaR7YZDLANMuuWJZDmnTku6DP+MmQoltBeLmVvz1BAAZgk41xzxdq6H2FQ==", + "requires": { + "@ionic/utils-terminal": "2.3.3", + "debug": "^4.0.0", + "tslib": "^2.0.1" + } + }, + "@ionic/utils-array": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-array/-/utils-array-2.1.5.tgz", + "integrity": "sha512-HD72a71IQVBmQckDwmA8RxNVMTbxnaLbgFOl+dO5tbvW9CkkSFCv41h6fUuNsSEVgngfkn0i98HDuZC8mk+lTA==", + "requires": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + } + }, + "@ionic/utils-fs": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.6.tgz", + "integrity": "sha512-eikrNkK89CfGPmexjTfSWl4EYqsPSBh0Ka7by4F0PLc1hJZYtJxUZV3X4r5ecA8ikjicUmcbU7zJmAjmqutG/w==", + "requires": { + "@types/fs-extra": "^8.0.0", + "debug": "^4.0.0", + "fs-extra": "^9.0.0", + "tslib": "^2.0.1" + }, + "dependencies": { + "@types/fs-extra": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", + "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", + "requires": { + "@types/node": "*" + } + } + } + }, + "@ionic/utils-object": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.5.tgz", + "integrity": "sha512-XnYNSwfewUqxq+yjER1hxTKggftpNjFLJH0s37jcrNDwbzmbpFTQTVAp4ikNK4rd9DOebX/jbeZb8jfD86IYxw==", + "requires": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + } + }, + "@ionic/utils-process": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.10.tgz", + "integrity": "sha512-mZ7JEowcuGQK+SKsJXi0liYTcXd2bNMR3nE0CyTROpMECUpJeAvvaBaPGZf5ERQUPeWBVuwqAqjUmIdxhz5bxw==", + "requires": { + "@ionic/utils-object": "2.1.5", + "@ionic/utils-terminal": "2.3.3", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "tree-kill": "^1.2.2", + "tslib": "^2.0.1" + } + }, + "@ionic/utils-stream": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-stream/-/utils-stream-3.1.5.tgz", + "integrity": "sha512-hkm46uHvEC05X/8PHgdJi4l4zv9VQDELZTM+Kz69odtO9zZYfnt8DkfXHJqJ+PxmtiE5mk/ehJWLnn/XAczTUw==", + "requires": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + } + }, + "@ionic/utils-subprocess": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@ionic/utils-subprocess/-/utils-subprocess-2.1.11.tgz", + "integrity": "sha512-6zCDixNmZCbMCy5np8klSxOZF85kuDyzZSTTQKQP90ZtYNCcPYmuFSzaqDwApJT4r5L3MY3JrqK1gLkc6xiUPw==", + "requires": { + "@ionic/utils-array": "2.1.5", + "@ionic/utils-fs": "3.1.6", + "@ionic/utils-process": "2.1.10", + "@ionic/utils-stream": "3.1.5", + "@ionic/utils-terminal": "2.3.3", + "cross-spawn": "^7.0.3", + "debug": "^4.0.0", + "tslib": "^2.0.1" + } + }, + "@ionic/utils-terminal": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.3.tgz", + "integrity": "sha512-RnuSfNZ5fLEyX3R5mtcMY97cGD1A0NVBbarsSQ6yMMfRJ5YHU7hHVyUfvZeClbqkBC/pAqI/rYJuXKCT9YeMCQ==", + "requires": { + "@types/slice-ansi": "^4.0.0", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "slice-ansi": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "tslib": "^2.0.1", + "untildify": "^4.0.0", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "@types/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==" + } + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@prettier/plugin-xml": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@prettier/plugin-xml/-/plugin-xml-1.2.0.tgz", + "integrity": "sha512-bFvVAZKs59XNmntYjyefn3K4TBykS6E+d6ZW8IcylAs88ZO+TzLhp0dPpi0VKfPzq1Nb+kpDnPRTiwb4zY6NgA==", + "requires": { + "@xml-tools/parser": "^1.0.11", + "prettier": ">=2.3" + } + }, + "@trapezedev/configure": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@trapezedev/configure/-/configure-7.0.5.tgz", + "integrity": "sha512-RsweaxUNf0aGzJYdaW+cMu5Pa5EetVRBUThwSdKvsZyF5fima3DMk1XUiMwVHUzRA76CHPfp54DRarzm4gVUtQ==", + "requires": { + "@ionic/cli-framework-output": "^2.2.2", + "@ionic/utils-fs": "^3.1.5", + "@ionic/utils-subprocess": "^2.1.8", + "@ionic/utils-terminal": "^2.3.1", + "@prettier/plugin-xml": "^1.1.0", + "@trapezedev/project": "7.0.5", + "@types/fs-extra": "^9.0.13", + "@types/jest": "^27.0.2", + "@types/lodash": "^4.14.175", + "@types/plist": "^3.0.2", + "@types/prompts": "^2.0.14", + "@types/slice-ansi": "^5.0.0", + "commander": "^8.2.0", + "conventional-changelog": "^3.1.4", + "env-paths": "^3.0.0", + "kleur": "^4.1.4", + "lodash": "^4.17.21", + "npm-watch": "^0.9.0", + "plist": "^3.0.4", + "prompts": "^2.4.2", + "replace": "^1.1.0", + "tmp": "^0.2.1", + "ts-node": "^10.2.1", + "yaml": "^1.10.2", + "yargs": "^17.2.1" + } + }, + "@trapezedev/gradle-parse": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@trapezedev/gradle-parse/-/gradle-parse-7.0.5.tgz", + "integrity": "sha512-j4dHM0b8/5nDi2GbuiaKUJCXP6zplIW+nO4k6m5kCBQxz1JstB5/2l86Y04ivfRe5Xg0KiSje9K8S5KA3mX5pA==" + }, + "@trapezedev/project": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@trapezedev/project/-/project-7.0.5.tgz", + "integrity": "sha512-0NbBHHbcw8q0OKobGDtqpB9eS42gWIrpAAy6VKK2XRs8mVizMkBNxb0i1xDZ2wiLeABYoPR97suFMZwFbkYyTQ==", + "requires": { + "@ionic/utils-fs": "^3.1.5", + "@ionic/utils-subprocess": "^2.1.8", + "@prettier/plugin-xml": "^2.2.0", + "@trapezedev/gradle-parse": "7.0.5", + "@types/cross-spawn": "^6.0.2", + "@types/diff": "^5.0.2", + "@types/fs-extra": "^9.0.13", + "@types/ini": "^1.3.31", + "@types/jest": "^27.0.2", + "@types/lodash": "^4.14.175", + "@types/plist": "^3.0.2", + "@types/slice-ansi": "^5.0.0", + "@xmldom/xmldom": "^0.7.5", + "conventional-changelog": "^3.1.4", + "cross-fetch": "^3.1.5", + "cross-spawn": "^7.0.3", + "diff": "^5.1.0", + "env-paths": "^3.0.0", + "gradle-to-js": "^2.0.0", + "ini": "^2.0.0", + "kleur": "^4.1.5", + "lodash": "^4.17.21", + "mergexml": "^1.2.3", + "npm-watch": "^0.9.0", + "plist": "^3.0.4", + "prettier": "^2.7.1", + "prompts": "^2.4.2", + "replace": "^1.1.0", + "tempy": "^1.0.1", + "tmp": "^0.2.1", + "ts-node": "^10.2.1", + "xcode": "^3.0.1", + "xml-js": "^1.6.11", + "xpath": "^0.0.32", + "yargs": "^17.2.1" + }, + "dependencies": { + "@prettier/plugin-xml": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@prettier/plugin-xml/-/plugin-xml-2.2.0.tgz", + "integrity": "sha512-UWRmygBsyj4bVXvDiqSccwT1kmsorcwQwaIy30yVh8T+Gspx4OlC0shX1y+ZuwXZvgnafmpRYKks0bAu9urJew==", + "requires": { + "@xml-tools/parser": "^1.0.11", + "prettier": ">=2.4.0" + } + } + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "@types/cross-spawn": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz", + "integrity": "sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==", + "requires": { + "@types/node": "*" + } + }, + "@types/diff": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.0.2.tgz", + "integrity": "sha512-uw8eYMIReOwstQ0QKF0sICefSy8cNO/v7gOTiIy9SbwuHyEecJUm7qlgueOO5S1udZ5I/irVydHVwMchgzbKTg==" + }, + "@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "requires": { + "@types/node": "*" + } + }, + "@types/ini": { + "version": "1.3.31", + "resolved": "https://registry.npmjs.org/@types/ini/-/ini-1.3.31.tgz", + "integrity": "sha512-8ecxxaG4AlVEM1k9+BsziMw8UsX0qy3jYI1ad/71RrDZ+rdL6aZB0wLfAuflQiDhkD5o4yJ0uPK3OSUic3fG0w==" + }, + "@types/jest": { + "version": "27.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", + "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", + "requires": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "@types/lodash": { + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==" + }, + "@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==" + }, + "@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==" + }, + "@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==" + }, + "@types/plist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz", + "integrity": "sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==", + "requires": { + "@types/node": "*", + "xmlbuilder": ">=11.0.1" + } + }, + "@types/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-TwNx7qsjvRIUv/BCx583tqF5IINEVjCNqg9ofKHRlSoUHE62WBHrem4B1HGXcIrG511v29d1kJ9a/t2Esz7MIg==", + "requires": { + "@types/node": "*", + "kleur": "^3.0.3" + }, + "dependencies": { + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + } + } + }, + "@types/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-Bt9wdwNObyD9EQMNN2GSeutWmpsZUC1/bip6XKawJ+cAK9Vhf2EwnSgg7G9Zd7KJv0fTvEbgHFjrHnImemyYQg==" + }, + "@xml-tools/parser": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@xml-tools/parser/-/parser-1.0.11.tgz", + "integrity": "sha512-aKqQ077XnR+oQtHJlrAflaZaL7qZsulWc/i/ZEooar5JiWj1eLt0+Wg28cpa+XLney107wXqneC+oG1IZvxkTA==", + "requires": { + "chevrotain": "7.1.1" + } + }, + "@xmldom/xmldom": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.9.tgz", + "integrity": "sha512-yceMpm/xd4W2a85iqZyO09gTnHvXF6pyiWjD2jcOJs7hRoZtNNOO1eJlhHj1ixA+xip2hOyGn+LgcvLCMo5zXA==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==" + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" + }, + "add-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==" + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==" + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "bplist-creator": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz", + "integrity": "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==", + "requires": { + "stream-buffers": "2.2.x" + } + }, + "bplist-parser": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz", + "integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==", + "requires": { + "big-integer": "1.6.x" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chevrotain": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-7.1.1.tgz", + "integrity": "sha512-wy3mC1x4ye+O+QkEinVJkPf5u2vsrDIYW9G7ZuwFl6v/Yu0LwUuT2POsb+NUWApebyxfkQq6+yDfRExbnI5rcw==", + "requires": { + "regexp-to-ast": "0.5.0" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" + }, + "compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "requires": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "conventional-changelog": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz", + "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==", + "requires": { + "conventional-changelog-angular": "^5.0.12", + "conventional-changelog-atom": "^2.0.8", + "conventional-changelog-codemirror": "^2.0.8", + "conventional-changelog-conventionalcommits": "^4.5.0", + "conventional-changelog-core": "^4.2.1", + "conventional-changelog-ember": "^2.0.9", + "conventional-changelog-eslint": "^3.0.9", + "conventional-changelog-express": "^2.0.6", + "conventional-changelog-jquery": "^3.0.11", + "conventional-changelog-jshint": "^2.0.9", + "conventional-changelog-preset-loader": "^2.3.4" + } + }, + "conventional-changelog-angular": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "requires": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + } + }, + "conventional-changelog-atom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", + "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-codemirror": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", + "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-conventionalcommits": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz", + "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==", + "requires": { + "compare-func": "^2.0.0", + "lodash": "^4.17.15", + "q": "^1.5.1" + } + }, + "conventional-changelog-core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz", + "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==", + "requires": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^5.0.0", + "conventional-commits-parser": "^3.2.0", + "dateformat": "^3.0.0", + "get-pkg-repo": "^4.0.0", + "git-raw-commits": "^2.0.8", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^4.1.1", + "lodash": "^4.17.15", + "normalize-package-data": "^3.0.0", + "q": "^1.5.1", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0", + "through2": "^4.0.0" + } + }, + "conventional-changelog-ember": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", + "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-eslint": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", + "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-express": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", + "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-jquery": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", + "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-jshint": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", + "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", + "requires": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + } + }, + "conventional-changelog-preset-loader": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==" + }, + "conventional-changelog-writer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", + "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", + "requires": { + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + } + }, + "conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + } + }, + "conventional-commits-parser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", + "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "requires": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "requires": { + "node-fetch": "2.6.7" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" + }, + "dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==" + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==" + }, + "decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==" + } + } + }, + "del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "requires": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + } + }, + "diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==" + }, + "diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==" + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + } + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "requires": { + "is-obj": "^2.0.0" + } + }, + "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==" + }, + "env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==" + }, + "error-ex": { + "version": "1.3.2", + "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" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "requires": { + "reusify": "^1.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "requires": { + "locate-path": "^2.0.0" + } + }, + "formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==" + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-pkg-repo": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", + "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", + "requires": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "through2": "^2.0.0", + "yargs": "^16.2.0" + }, + "dependencies": { + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "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" + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + } + } + }, + "git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "requires": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + } + }, + "git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", + "requires": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + } + }, + "git-semver-tags": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", + "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", + "requires": { + "meow": "^8.0.0", + "semver": "^6.0.0" + } + }, + "gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", + "requires": { + "ini": "^1.3.2" + }, + "dependencies": { + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + } + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "gradle-to-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gradle-to-js/-/gradle-to-js-2.0.1.tgz", + "integrity": "sha512-is3hDn9zb8XXnjbEeAEIqxTpLHUiGBqjegLmXPuyMBfKAggpadWFku4/AP8iYAGBX6qR9/5UIUIp47V0XI3aMw==", + "requires": { + "lodash.merge": "^4.6.2" + } + }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==" + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "is-binary-path": { + "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": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-fullwidth-code-point": { + "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": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==" + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==" + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "requires": { + "text-extensions": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==" + }, + "jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "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-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==" + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==" + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==" + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==" + }, + "meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + } + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "mergexml": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/mergexml/-/mergexml-1.2.3.tgz", + "integrity": "sha512-sNc9qswtLUoGmN0MB3dY+MCIJqCGEZZrtYp0Z5Iwsk6ELc/V96SFIuv5Y6O6tYAsFtdpJcPFV0FgOSHSciJLbA==", + "requires": { + "@xmldom/xmldom": "^0.7.0", + "formidable": "^1.2.1", + "xpath": "0.0.27" + }, + "dependencies": { + "xpath": { + "version": "0.0.27", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz", + "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==" + } + } + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + } + }, + "modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "nodemon": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", + "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "requires": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "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" + } + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "npm-watch": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/npm-watch/-/npm-watch-0.9.0.tgz", + "integrity": "sha512-C5Rgh5+jvY33K1EH8Qjr1hfpH9Nhasc90QJ0W+JyKg2ogE0LOCZI4xirC8QmywW7XinyBpynwxlrN6aPfjc3Hw==", + "requires": { + "nodemon": "^2.0.7", + "through2": "^4.0.2" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==" + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==" + } + } + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" + }, + "plist": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz", + "integrity": "sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA==", + "requires": { + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + } + }, + "prettier": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", + "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==" + }, + "pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "requires": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" + } + } + }, + "process-nextick-args": { + "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==" + }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "dependencies": { + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + } + } + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==" + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "regexp-to-ast": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz", + "integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==" + }, + "replace": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/replace/-/replace-1.2.2.tgz", + "integrity": "sha512-C4EDifm22XZM2b2JOYe6Mhn+lBsLBAvLbK8drfUQLTfD1KYl/n3VaW/CDju0Ny4w3xTtegBpg8YNSpFJPUDSjA==", + "requires": { + "chalk": "2.4.2", + "minimatch": "3.0.5", + "yargs": "^15.3.1" + }, + "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.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "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" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + } + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "simple-plist": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.1.tgz", + "integrity": "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==", + "requires": { + "bplist-creator": "0.1.0", + "bplist-parser": "0.3.1", + "plist": "^3.0.5" + } + }, + "simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "requires": { + "semver": "~7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" + } + } + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==" + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "requires": { + "readable-stream": "^3.0.0" + } + }, + "stream-buffers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==" + }, + "string_decoder": { + "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.2.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "requires": { + "min-indent": "^1.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==" + }, + "tempy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-1.0.1.tgz", + "integrity": "sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==", + "requires": { + "del": "^6.0.0", + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "dependencies": { + "type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==" + } + } + }, + "text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "requires": { + "readable-stream": "3" + } + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + } + }, + "to-regex-range": { + "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": "^7.0.0" + } + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "requires": { + "nopt": "~1.0.10" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" + }, + "trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==" + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + } + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==" + }, + "typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "peer": true + }, + "uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "optional": true + }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + }, + "untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==" + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "xcode": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz", + "integrity": "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==", + "requires": { + "simple-plist": "^1.1.0", + "uuid": "^7.0.3" + } + }, + "xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "requires": { + "sax": "^1.2.4" + } + }, + "xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==" + }, + "xpath": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz", + "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + }, + "yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "dependencies": { + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + } + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + } + } +} diff --git a/apps/wyatt_app_template/starting_template/package.json b/apps/wyatt_app_template/starting_template/package.json new file mode 100644 index 0000000..3c8f622 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "@trapezedev/configure": "^7.0.5" + } +} diff --git a/apps/wyatt_app_template/starting_template/pubspec.yaml b/apps/wyatt_app_template/starting_template/pubspec.yaml new file mode 100644 index 0000000..eca5ba2 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/pubspec.yaml @@ -0,0 +1,90 @@ +name: starting_template +description: A short project description + +publish_to: "none" + +version: 1.0.0+1 + +environment: + sdk: ">=2.18.0 <3.0.0" + flutter: ">=3.0.0" + +dependencies: + flutter: { sdk: flutter } + flutter_localizations: { sdk: flutter } + intl: ^0.17.0 + go_router: ^6.0.1 + equatable: ^2.0.5 + freezed_annotation: ^2.2.0 + json_annotation: ^4.8.0 + cupertino_icons: ^1.0.5 + get_it: ^7.2.0 + flutter_dotenv: ^5.0.2 + gap: ^2.0.1 + flutter_bloc: ^8.1.1 + url_launcher: ^6.1.7 + uuid: ^3.0.7 + flutter_native_splash: ^2.2.15 + wyatt_architecture: + hosted: + url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + name: wyatt_architecture + version: 0.1.0+1 + wyatt_bloc_helper: + hosted: + url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + name: wyatt_bloc_helper + version: 2.0.0 + wyatt_type_utils: + hosted: + url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + name: wyatt_type_utils + version: 0.0.4 + +dev_dependencies: + flutter_test: { sdk: flutter } + dependency_validator: ^3.2.2 + build_runner: ^2.3.3 + flutter_gen_runner: ^5.1.0+1 + freezed: ^2.3.2 + json_serializable: ^6.6.0 + flutter_launcher_icons: ^0.11.0 + dart_code_metrics: ^5.4.0 + rename: ^2.1.1 + wyatt_analysis: + hosted: + url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + name: wyatt_analysis + version: 2.3.0 + +flutter: + uses-material-design: true + generate: true + assets: + - .env + - assets/images/ + +flutter_gen: + output: lib/gen/ + integrations: + flutter_svg: true + flare_flutter: true + rive: true + lottie: true + colors: + inputs: + - assets/colors.xml + +flutter_icons: + android: "launcher_icon" + ios: true + image_path: "assets/images/wyatt_logo.jpeg" + adaptive_icon_background: "#FFFFFF" + +flutter_native_splash: + image: "assets/images/wyatt_logo.jpeg" + color: "#FFFFFF" + android: true + ios: true + android_gravity: fill + ios_content_mode: scaleAspectFit diff --git a/apps/wyatt_app_template/starting_template/pubspec_overrides.yaml b/apps/wyatt_app_template/starting_template/pubspec_overrides.yaml new file mode 100644 index 0000000..c3425c6 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/pubspec_overrides.yaml @@ -0,0 +1,2 @@ +# For local package development/modification. +dependency_overrides: \ No newline at end of file diff --git a/apps/wyatt_app_template/starting_template/test/widget_test.dart b/apps/wyatt_app_template/starting_template/test/widget_test.dart new file mode 100644 index 0000000..3a06c0e --- /dev/null +++ b/apps/wyatt_app_template/starting_template/test/widget_test.dart @@ -0,0 +1 @@ +// TODO(wyatt): add some tests diff --git a/apps/wyatt_app_template/starting_template/trapeze.yaml b/apps/wyatt_app_template/starting_template/trapeze.yaml new file mode 100644 index 0000000..9eb7ea8 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/trapeze.yaml @@ -0,0 +1,36 @@ +vars: + PACKAGE_NAME: + default: starting_template + BUNDLE_ID: + default: io.wyattapp.start + APP_NAME: + default: Display Name + +platforms: + android: + appName: $APP_NAME + packageName: $BUNDLE_ID + # Uncomment to add some permissions + # manifest: + # - file: AndroidManifest.xml + # target: manifest/application + # inject: + # + ios: + targets: + Runner: + bundleId: $BUNDLE_ID + productName: $APP_NAME + displayName: $APP_NAME + entitlements: + replace: true + # Workaround for https://stackoverflow.com/questions/55167611/flutter-ios-app-submission-issue-warning-missing-push-notification-entitlement + entries: + - aps-environment: development + # Uncomment to add some permissions + # plist: + # - replace: true + # entries: + # - UISupportedInterfaceOrientations: + # - UIInterfaceOrientationPortrait + diff --git a/apps/wyatt_app_template/starting_template/web/favicon.png b/apps/wyatt_app_template/starting_template/web/favicon.png new file mode 100644 index 0000000..8aaa46a Binary files /dev/null and b/apps/wyatt_app_template/starting_template/web/favicon.png differ diff --git a/apps/wyatt_app_template/starting_template/web/icons/Icon-192.png b/apps/wyatt_app_template/starting_template/web/icons/Icon-192.png new file mode 100644 index 0000000..b749bfe Binary files /dev/null and b/apps/wyatt_app_template/starting_template/web/icons/Icon-192.png differ diff --git a/apps/wyatt_app_template/starting_template/web/icons/Icon-512.png b/apps/wyatt_app_template/starting_template/web/icons/Icon-512.png new file mode 100644 index 0000000..88cfd48 Binary files /dev/null and b/apps/wyatt_app_template/starting_template/web/icons/Icon-512.png differ diff --git a/apps/wyatt_app_template/starting_template/web/icons/Icon-maskable-192.png b/apps/wyatt_app_template/starting_template/web/icons/Icon-maskable-192.png new file mode 100644 index 0000000..eb9b4d7 Binary files /dev/null and b/apps/wyatt_app_template/starting_template/web/icons/Icon-maskable-192.png differ diff --git a/apps/wyatt_app_template/starting_template/web/icons/Icon-maskable-512.png b/apps/wyatt_app_template/starting_template/web/icons/Icon-maskable-512.png new file mode 100644 index 0000000..d69c566 Binary files /dev/null and b/apps/wyatt_app_template/starting_template/web/icons/Icon-maskable-512.png differ diff --git a/apps/wyatt_app_template/starting_template/web/index.html b/apps/wyatt_app_template/starting_template/web/index.html new file mode 100644 index 0000000..bf34233 --- /dev/null +++ b/apps/wyatt_app_template/starting_template/web/index.html @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + Display Name + + + + + + + + + + diff --git a/apps/wyatt_app_template/starting_template/web/manifest.json b/apps/wyatt_app_template/starting_template/web/manifest.json new file mode 100644 index 0000000..f86027e --- /dev/null +++ b/apps/wyatt_app_template/starting_template/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "Display Name", + "short_name": "Display Name", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A short project description", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/apps/wyatt_brick_template/README.md b/apps/wyatt_brick_template/README.md new file mode 100644 index 0000000..886e93e --- /dev/null +++ b/apps/wyatt_brick_template/README.md @@ -0,0 +1,23 @@ + + +# Wyatt - Brick Template + +> Brickception + +Generated with `Brickgen`... to generate other `Brickgen` bricks. \ No newline at end of file diff --git a/apps/wyatt_brick_template/brickgen.yaml b/apps/wyatt_brick_template/brickgen.yaml new file mode 100644 index 0000000..11abecd --- /dev/null +++ b/apps/wyatt_brick_template/brickgen.yaml @@ -0,0 +1,36 @@ +name: wyatt_brick_template +description: Template to create a compilable project that can be converted with Brickgen + +version: 0.1.0 + +vars: + brick_name: + compilable: brick_name + type: string + description: Name of the brick + default: brick_name + prompt: "What is the brick name?" + + brick_description: + compilable: brick_description + type: string + description: Description of the brick + default: brick_description + prompt: "What is the brick description?" + + hooks: + type: boolean + description: Enables hooks for this brick. + default: false + prompt: "Do you want to enable `hooks` for this brick ?" + +brickgen: + path_to_brickify: wyatt_brick_template + hooks: true + ignore: + - .env + boolean_file_system: + hooks: + folders: + on_true: + - hooks \ No newline at end of file diff --git a/apps/wyatt_brick_template/hooks/post_gen.dart b/apps/wyatt_brick_template/hooks/post_gen.dart new file mode 100644 index 0000000..398a858 --- /dev/null +++ b/apps/wyatt_brick_template/hooks/post_gen.dart @@ -0,0 +1,39 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:mason/mason.dart'; + +void removeGitKeepFiles(String targetPath) { + if (!FileSystemEntity.isDirectorySync(targetPath)) { + throw ArgumentError('Target must be a directory', 'targetPath'); + } + + Directory(targetPath) + .listSync(recursive: true) + .whereType() + .forEach((file) { + if (file.path.contains('.gitkeep')) { + file.deleteSync(recursive: true); + } + }); +} + +Future run(HookContext context) async { + final workingDirectory = Directory.current.path; + removeGitKeepFiles(workingDirectory); +} diff --git a/apps/wyatt_brick_template/hooks/pubspec.yaml b/apps/wyatt_brick_template/hooks/pubspec.yaml new file mode 100644 index 0000000..454f6df --- /dev/null +++ b/apps/wyatt_brick_template/hooks/pubspec.yaml @@ -0,0 +1,7 @@ +name: hooks + +environment: + sdk: ">=2.18.0 <3.0.0" + +dependencies: + mason: any \ No newline at end of file diff --git a/apps/wyatt_brick_template/wyatt_brick_template/brick_name/README.md b/apps/wyatt_brick_template/wyatt_brick_template/brick_name/README.md new file mode 100644 index 0000000..8c74374 --- /dev/null +++ b/apps/wyatt_brick_template/wyatt_brick_template/brick_name/README.md @@ -0,0 +1,3 @@ +# display_name + +Brick generated with `Brickgen`. \ No newline at end of file diff --git a/apps/wyatt_brick_template/wyatt_brick_template/brick_name/android/android.xml b/apps/wyatt_brick_template/wyatt_brick_template/brick_name/android/android.xml new file mode 100644 index 0000000..7a55e0f --- /dev/null +++ b/apps/wyatt_brick_template/wyatt_brick_template/brick_name/android/android.xml @@ -0,0 +1,18 @@ + + diff --git a/apps/wyatt_brick_template/wyatt_brick_template/brick_name/bin/cli.dart b/apps/wyatt_brick_template/wyatt_brick_template/brick_name/bin/cli.dart new file mode 100644 index 0000000..db18bca --- /dev/null +++ b/apps/wyatt_brick_template/wyatt_brick_template/brick_name/bin/cli.dart @@ -0,0 +1,16 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + diff --git a/apps/wyatt_brick_template/wyatt_brick_template/brick_name/ios/ios.plist b/apps/wyatt_brick_template/wyatt_brick_template/brick_name/ios/ios.plist new file mode 100644 index 0000000..7a55e0f --- /dev/null +++ b/apps/wyatt_brick_template/wyatt_brick_template/brick_name/ios/ios.plist @@ -0,0 +1,18 @@ + + diff --git a/apps/wyatt_brick_template/wyatt_brick_template/brickgen.yaml b/apps/wyatt_brick_template/wyatt_brick_template/brickgen.yaml new file mode 100644 index 0000000..b41b856 --- /dev/null +++ b/apps/wyatt_brick_template/wyatt_brick_template/brickgen.yaml @@ -0,0 +1,39 @@ +name: brick_name +description: brick_description + +version: 0.1.0 + +vars: + display_name: + compilable: display_name + type: string + description: The display name + default: Display Name + prompt: "What is the display name?" + + product_name: + compilable: product_name + type: string + description: The product name + default: product_name + prompt: "What is the product name?" + + flutter: + type: boolean + description: If this app is a Flutter or Dart application. + default: false + prompt: "Is this a Flutter appplication ?" + +brickgen: + path_to_brickify: brick_name + hooks: true + ignore: + - .env + boolean_file_system: + flutter: + folders: + on_true: + - android + - ios + on_false: + - bin \ No newline at end of file diff --git a/apps/wyatt_brick_template/wyatt_brick_template/hooks/post_gen.dart b/apps/wyatt_brick_template/wyatt_brick_template/hooks/post_gen.dart new file mode 100644 index 0000000..398a858 --- /dev/null +++ b/apps/wyatt_brick_template/wyatt_brick_template/hooks/post_gen.dart @@ -0,0 +1,39 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:mason/mason.dart'; + +void removeGitKeepFiles(String targetPath) { + if (!FileSystemEntity.isDirectorySync(targetPath)) { + throw ArgumentError('Target must be a directory', 'targetPath'); + } + + Directory(targetPath) + .listSync(recursive: true) + .whereType() + .forEach((file) { + if (file.path.contains('.gitkeep')) { + file.deleteSync(recursive: true); + } + }); +} + +Future run(HookContext context) async { + final workingDirectory = Directory.current.path; + removeGitKeepFiles(workingDirectory); +} diff --git a/apps/wyatt_brick_template/wyatt_brick_template/hooks/pubspec.yaml b/apps/wyatt_brick_template/wyatt_brick_template/hooks/pubspec.yaml new file mode 100644 index 0000000..454f6df --- /dev/null +++ b/apps/wyatt_brick_template/wyatt_brick_template/hooks/pubspec.yaml @@ -0,0 +1,7 @@ +name: hooks + +environment: + sdk: ">=2.18.0 <3.0.0" + +dependencies: + mason: any \ No newline at end of file diff --git a/apps/wyatt_clean_code/.vscode/settings.json b/apps/wyatt_clean_code/.vscode/settings.json index fa6f612..855293b 100644 --- a/apps/wyatt_clean_code/.vscode/settings.json +++ b/apps/wyatt_clean_code/.vscode/settings.json @@ -1,5 +1,4 @@ { - "dart.flutterSdkPath": ".fvm/flutter_sdk", "bloc.newCubitTemplate.type": "equatable", "psi-header.config": { "blankLinesAfter": 0, diff --git a/apps/wyatt_clean_code/lib/core/routes/router.dart b/apps/wyatt_clean_code/lib/core/routes/router.dart index ee99f64..d908c25 100644 --- a/apps/wyatt_clean_code/lib/core/routes/router.dart +++ b/apps/wyatt_clean_code/lib/core/routes/router.dart @@ -16,8 +16,8 @@ abstract class AppRouter { static final List routes = [ GoRoute( - path: '/', name: InitialPage.pageName, + path: '/', pageBuilder: (context, state) => defaultTransition( context, state, diff --git a/apps/wyatt_feature_brick/analysis_options.yaml b/apps/wyatt_feature_brick/analysis_options.yaml index abfedf0..8c9daa4 100644 --- a/apps/wyatt_feature_brick/analysis_options.yaml +++ b/apps/wyatt_feature_brick/analysis_options.yaml @@ -1 +1 @@ -include: package:wyatt_analysis/analysis_options.flutter.experimental.yaml +include: package:wyatt_analysis/analysis_options.flutter.yaml diff --git a/apps/wyatt_feature_brick/brick_config.yaml b/apps/wyatt_feature_brick/brick_config.yaml index 9b0e733..08597d8 100644 --- a/apps/wyatt_feature_brick/brick_config.yaml +++ b/apps/wyatt_feature_brick/brick_config.yaml @@ -1,20 +1,13 @@ -brick_name: wyatt_feature_brick - +name: wyatt_feature_brick +description: New feature brick including state mananement path_to_brickify: lib/feature_name -variables: +version: 0.1.1 + +vars: feature_name: - variable_name: feature_name type: string - syntax: - camel_case: featureName - constant_case: FEATURE_NAME - dot_case: feature.name - header_case: Feature-Name - lower_case: feature name - pascal_case: FeatureName - param_case: feature-name - sentence_case: Feature name - title_case: Feature Name - upper_case: FEATURE NAME - snake_case: feature_name + name: feature_name + description: Name of the feature + default: Dash + prompt: What is the name of your new feature \ No newline at end of file diff --git a/apps/wyatt_feature_brick/lib/feature_name/bloc/feature_name_bloc.dart b/apps/wyatt_feature_brick/lib/feature_name/blocs/feature_name_bloc/feature_name_bloc.dart similarity index 70% rename from apps/wyatt_feature_brick/lib/feature_name/bloc/feature_name_bloc.dart rename to apps/wyatt_feature_brick/lib/feature_name/blocs/feature_name_bloc/feature_name_bloc.dart index cc58fd7..21f587a 100644 --- a/apps/wyatt_feature_brick/lib/feature_name/bloc/feature_name_bloc.dart +++ b/apps/wyatt_feature_brick/lib/feature_name/blocs/feature_name_bloc/feature_name_bloc.dart @@ -6,7 +6,11 @@ import 'package:flutter_bloc/flutter_bloc.dart'; part 'feature_name_event.dart'; part 'feature_name_state.dart'; +/// {@template feature_name_bloc} +/// FeatureNameBloc description +/// {@endtemplate} class FeatureNameBloc extends Bloc { + /// {@macro feature_name_bloc} FeatureNameBloc() : super(const FeatureNameInitial()) { on(_onCustomFeatureNameEvent); } @@ -14,7 +18,9 @@ class FeatureNameBloc extends Bloc { FutureOr _onCustomFeatureNameEvent( CustomFeatureNameEvent event, Emitter emit, - ) { - // TODO(wyattstudio): Add Logic + ) async { + // TODO(wyatt): Add custom UI logic + const _ = 1 + 1; + return; } } diff --git a/apps/wyatt_feature_brick/lib/feature_name/bloc/feature_name_event.dart b/apps/wyatt_feature_brick/lib/feature_name/blocs/feature_name_bloc/feature_name_event.dart similarity index 76% rename from apps/wyatt_feature_brick/lib/feature_name/bloc/feature_name_event.dart rename to apps/wyatt_feature_brick/lib/feature_name/blocs/feature_name_bloc/feature_name_event.dart index 3d866ae..f0b263e 100644 --- a/apps/wyatt_feature_brick/lib/feature_name/bloc/feature_name_event.dart +++ b/apps/wyatt_feature_brick/lib/feature_name/blocs/feature_name_bloc/feature_name_event.dart @@ -1,6 +1,10 @@ part of 'feature_name_bloc.dart'; +/// {@template feature_name_event} +/// FeatureNameEvent description +/// {@endtemplate} abstract class FeatureNameEvent extends Equatable { + /// {@macro feature_name_event} const FeatureNameEvent(); } diff --git a/apps/wyatt_feature_brick/lib/feature_name/bloc/feature_name_state.dart b/apps/wyatt_feature_brick/lib/feature_name/blocs/feature_name_bloc/feature_name_state.dart similarity index 100% rename from apps/wyatt_feature_brick/lib/feature_name/bloc/feature_name_state.dart rename to apps/wyatt_feature_brick/lib/feature_name/blocs/feature_name_bloc/feature_name_state.dart diff --git a/apps/wyatt_feature_brick/lib/feature_name/cubit/feature_name_cubit.dart b/apps/wyatt_feature_brick/lib/feature_name/blocs/feature_name_cubit/feature_name_cubit.dart similarity index 56% rename from apps/wyatt_feature_brick/lib/feature_name/cubit/feature_name_cubit.dart rename to apps/wyatt_feature_brick/lib/feature_name/blocs/feature_name_cubit/feature_name_cubit.dart index 37e3d54..4cd8374 100644 --- a/apps/wyatt_feature_brick/lib/feature_name/cubit/feature_name_cubit.dart +++ b/apps/wyatt_feature_brick/lib/feature_name/blocs/feature_name_cubit/feature_name_cubit.dart @@ -5,11 +5,17 @@ import 'package:flutter_bloc/flutter_bloc.dart'; part 'feature_name_state.dart'; +/// {@template feature_name_cubit} +/// FeatureNameCubit description +/// {@endtemplate} class FeatureNameCubit extends Cubit { + /// {@macro feature_name_cubit} FeatureNameCubit() : super(const FeatureNameInitial()); /// A description for yourCustomFunction - FutureOr yourCustomFunction() { - // TODO(wyattstudio): Add Logic + FutureOr yourCustomFunction() async { + // TODO(wyatt): Add custom UI logic + const _ = 1 + 1; + return; } } diff --git a/apps/wyatt_feature_brick/lib/feature_name/cubit/feature_name_state.dart b/apps/wyatt_feature_brick/lib/feature_name/blocs/feature_name_cubit/feature_name_state.dart similarity index 100% rename from apps/wyatt_feature_brick/lib/feature_name/cubit/feature_name_state.dart rename to apps/wyatt_feature_brick/lib/feature_name/blocs/feature_name_cubit/feature_name_state.dart diff --git a/apps/wyatt_feature_brick/lib/feature_name/feature_name.dart b/apps/wyatt_feature_brick/lib/feature_name/feature_name.dart index a071f26..ee71b07 100644 --- a/apps/wyatt_feature_brick/lib/feature_name/feature_name.dart +++ b/apps/wyatt_feature_brick/lib/feature_name/feature_name.dart @@ -1 +1,2 @@ -export './state_management/feature_name_state_management.dart'; +export 'screens/feature_name_provider.dart'; +export 'screens/feature_name_screen.dart'; diff --git a/apps/wyatt_feature_brick/lib/feature_name/screens/feature_name_parent.dart b/apps/wyatt_feature_brick/lib/feature_name/screens/feature_name_parent.dart new file mode 100644 index 0000000..977c5f3 --- /dev/null +++ b/apps/wyatt_feature_brick/lib/feature_name/screens/feature_name_parent.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; + +class FeatureNameParent extends StatelessWidget { + const FeatureNameParent({ + required this.child, + super.key, + }); + + final Widget child; + + @override + Widget build(BuildContext context) => Scaffold( + body: SafeArea(child: child), + ); +} diff --git a/apps/wyatt_feature_brick/lib/feature_name/screens/feature_name_provider.dart b/apps/wyatt_feature_brick/lib/feature_name/screens/feature_name_provider.dart new file mode 100644 index 0000000..c153af2 --- /dev/null +++ b/apps/wyatt_feature_brick/lib/feature_name/screens/feature_name_provider.dart @@ -0,0 +1,22 @@ +// ignore_for_file: always_use_package_imports + +import 'package:flutter/material.dart'; +import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; + +import '../blocs/feature_name_cubit/feature_name_cubit.dart'; +import 'widgets/feature_name_consumer_widget.dart'; + +/// {@template feature_name_provider} +/// FeatureNameProvider provides bloc to his children. +/// {@endtemplate} +class FeatureNameProvider + extends CubitProviderScreen { + /// {@macro feature_name_provider} + const FeatureNameProvider({super.key}); + + @override + FeatureNameCubit create(BuildContext context) => FeatureNameCubit(); + + @override + Widget builder(BuildContext context) => const FeatureNameConsumerWidget(); +} diff --git a/apps/wyatt_feature_brick/lib/feature_name/screens/feature_name_screen.dart b/apps/wyatt_feature_brick/lib/feature_name/screens/feature_name_screen.dart new file mode 100644 index 0000000..26e6dd0 --- /dev/null +++ b/apps/wyatt_feature_brick/lib/feature_name/screens/feature_name_screen.dart @@ -0,0 +1,33 @@ +// ignore_for_file: always_use_package_imports + +import 'package:flutter/material.dart'; +import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; + +import '../blocs/feature_name_cubit/feature_name_cubit.dart'; +import '../stateless/feature_name_widget.dart'; +import 'feature_name_parent.dart'; + +/// {@template feature_name_screen} +/// FeatureNameScreen is the merge of Provider and Consumer. +/// {@endtemplate} +class FeatureNameScreen + extends CubitScreen { + /// {@macro feature_name_screen} + const FeatureNameScreen({super.key}); + + @override + FeatureNameCubit create(BuildContext context) => FeatureNameCubit(); + + @override + FeatureNameCubit init(BuildContext context, FeatureNameCubit bloc) => + bloc..yourCustomFunction(); + + @override + Widget parent(BuildContext context, Widget child) => + FeatureNameParent(child: child); + + // Rebuild on every bloc changes + @override + Widget onBuild(BuildContext context, FeatureNameState state) => + const FeatureNameWidget(); +} diff --git a/apps/wyatt_feature_brick/lib/feature_name/screens/widgets/feature_name_consumer_widget.dart b/apps/wyatt_feature_brick/lib/feature_name/screens/widgets/feature_name_consumer_widget.dart new file mode 100644 index 0000000..d207eb7 --- /dev/null +++ b/apps/wyatt_feature_brick/lib/feature_name/screens/widgets/feature_name_consumer_widget.dart @@ -0,0 +1,18 @@ +// ignore_for_file: always_use_package_imports + +import 'package:flutter/material.dart'; +import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; + +import '../../blocs/feature_name_cubit/feature_name_cubit.dart'; + +/// {@template feature_name_consumer_widget} +/// FeatureNameConsumerWidget is a stateful widget. Aware of state changes. +/// {@endtemplate} +class FeatureNameConsumerWidget + extends CubitConsumerScreen { + /// {@macro feature_name_consumer_widget} + const FeatureNameConsumerWidget({super.key}); + + @override + Widget onBuild(BuildContext context, FeatureNameState state) => Container(); +} diff --git a/apps/wyatt_feature_brick/lib/feature_name/state_management/feature_name_state_management.dart b/apps/wyatt_feature_brick/lib/feature_name/state_management/feature_name_state_management.dart deleted file mode 100644 index 5c958f4..0000000 --- a/apps/wyatt_feature_brick/lib/feature_name/state_management/feature_name_state_management.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; - -// ignore: always_use_package_imports -import './feature_name_wrapper_widget.dart'; -// ignore: always_use_package_imports -import './widgets/feature_name_widget.dart'; -// ignore: always_use_package_imports -import '../cubit/feature_name_cubit.dart'; - -class FeatureNameCubitStateManagement - extends CubitScreen { - const FeatureNameCubitStateManagement({super.key}); - - @override - FeatureNameCubit create(BuildContext context) => FeatureNameCubit(); - - @override - Widget onWrap(BuildContext context, Widget child) => - FeatureNameWrapperWidget(child: child); - - @override - Widget onBuild(BuildContext context, FeatureNameState state) => - const FeatureNameWidget(); -} diff --git a/apps/wyatt_feature_brick/lib/feature_name/state_management/feature_name_wrapper_widget.dart b/apps/wyatt_feature_brick/lib/feature_name/state_management/feature_name_wrapper_widget.dart deleted file mode 100644 index 6fa4070..0000000 --- a/apps/wyatt_feature_brick/lib/feature_name/state_management/feature_name_wrapper_widget.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class FeatureNameWrapperWidget extends StatelessWidget { - final Widget child; - const FeatureNameWrapperWidget({ - required this.child, - super.key, - }); - - @override - Widget build(BuildContext context) => Container( - child: child, - ); -} diff --git a/apps/wyatt_feature_brick/lib/feature_name/state_management/widgets/feature_name_widget.dart b/apps/wyatt_feature_brick/lib/feature_name/state_management/widgets/feature_name_widget.dart deleted file mode 100644 index 9ab7ada..0000000 --- a/apps/wyatt_feature_brick/lib/feature_name/state_management/widgets/feature_name_widget.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:flutter/material.dart'; - -class FeatureNameWidget extends StatelessWidget { - const FeatureNameWidget({super.key}); - - @override - Widget build(BuildContext context) => const SizedBox(); -} diff --git a/apps/wyatt_feature_brick/lib/feature_name/stateless/feature_name_widget.dart b/apps/wyatt_feature_brick/lib/feature_name/stateless/feature_name_widget.dart new file mode 100644 index 0000000..9a4fd85 --- /dev/null +++ b/apps/wyatt_feature_brick/lib/feature_name/stateless/feature_name_widget.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +/// {@template feature_name_widget} +/// FeatureNameWidget is a stateless widget. (Not aware of cubit or bloc states) +/// {@endtemplate} +class FeatureNameWidget extends StatelessWidget { + /// {@macro feature_name_widget} + const FeatureNameWidget({super.key}); + + @override + Widget build(BuildContext context) => Container(); +} diff --git a/apps/wyatt_feature_brick/pubspec.yaml b/apps/wyatt_feature_brick/pubspec.yaml index e73da2d..92a89c6 100644 --- a/apps/wyatt_feature_brick/pubspec.yaml +++ b/apps/wyatt_feature_brick/pubspec.yaml @@ -1,99 +1,33 @@ name: wyatt_feature_brick description: A new Flutter project. - -# The following line prevents the package from being accidentally published to -# pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: "none" # Remove this line if you wish to publish to pub.dev - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html version: 1.0.0+1 +publish_to: "none" + environment: - sdk: ">=2.17.6 <3.0.0" + sdk: ">=2.18.0 <3.0.0" -# Dependencies specify other packages that your package needs in order to work. -# To automatically upgrade your package dependencies to the latest versions -# consider running `flutter pub upgrade --major-versions`. Alternatively, -# dependencies can be manually updated by changing the version numbers below to -# the latest version available on pub.dev. To see which dependencies have newer -# versions available, run `flutter pub outdated`. dependencies: - flutter: - sdk: flutter + flutter: { sdk: flutter } - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 flutter_bloc: ^8.0.1 equatable: ^2.0.3 + wyatt_bloc_helper: - git: - url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages - ref: bloc/feature/fix_and_repo - path: packages/wyatt_bloc_helper + hosted: + url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + name: wyatt_bloc_helper + version: 2.0.0 dev_dependencies: - flutter_test: - sdk: flutter + flutter_test: { sdk: flutter } + wyatt_analysis: - git: - url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages - ref: wyatt_analysis-v2.1.0 - path: packages/wyatt_analysis + hosted: + url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + name: wyatt_analysis + version: 2.3.0 - # The "flutter_lints" package below contains a set of recommended lints to - # encourage good coding practices. The lint set provided by the package is - # activated in the `analysis_options.yaml` file located at the root of your - # package. See that file for information about deactivating specific lint - # rules and activating additional ones. - flutter_lints: ^2.0.0 - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter packages. flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/apps/wyatt_feature_brick/test/widget_test.dart b/apps/wyatt_feature_brick/test/widget_test.dart deleted file mode 100644 index 1ce5d91..0000000 --- a/apps/wyatt_feature_brick/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility in the flutter_test package. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:wyatt_feature_brick/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/apps/wyatt_package_template/brickgen.yaml b/apps/wyatt_package_template/brickgen.yaml new file mode 100644 index 0000000..a952fd8 --- /dev/null +++ b/apps/wyatt_package_template/brickgen.yaml @@ -0,0 +1,48 @@ +name: wyatt_package_template +description: New package template for Wyatt Studio projects. + +version: 0.1.0 + +vars: + package_name: + compilable: package_name + type: string + description: The package name + default: package_name + prompt: "What is the package name?" + formats: + - snake_case + - title_case + - pascal_case + + description: + compilable: A short package description + type: string + description: A short package description + default: A package by Wyatt Studio. + prompt: "What is the package description?" + formats: + - sentence_case + + flutter: + type: boolean + description: Should generate a plugin (Flutter only) or a package (Dart and Flutter). + default: false + prompt: "Should generate Flutter only plugin ?" + +brickgen: + path_to_brickify: wyatt_package_template + hooks: true + ignore: + - .env + - .dart_tool/ + - .idea/ + - example/.dart_tool/ + - example/.idea/ + boolean_file_system: + flutter: + folders: + on_true: + - example/web + on_false: + - example/bin diff --git a/apps/wyatt_package_template/hooks/post_gen.dart b/apps/wyatt_package_template/hooks/post_gen.dart new file mode 100644 index 0000000..babd1b7 --- /dev/null +++ b/apps/wyatt_package_template/hooks/post_gen.dart @@ -0,0 +1,39 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:mason/mason.dart'; + +void removeGitKeepFiles(String targetPath) { + if (!FileSystemEntity.isDirectorySync(targetPath)) { + throw ArgumentError('Target must be a directory', 'targetPath'); + } + + Directory(targetPath) + .listSync(recursive: true) + .whereType() + .forEach((file) { + if (file.path.contains('.gitkeep')) { + file.deleteSync(recursive: true); + } + }); +} + +Future run(HookContext context) async { + final workingDirectory = Directory.current.path; + removeGitKeepFiles(workingDirectory); +} diff --git a/apps/wyatt_package_template/hooks/pre_gen.dart b/apps/wyatt_package_template/hooks/pre_gen.dart new file mode 100644 index 0000000..ea2f0c7 --- /dev/null +++ b/apps/wyatt_package_template/hooks/pre_gen.dart @@ -0,0 +1,21 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:mason/mason.dart'; + +void run(HookContext context) { + context.vars = {...context.vars, 'year': DateTime.now().year.toString()}; +} \ No newline at end of file diff --git a/apps/wyatt_package_template/hooks/pubspec.yaml b/apps/wyatt_package_template/hooks/pubspec.yaml new file mode 100644 index 0000000..454f6df --- /dev/null +++ b/apps/wyatt_package_template/hooks/pubspec.yaml @@ -0,0 +1,7 @@ +name: hooks + +environment: + sdk: ">=2.18.0 <3.0.0" + +dependencies: + mason: any \ No newline at end of file diff --git a/apps/wyatt_package_template/wyatt_package_template/.gitignore b/apps/wyatt_package_template/wyatt_package_template/.gitignore new file mode 100644 index 0000000..3cceda5 --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/.gitignore @@ -0,0 +1,7 @@ +# https://dart.dev/guides/libraries/private-files +# Created by `dart pub` +.dart_tool/ + +# Avoid committing pubspec.lock for library packages; see +# https://dart.dev/guides/libraries/private-files#pubspeclock. +pubspec.lock diff --git a/apps/wyatt_package_template/wyatt_package_template/.vscode/extensions.json b/apps/wyatt_package_template/wyatt_package_template/.vscode/extensions.json new file mode 100644 index 0000000..30cd223 --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/.vscode/extensions.json @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2022 WYATT GROUP + * Please see the AUTHORS file for details. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +{ + "recommendations": [ + "psioniq.psi-header", + "blaugold.melos-code" + ] +} \ No newline at end of file diff --git a/apps/wyatt_package_template/wyatt_package_template/.vscode/launch.json b/apps/wyatt_package_template/wyatt_package_template/.vscode/launch.json new file mode 100644 index 0000000..653eabc --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/.vscode/launch.json @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 WYATT GROUP + * Please see the AUTHORS file for details. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Example", + "request": "launch", + "type": "dart", + "cwd": "example/", + "program": "lib/main.dart", + "flutterMode": "debug" + }, + ] +} \ No newline at end of file diff --git a/apps/wyatt_package_template/wyatt_package_template/.vscode/settings.json b/apps/wyatt_package_template/wyatt_package_template/.vscode/settings.json new file mode 100644 index 0000000..a729c46 --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/.vscode/settings.json @@ -0,0 +1,72 @@ +{ + "dart.runPubGetOnPubspecChanges": "never", + "bloc.newCubitTemplate.type": "equatable", + "psi-header.changes-tracking": { + "isActive": true + }, + "psi-header.config": { + "blankLinesAfter": 1, + "forceToTop": true + }, + "psi-header.lang-config": [ + { + "beforeHeader": [ + "# -*- coding:utf-8 -*-", + "#!/usr/bin/env python3" + ], + "begin": "###", + "end": "###", + "language": "python", + "prefix": "# " + }, + { + "beforeHeader": [ + "#!/usr/bin/env sh", + "" + ], + "language": "shellscript", + "begin": "", + "end": "", + "prefix": "# " + }, + { + "begin": "", + "end": "", + "language": "dart", + "prefix": "// " + }, + { + "begin": "", + "end": "", + "language": "yaml", + "prefix": "# " + }, + { + "begin": "", + "language": "markdown", + }, + ], + "psi-header.templates": [ + { + "language": "*", + "template": [ + "Copyright (C) <> WYATT GROUP", + "Please see the AUTHORS file for details.", + "", + "This program is free software: you can redistribute it and/or modify", + "it under the terms of the GNU General Public License as published by", + "the Free Software Foundation, either version 3 of the License, or", + "any later version.", + "", + "This program is distributed in the hope that it will be useful,", + "but WITHOUT ANY WARRANTY; without even the implied warranty of", + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", + "GNU General Public License for more details.", + "", + "You should have received a copy of the GNU General Public License", + "along with this program. If not, see ." + ], + } + ], +} \ No newline at end of file diff --git a/apps/wyatt_package_template/wyatt_package_template/CHANGELOG.md b/apps/wyatt_package_template/wyatt_package_template/CHANGELOG.md new file mode 100644 index 0000000..effe43c --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +- Initial version. diff --git a/apps/wyatt_package_template/wyatt_package_template/README.md b/apps/wyatt_package_template/wyatt_package_template/README.md new file mode 100644 index 0000000..6576b4e --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/README.md @@ -0,0 +1,65 @@ + + +{{#flutter}} + +# Flutter - Package Name + +

+ Style: Wyatt Analysis + SDK: Flutter +

+ +{{/flutter}} + +{{^flutter}} + +# Dart - Package Name + +

+ Style: Wyatt Analysis + SDK: Dart & Flutter +

+ +{{/flutter}} + +A short package description + +## Features + +TODO: List what your package can do. Maybe include images, gifs, or videos. + +## Getting started + +TODO: List prerequisites and provide or point to information on how to +start using the package. + +## Usage + +TODO: Include short and useful examples for package users. Add longer examples +to `/example` folder. + +```dart +const like = 'sample'; +``` + +## Additional information + +TODO: Tell users more about the package: where to find more information, how to +contribute to the package, how to file issues, what response they can expect +from the package authors, and more. diff --git a/apps/wyatt_package_template/wyatt_package_template/analysis_options.yaml b/apps/wyatt_package_template/wyatt_package_template/analysis_options.yaml new file mode 100644 index 0000000..8773f69 --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/analysis_options.yaml @@ -0,0 +1,6 @@ +### {{#flutter}} +###include: package:wyatt_analysis/analysis_options.flutter.yaml +### {{/flutter}} +### {{^flutter}} +include: package:wyatt_analysis/analysis_options.yaml +### {{/flutter}} diff --git a/apps/wyatt_package_template/wyatt_package_template/example/.gitignore b/apps/wyatt_package_template/wyatt_package_template/example/.gitignore new file mode 100644 index 0000000..24476c5 --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/example/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/apps/wyatt_package_template/wyatt_package_template/example/.metadata b/apps/wyatt_package_template/wyatt_package_template/example/.metadata new file mode 100644 index 0000000..30e0d3c --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/example/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + channel: stable + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + - platform: web + create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/apps/wyatt_package_template/wyatt_package_template/example/README.md b/apps/wyatt_package_template/wyatt_package_template/example/README.md new file mode 100644 index 0000000..2b3fce4 --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/example/README.md @@ -0,0 +1,16 @@ +# example + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/apps/wyatt_package_template/wyatt_package_template/example/analysis_options.yaml b/apps/wyatt_package_template/wyatt_package_template/example/analysis_options.yaml new file mode 100644 index 0000000..8773f69 --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/example/analysis_options.yaml @@ -0,0 +1,6 @@ +### {{#flutter}} +###include: package:wyatt_analysis/analysis_options.flutter.yaml +### {{/flutter}} +### {{^flutter}} +include: package:wyatt_analysis/analysis_options.yaml +### {{/flutter}} diff --git a/apps/wyatt_package_template/wyatt_package_template/example/bin/package_name_example.dart b/apps/wyatt_package_template/wyatt_package_template/example/bin/package_name_example.dart new file mode 100644 index 0000000..de74ad7 --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/example/bin/package_name_example.dart @@ -0,0 +1,24 @@ +// Copyright (C) {{year}} WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:package_name_example/main.dart'; + +void main(List args) { + PackageNameExample.run(args); + exit(0); +} diff --git a/apps/wyatt_package_template/wyatt_package_template/example/lib/main.dart b/apps/wyatt_package_template/wyatt_package_template/example/lib/main.dart new file mode 100644 index 0000000..0afee77 --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/example/lib/main.dart @@ -0,0 +1,56 @@ +// Copyright (C) {{year}} WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +///{{#flutter}} +import 'package:flutter/material.dart'; + +///{{/flutter}} +import 'package:package_name/package_name.dart'; + +///{{^flutter}} +class PackageNameExample { + static void run(List args) { + print(PackageName.testString); + } +} + +///{{/flutter}} + +///{{#flutter}} +void main(List args) { + runApp(const App()); +} + +class App extends StatelessWidget { + const App({super.key}); + + static const String title = 'Package Name Example'; + + @override + Widget build(BuildContext context) => MaterialApp( + title: title, + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Scaffold( + appBar: AppBar( + title: const Text(title), + ), + body: Center(child: Text(PackageName.testString)), + ), + ); +} +///{{/flutter}} diff --git a/apps/wyatt_package_template/wyatt_package_template/example/pubspec.yaml b/apps/wyatt_package_template/wyatt_package_template/example/pubspec.yaml new file mode 100644 index 0000000..a8d3f00 --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/example/pubspec.yaml @@ -0,0 +1,34 @@ +name: package_name_example +description: A new Flutter project. +version: 1.0.0 + +publish_to: 'none' + +environment: + sdk: ">=2.19.0 <3.0.0" + +dependencies: +### {{#flutter}} + flutter: { sdk: flutter } +### {{/flutter}} + + package_name: + path: "../" + +dev_dependencies: +### {{#flutter}} + flutter_test: { sdk: flutter } +### {{/flutter}} +### {{^flutter}} +### test: ^1.21.0 +### {{/flutter}} + + wyatt_analysis: + hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub + version: ^2.3.0 + +###{{#flutter}} +#### The following section is specific to Flutter. +###flutter: +### uses-material-design: true +###{{/flutter}} \ No newline at end of file diff --git a/apps/wyatt_package_template/wyatt_package_template/example/test/widget_test.dart b/apps/wyatt_package_template/wyatt_package_template/example/test/widget_test.dart new file mode 100644 index 0000000..e69de29 diff --git a/apps/wyatt_package_template/wyatt_package_template/example/web/favicon.png b/apps/wyatt_package_template/wyatt_package_template/example/web/favicon.png new file mode 100644 index 0000000..8aaa46a Binary files /dev/null and b/apps/wyatt_package_template/wyatt_package_template/example/web/favicon.png differ diff --git a/apps/wyatt_package_template/wyatt_package_template/example/web/icons/Icon-192.png b/apps/wyatt_package_template/wyatt_package_template/example/web/icons/Icon-192.png new file mode 100644 index 0000000..b749bfe Binary files /dev/null and b/apps/wyatt_package_template/wyatt_package_template/example/web/icons/Icon-192.png differ diff --git a/apps/wyatt_package_template/wyatt_package_template/example/web/icons/Icon-512.png b/apps/wyatt_package_template/wyatt_package_template/example/web/icons/Icon-512.png new file mode 100644 index 0000000..88cfd48 Binary files /dev/null and b/apps/wyatt_package_template/wyatt_package_template/example/web/icons/Icon-512.png differ diff --git a/apps/wyatt_package_template/wyatt_package_template/example/web/icons/Icon-maskable-192.png b/apps/wyatt_package_template/wyatt_package_template/example/web/icons/Icon-maskable-192.png new file mode 100644 index 0000000..eb9b4d7 Binary files /dev/null and b/apps/wyatt_package_template/wyatt_package_template/example/web/icons/Icon-maskable-192.png differ diff --git a/apps/wyatt_package_template/wyatt_package_template/example/web/icons/Icon-maskable-512.png b/apps/wyatt_package_template/wyatt_package_template/example/web/icons/Icon-maskable-512.png new file mode 100644 index 0000000..d69c566 Binary files /dev/null and b/apps/wyatt_package_template/wyatt_package_template/example/web/icons/Icon-maskable-512.png differ diff --git a/apps/wyatt_package_template/wyatt_package_template/example/web/index.html b/apps/wyatt_package_template/wyatt_package_template/example/web/index.html new file mode 100644 index 0000000..be820e8 --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/example/web/index.html @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + example + + + + + + + + + + diff --git a/apps/wyatt_package_template/wyatt_package_template/example/web/manifest.json b/apps/wyatt_package_template/wyatt_package_template/example/web/manifest.json new file mode 100644 index 0000000..096edf8 --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/example/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "example", + "short_name": "example", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/apps/wyatt_package_template/wyatt_package_template/lib/package_name.dart b/apps/wyatt_package_template/wyatt_package_template/lib/package_name.dart new file mode 100644 index 0000000..3a091f9 --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/lib/package_name.dart @@ -0,0 +1,20 @@ +// Copyright (C) {{year}} WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +/// A short package description +library package_name; + +export 'src/package_name.dart'; diff --git a/apps/wyatt_package_template/wyatt_package_template/lib/src/package_name.dart b/apps/wyatt_package_template/wyatt_package_template/lib/src/package_name.dart new file mode 100644 index 0000000..23b30c3 --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/lib/src/package_name.dart @@ -0,0 +1,19 @@ +// Copyright (C) {{year}} WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +abstract class PackageName { + static String get testString => 'Package: Package Name'; +} diff --git a/apps/wyatt_package_template/wyatt_package_template/pubspec.yaml b/apps/wyatt_package_template/wyatt_package_template/pubspec.yaml new file mode 100644 index 0000000..f9f6e4a --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/pubspec.yaml @@ -0,0 +1,32 @@ +name: package_name +description: A short package description. +repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/package_name +version: 1.0.0 + +environment: + sdk: ">=2.19.0 <3.0.0" + +dependencies: +### {{#flutter}} +### flutter: { sdk: flutter } +### {{/flutter}} + path: ^1.8.0 + +dev_dependencies: +### {{#flutter}} +### flutter_test: { sdk: flutter } +### {{/flutter}} + +### {{^flutter}} + test: ^1.21.0 +### {{/flutter}} + + wyatt_analysis: + hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub + version: ^2.3.0 + +###{{#flutter}} +#### The following section is specific to Flutter. +###flutter: +### uses-material-design: true +###{{/flutter}} \ No newline at end of file diff --git a/apps/wyatt_package_template/wyatt_package_template/test/package_name_test.dart b/apps/wyatt_package_template/wyatt_package_template/test/package_name_test.dart new file mode 100644 index 0000000..771213c --- /dev/null +++ b/apps/wyatt_package_template/wyatt_package_template/test/package_name_test.dart @@ -0,0 +1 @@ +// TODO(wyatt): add some tests \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/.env.example b/bricks/wyatt_app_template/__brick__/.env.example new file mode 100644 index 0000000..e69de29 diff --git a/bricks/wyatt_app_template/__brick__/.gitignore b/bricks/wyatt_app_template/__brick__/.gitignore new file mode 100644 index 0000000..9e1210f --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/.gitignore @@ -0,0 +1,54 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ +*.env.* +!*.env.example + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release +.mason/ + +.env +!.env.example +node_modules/ \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/.metadata b/bricks/wyatt_app_template/__brick__/.metadata new file mode 100644 index 0000000..32d8944 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 135454af32477f815a7525073027a3ff9eff1bfd + channel: stable + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + - platform: web + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/bricks/wyatt_app_template/__brick__/.vscode/launch.json b/bricks/wyatt_app_template/__brick__/.vscode/launch.json new file mode 100644 index 0000000..3e84edd --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/.vscode/launch.json @@ -0,0 +1,77 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch development/debug:mocks", + "request": "launch", + "type": "dart", + "program": "lib/main_development.dart", + "args": [ + "--dart-define=dev_mode=mock", + "--target", + "lib/main_development.dart" + ], + "flutterMode": "debug" + }, + { + "name": "Launch development/debug:emulator", + "request": "launch", + "type": "dart", + "program": "lib/main_development.dart", + "args": [ + "--dart-define=dev_mode=emulator", + "--target", + "lib/main_development.dart" + ], + "flutterMode": "debug" + }, + { + "name": "Launch development/debug:real", + "request": "launch", + "type": "dart", + "program": "lib/main_development.dart", + "args": [ + "--dart-define=dev_mode=real", + "--target", + "lib/main_development.dart" + ], + "flutterMode": "debug" + }, + { + "name": "Launch staging/debug", + "request": "launch", + "type": "dart", + "program": "lib/main_staging.dart", + "args": [ + "--target", + "lib/main_staging.dart" + ], + "flutterMode": "debug" + }, + { + "name": "Launch production/debug", + "request": "launch", + "type": "dart", + "program": "lib/main_production.dart", + "args": [ + "--target", + "lib/main_production.dart" + ], + "flutterMode": "debug" + }, + { + "name": "Launch production/release", + "request": "launch", + "type": "dart", + "program": "lib/main_production.dart", + "args": [ + "--target", + "lib/main_production.dart" + ], + "flutterMode": "release" + }, + ] +} \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/.vscode/settings.json b/bricks/wyatt_app_template/__brick__/.vscode/settings.json new file mode 100644 index 0000000..ee6d931 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/.vscode/settings.json @@ -0,0 +1,15 @@ +{ + "bloc.newCubitTemplate.type": "equatable", + "psi-header.config": { + "blankLinesAfter": 0, + "forceToTop": true, + }, + "psi-header.templates": [ + { + "language": "*", + "template": [ + "{{#titleCase}}{{display_name}}{{/titleCase}} Copyright (c) <>" + ] + } + ], +} \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/README.md b/bricks/wyatt_app_template/__brick__/README.md new file mode 100644 index 0000000..7bdb1d6 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/README.md @@ -0,0 +1,59 @@ +# {{#titleCase}}{{display_name}}{{/titleCase}} + +{{#sentenceCase}}{{description}}{{/sentenceCase}} + +## Requirements + +* Flutter +* Taskfile +* Trapeze (with `npm install` thanks to `package.json`) + +### Configuration + +Create `.env` file with + +```sh +cp .env.example .env +``` + +### Taskfile + +Available tasks: + +| Command | Description | Aliases | +|----|-----|-----| +| `clean` | Cleans the environment.| `cl` | +| `format` |Formats the code.| `fmt` | +| `help` |Help dialog.| `h, default` | +| `lint` |Lints the code.| `l` | +| `start-emulators` | Start needed emulators.| `emu` | +| `build:android` | Building Android APK| `build:a` | +| `build:ios` | Building iOS IPA| `build:i` | +| `gen:build` | Running build runner| `gen:b` | +| `gen:build-delete` |Running build runner with deletion of conflicting outputs| `gen:d` | +| `gen:clean` | Cleaning build runner| `gen:c` | +| `gen:intl` |Generating internationalization file| `gen:i` | +| `gen:trapeze` | Running Trapeze config| `gen:t` | +| `gen:watch` | Running build runner in watch mode| `gen:w` | +| `pub:get` | Getting latest dependencies| `pub:g` | +| `pub:outdated` |Checking for outdated dependencies| `pub:o` | +| `pub:upgrade` | Upgrading dependencies| `pub:u` | +| `pub:upgrade-major` | Upgrading dependencies| `pub:um` | +| `pub:validate` |Running dependency validator| `pub:v` | +| `run:dev` | Run app in development environment| `run:d` | +| `run:emu` | Run app in development with emulated environment| `run:e` | +| `run:logs` |Show log output for running Flutter apps| `run:l` | +| `run:mock` |Run app in development environment with mocks| `run:m` | +| `run:prod` |Run app in production environment| `run:p` | +| `run:release` | Run app in production environment and in release mode| `run:r` | +| `run:staging` | Run app in staging environment| `run:s` | + +### Flavors + +| Flavor | Details | +|-------|--------| +| Development | Use `--dart-define="dev_mode="` to choose between `mock` , `emulator` and `real` | +| Staging | With a green banner. Only `real` mode available (remote data sources) | +| Production | Only `real` mode available (remote data sources) | + +> In `lib/core/flavors/flavor.dart` you can customize flavors. diff --git a/bricks/wyatt_app_template/__brick__/Taskfile.yml b/bricks/wyatt_app_template/__brick__/Taskfile.yml new file mode 100644 index 0000000..43888b9 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/Taskfile.yml @@ -0,0 +1,51 @@ +version: 3 + +vars: + RED: '\033[0;31m' + GREEN: '\033[0;32m' + COLOROFF: '\033[0m' + PREFIX: "⏳" + +includes: + gen: ./automation/generator.yml + pub: ./automation/pub.yml + run: ./automation/run.yml + build: ./automation/build.yml + +silent: true + +tasks: + help: + desc: Help dialog. + aliases: [h, default] + cmds: + - task --summary --list-all + + clean: + desc: Cleans the environment. + aliases: [cl] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Cleaning the project...{{.COLOROFF}}" + - flutter clean + + format: + desc: Formats the code. + aliases: [fmt] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Formatting the code...{{.COLOROFF}}" + - flutter format --fix + - dart fix --apply + + lint: + desc: Lints the code. + aliases: [l] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Verifying code...{{.COLOROFF}}" + - dart analyze . || (echo "Error in project"; exit 1) + + start-emulators: + desc: Start needed emulators. + aliases: [emu] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Start Firebase emulators...{{.COLOROFF}}" + - firebase emulators:start --only auth,functions,firestore,storage --import=./functions/saved-data --export-on-exit=./functions/saved-data diff --git a/bricks/wyatt_app_template/__brick__/analysis_options.yaml b/bricks/wyatt_app_template/__brick__/analysis_options.yaml new file mode 100644 index 0000000..6b75b4c --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/analysis_options.yaml @@ -0,0 +1,27 @@ +include: package:wyatt_analysis/analysis_options.flutter.yaml + +analyzer: + plugins: + - dart_code_metrics + +dart_code_metrics: + anti-patterns: + - long-method + - long-parameter-list + metrics: + cyclomatic-complexity: 20 + maximum-nesting-level: 5 + number-of-parameters: 4 + source-lines-of-code: 50 + metrics-exclude: + - test/** + rules: + - newline-before-return + - no-boolean-literal-compare + - no-empty-block + - prefer-trailing-comma + - prefer-conditional-expressions + - no-equal-then-else + - avoid-border-all + - prefer-const-border-radius + - prefer-using-list-view diff --git a/bricks/wyatt_app_template/__brick__/android/.gitignore b/bricks/wyatt_app_template/__brick__/android/.gitignore new file mode 100644 index 0000000..6f56801 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/android/.gitignore @@ -0,0 +1,13 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +**/*.keystore +**/*.jks diff --git a/bricks/wyatt_app_template/__brick__/android/app/build.gradle b/bricks/wyatt_app_template/__brick__/android/app/build.gradle new file mode 100644 index 0000000..61ce318 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/android/app/build.gradle @@ -0,0 +1,71 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion flutter.compileSdkVersion + ndkVersion flutter.ndkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "{{#dotCase}}{{bundle_id}}{{/dotCase}}" + // You can update the following values to match your application needs. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. + minSdkVersion flutter.minSdkVersion + targetSdkVersion flutter.targetSdkVersion + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} diff --git a/bricks/wyatt_app_template/__brick__/android/app/src/debug/AndroidManifest.xml b/bricks/wyatt_app_template/__brick__/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..7791af8 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + diff --git a/bricks/wyatt_app_template/__brick__/android/app/src/main/AndroidManifest.xml b/bricks/wyatt_app_template/__brick__/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..46a06f9 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + diff --git a/tools/brick_generator/assets/MainActivity.kt b/bricks/wyatt_app_template/__brick__/android/app/src/main/kotlin/io/wyattapp/start/MainActivity.kt similarity index 50% rename from tools/brick_generator/assets/MainActivity.kt rename to bricks/wyatt_app_template/__brick__/android/app/src/main/kotlin/io/wyattapp/start/MainActivity.kt index eb6d0bb..e1ea0f7 100644 --- a/tools/brick_generator/assets/MainActivity.kt +++ b/bricks/wyatt_app_template/__brick__/android/app/src/main/kotlin/io/wyattapp/start/MainActivity.kt @@ -1,6 +1,6 @@ -package {{#dotCase}}{{org_name}}{{/dotCase}}.{{#snakeCase}}{{project_name}}{{/snakeCase}} +package {{#dotCase}}{{bundle_id}}{{/dotCase}} import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { -} \ No newline at end of file +} diff --git a/bricks/wyatt_app_template/__brick__/android/app/src/main/res/drawable-v21/launch_background.xml b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/bricks/wyatt_app_template/__brick__/android/app/src/main/res/drawable/launch_background.xml b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/bricks/wyatt_app_template/__brick__/android/app/src/main/res/values-night/styles.xml b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/bricks/wyatt_app_template/__brick__/android/app/src/main/res/values/styles.xml b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..cb1ef88 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/bricks/wyatt_app_template/__brick__/android/app/src/profile/AndroidManifest.xml b/bricks/wyatt_app_template/__brick__/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..7791af8 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + diff --git a/bricks/wyatt_app_template/__brick__/android/build.gradle b/bricks/wyatt_app_template/__brick__/android/build.gradle new file mode 100644 index 0000000..83ae220 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/android/build.gradle @@ -0,0 +1,31 @@ +buildscript { + ext.kotlin_version = '1.6.10' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.1.2' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/bricks/wyatt_app_template/__brick__/android/gradle.properties b/bricks/wyatt_app_template/__brick__/android/gradle.properties new file mode 100644 index 0000000..94adc3a --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true diff --git a/bricks/wyatt_app_template/__brick__/android/gradle/wrapper/gradle-wrapper.properties b/bricks/wyatt_app_template/__brick__/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..cb24abd --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip diff --git a/bricks/wyatt_app_template/__brick__/android/settings.gradle b/bricks/wyatt_app_template/__brick__/android/settings.gradle new file mode 100644 index 0000000..44e62bc --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/bricks/wyatt_app_template/__brick__/assets/colors.xml b/bricks/wyatt_app_template/__brick__/assets/colors.xml new file mode 100644 index 0000000..503e1f0 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/assets/colors.xml @@ -0,0 +1,5 @@ + + + #FFFFFF + #000000 + \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/assets/fonts/.gitkeep b/bricks/wyatt_app_template/__brick__/assets/fonts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/bricks/wyatt_app_template/__brick__/assets/images/wyatt_logo.jpeg b/bricks/wyatt_app_template/__brick__/assets/images/wyatt_logo.jpeg new file mode 100644 index 0000000..09e8249 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/assets/images/wyatt_logo.jpeg differ diff --git a/bricks/wyatt_app_template/__brick__/assets/l10n/intl_fr.arb b/bricks/wyatt_app_template/__brick__/assets/l10n/intl_fr.arb new file mode 100644 index 0000000..b95f76d --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/assets/l10n/intl_fr.arb @@ -0,0 +1,20 @@ +{ + "@@locale": "fr", + "counterAppBarTitle": "Compteur", + "@counterAppBarTitle": { + "description": "Texte affiché dans l'AppBar de la page Compteur" + }, + "youHavePushed": "Vous avez appuyé {count} fois sur le bouton !", + "@youHavePushed": { + "description": "Message affiché sur la page compteur", + "placeholders": { + "count": { + "type": "int" + } + } + }, + "goToCounter": "Aller au Compteur", + "@goToCounter": { + "description": "Texte affiché dans le bouton ammenant vers la page Compteur" + } +} \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/automation/build.yml b/bricks/wyatt_app_template/__brick__/automation/build.yml new file mode 100644 index 0000000..7dbc051 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/automation/build.yml @@ -0,0 +1,38 @@ +version: 3 + +vars: + RED: '\033[0;31m' + GREEN: '\033[0;32m' + COLOROFF: '\033[0m' + PREFIX: "⏳" + +silent: true + +tasks: + clean: + desc: Cleans the environment. + internal: true + cmds: + - flutter clean + + get: + desc: Getting latest dependencies. + internal: true + cmds: + - flutter pub get + + android: + desc: Building Android APK + deps: [clean, get] + aliases: [a] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Building Android APK...{{.COLOROFF}}" + - flutter build lib/main_production apk --no-pub --no-shrink + + ios: + desc: Building iOS IPA + deps: [clean, get] + aliases: [i] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Building iOS IPA...{{.COLOROFF}}" + - flutter build lib/main_production ipa --no-pub \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/automation/generator.yml b/bricks/wyatt_app_template/__brick__/automation/generator.yml new file mode 100644 index 0000000..33cd1ea --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/automation/generator.yml @@ -0,0 +1,63 @@ +version: 3 + +vars: + RED: '\033[0;31m' + GREEN: '\033[0;32m' + COLOROFF: '\033[0m' + PREFIX: "⏳" + +silent: true + +tasks: + get: + internal: true + desc: Gets dependencies. + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Getting the dependencies...{{.COLOROFF}}" + - flutter pub get + + build: + desc: Running build runner + deps: [get] + aliases: [b] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Running build runner...{{.COLOROFF}}" + - flutter pub run build_runner build + + intl: + desc: Generating internationalization file + deps: [get] + aliases: [i] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Running intl generation...{{.COLOROFF}}" + - flutter gen-l10n + + build-delete: + desc: Running build runner with deletion of conflicting outputs + deps: [get] + aliases: [d] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Running build runner with deletion of conflicting outputs...{{.COLOROFF}}" + - flutter pub run build_runner build --delete-conflicting-outputs + + clean: + desc: Cleaning build runner + aliases: [c] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Cleaning build runner...{{.COLOROFF}}" + - flutter pub run build_runner clean + + watch: + desc: Running build runner in watch mode + deps: [get] + aliases: [w] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Running build runner in watch mode...{{.COLOROFF}}" + - flutter pub run build_runner watch + + trapeze: + desc: Running Trapeze config + aliases: [t] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Running Trapeze config...{{.COLOROFF}}" + - npx trapeze run trapeze.yaml --android-project android --ios-project ios diff --git a/bricks/wyatt_app_template/__brick__/automation/pub.yml b/bricks/wyatt_app_template/__brick__/automation/pub.yml new file mode 100644 index 0000000..fe49212 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/automation/pub.yml @@ -0,0 +1,47 @@ +version: 3 + +vars: + RED: '\033[0;31m' + GREEN: '\033[0;32m' + COLOROFF: '\033[0m' + PREFIX: "⏳" + +silent: true + +tasks: + get: + desc: Getting latest dependencies + aliases: [g] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Getting latest dependencies...{{.COLOROFF}}" + - flutter pub get + + upgrade: + desc: Upgrading dependencies + aliases: [u] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Upgrading dependencies...{{.COLOROFF}}" + - flutter pub upgrade + + upgrade-major: + desc: Upgrading dependencies + aliases: [um] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Upgrading dependencies --major-versions...{{.COLOROFF}}" + - flutter pub upgrade --major-versions + + outdated: + desc: Checking for outdated dependencies + deps: [upgrade] + aliases: [o] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Checking for outdated dependencies...{{.COLOROFF}}" + - flutter pub upgrade + + validate: + desc: Running dependency validator + deps: [get] + aliases: [v] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Validating dependencies...{{.COLOROFF}}" + - flutter pub run dependency_validator diff --git a/bricks/wyatt_app_template/__brick__/automation/run.yml b/bricks/wyatt_app_template/__brick__/automation/run.yml new file mode 100644 index 0000000..3b1eb77 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/automation/run.yml @@ -0,0 +1,59 @@ +version: 3 + +vars: + RED: '\033[0;31m' + GREEN: '\033[0;32m' + COLOROFF: '\033[0m' + PREFIX: "⏳" + +silent: true + +tasks: + logs: + desc: Show log output for running Flutter apps + aliases: [l] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Showing log output for running Flutter apps...{{.COLOROFF}}" + - flutter logs + + mock: + desc: Run app in development environment with mocks + aliases: [m] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (development/debug:mocks)...{{.COLOROFF}}" + - flutter run --target lib/main_development.dart --dart-define="dev_mode=mock" + + emu: + desc: Run app in development with emulated environment + aliases: [e] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (development/debug:emulator)...{{.COLOROFF}}" + - flutter run --target lib/main_development.dart --dart-define="dev_mode=emulator" + + dev: + desc: Run app in development environment + aliases: [d] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (development/debug:real)...{{.COLOROFF}}" + - flutter run --target lib/main_development.dart --dart-define="dev_mode=real" + + staging: + desc: Run app in staging environment + aliases: [s] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (staging/debug)...{{.COLOROFF}}" + - flutter run --target lib/main_staging.dart + + prod: + desc: Run app in production environment + aliases: [p] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (production/debug)...{{.COLOROFF}}" + - flutter run --target lib/main_production.dart + + release: + desc: Run app in production environment and in release mode + aliases: [r] + cmds: + - echo -e "{{.GREEN}}{{.PREFIX}} Running the app (production/release)...{{.COLOROFF}}" + - flutter run --target lib/main_production.dart --release diff --git a/bricks/wyatt_app_template/__brick__/ios/.gitignore b/bricks/wyatt_app_template/__brick__/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/bricks/wyatt_app_template/__brick__/ios/Flutter/AppFrameworkInfo.plist b/bricks/wyatt_app_template/__brick__/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..9625e10 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 11.0 + + diff --git a/bricks/wyatt_app_template/__brick__/ios/Flutter/Debug.xcconfig b/bricks/wyatt_app_template/__brick__/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..ec97fc6 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/bricks/wyatt_app_template/__brick__/ios/Flutter/Release.xcconfig b/bricks/wyatt_app_template/__brick__/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..c4855bf --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/bricks/wyatt_app_template/__brick__/ios/Podfile b/bricks/wyatt_app_template/__brick__/ios/Podfile new file mode 100644 index 0000000..88359b2 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Podfile @@ -0,0 +1,41 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '11.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/bricks/wyatt_app_template/__brick__/ios/Podfile.lock b/bricks/wyatt_app_template/__brick__/ios/Podfile.lock new file mode 100644 index 0000000..cf0efe4 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Podfile.lock @@ -0,0 +1,28 @@ +PODS: + - Flutter (1.0.0) + - flutter_native_splash (0.0.1): + - Flutter + - url_launcher_ios (0.0.1): + - Flutter + +DEPENDENCIES: + - Flutter (from `Flutter`) + - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + flutter_native_splash: + :path: ".symlinks/plugins/flutter_native_splash/ios" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" + +SPEC CHECKSUMS: + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef + url_launcher_ios: ae1517e5e344f5544fb090b079e11f399dfbe4d2 + +PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 + +COCOAPODS: 1.11.3 diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/project.pbxproj b/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..059fb6b --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,556 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 50F1D9CF301DADBFF7F91098 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F58D6DFA5E148E9B1E5401F /* Pods_Runner.framework */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 01240B090F6ECE02483CB484 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 18B4FB2B44E101F10AB8D41B /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 1F58D6DFA5E148E9B1E5401F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + EA780011634A6BC46817CBE0 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 50F1D9CF301DADBFF7F91098 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 10872F84FB14C7DD915284C6 /* Pods */ = { + isa = PBXGroup; + children = ( + 18B4FB2B44E101F10AB8D41B /* Pods-Runner.debug.xcconfig */, + 01240B090F6ECE02483CB484 /* Pods-Runner.release.xcconfig */, + EA780011634A6BC46817CBE0 /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 4204558B17A62367423769E8 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1F58D6DFA5E148E9B1E5401F /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 10872F84FB14C7DD915284C6 /* Pods */, + 4204558B17A62367423769E8 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + B0C681F6443208846EBFB7D2 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + CF936C6216E6F00FB5F73F4C /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + B0C681F6443208846EBFB7D2 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + CF936C6216E6F00FB5F73F4C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 6Z5P8GG96U; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = {{#dotCase}}{{bundle_id}}{{/dotCase}}; + PRODUCT_NAME = "{{#titleCase}}{{display_name}}{{/titleCase}}"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 6Z5P8GG96U; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = {{#dotCase}}{{bundle_id}}{{/dotCase}}; + PRODUCT_NAME = "{{#titleCase}}{{display_name}}{{/titleCase}}"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 6Z5P8GG96U; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = {{#dotCase}}{{bundle_id}}{{/dotCase}}; + PRODUCT_NAME = "{{#titleCase}}{{display_name}}{{/titleCase}}"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/configuration/.gitkeep b/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/configuration/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..c87d15a --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner.xcworkspace/contents.xcworkspacedata b/bricks/wyatt_app_template/__brick__/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/bricks/wyatt_app_template/__brick__/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/bricks/wyatt_app_template/__brick__/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner.xcworkspace/xcshareddata/swiftpm/configuration/.gitkeep b/bricks/wyatt_app_template/__brick__/ios/Runner.xcworkspace/xcshareddata/swiftpm/configuration/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/AppDelegate.swift b/bricks/wyatt_app_template/__brick__/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..70693e4 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..28c6bf0 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..f091b6b Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cde121 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..d0ef06e Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..dcdc230 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..c8f9ed8 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..75b2d16 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..c4df70d Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..6a84f41 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..d0e1f58 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Base.lproj/LaunchScreen.storyboard b/bricks/wyatt_app_template/__brick__/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Base.lproj/Main.storyboard b/bricks/wyatt_app_template/__brick__/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Info.plist b/bricks/wyatt_app_template/__brick__/ios/Runner/Info.plist new file mode 100644 index 0000000..c8fdef9 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner/Info.plist @@ -0,0 +1,51 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + {{#titleCase}}{{display_name}}{{/titleCase}} + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + {{#titleCase}}{{display_name}}{{/titleCase}} + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + + \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Runner-Bridging-Header.h b/bricks/wyatt_app_template/__brick__/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/bricks/wyatt_app_template/__brick__/ios/Runner/Runner.entitlements b/bricks/wyatt_app_template/__brick__/ios/Runner/Runner.entitlements new file mode 100644 index 0000000..74c85d2 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/ios/Runner/Runner.entitlements @@ -0,0 +1,8 @@ + + + + + aps-environment + development + + \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/l10n.yaml b/bricks/wyatt_app_template/__brick__/l10n.yaml new file mode 100644 index 0000000..1518d35 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/l10n.yaml @@ -0,0 +1,8 @@ +arb-dir: assets/l10n +template-arb-file: intl_fr.arb +output-localization-file: app_localizations.dart +output-dir: lib/gen/ +nullable-getter: false +use-deferred-loading: true +synthetic-package: false +header: "/// {{#titleCase}}{{display_name}}{{/titleCase}}, localized files. Automatically generated with `task gen:intl`." \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/lib/bootstrap.dart b/bricks/wyatt_app_template/__brick__/lib/bootstrap.dart new file mode 100644 index 0000000..7f454b7 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/bootstrap.dart @@ -0,0 +1,20 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/dependency_injection/get_it.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/flavors/flavor.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/utils/app_bloc_observer.dart'; + +Future bootstrap(FutureOr Function() builder) async { + final widgetsBinding = WidgetsFlutterBinding.ensureInitialized(); + // FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding); + + Bloc.observer = AppBlocObserver(); + + debugPrint('Flavor: ${Flavor.get()}'); + + await GetItInitializer.init(); + + runApp(await builder()); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/core/constants/emulator.dart b/bricks/wyatt_app_template/__brick__/lib/core/constants/emulator.dart new file mode 100644 index 0000000..00258ff --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/core/constants/emulator.dart @@ -0,0 +1,18 @@ +/// Firebase Emulator constants. +/// +/// If you don't use Firebase, it can be safely deleted. +abstract class Emulator { + static const String firebaseCloudFunctionEnvKey = + 'EMULATOR_FIREBASE_CLOUD_FUNCTION_PORT'; + static const String firebaseFirestoreEnvKey = + 'EMULATOR_FIREBASE_FIRESTORE_PORT'; + static const String firebaseAuthEnvKey = 'EMULATOR_FIREBASE_AUTH_PORT'; + static const String firebaseStorageEnvKey = 'EMULATOR_FIREBASE_STORAGE_PORT'; + static const String hostEnvKey = 'EMULATOR_HOST'; + + static const int defaultFirebaseCloudFunctionPort = 5001; + static const int defaultFirebaseFirestorePort = 8080; + static const int defaultFirebaseAuthPort = 9099; + static const int defaultFirebaseStoragePort = 9199; + static const defaultHost = 'localhost'; +} diff --git a/bricks/wyatt_app_template/__brick__/lib/core/dependency_injection/get_it.dart b/bricks/wyatt_app_template/__brick__/lib/core/dependency_injection/get_it.dart new file mode 100644 index 0000000..3ed791e --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/core/dependency_injection/get_it.dart @@ -0,0 +1,40 @@ +import 'dart:async'; + +import 'package:get_it/get_it.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/enums/dev_mode.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/flavors/flavor.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/data/data_sources/local/counter_data_source_impl.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/data_sources/local/counter_data_source.dart'; + +final getIt = GetIt.I; + +/// Service and Data Source locator +abstract class GetItInitializer { + static FutureOr _initCommon() async { + // Initialize common sources/services + getIt.registerLazySingleton( + CounterDataSourceImpl.new, + ); + } + + static FutureOr _initMocks() async { + // Initialize mocked sources/services. + } + + static FutureOr _initReal() async { + // Initialize real sources/services + } + + static FutureOr init() async { + await _initCommon(); + final flavor = Flavor.get(); + + if (flavor.devMode == DevMode.mock) { + await _initMocks(); + } else { + await _initReal(); + } + + await getIt.allReady(); + } +} diff --git a/bricks/wyatt_app_template/__brick__/lib/core/enums/dev_mode.dart b/bricks/wyatt_app_template/__brick__/lib/core/enums/dev_mode.dart new file mode 100644 index 0000000..bd4ad84 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/core/enums/dev_mode.dart @@ -0,0 +1,20 @@ +enum DevMode { + mock, + emulator, + real; + + @override + String toString() => name; + + /// Tries to parse String and returns mode. Fallback is returned if there + /// is an error during parsing. + static DevMode fromString(String? mode, {DevMode fallback = DevMode.mock}) { + for (final m in values) { + if (m.name == mode) { + return m; + } + } + + return fallback; + } +} diff --git a/bricks/wyatt_app_template/__brick__/lib/core/extensions/build_context_extension.dart b/bricks/wyatt_app_template/__brick__/lib/core/extensions/build_context_extension.dart new file mode 100644 index 0000000..34c7346 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/core/extensions/build_context_extension.dart @@ -0,0 +1,6 @@ +import 'package:flutter/widgets.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/gen/app_localizations.dart'; + +extension BuildContextExtension on BuildContext { + AppLocalizations get l10n => AppLocalizations.of(this); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/core/flavors/flavor.dart b/bricks/wyatt_app_template/__brick__/lib/core/flavors/flavor.dart new file mode 100644 index 0000000..60f1f8c --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/core/flavors/flavor.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/enums/dev_mode.dart'; + +abstract class Flavor { + Flavor._({ + this.banner, + this.bannerColor = Colors.red, + this.devMode, + }) { + _instance = this; + } + + static Flavor? _instance; + + final String? banner; + final Color bannerColor; + final DevMode? devMode; + + /// Returns [Flavor] instance. + static Flavor get() { + if (_instance == null) { + throw Exception('Flavor not initialized!'); + } + + return _instance!; + } + + @override + String toString() => runtimeType.toString().replaceAll('Flavor', ''); +} + +class DevelopmentFlavor extends Flavor { + factory DevelopmentFlavor() { + const modeString = String.fromEnvironment('dev_mode', defaultValue: 'mock'); + final mode = DevMode.fromString(modeString); + + return DevelopmentFlavor._(devMode: mode); + } + DevelopmentFlavor._({ + required DevMode devMode, + }) : super._( + banner: 'Dev', + devMode: devMode, + ); +} + +class StagingFlavor extends Flavor { + StagingFlavor() + : super._( + banner: 'Staging', + bannerColor: Colors.green, + ); +} + +class ProductionFlavor extends Flavor { + ProductionFlavor() : super._(); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/core/routes/router.dart b/bricks/wyatt_app_template/__brick__/lib/core/routes/router.dart new file mode 100644 index 0000000..49679ce --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/core/routes/router.dart @@ -0,0 +1,65 @@ +import 'package:flutter/cupertino.dart'; +import 'package:go_router/go_router.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/counter/counter.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/home/home.dart'; + +abstract class AppRouter { + /// Default transition for all pages + static Page defaultTransition( + BuildContext context, + GoRouterState state, + Widget child, + ) => + CupertinoPage( + key: state.pageKey, + child: child, + ); + + /// Disable transition animation + static Page noTransition( + BuildContext context, + GoRouterState state, + Widget child, + ) => + CustomTransitionPage( + key: state.pageKey, + transitionsBuilder: (_, __, ___, child) => child, + child: child, + ); + + /// Defines public routes (no authentication needed). + /// + /// Example: + /// ```dart + /// static final publicRoutes = [ + /// '/', + /// '/sign_in', + /// '/sign_up', + /// ]; + /// ``` + static final List publicRoutes = []; + + /// Defines GoRoute routes. + static final List routes = [ + GoRoute( + path: '/', + name: Home.pageName, + pageBuilder: (context, state) => + defaultTransition(context, state, const Home()), + ), + GoRoute( + path: '/counter', + name: Counter.pageName, + pageBuilder: (context, state) => + defaultTransition(context, state, const Counter()), + ), + ]; + + /// Router + static GoRouter router = GoRouter( + initialLocation: '/', + routes: AppRouter.routes, + debugLogDiagnostics: true, + redirect: (context, state) => null, + ); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/core/utils/app_bloc_observer.dart b/bricks/wyatt_app_template/__brick__/lib/core/utils/app_bloc_observer.dart new file mode 100644 index 0000000..92be592 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/core/utils/app_bloc_observer.dart @@ -0,0 +1,74 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +const _messageLength = 100; + +class AppBlocObserver extends BlocObserver { + AppBlocObserver({ + this.printEvent = true, + this.printError = true, + this.printTransition = false, + this.printChange = true, + this.fullPrint = false, + }); + + final bool printEvent; + final bool printError; + final bool printChange; + final bool printTransition; + final bool fullPrint; + + String sanitize(Object? object) { + final message = object.toString(); + + return fullPrint + ? message + : message.substring( + 0, + message.length < _messageLength ? message.length : _messageLength, + ); + } + + @override + void onEvent(Bloc bloc, Object? event) { + super.onEvent(bloc, event); + if (printEvent) { + debugPrint('onEvent: ${bloc.runtimeType}\n' + '> event: ${sanitize(event)}'); + } + } + + @override + void onError(BlocBase bloc, Object error, StackTrace stackTrace) { + if (printError) { + debugPrint('onError: ${bloc.runtimeType}\n' + '> error: ${sanitize(error)}\n' + '$stackTrace'); + } + super.onError(bloc, error, stackTrace); + } + + @override + void onChange(BlocBase bloc, Change change) { + super.onChange(bloc, change); + if (printChange) { + debugPrint('onChange: ${bloc.runtimeType}\n' + '> currentState: ${sanitize(change.currentState)}\n' + '> nextState: ${sanitize(change.nextState)}'); + } + } + + @override + void onTransition( + Bloc bloc, + Transition transition, + ) { + super.onTransition(bloc, transition); + if (printTransition) { + debugPrint('onTransition: ${bloc.runtimeType}\n' + '> currentState: ${sanitize(transition.currentState)}\n' + '> event: ${sanitize(transition.event)}\n' + '> nextState: ${sanitize(transition.nextState)}'); + } + } +} diff --git a/bricks/wyatt_app_template/__brick__/lib/data/data_sources/local/counter_data_source_impl.dart b/bricks/wyatt_app_template/__brick__/lib/data/data_sources/local/counter_data_source_impl.dart new file mode 100644 index 0000000..16c5b54 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/data/data_sources/local/counter_data_source_impl.dart @@ -0,0 +1,59 @@ +import 'dart:convert'; + +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/data/models/integer_model.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/data_sources/local/counter_data_source.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/entities/integer.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +class CounterDataSourceImpl extends CounterDataSource { + // Simulate external data processing + String actual = '{"value": 0}'; + + @override + Future decrement(Integer value) async { + final current = + IntegerModel.fromJson(json.decode(actual) as Map); + + final newValue = current.value - value.value; + if (newValue < 0) { + throw ClientException("Counter can't be negative!"); + } + + final newInteger = IntegerModel(value: newValue); + actual = jsonEncode(newInteger.toJson()); + + return newInteger; + } + + @override + Future increment(Integer value) async { + final current = + IntegerModel.fromJson(json.decode(actual) as Map); + + final newValue = current.value + value.value; + if (newValue < 0) { + throw ClientException("Counter can't be negative!"); + } + + final newInteger = IntegerModel(value: newValue); + actual = jsonEncode(newInteger.toJson()); + + return newInteger; + } + + @override + Future getCurrent() async { + final current = + IntegerModel.fromJson(json.decode(actual) as Map); + + return current; + } + + @override + Future reset() async { + const newInteger = IntegerModel(value: 0); + actual = jsonEncode(newInteger.toJson()); + + return newInteger; + } +} diff --git a/bricks/wyatt_app_template/__brick__/lib/data/data_sources/remote/.gitkeep b/bricks/wyatt_app_template/__brick__/lib/data/data_sources/remote/.gitkeep new file mode 100644 index 0000000..f94cb6f --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/data/data_sources/remote/.gitkeep @@ -0,0 +1 @@ +# just to keep empty folder in brick generation \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/lib/data/models/integer_model.dart b/bricks/wyatt_app_template/__brick__/lib/data/models/integer_model.dart new file mode 100644 index 0000000..292c1c9 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/data/models/integer_model.dart @@ -0,0 +1,15 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/entities/integer.dart'; + +part 'integer_model.freezed.dart'; +part 'integer_model.g.dart'; + +@freezed +class IntegerModel extends Integer with _$IntegerModel { + const factory IntegerModel({ + required int value, + }) = _IntegerModel; + + factory IntegerModel.fromJson(Map json) => + _$IntegerModelFromJson(json); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/data/models/integer_model.freezed.dart b/bricks/wyatt_app_template/__brick__/lib/data/models/integer_model.freezed.dart new file mode 100644 index 0000000..bed9972 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/data/models/integer_model.freezed.dart @@ -0,0 +1,151 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'integer_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + +IntegerModel _$IntegerModelFromJson(Map json) { + return _IntegerModel.fromJson(json); +} + +/// @nodoc +mixin _$IntegerModel { + int get value => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $IntegerModelCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $IntegerModelCopyWith<$Res> { + factory $IntegerModelCopyWith( + IntegerModel value, $Res Function(IntegerModel) then) = + _$IntegerModelCopyWithImpl<$Res, IntegerModel>; + @useResult + $Res call({int value}); +} + +/// @nodoc +class _$IntegerModelCopyWithImpl<$Res, $Val extends IntegerModel> + implements $IntegerModelCopyWith<$Res> { + _$IntegerModelCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? value = null, + }) { + return _then(_value.copyWith( + value: null == value + ? _value.value + : value // ignore: cast_nullable_to_non_nullable + as int, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$_IntegerModelCopyWith<$Res> + implements $IntegerModelCopyWith<$Res> { + factory _$$_IntegerModelCopyWith( + _$_IntegerModel value, $Res Function(_$_IntegerModel) then) = + __$$_IntegerModelCopyWithImpl<$Res>; + @override + @useResult + $Res call({int value}); +} + +/// @nodoc +class __$$_IntegerModelCopyWithImpl<$Res> + extends _$IntegerModelCopyWithImpl<$Res, _$_IntegerModel> + implements _$$_IntegerModelCopyWith<$Res> { + __$$_IntegerModelCopyWithImpl( + _$_IntegerModel _value, $Res Function(_$_IntegerModel) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? value = null, + }) { + return _then(_$_IntegerModel( + value: null == value + ? _value.value + : value // ignore: cast_nullable_to_non_nullable + as int, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$_IntegerModel implements _IntegerModel { + const _$_IntegerModel({required this.value}); + + factory _$_IntegerModel.fromJson(Map json) => + _$$_IntegerModelFromJson(json); + + @override + final int value; + + @override + String toString() { + return 'IntegerModel(value: $value)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_IntegerModel && + (identical(other.value, value) || other.value == value)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash(runtimeType, value); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$_IntegerModelCopyWith<_$_IntegerModel> get copyWith => + __$$_IntegerModelCopyWithImpl<_$_IntegerModel>(this, _$identity); + + @override + Map toJson() { + return _$$_IntegerModelToJson( + this, + ); + } +} + +abstract class _IntegerModel implements IntegerModel { + const factory _IntegerModel({required final int value}) = _$_IntegerModel; + + factory _IntegerModel.fromJson(Map json) = + _$_IntegerModel.fromJson; + + @override + int get value; + @override + @JsonKey(ignore: true) + _$$_IntegerModelCopyWith<_$_IntegerModel> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/bricks/wyatt_app_template/__brick__/lib/data/models/integer_model.g.dart b/bricks/wyatt_app_template/__brick__/lib/data/models/integer_model.g.dart new file mode 100644 index 0000000..291e5cf --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/data/models/integer_model.g.dart @@ -0,0 +1,17 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'integer_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$_IntegerModel _$$_IntegerModelFromJson(Map json) => + _$_IntegerModel( + value: json['value'] as int, + ); + +Map _$$_IntegerModelToJson(_$_IntegerModel instance) => + { + 'value': instance.value, + }; diff --git a/bricks/wyatt_app_template/__brick__/lib/data/repositories/counter_repository_impl.dart b/bricks/wyatt_app_template/__brick__/lib/data/repositories/counter_repository_impl.dart new file mode 100644 index 0000000..1249785 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/data/repositories/counter_repository_impl.dart @@ -0,0 +1,41 @@ +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/data_sources/local/counter_data_source.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/entities/integer.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/repositories/counter_repository.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; +import 'package:wyatt_type_utils/wyatt_type_utils.dart'; + +class CounterRepositoryImpl extends CounterRepository { + CounterRepositoryImpl({ + required CounterDataSource counterDataSource, + }) : _counterDataSource = counterDataSource; + + final CounterDataSource _counterDataSource; + + @override + FutureOrResult decrement({Integer by = const Integer(1)}) => + Result.tryCatchAsync( + () async => _counterDataSource.decrement(by), + (error) => error, + ); + + @override + FutureOrResult increment({Integer by = const Integer(1)}) => + Result.tryCatchAsync( + () async => _counterDataSource.increment(by), + (error) => error, + ); + + @override + FutureOrResult getCurrent() => + Result.tryCatchAsync( + () async => _counterDataSource.getCurrent(), + (error) => error, + ); + + @override + FutureOrResult reset() => + Result.tryCatchAsync( + () async => _counterDataSource.reset(), + (error) => error, + ); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/domain/data_sources/local/counter_data_source.dart b/bricks/wyatt_app_template/__brick__/lib/domain/data_sources/local/counter_data_source.dart new file mode 100644 index 0000000..cfbaa26 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/domain/data_sources/local/counter_data_source.dart @@ -0,0 +1,9 @@ +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/entities/integer.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +abstract class CounterDataSource extends BaseDataSource { + Future decrement(Integer value); + Future increment(Integer value); + Future getCurrent(); + Future reset(); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/domain/data_sources/remote/.gitkeep b/bricks/wyatt_app_template/__brick__/lib/domain/data_sources/remote/.gitkeep new file mode 100644 index 0000000..f94cb6f --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/domain/data_sources/remote/.gitkeep @@ -0,0 +1 @@ +# just to keep empty folder in brick generation \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/lib/domain/entities/integer.dart b/bricks/wyatt_app_template/__brick__/lib/domain/entities/integer.dart new file mode 100644 index 0000000..aea24f1 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/domain/entities/integer.dart @@ -0,0 +1,11 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +class Integer extends Entity { + const Integer(this.value); + + final int value; + + @override + String toString() => 'Integer(value: $value)'; +} diff --git a/bricks/wyatt_app_template/__brick__/lib/domain/repositories/counter_repository.dart b/bricks/wyatt_app_template/__brick__/lib/domain/repositories/counter_repository.dart new file mode 100644 index 0000000..5a0590b --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/domain/repositories/counter_repository.dart @@ -0,0 +1,9 @@ +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/entities/integer.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +abstract class CounterRepository extends BaseRepository { + FutureOrResult decrement({Integer by = const Integer(1)}); + FutureOrResult increment({Integer by = const Integer(1)}); + FutureOrResult getCurrent(); + FutureOrResult reset(); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/domain/usecases/counter/decrement.dart b/bricks/wyatt_app_template/__brick__/lib/domain/usecases/counter/decrement.dart new file mode 100644 index 0000000..af614aa --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/domain/usecases/counter/decrement.dart @@ -0,0 +1,18 @@ +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/entities/integer.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/repositories/counter_repository.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +class Decrement extends AsyncUseCase { + Decrement({ + required CounterRepository counterRepository, + }) : _counterRepository = counterRepository; + + final CounterRepository _counterRepository; + + @override + FutureOrResult execute(int? params) async { + final step = Integer(params ?? 1); + + return _counterRepository.decrement(by: step); + } +} diff --git a/bricks/wyatt_app_template/__brick__/lib/domain/usecases/counter/get_current.dart b/bricks/wyatt_app_template/__brick__/lib/domain/usecases/counter/get_current.dart new file mode 100644 index 0000000..95ea3f5 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/domain/usecases/counter/get_current.dart @@ -0,0 +1,31 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/entities/integer.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/repositories/counter_repository.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +class GetCurrent extends AsyncUseCase { + GetCurrent({ + required CounterRepository counterRepository, + }) : _counterRepository = counterRepository; + + final CounterRepository _counterRepository; + + @override + FutureOrResult execute(void params) async => + _counterRepository.getCurrent(); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/domain/usecases/counter/increment.dart b/bricks/wyatt_app_template/__brick__/lib/domain/usecases/counter/increment.dart new file mode 100644 index 0000000..b18434b --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/domain/usecases/counter/increment.dart @@ -0,0 +1,18 @@ +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/entities/integer.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/repositories/counter_repository.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +class Increment extends AsyncUseCase { + Increment({ + required CounterRepository counterRepository, + }) : _counterRepository = counterRepository; + + final CounterRepository _counterRepository; + + @override + FutureOrResult execute(int? params) async { + final step = Integer(params ?? 1); + + return _counterRepository.increment(by: step); + } +} diff --git a/bricks/wyatt_app_template/__brick__/lib/domain/usecases/counter/reset.dart b/bricks/wyatt_app_template/__brick__/lib/domain/usecases/counter/reset.dart new file mode 100644 index 0000000..0839bbe --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/domain/usecases/counter/reset.dart @@ -0,0 +1,31 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/entities/integer.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/repositories/counter_repository.dart'; +import 'package:wyatt_architecture/wyatt_architecture.dart'; + +class Reset extends AsyncUseCase { + Reset({ + required CounterRepository counterRepository, + }) : _counterRepository = counterRepository; + + final CounterRepository _counterRepository; + + @override + FutureOrResult execute(void params) async => + _counterRepository.reset(); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/gen/app_localizations.dart b/bricks/wyatt_app_template/__brick__/lib/gen/app_localizations.dart new file mode 100644 index 0000000..a3d0b47 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/gen/app_localizations.dart @@ -0,0 +1,142 @@ +/// {{#titleCase}}{{display_name}}{{/titleCase}}, localized files. Automatically generated with `task gen:intl`. +import 'dart:async'; + +import 'package:flutter/widgets.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:intl/intl.dart' as intl; + +import 'app_localizations_fr.dart' deferred as app_localizations_fr; + +/// Callers can lookup localized strings with an instance of AppLocalizations +/// returned by `AppLocalizations.of(context)`. +/// +/// Applications need to include `AppLocalizations.delegate()` in their app's +/// `localizationDelegates` list, and the locales they support in the app's +/// `supportedLocales` list. For example: +/// +/// ```dart +/// import 'gen/app_localizations.dart'; +/// +/// return MaterialApp( +/// localizationsDelegates: AppLocalizations.localizationsDelegates, +/// supportedLocales: AppLocalizations.supportedLocales, +/// home: MyApplicationHome(), +/// ); +/// ``` +/// +/// ## Update pubspec.yaml +/// +/// Please make sure to update your pubspec.yaml to include the following +/// packages: +/// +/// ```yaml +/// dependencies: +/// # Internationalization support. +/// flutter_localizations: +/// sdk: flutter +/// intl: any # Use the pinned version from flutter_localizations +/// +/// # Rest of dependencies +/// ``` +/// +/// ## iOS Applications +/// +/// iOS applications define key application metadata, including supported +/// locales, in an Info.plist file that is built into the application bundle. +/// To configure the locales supported by your app, you’ll need to edit this +/// file. +/// +/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file. +/// Then, in the Project Navigator, open the Info.plist file under the Runner +/// project’s Runner folder. +/// +/// Next, select the Information Property List item, select Add Item from the +/// Editor menu, then select Localizations from the pop-up menu. +/// +/// Select and expand the newly-created Localizations item then, for each +/// locale your application supports, add a new item and select the locale +/// you wish to add from the pop-up menu in the Value field. This list should +/// be consistent with the languages listed in the AppLocalizations.supportedLocales +/// property. +abstract class AppLocalizations { + AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString()); + + final String localeName; + + static AppLocalizations of(BuildContext context) { + return Localizations.of(context, AppLocalizations)!; + } + + static const LocalizationsDelegate delegate = _AppLocalizationsDelegate(); + + /// A list of this localizations delegate along with the default localizations + /// delegates. + /// + /// Returns a list of localizations delegates containing this delegate along with + /// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, + /// and GlobalWidgetsLocalizations.delegate. + /// + /// Additional delegates can be added by appending to this list in + /// MaterialApp. This list does not have to be used at all if a custom list + /// of delegates is preferred or required. + static const List> localizationsDelegates = >[ + delegate, + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ]; + + /// A list of this localizations delegate's supported locales. + static const List supportedLocales = [ + Locale('fr') + ]; + + /// Texte affiché dans l'AppBar de la page Compteur + /// + /// In fr, this message translates to: + /// **'Compteur'** + String get counterAppBarTitle; + + /// Message affiché sur la page compteur + /// + /// In fr, this message translates to: + /// **'Vous avez appuyé {count} fois sur le bouton !'** + String youHavePushed(int count); + + /// Texte affiché dans le bouton ammenant vers la page Compteur + /// + /// In fr, this message translates to: + /// **'Aller au Compteur'** + String get goToCounter; +} + +class _AppLocalizationsDelegate extends LocalizationsDelegate { + const _AppLocalizationsDelegate(); + + @override + Future load(Locale locale) { + return lookupAppLocalizations(locale); + } + + @override + bool isSupported(Locale locale) => ['fr'].contains(locale.languageCode); + + @override + bool shouldReload(_AppLocalizationsDelegate old) => false; +} + +Future lookupAppLocalizations(Locale locale) { + + + // Lookup logic when only language code is specified. + switch (locale.languageCode) { + case 'fr': return app_localizations_fr.loadLibrary().then((dynamic _) => app_localizations_fr.AppLocalizationsFr()); + } + + throw FlutterError( + 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.' + ); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/gen/app_localizations_fr.dart b/bricks/wyatt_app_template/__brick__/lib/gen/app_localizations_fr.dart new file mode 100644 index 0000000..b1bb5cd --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/gen/app_localizations_fr.dart @@ -0,0 +1,19 @@ +/// {{#titleCase}}{{display_name}}{{/titleCase}}, localized files. Automatically generated with `task gen:intl`. + +import 'app_localizations.dart'; + +/// The translations for French (`fr`). +class AppLocalizationsFr extends AppLocalizations { + AppLocalizationsFr([String locale = 'fr']) : super(locale); + + @override + String get counterAppBarTitle => 'Compteur'; + + @override + String youHavePushed(int count) { + return 'Vous avez appuyé $count fois sur le bouton !'; + } + + @override + String get goToCounter => 'Aller au Compteur'; +} diff --git a/bricks/wyatt_app_template/__brick__/lib/gen/assets.gen.dart b/bricks/wyatt_app_template/__brick__/lib/gen/assets.gen.dart new file mode 100644 index 0000000..3deea52 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/gen/assets.gen.dart @@ -0,0 +1,92 @@ +/// GENERATED CODE - DO NOT MODIFY BY HAND +/// ***************************************************** +/// FlutterGen +/// ***************************************************** + +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal + +import 'package:flutter/widgets.dart'; + +class $AssetsImagesGen { + const $AssetsImagesGen(); + + /// File path: assets/images/wyatt_logo.jpeg + AssetGenImage get wyattLogo => + const AssetGenImage('assets/images/wyatt_logo.jpeg'); + + /// List of all assets + List get values => [wyattLogo]; +} + +class Assets { + Assets._(); + + static const $AssetsImagesGen images = $AssetsImagesGen(); +} + +class AssetGenImage { + const AssetGenImage(this._assetName); + + final String _assetName; + + Image image({ + Key? key, + AssetBundle? bundle, + ImageFrameBuilder? frameBuilder, + ImageErrorWidgetBuilder? errorBuilder, + String? semanticLabel, + bool excludeFromSemantics = false, + double? scale, + double? width, + double? height, + Color? color, + Animation? opacity, + BlendMode? colorBlendMode, + BoxFit? fit, + AlignmentGeometry alignment = Alignment.center, + ImageRepeat repeat = ImageRepeat.noRepeat, + Rect? centerSlice, + bool matchTextDirection = false, + bool gaplessPlayback = false, + bool isAntiAlias = false, + String? package, + FilterQuality filterQuality = FilterQuality.low, + int? cacheWidth, + int? cacheHeight, + }) { + return Image.asset( + _assetName, + key: key, + bundle: bundle, + frameBuilder: frameBuilder, + errorBuilder: errorBuilder, + semanticLabel: semanticLabel, + excludeFromSemantics: excludeFromSemantics, + scale: scale, + width: width, + height: height, + color: color, + opacity: opacity, + colorBlendMode: colorBlendMode, + fit: fit, + alignment: alignment, + repeat: repeat, + centerSlice: centerSlice, + matchTextDirection: matchTextDirection, + gaplessPlayback: gaplessPlayback, + isAntiAlias: isAntiAlias, + package: package, + filterQuality: filterQuality, + cacheWidth: cacheWidth, + cacheHeight: cacheHeight, + ); + } + + ImageProvider provider() => AssetImage(_assetName); + + String get path => _assetName; + + String get keyName => _assetName; +} diff --git a/bricks/wyatt_app_template/__brick__/lib/gen/colors.gen.dart b/bricks/wyatt_app_template/__brick__/lib/gen/colors.gen.dart new file mode 100644 index 0000000..7140be2 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/gen/colors.gen.dart @@ -0,0 +1,21 @@ +/// GENERATED CODE - DO NOT MODIFY BY HAND +/// ***************************************************** +/// FlutterGen +/// ***************************************************** + +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal + +import 'package:flutter/painting.dart'; +import 'package:flutter/material.dart'; + +class ColorName { + ColorName._(); + + /// Color: #000000 + static const Color black = Color(0xFF000000); + + /// Color: #FFFFFF + static const Color white = Color(0xFFFFFFFF); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/main.dart b/bricks/wyatt_app_template/__brick__/lib/main.dart new file mode 100644 index 0000000..e016029 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/main.dart @@ -0,0 +1,115 @@ +import 'package:flutter/material.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + // This is the theme of your application. + // + // Try running your application with "flutter run". You'll see the + // application has a blue toolbar. Then, without quitting the app, try + // changing the primarySwatch below to Colors.green and then invoke + // "hot reload" (press "r" in the console where you ran "flutter run", + // or simply save your changes to "hot reload" in a Flutter IDE). + // Notice that the counter didn't reset back to zero; the application + // is not restarted. + primarySwatch: Colors.blue, + ), + home: const MyHomePage(title: 'Flutter Demo Home Page'), + ); + } +} + +class MyHomePage extends StatefulWidget { + const MyHomePage({super.key, required this.title}); + + // This widget is the home page of your application. It is stateful, meaning + // that it has a State object (defined below) that contains fields that affect + // how it looks. + + // This class is the configuration for the state. It holds the values (in this + // case the title) provided by the parent (in this case the App widget) and + // used by the build method of the State. Fields in a Widget subclass are + // always marked "final". + + final String title; + + @override + State createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + int _counter = 0; + + void _incrementCounter() { + setState(() { + // This call to setState tells the Flutter framework that something has + // changed in this State, which causes it to rerun the build method below + // so that the display can reflect the updated values. If we changed + // _counter without calling setState(), then the build method would not be + // called again, and so nothing would appear to happen. + _counter++; + }); + } + + @override + Widget build(BuildContext context) { + // This method is rerun every time setState is called, for instance as done + // by the _incrementCounter method above. + // + // The Flutter framework has been optimized to make rerunning build methods + // fast, so that you can just rebuild anything that needs updating rather + // than having to individually change instances of widgets. + return Scaffold( + appBar: AppBar( + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text(widget.title), + ), + body: Center( + // Center is a layout widget. It takes a single child and positions it + // in the middle of the parent. + child: Column( + // Column is also a layout widget. It takes a list of children and + // arranges them vertically. By default, it sizes itself to fit its + // children horizontally, and tries to be as tall as its parent. + // + // Invoke "debug painting" (press "p" in the console, choose the + // "Toggle Debug Paint" action from the Flutter Inspector in Android + // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) + // to see the wireframe for each widget. + // + // Column has various properties to control how it sizes itself and + // how it positions its children. Here we use mainAxisAlignment to + // center the children vertically; the main axis here is the vertical + // axis because Columns are vertical (the cross axis would be + // horizontal). + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + 'You have pushed the button this many times:', + ), + Text( + '$_counter', + style: Theme.of(context).textTheme.headline4, + ), + ], + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: _incrementCounter, + tooltip: 'Increment', + child: const Icon(Icons.add), + ), // This trailing comma makes auto-formatting nicer for build methods. + ); + } +} diff --git a/bricks/wyatt_app_template/__brick__/lib/main_development.dart b/bricks/wyatt_app_template/__brick__/lib/main_development.dart new file mode 100644 index 0000000..d327e4d --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/main_development.dart @@ -0,0 +1,11 @@ +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/bootstrap.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/flavors/flavor.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/app/app.dart'; + +void main(List args) { + // Define environment + DevelopmentFlavor(); + + // Initialize environment and variables + bootstrap(App.new); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/main_production.dart b/bricks/wyatt_app_template/__brick__/lib/main_production.dart new file mode 100644 index 0000000..f5f0bb4 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/main_production.dart @@ -0,0 +1,11 @@ +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/bootstrap.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/flavors/flavor.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/app/app.dart'; + +void main(List args) { + // Define environment + ProductionFlavor(); + + // Initialize environment and variables + bootstrap(App.new); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/main_staging.dart b/bricks/wyatt_app_template/__brick__/lib/main_staging.dart new file mode 100644 index 0000000..d2d8017 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/main_staging.dart @@ -0,0 +1,11 @@ +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/bootstrap.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/flavors/flavor.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/app/app.dart'; + +void main(List args) { + // Define environment + StagingFlavor(); + + // Initialize environment and variables + bootstrap(App.new); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/features/app/app.dart b/bricks/wyatt_app_template/__brick__/lib/presentation/features/app/app.dart new file mode 100644 index 0000000..510bf9c --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/features/app/app.dart @@ -0,0 +1,63 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/dependency_injection/get_it.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/flavors/flavor.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/routes/router.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/data/repositories/counter_repository_impl.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/repositories/counter_repository.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/gen/app_localizations.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/counter/blocs/counter_bloc/counter_bloc.dart'; +import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; + +class App extends StatelessWidget { + const App({super.key}); + + Widget _flavorBanner(Widget child) { + final flavor = Flavor.get(); + if (flavor.banner != null && !kReleaseMode) { + return Directionality( + textDirection: TextDirection.ltr, + child: Banner( + location: BannerLocation.topEnd, + message: flavor.banner!, + color: flavor.bannerColor, + child: child, + ), + ); + } + + return child; + } + + @override + Widget build(BuildContext context) => MultiProvider( + repositoryProviders: [ + RepositoryProvider( + create: (_) => CounterRepositoryImpl(counterDataSource: getIt()), + ), + ], + blocProviders: [ + BlocProvider( + create: (_) => CounterBloc(), + ), + ], + child: _flavorBanner( + MaterialApp.router( + title: '{{#titleCase}}{{display_name}}{{/titleCase}}', + debugShowCheckedModeBanner: false, + routerDelegate: AppRouter.router.routerDelegate, + routeInformationParser: AppRouter.router.routeInformationParser, + routeInformationProvider: AppRouter.router.routeInformationProvider, + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: AppLocalizations.supportedLocales, + ), + ), + ); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_bloc/counter_bloc.dart b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_bloc/counter_bloc.dart new file mode 100644 index 0000000..cd0683d --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_bloc/counter_bloc.dart @@ -0,0 +1,27 @@ +import 'dart:async'; + +import 'package:equatable/equatable.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +part 'counter_event.dart'; +part 'counter_state.dart'; + +/// {@template counter_bloc} +/// CounterBloc description +/// {@endtemplate} +class CounterBloc extends Bloc { + /// {@macro counter_bloc} + CounterBloc() : super(const CounterInitial()) { + on(_onCustomCounterEvent); + } + + FutureOr _onCustomCounterEvent( + CustomCounterEvent event, + Emitter emit, + ) async { + // TODO(wyatt): Add custom UI logic + const _ = 1 + 1; + + return; + } +} diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_bloc/counter_event.dart b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_bloc/counter_event.dart new file mode 100644 index 0000000..49c34d2 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_bloc/counter_event.dart @@ -0,0 +1,20 @@ +part of 'counter_bloc.dart'; + +/// {@template counter_event} +/// CounterEvent description +/// {@endtemplate} +abstract class CounterEvent extends Equatable { + /// {@macro counter_event} + const CounterEvent(); +} + +/// {@template custom_counter_event} +/// Event added when some custom logic happens +/// {@endtemplate} +class CustomCounterEvent extends CounterEvent { + /// {@macro custom_counter_event} + const CustomCounterEvent(); + + @override + List get props => []; +} diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_bloc/counter_state.dart b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_bloc/counter_state.dart new file mode 100644 index 0000000..79dfd2f --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_bloc/counter_state.dart @@ -0,0 +1,20 @@ +part of 'counter_bloc.dart'; + +/// {@template counter_state} +/// CounterState description +/// {@endtemplate} +abstract class CounterState extends Equatable { + /// {@macro counter_state} + const CounterState(); +} + +/// {@template counter_initial} +/// The initial state of CounterState +/// {@endtemplate} +class CounterInitial extends CounterState { + /// {@macro counter_initial} + const CounterInitial(); + + @override + List get props => []; +} diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_cubit/counter_cubit.dart b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_cubit/counter_cubit.dart new file mode 100644 index 0000000..5467bd3 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_cubit/counter_cubit.dart @@ -0,0 +1,86 @@ +import 'dart:async'; + +import 'package:equatable/equatable.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/usecases/counter/decrement.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/usecases/counter/get_current.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/usecases/counter/increment.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/usecases/counter/reset.dart'; + +part 'counter_state.dart'; + +/// {@template counter_cubit} +/// CounterCubit manages UI depending on counter state. +/// {@endtemplate} +class CounterCubit extends Cubit { + /// {@macro counter_cubit} + CounterCubit({ + required Decrement decrement, + required Increment increment, + required GetCurrent getCurrent, + required Reset reset, + }) : _decrement = decrement, + _increment = increment, + _getCurrent = getCurrent, + _reset = reset, + super(const CounterState(0)); + + final Decrement _decrement; + final Increment _increment; + final GetCurrent _getCurrent; + final Reset _reset; + + /// Decrement counter. + FutureOr decrement([int by = 1]) async { + final result = await _decrement.call(by); + + result.fold( + (integer) => emit(CounterState(integer.value)), + addError, + ); + + return; + } + + /// Increment counter. + FutureOr increment([int by = 1]) async { + final result = await _increment.call(by); + + result.fold( + (integer) => emit(CounterState(integer.value)), + addError, + ); + + return; + } + + /// Get current counter state. + FutureOr getCurrent() async { + final result = await _getCurrent.call(null); + + result.fold( + (integer) => emit(CounterState(integer.value)), + addError, + ); + + return; + } + + /// Reset counter state. + FutureOr reset() async { + final result = await _reset.call(null); + + result.fold( + (integer) => emit(CounterState(integer.value)), + addError, + ); + + return; + } + + @override + void onError(Object error, StackTrace stackTrace) { + emit(state); + super.onError(error, stackTrace); + } +} diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_cubit/counter_state.dart b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_cubit/counter_state.dart new file mode 100644 index 0000000..50132cd --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/blocs/counter_cubit/counter_state.dart @@ -0,0 +1,14 @@ +part of 'counter_cubit.dart'; + +/// {@template counter_state} +/// CounterState containing counter value +/// {@endtemplate} +class CounterState extends Equatable { + /// {@macro counter_state} + const CounterState(this.value); + + final int value; + + @override + List get props => [value]; +} diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/counter.dart b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/counter.dart new file mode 100644 index 0000000..812d65c --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/counter.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/counter/screens/counter_provider.dart'; + +class Counter extends StatelessWidget { + const Counter({super.key}); + + static const String pageName = 'counterPage'; + + @override + Widget build(BuildContext context) => const CounterProvider(); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/screens/counter_provider.dart b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/screens/counter_provider.dart new file mode 100644 index 0000000..8b56c08 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/screens/counter_provider.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/extensions/build_context_extension.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/repositories/counter_repository.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/usecases/counter/decrement.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/usecases/counter/get_current.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/usecases/counter/increment.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/domain/usecases/counter/reset.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/counter/blocs/counter_cubit/counter_cubit.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/counter/screens/widgets/counter_consumer_widget.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/shared/layouts/wyatt_app_template_scaffold.dart'; +import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; + +/// {@template counter_provider} +/// CounterProvider provides bloc to his children. +/// {@endtemplate} +class CounterProvider extends CubitProviderScreen { + /// {@macro counter_provider} + const CounterProvider({super.key}); + + @override + CounterCubit create(BuildContext context) => CounterCubit( + decrement: Decrement( + counterRepository: repo(context), + ), + increment: Increment( + counterRepository: repo(context), + ), + getCurrent: GetCurrent( + counterRepository: repo(context), + ), + reset: Reset( + counterRepository: repo(context), + ), + ); + + @override + CounterCubit init(BuildContext context, CounterCubit bloc) => + bloc..getCurrent(); + + @override + Widget builder(BuildContext context) => WyattAppTemplateScaffold( + title: Text(context.l10n.counterAppBarTitle), + body: const CounterConsumerWidget(), + fabChildren: [ + FloatingActionButton( + heroTag: 'increment_tag', + onPressed: () => bloc(context).increment(), + child: const Icon(Icons.add), + ), + const SizedBox(height: 8), + FloatingActionButton( + heroTag: 'increment_10_tag', + onPressed: () => bloc(context).increment(10), + child: const Text('+10'), + ), + const SizedBox(height: 8), + FloatingActionButton( + heroTag: 'decrement_tag', + onPressed: () => bloc(context).decrement(), + child: const Icon(Icons.remove), + ), + const SizedBox(height: 8), + FloatingActionButton( + heroTag: 'decrement_10_tag', + onPressed: () => bloc(context).decrement(10), + child: const Text('-10'), + ), + const SizedBox(height: 8), + FloatingActionButton( + heroTag: 'reset_tag', + onPressed: () => bloc(context).reset(), + child: const Icon(Icons.refresh), + ), + ], + ); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/screens/widgets/counter_consumer_widget.dart b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/screens/widgets/counter_consumer_widget.dart new file mode 100644 index 0000000..5883630 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/screens/widgets/counter_consumer_widget.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/extensions/build_context_extension.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/counter/blocs/counter_cubit/counter_cubit.dart'; +import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; + +/// {@template counter_consumer_widget} +/// CounterConsumerWidget is a stateful widget. Aware of state changes. +/// {@endtemplate} +class CounterConsumerWidget + extends CubitConsumerScreen { + /// {@macro counter_consumer_widget} + const CounterConsumerWidget({super.key}); + + @override + Widget onBuild(BuildContext context, CounterState state) => Text( + context.l10n.youHavePushed(state.value), + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.headline3, + ); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/stateless/counter_widget.dart b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/stateless/counter_widget.dart new file mode 100644 index 0000000..32a7619 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/features/counter/stateless/counter_widget.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +/// {@template counter_widget} +/// CounterWidget is a stateless widget. (Not aware of cubit or bloc states) +/// {@endtemplate} +class CounterWidget extends StatelessWidget { + /// {@macro counter_widget} + const CounterWidget({super.key}); + + @override + Widget build(BuildContext context) => Container(); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/features/home/home.dart b/bricks/wyatt_app_template/__brick__/lib/presentation/features/home/home.dart new file mode 100644 index 0000000..e9deaaa --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/features/home/home.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; +import 'package:go_router/go_router.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/extensions/build_context_extension.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/gen/assets.gen.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/features/counter/counter.dart'; +import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/shared/layouts/wyatt_app_template_scaffold.dart'; + +class Home extends StatelessWidget { + const Home({super.key}); + + static const String pageName = 'homePage'; + + @override + Widget build(BuildContext context) => WyattAppTemplateScaffold( + body: Center( + child: Column( + children: [ + Assets.images.wyattLogo.image(width: 150), + const Gap(30), + ElevatedButton( + child: Text(context.l10n.goToCounter), + onPressed: () => context.pushNamed(Counter.pageName), + ), + ], + ), + ), + ); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/shared/layouts/wyatt_app_template_scaffold.dart b/bricks/wyatt_app_template/__brick__/lib/presentation/shared/layouts/wyatt_app_template_scaffold.dart new file mode 100644 index 0000000..60e2dee --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/shared/layouts/wyatt_app_template_scaffold.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; + +class WyattAppTemplateScaffold extends StatelessWidget { + const WyattAppTemplateScaffold({ + required this.body, + super.key, + this.title, + this.fabChildren, + }); + + final Widget? title; + final Widget body; + final List? fabChildren; + + @override + Widget build(BuildContext context) => Scaffold( + appBar: AppBar(title: title), + body: body, + floatingActionButton: (fabChildren?.isNotEmpty ?? false) + ? Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, + children: fabChildren!, + ) + : null, + ); +} diff --git a/bricks/wyatt_app_template/__brick__/lib/presentation/shared/widgets/.gitkeep b/bricks/wyatt_app_template/__brick__/lib/presentation/shared/widgets/.gitkeep new file mode 100644 index 0000000..f94cb6f --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/lib/presentation/shared/widgets/.gitkeep @@ -0,0 +1 @@ +# just to keep empty folder in brick generation \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/local_packages/README.md b/bricks/wyatt_app_template/__brick__/local_packages/README.md new file mode 100644 index 0000000..1051ebd --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/local_packages/README.md @@ -0,0 +1,2 @@ +Here you can find local package development copies. +Clone the package you want to customize here, then add it in `pubspec_overrides.yaml`. \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/package.json b/bricks/wyatt_app_template/__brick__/package.json new file mode 100644 index 0000000..3c8f622 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "@trapezedev/configure": "^7.0.5" + } +} diff --git a/bricks/wyatt_app_template/__brick__/pubspec.yaml b/bricks/wyatt_app_template/__brick__/pubspec.yaml new file mode 100644 index 0000000..025fb56 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/pubspec.yaml @@ -0,0 +1,90 @@ +name: {{#snakeCase}}{{project_name}}{{/snakeCase}} +description: {{#sentenceCase}}{{description}}{{/sentenceCase}} + +publish_to: "none" + +version: 1.0.0+1 + +environment: + sdk: ">=2.18.0 <3.0.0" + flutter: ">=3.0.0" + +dependencies: + flutter: { sdk: flutter } + flutter_localizations: { sdk: flutter } + intl: ^0.17.0 + go_router: ^6.0.1 + equatable: ^2.0.5 + freezed_annotation: ^2.2.0 + json_annotation: ^4.8.0 + cupertino_icons: ^1.0.5 + get_it: ^7.2.0 + flutter_dotenv: ^5.0.2 + gap: ^2.0.1 + flutter_bloc: ^8.1.1 + url_launcher: ^6.1.7 + uuid: ^3.0.7 + flutter_native_splash: ^2.2.15 + wyatt_architecture: + hosted: + url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + name: wyatt_architecture + version: 0.1.0+1 + wyatt_bloc_helper: + hosted: + url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + name: wyatt_bloc_helper + version: 2.0.0 + wyatt_type_utils: + hosted: + url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + name: wyatt_type_utils + version: 0.0.4 + +dev_dependencies: + flutter_test: { sdk: flutter } + dependency_validator: ^3.2.2 + build_runner: ^2.3.3 + flutter_gen_runner: ^5.1.0+1 + freezed: ^2.3.2 + json_serializable: ^6.6.0 + flutter_launcher_icons: ^0.11.0 + dart_code_metrics: ^5.4.0 + rename: ^2.1.1 + wyatt_analysis: + hosted: + url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + name: wyatt_analysis + version: 2.3.0 + +flutter: + uses-material-design: true + generate: true + assets: + - .env + - assets/images/ + +flutter_gen: + output: lib/gen/ + integrations: + flutter_svg: true + flare_flutter: true + rive: true + lottie: true + colors: + inputs: + - assets/colors.xml + +flutter_icons: + android: "launcher_icon" + ios: true + image_path: "assets/images/wyatt_logo.jpeg" + adaptive_icon_background: "#FFFFFF" + +flutter_native_splash: + image: "assets/images/wyatt_logo.jpeg" + color: "#FFFFFF" + android: true + ios: true + android_gravity: fill + ios_content_mode: scaleAspectFit diff --git a/bricks/wyatt_app_template/__brick__/pubspec_overrides.yaml b/bricks/wyatt_app_template/__brick__/pubspec_overrides.yaml new file mode 100644 index 0000000..c3425c6 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/pubspec_overrides.yaml @@ -0,0 +1,2 @@ +# For local package development/modification. +dependency_overrides: \ No newline at end of file diff --git a/bricks/wyatt_app_template/__brick__/test/widget_test.dart b/bricks/wyatt_app_template/__brick__/test/widget_test.dart new file mode 100644 index 0000000..3a06c0e --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/test/widget_test.dart @@ -0,0 +1 @@ +// TODO(wyatt): add some tests diff --git a/bricks/wyatt_app_template/__brick__/trapeze.yaml b/bricks/wyatt_app_template/__brick__/trapeze.yaml new file mode 100644 index 0000000..2177b57 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/trapeze.yaml @@ -0,0 +1,36 @@ +vars: + PACKAGE_NAME: + default: {{#snakeCase}}{{project_name}}{{/snakeCase}} + BUNDLE_ID: + default: {{#dotCase}}{{bundle_id}}{{/dotCase}} + APP_NAME: + default: {{#titleCase}}{{display_name}}{{/titleCase}} + +platforms: + android: + appName: $APP_NAME + packageName: $BUNDLE_ID + # Uncomment to add some permissions + # manifest: + # - file: AndroidManifest.xml + # target: manifest/application + # inject: + # + ios: + targets: + Runner: + bundleId: $BUNDLE_ID + productName: $APP_NAME + displayName: $APP_NAME + entitlements: + replace: true + # Workaround for https://stackoverflow.com/questions/55167611/flutter-ios-app-submission-issue-warning-missing-push-notification-entitlement + entries: + - aps-environment: development + # Uncomment to add some permissions + # plist: + # - replace: true + # entries: + # - UISupportedInterfaceOrientations: + # - UIInterfaceOrientationPortrait + diff --git a/bricks/wyatt_app_template/__brick__/web/favicon.png b/bricks/wyatt_app_template/__brick__/web/favicon.png new file mode 100644 index 0000000..8aaa46a Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/web/favicon.png differ diff --git a/bricks/wyatt_app_template/__brick__/web/icons/Icon-192.png b/bricks/wyatt_app_template/__brick__/web/icons/Icon-192.png new file mode 100644 index 0000000..b749bfe Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/web/icons/Icon-192.png differ diff --git a/bricks/wyatt_app_template/__brick__/web/icons/Icon-512.png b/bricks/wyatt_app_template/__brick__/web/icons/Icon-512.png new file mode 100644 index 0000000..88cfd48 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/web/icons/Icon-512.png differ diff --git a/bricks/wyatt_app_template/__brick__/web/icons/Icon-maskable-192.png b/bricks/wyatt_app_template/__brick__/web/icons/Icon-maskable-192.png new file mode 100644 index 0000000..eb9b4d7 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/web/icons/Icon-maskable-192.png differ diff --git a/bricks/wyatt_app_template/__brick__/web/icons/Icon-maskable-512.png b/bricks/wyatt_app_template/__brick__/web/icons/Icon-maskable-512.png new file mode 100644 index 0000000..d69c566 Binary files /dev/null and b/bricks/wyatt_app_template/__brick__/web/icons/Icon-maskable-512.png differ diff --git a/bricks/wyatt_app_template/__brick__/web/index.html b/bricks/wyatt_app_template/__brick__/web/index.html new file mode 100644 index 0000000..ad65153 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/web/index.html @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + {{#titleCase}}{{display_name}}{{/titleCase}} + + + + + + + + + + diff --git a/bricks/wyatt_app_template/__brick__/web/manifest.json b/bricks/wyatt_app_template/__brick__/web/manifest.json new file mode 100644 index 0000000..556e6b9 --- /dev/null +++ b/bricks/wyatt_app_template/__brick__/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "{{#titleCase}}{{display_name}}{{/titleCase}}", + "short_name": "{{#titleCase}}{{display_name}}{{/titleCase}}", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "{{#sentenceCase}}{{description}}{{/sentenceCase}}", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/bricks/wyatt_app_template/brick.yaml b/bricks/wyatt_app_template/brick.yaml new file mode 100644 index 0000000..98ab6b3 --- /dev/null +++ b/bricks/wyatt_app_template/brick.yaml @@ -0,0 +1,30 @@ +name: wyatt_app_template +description: New app template for Wyatt Studio projects. + +version: 0.1.0 + +vars: + display_name: + type: string + description: The display name + default: Display Name + prompt: What is the display name? + + project_name: + type: string + description: The project name + default: starting_template + prompt: What is the project name? + + bundle_id: + type: string + description: The bundle id used in Android and iOS + default: io.wyattapp.start + prompt: What is the bundle id? + + description: + type: string + description: A short project description + default: An app by Wyatt Studio. + prompt: What is the project description? + diff --git a/bricks/wyatt_app_template/hooks/post_gen.dart b/bricks/wyatt_app_template/hooks/post_gen.dart new file mode 100644 index 0000000..398a858 --- /dev/null +++ b/bricks/wyatt_app_template/hooks/post_gen.dart @@ -0,0 +1,39 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:mason/mason.dart'; + +void removeGitKeepFiles(String targetPath) { + if (!FileSystemEntity.isDirectorySync(targetPath)) { + throw ArgumentError('Target must be a directory', 'targetPath'); + } + + Directory(targetPath) + .listSync(recursive: true) + .whereType() + .forEach((file) { + if (file.path.contains('.gitkeep')) { + file.deleteSync(recursive: true); + } + }); +} + +Future run(HookContext context) async { + final workingDirectory = Directory.current.path; + removeGitKeepFiles(workingDirectory); +} diff --git a/bricks/wyatt_app_template/hooks/pubspec.yaml b/bricks/wyatt_app_template/hooks/pubspec.yaml new file mode 100644 index 0000000..454f6df --- /dev/null +++ b/bricks/wyatt_app_template/hooks/pubspec.yaml @@ -0,0 +1,7 @@ +name: hooks + +environment: + sdk: ">=2.18.0 <3.0.0" + +dependencies: + mason: any \ No newline at end of file diff --git a/bricks/wyatt_brick_template/__brick__/brickgen.yaml b/bricks/wyatt_brick_template/__brick__/brickgen.yaml new file mode 100644 index 0000000..0bf47a3 --- /dev/null +++ b/bricks/wyatt_brick_template/__brick__/brickgen.yaml @@ -0,0 +1,39 @@ +name: {{#snakeCase}}{{brick_name}}{{/snakeCase}} +description: {{#snakeCase}}{{brick_description}}{{/snakeCase}} + +version: 0.1.0 + +vars: + display_name: + compilable: display_name + type: string + description: The display name + default: Display Name + prompt: "What is the display name?" + + product_name: + compilable: product_name + type: string + description: The product name + default: product_name + prompt: "What is the product name?" + + flutter: + type: boolean + description: If this app is a Flutter or Dart application. + default: false + prompt: "Is this a Flutter appplication ?" + +brickgen: + path_to_brickify: {{#snakeCase}}{{brick_name}}{{/snakeCase}} + hooks: true + ignore: + - .env + boolean_file_system: + flutter: + folders: + on_true: + - android + - ios + on_false: + - bin \ No newline at end of file diff --git a/bricks/wyatt_brick_template/__brick__/{{#hooks}}hooks{{/hooks}}/post_gen.dart b/bricks/wyatt_brick_template/__brick__/{{#hooks}}hooks{{/hooks}}/post_gen.dart new file mode 100644 index 0000000..398a858 --- /dev/null +++ b/bricks/wyatt_brick_template/__brick__/{{#hooks}}hooks{{/hooks}}/post_gen.dart @@ -0,0 +1,39 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:mason/mason.dart'; + +void removeGitKeepFiles(String targetPath) { + if (!FileSystemEntity.isDirectorySync(targetPath)) { + throw ArgumentError('Target must be a directory', 'targetPath'); + } + + Directory(targetPath) + .listSync(recursive: true) + .whereType() + .forEach((file) { + if (file.path.contains('.gitkeep')) { + file.deleteSync(recursive: true); + } + }); +} + +Future run(HookContext context) async { + final workingDirectory = Directory.current.path; + removeGitKeepFiles(workingDirectory); +} diff --git a/bricks/wyatt_brick_template/__brick__/{{#hooks}}hooks{{/hooks}}/pubspec.yaml b/bricks/wyatt_brick_template/__brick__/{{#hooks}}hooks{{/hooks}}/pubspec.yaml new file mode 100644 index 0000000..454f6df --- /dev/null +++ b/bricks/wyatt_brick_template/__brick__/{{#hooks}}hooks{{/hooks}}/pubspec.yaml @@ -0,0 +1,7 @@ +name: hooks + +environment: + sdk: ">=2.18.0 <3.0.0" + +dependencies: + mason: any \ No newline at end of file diff --git a/bricks/wyatt_brick_template/__brick__/{{brick_name.snakeCase()}}/README.md b/bricks/wyatt_brick_template/__brick__/{{brick_name.snakeCase()}}/README.md new file mode 100644 index 0000000..8c74374 --- /dev/null +++ b/bricks/wyatt_brick_template/__brick__/{{brick_name.snakeCase()}}/README.md @@ -0,0 +1,3 @@ +# display_name + +Brick generated with `Brickgen`. \ No newline at end of file diff --git a/bricks/wyatt_brick_template/__brick__/{{brick_name.snakeCase()}}/android/android.xml b/bricks/wyatt_brick_template/__brick__/{{brick_name.snakeCase()}}/android/android.xml new file mode 100644 index 0000000..7a55e0f --- /dev/null +++ b/bricks/wyatt_brick_template/__brick__/{{brick_name.snakeCase()}}/android/android.xml @@ -0,0 +1,18 @@ + + diff --git a/bricks/wyatt_brick_template/__brick__/{{brick_name.snakeCase()}}/bin/cli.dart b/bricks/wyatt_brick_template/__brick__/{{brick_name.snakeCase()}}/bin/cli.dart new file mode 100644 index 0000000..db18bca --- /dev/null +++ b/bricks/wyatt_brick_template/__brick__/{{brick_name.snakeCase()}}/bin/cli.dart @@ -0,0 +1,16 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + diff --git a/bricks/wyatt_brick_template/__brick__/{{brick_name.snakeCase()}}/ios/ios.plist b/bricks/wyatt_brick_template/__brick__/{{brick_name.snakeCase()}}/ios/ios.plist new file mode 100644 index 0000000..7a55e0f --- /dev/null +++ b/bricks/wyatt_brick_template/__brick__/{{brick_name.snakeCase()}}/ios/ios.plist @@ -0,0 +1,18 @@ + + diff --git a/bricks/wyatt_brick_template/brick.yaml b/bricks/wyatt_brick_template/brick.yaml new file mode 100644 index 0000000..268cc2e --- /dev/null +++ b/bricks/wyatt_brick_template/brick.yaml @@ -0,0 +1,24 @@ +name: wyatt_brick_template +description: Template to create a compilable project that can be converted with Brickgen + +version: 0.1.0 + +vars: + brick_name: + type: string + description: Name of the brick + default: brick_name + prompt: What is the brick name? + + brick_description: + type: string + description: Description of the brick + default: brick_description + prompt: What is the brick description? + + hooks: + type: boolean + description: Enables hooks for this brick. + default: false + prompt: Do you want to enable `hooks` for this brick ? + diff --git a/bricks/wyatt_brick_template/hooks/post_gen.dart b/bricks/wyatt_brick_template/hooks/post_gen.dart new file mode 100644 index 0000000..398a858 --- /dev/null +++ b/bricks/wyatt_brick_template/hooks/post_gen.dart @@ -0,0 +1,39 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:mason/mason.dart'; + +void removeGitKeepFiles(String targetPath) { + if (!FileSystemEntity.isDirectorySync(targetPath)) { + throw ArgumentError('Target must be a directory', 'targetPath'); + } + + Directory(targetPath) + .listSync(recursive: true) + .whereType() + .forEach((file) { + if (file.path.contains('.gitkeep')) { + file.deleteSync(recursive: true); + } + }); +} + +Future run(HookContext context) async { + final workingDirectory = Directory.current.path; + removeGitKeepFiles(workingDirectory); +} diff --git a/bricks/wyatt_brick_template/hooks/pubspec.yaml b/bricks/wyatt_brick_template/hooks/pubspec.yaml new file mode 100644 index 0000000..454f6df --- /dev/null +++ b/bricks/wyatt_brick_template/hooks/pubspec.yaml @@ -0,0 +1,7 @@ +name: hooks + +environment: + sdk: ">=2.18.0 <3.0.0" + +dependencies: + mason: any \ No newline at end of file diff --git a/bricks/wyatt_feature_brick/CHANGELOG.md b/bricks/wyatt_feature_brick/CHANGELOG.md deleted file mode 100644 index f0640d6..0000000 --- a/bricks/wyatt_feature_brick/CHANGELOG.md +++ /dev/null @@ -1,3 +0,0 @@ -# 0.1.0+1 - -- TODO: Describe initial release. diff --git a/bricks/wyatt_feature_brick/LICENSE b/bricks/wyatt_feature_brick/LICENSE deleted file mode 100644 index ba75c69..0000000 --- a/bricks/wyatt_feature_brick/LICENSE +++ /dev/null @@ -1 +0,0 @@ -TODO: Add your license here. diff --git a/bricks/wyatt_feature_brick/README.md b/bricks/wyatt_feature_brick/README.md index b714e43..334e373 100644 --- a/bricks/wyatt_feature_brick/README.md +++ b/bricks/wyatt_feature_brick/README.md @@ -2,15 +2,12 @@ [![Powered by Mason](https://img.shields.io/endpoint?url=https%3A%2F%2Ftinyurl.com%2Fmason-badge)](https://github.com/felangel/mason) - - - A brick to create a feature using best practices and your state management of choice! Supports Bloc & Cubit. ## How to use 🚀 ``` -mason make feature_brick --feature_name audit --state_management cubit --use_equatable true +mason make feature_brick --feature_name audit ``` ## Variables ✨ @@ -22,25 +19,34 @@ mason make feature_brick --feature_name audit --state_management cubit --use_equ ## Outputs 📦 -### Using Bloc - ```shell ---feature_name login --state_management bloc +--feature_name feature ``` ``` ├── feature │ ├── blocs -| | └── feature_bloc -│ │ ├── feature_bloc.dart -│ │ ├── feature_event.dart +│ │ ├── feature_bloc +│ │ │ ├── feature_bloc.dart +│ │ │ ├── feature_event.dart +│ │ │ └── feature_state.dart +│ │ └── feature_cubit +│ │ ├── feature_cubit.dart │ │ └── feature_state.dart -│ ├── state_management -| | └── ... +│ ├── screens +│ │ ├── widgets +│ │ │ └── feature_consumer_widget.dart +│ │ ├── feature_parent.dart +│ │ ├── feature_provider.dart +│ │ └── feature_screen.dart +│ ├── stateless +│ │ └── feature_widget.dart │ └── feature.dart └── ... ``` +## Using BLoC + - {{featureName}}_bloc.dart ```dart diff --git a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/bloc/{{feature_name.snakeCase()}}_bloc.dart b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/blocs/{{feature_name.snakeCase()}}_bloc/{{feature_name.snakeCase()}}_bloc.dart similarity index 75% rename from bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/bloc/{{feature_name.snakeCase()}}_bloc.dart rename to bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/blocs/{{feature_name.snakeCase()}}_bloc/{{feature_name.snakeCase()}}_bloc.dart index 68dcdbf..899569a 100644 --- a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/bloc/{{feature_name.snakeCase()}}_bloc.dart +++ b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/blocs/{{feature_name.snakeCase()}}_bloc/{{feature_name.snakeCase()}}_bloc.dart @@ -6,7 +6,11 @@ import 'package:flutter_bloc/flutter_bloc.dart'; part '{{#snakeCase}}{{feature_name}}{{/snakeCase}}_event.dart'; part '{{#snakeCase}}{{feature_name}}{{/snakeCase}}_state.dart'; +/// {@template {{#snakeCase}}{{feature_name}}{{/snakeCase}}_bloc} +/// {{#pascalCase}}{{feature_name}}{{/pascalCase}}Bloc description +/// {@endtemplate} class {{#pascalCase}}{{feature_name}}{{/pascalCase}}Bloc extends Bloc<{{#pascalCase}}{{feature_name}}{{/pascalCase}}Event, {{#pascalCase}}{{feature_name}}{{/pascalCase}}State> { + /// {@macro {{#snakeCase}}{{feature_name}}{{/snakeCase}}_bloc} {{#pascalCase}}{{feature_name}}{{/pascalCase}}Bloc() : super(const {{#pascalCase}}{{feature_name}}{{/pascalCase}}Initial()) { on(_onCustom{{#pascalCase}}{{feature_name}}{{/pascalCase}}Event); } @@ -14,7 +18,9 @@ class {{#pascalCase}}{{feature_name}}{{/pascalCase}}Bloc extends Bloc<{{#pascalC FutureOr _onCustom{{#pascalCase}}{{feature_name}}{{/pascalCase}}Event( Custom{{#pascalCase}}{{feature_name}}{{/pascalCase}}Event event, Emitter<{{#pascalCase}}{{feature_name}}{{/pascalCase}}State> emit, - ) { - // TODO(wyattstudio): Add Logic + ) async { + // TODO(wyatt): Add custom UI logic + const _ = 1 + 1; + return; } } diff --git a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/bloc/{{feature_name.snakeCase()}}_event.dart b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/blocs/{{feature_name.snakeCase()}}_bloc/{{feature_name.snakeCase()}}_event.dart similarity index 75% rename from bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/bloc/{{feature_name.snakeCase()}}_event.dart rename to bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/blocs/{{feature_name.snakeCase()}}_bloc/{{feature_name.snakeCase()}}_event.dart index 87bdc73..8175332 100644 --- a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/bloc/{{feature_name.snakeCase()}}_event.dart +++ b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/blocs/{{feature_name.snakeCase()}}_bloc/{{feature_name.snakeCase()}}_event.dart @@ -1,6 +1,10 @@ part of '{{#snakeCase}}{{feature_name}}{{/snakeCase}}_bloc.dart'; +/// {@template {{#snakeCase}}{{feature_name}}{{/snakeCase}}_event} +/// {{#pascalCase}}{{feature_name}}{{/pascalCase}}Event description +/// {@endtemplate} abstract class {{#pascalCase}}{{feature_name}}{{/pascalCase}}Event extends Equatable { + /// {@macro {{#snakeCase}}{{feature_name}}{{/snakeCase}}_event} const {{#pascalCase}}{{feature_name}}{{/pascalCase}}Event(); } diff --git a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/bloc/{{feature_name.snakeCase()}}_state.dart b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/blocs/{{feature_name.snakeCase()}}_bloc/{{feature_name.snakeCase()}}_state.dart similarity index 100% rename from bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/bloc/{{feature_name.snakeCase()}}_state.dart rename to bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/blocs/{{feature_name.snakeCase()}}_bloc/{{feature_name.snakeCase()}}_state.dart diff --git a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/cubit/{{feature_name.snakeCase()}}_cubit.dart b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/blocs/{{feature_name.snakeCase()}}_cubit/{{feature_name.snakeCase()}}_cubit.dart similarity index 58% rename from bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/cubit/{{feature_name.snakeCase()}}_cubit.dart rename to bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/blocs/{{feature_name.snakeCase()}}_cubit/{{feature_name.snakeCase()}}_cubit.dart index 258b7c8..7ecac4c 100644 --- a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/cubit/{{feature_name.snakeCase()}}_cubit.dart +++ b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/blocs/{{feature_name.snakeCase()}}_cubit/{{feature_name.snakeCase()}}_cubit.dart @@ -5,11 +5,17 @@ import 'package:flutter_bloc/flutter_bloc.dart'; part '{{#snakeCase}}{{feature_name}}{{/snakeCase}}_state.dart'; +/// {@template {{#snakeCase}}{{feature_name}}{{/snakeCase}}_cubit} +/// {{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit description +/// {@endtemplate} class {{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit extends Cubit<{{#pascalCase}}{{feature_name}}{{/pascalCase}}State> { + /// {@macro {{#snakeCase}}{{feature_name}}{{/snakeCase}}_cubit} {{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit() : super(const {{#pascalCase}}{{feature_name}}{{/pascalCase}}Initial()); /// A description for yourCustomFunction - FutureOr yourCustomFunction() { - // TODO(wyattstudio): Add Logic + FutureOr yourCustomFunction() async { + // TODO(wyatt): Add custom UI logic + const _ = 1 + 1; + return; } } diff --git a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/cubit/{{feature_name.snakeCase()}}_state.dart b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/blocs/{{feature_name.snakeCase()}}_cubit/{{feature_name.snakeCase()}}_state.dart similarity index 100% rename from bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/cubit/{{feature_name.snakeCase()}}_state.dart rename to bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/blocs/{{feature_name.snakeCase()}}_cubit/{{feature_name.snakeCase()}}_state.dart diff --git a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/screens/widgets/{{feature_name.snakeCase()}}_consumer_widget.dart b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/screens/widgets/{{feature_name.snakeCase()}}_consumer_widget.dart new file mode 100644 index 0000000..f40a34f --- /dev/null +++ b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/screens/widgets/{{feature_name.snakeCase()}}_consumer_widget.dart @@ -0,0 +1,18 @@ +// ignore_for_file: always_use_package_imports + +import 'package:flutter/material.dart'; +import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; + +import '../../blocs/{{#snakeCase}}{{feature_name}}{{/snakeCase}}_cubit/{{#snakeCase}}{{feature_name}}{{/snakeCase}}_cubit.dart'; + +/// {@template {{#snakeCase}}{{feature_name}}{{/snakeCase}}_consumer_widget} +/// {{#pascalCase}}{{feature_name}}{{/pascalCase}}ConsumerWidget is a stateful widget. Aware of state changes. +/// {@endtemplate} +class {{#pascalCase}}{{feature_name}}{{/pascalCase}}ConsumerWidget + extends CubitConsumerScreen<{{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit, {{#pascalCase}}{{feature_name}}{{/pascalCase}}State> { + /// {@macro {{#snakeCase}}{{feature_name}}{{/snakeCase}}_sf_widget} + const {{#pascalCase}}{{feature_name}}{{/pascalCase}}ConsumerWidget({super.key}); + + @override + Widget onBuild(BuildContext context, {{#pascalCase}}{{feature_name}}{{/pascalCase}}State state) => Container(); +} diff --git a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/screens/{{feature_name.snakeCase()}}_parent.dart b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/screens/{{feature_name.snakeCase()}}_parent.dart new file mode 100644 index 0000000..1e6205d --- /dev/null +++ b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/screens/{{feature_name.snakeCase()}}_parent.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; + +class {{#pascalCase}}{{feature_name}}{{/pascalCase}}Parent extends StatelessWidget { + const {{#pascalCase}}{{feature_name}}{{/pascalCase}}Parent({ + required this.child, + super.key, + }); + + final Widget child; + + @override + Widget build(BuildContext context) => Scaffold( + body: SafeArea(child: child), + ); +} diff --git a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/screens/{{feature_name.snakeCase()}}_provider.dart b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/screens/{{feature_name.snakeCase()}}_provider.dart new file mode 100644 index 0000000..4c83ec6 --- /dev/null +++ b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/screens/{{feature_name.snakeCase()}}_provider.dart @@ -0,0 +1,22 @@ +// ignore_for_file: always_use_package_imports + +import 'package:flutter/material.dart'; +import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; + +import '../blocs/{{#snakeCase}}{{feature_name}}{{/snakeCase}}_cubit/{{#snakeCase}}{{feature_name}}{{/snakeCase}}_cubit.dart'; +import 'widgets/{{#snakeCase}}{{feature_name}}{{/snakeCase}}_consumer_widget.dart'; + +/// {@template {{#snakeCase}}{{feature_name}}{{/snakeCase}}_provider} +/// {{#pascalCase}}{{feature_name}}{{/pascalCase}}Provider provides bloc to his children. +/// {@endtemplate} +class {{#pascalCase}}{{feature_name}}{{/pascalCase}}Provider + extends CubitProviderScreen<{{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit, {{#pascalCase}}{{feature_name}}{{/pascalCase}}State> { + /// {@macro {{#snakeCase}}{{feature_name}}{{/snakeCase}}_provider} + const {{#pascalCase}}{{feature_name}}{{/pascalCase}}Provider({super.key}); + + @override + {{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit create(BuildContext context) => {{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit(); + + @override + Widget builder(BuildContext context) => const {{#pascalCase}}{{feature_name}}{{/pascalCase}}ConsumerWidget(); +} diff --git a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/screens/{{feature_name.snakeCase()}}_screen.dart b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/screens/{{feature_name.snakeCase()}}_screen.dart new file mode 100644 index 0000000..b60c95d --- /dev/null +++ b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/screens/{{feature_name.snakeCase()}}_screen.dart @@ -0,0 +1,33 @@ +// ignore_for_file: always_use_package_imports + +import 'package:flutter/material.dart'; +import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; + +import '../blocs/{{#snakeCase}}{{feature_name}}{{/snakeCase}}_cubit/{{#snakeCase}}{{feature_name}}{{/snakeCase}}_cubit.dart'; +import '../stateless/{{#snakeCase}}{{feature_name}}{{/snakeCase}}_widget.dart'; +import '{{#snakeCase}}{{feature_name}}{{/snakeCase}}_parent.dart'; + +/// {@template {{#snakeCase}}{{feature_name}}{{/snakeCase}}_screen} +/// {{#pascalCase}}{{feature_name}}{{/pascalCase}}Screen is the merge of Provider and Consumer. +/// {@endtemplate} +class {{#pascalCase}}{{feature_name}}{{/pascalCase}}Screen + extends CubitScreen<{{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit, {{#pascalCase}}{{feature_name}}{{/pascalCase}}State> { + /// {@macro {{#snakeCase}}{{feature_name}}{{/snakeCase}}_screen} + const {{#pascalCase}}{{feature_name}}{{/pascalCase}}Screen({super.key}); + + @override + {{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit create(BuildContext context) => {{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit(); + + @override + {{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit init(BuildContext context, {{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit bloc) => + bloc..yourCustomFunction(); + + @override + Widget parent(BuildContext context, Widget child) => + {{#pascalCase}}{{feature_name}}{{/pascalCase}}Parent(child: child); + + // Rebuild on every bloc changes + @override + Widget onBuild(BuildContext context, {{#pascalCase}}{{feature_name}}{{/pascalCase}}State state) => + const {{#pascalCase}}{{feature_name}}{{/pascalCase}}Widget(); +} diff --git a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/state_management/widgets/{{feature_name.snakeCase()}}_widget.dart b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/state_management/widgets/{{feature_name.snakeCase()}}_widget.dart deleted file mode 100644 index 427d8cb..0000000 --- a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/state_management/widgets/{{feature_name.snakeCase()}}_widget.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:flutter/material.dart'; - -class {{#pascalCase}}{{feature_name}}{{/pascalCase}}Widget extends StatelessWidget { - const {{#pascalCase}}{{feature_name}}{{/pascalCase}}Widget({super.key}); - - @override - Widget build(BuildContext context) => const SizedBox(); -} diff --git a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/state_management/{{feature_name.snakeCase()}}_state_management.dart b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/state_management/{{feature_name.snakeCase()}}_state_management.dart deleted file mode 100644 index 59d8bdb..0000000 --- a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/state_management/{{feature_name.snakeCase()}}_state_management.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; - -// ignore: always_use_package_imports -import './{{#snakeCase}}{{feature_name}}{{/snakeCase}}_wrapper_widget.dart'; -// ignore: always_use_package_imports -import './widgets/{{#snakeCase}}{{feature_name}}{{/snakeCase}}_widget.dart'; -// ignore: always_use_package_imports -import '../cubit/{{#snakeCase}}{{feature_name}}{{/snakeCase}}_cubit.dart'; - -class {{#pascalCase}}{{feature_name}}{{/pascalCase}}CubitStateManagement - extends CubitScreen<{{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit, {{#pascalCase}}{{feature_name}}{{/pascalCase}}State> { - const {{#pascalCase}}{{feature_name}}{{/pascalCase}}CubitStateManagement({super.key}); - - @override - {{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit create(BuildContext context) => {{#pascalCase}}{{feature_name}}{{/pascalCase}}Cubit(); - - @override - Widget onWrap(BuildContext context, Widget child) => - {{#pascalCase}}{{feature_name}}{{/pascalCase}}WrapperWidget(child: child); - - @override - Widget onBuild(BuildContext context, {{#pascalCase}}{{feature_name}}{{/pascalCase}}State state) => - const {{#pascalCase}}{{feature_name}}{{/pascalCase}}Widget(); -} diff --git a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/state_management/{{feature_name.snakeCase()}}_wrapper_widget.dart b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/state_management/{{feature_name.snakeCase()}}_wrapper_widget.dart deleted file mode 100644 index 70a2939..0000000 --- a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/state_management/{{feature_name.snakeCase()}}_wrapper_widget.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class {{#pascalCase}}{{feature_name}}{{/pascalCase}}WrapperWidget extends StatelessWidget { - final Widget child; - const {{#pascalCase}}{{feature_name}}{{/pascalCase}}WrapperWidget({ - required this.child, - super.key, - }); - - @override - Widget build(BuildContext context) => Container( - child: child, - ); -} diff --git a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/stateless/{{feature_name.snakeCase()}}_widget.dart b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/stateless/{{feature_name.snakeCase()}}_widget.dart new file mode 100644 index 0000000..d3f96d8 --- /dev/null +++ b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/stateless/{{feature_name.snakeCase()}}_widget.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +/// {@template {{#snakeCase}}{{feature_name}}{{/snakeCase}}_widget} +/// {{#pascalCase}}{{feature_name}}{{/pascalCase}}Widget is a stateless widget. (Not aware of cubit or bloc states) +/// {@endtemplate} +class {{#pascalCase}}{{feature_name}}{{/pascalCase}}Widget extends StatelessWidget { + /// {@macro {{#snakeCase}}{{feature_name}}{{/snakeCase}}_widget} + const {{#pascalCase}}{{feature_name}}{{/pascalCase}}Widget({super.key}); + + @override + Widget build(BuildContext context) => Container(); +} diff --git a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/{{feature_name.snakeCase()}}.dart b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/{{feature_name.snakeCase()}}.dart index a41ad18..d94cae3 100644 --- a/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/{{feature_name.snakeCase()}}.dart +++ b/bricks/wyatt_feature_brick/__brick__/{{feature_name.snakeCase()}}/{{feature_name.snakeCase()}}.dart @@ -1 +1,2 @@ -export './state_management/{{#snakeCase}}{{feature_name}}{{/snakeCase}}_state_management.dart'; +export 'screens/{{#snakeCase}}{{feature_name}}{{/snakeCase}}_provider.dart'; +export 'screens/{{#snakeCase}}{{feature_name}}{{/snakeCase}}_screen.dart'; diff --git a/bricks/wyatt_feature_brick/brick.yaml b/bricks/wyatt_feature_brick/brick.yaml index aa5c907..2df3e8f 100644 --- a/bricks/wyatt_feature_brick/brick.yaml +++ b/bricks/wyatt_feature_brick/brick.yaml @@ -1,10 +1,7 @@ name: wyatt_feature_brick -description: new feature brick including state mananement +description: New feature brick including state mananement -version: 0.1.0+1 - -environment: - mason: ">=0.1.0-dev.26 <0.1.0" +version: 0.1.1 vars: feature_name: diff --git a/bricks/wyatt_package_template/__brick__/.gitignore b/bricks/wyatt_package_template/__brick__/.gitignore new file mode 100644 index 0000000..3cceda5 --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/.gitignore @@ -0,0 +1,7 @@ +# https://dart.dev/guides/libraries/private-files +# Created by `dart pub` +.dart_tool/ + +# Avoid committing pubspec.lock for library packages; see +# https://dart.dev/guides/libraries/private-files#pubspeclock. +pubspec.lock diff --git a/bricks/wyatt_package_template/__brick__/.vscode/extensions.json b/bricks/wyatt_package_template/__brick__/.vscode/extensions.json new file mode 100644 index 0000000..30cd223 --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/.vscode/extensions.json @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2022 WYATT GROUP + * Please see the AUTHORS file for details. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +{ + "recommendations": [ + "psioniq.psi-header", + "blaugold.melos-code" + ] +} \ No newline at end of file diff --git a/bricks/wyatt_package_template/__brick__/.vscode/launch.json b/bricks/wyatt_package_template/__brick__/.vscode/launch.json new file mode 100644 index 0000000..653eabc --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/.vscode/launch.json @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 WYATT GROUP + * Please see the AUTHORS file for details. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Example", + "request": "launch", + "type": "dart", + "cwd": "example/", + "program": "lib/main.dart", + "flutterMode": "debug" + }, + ] +} \ No newline at end of file diff --git a/bricks/wyatt_package_template/__brick__/.vscode/settings.json b/bricks/wyatt_package_template/__brick__/.vscode/settings.json new file mode 100644 index 0000000..a729c46 --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/.vscode/settings.json @@ -0,0 +1,72 @@ +{ + "dart.runPubGetOnPubspecChanges": "never", + "bloc.newCubitTemplate.type": "equatable", + "psi-header.changes-tracking": { + "isActive": true + }, + "psi-header.config": { + "blankLinesAfter": 1, + "forceToTop": true + }, + "psi-header.lang-config": [ + { + "beforeHeader": [ + "# -*- coding:utf-8 -*-", + "#!/usr/bin/env python3" + ], + "begin": "###", + "end": "###", + "language": "python", + "prefix": "# " + }, + { + "beforeHeader": [ + "#!/usr/bin/env sh", + "" + ], + "language": "shellscript", + "begin": "", + "end": "", + "prefix": "# " + }, + { + "begin": "", + "end": "", + "language": "dart", + "prefix": "// " + }, + { + "begin": "", + "end": "", + "language": "yaml", + "prefix": "# " + }, + { + "begin": "", + "language": "markdown", + }, + ], + "psi-header.templates": [ + { + "language": "*", + "template": [ + "Copyright (C) <> WYATT GROUP", + "Please see the AUTHORS file for details.", + "", + "This program is free software: you can redistribute it and/or modify", + "it under the terms of the GNU General Public License as published by", + "the Free Software Foundation, either version 3 of the License, or", + "any later version.", + "", + "This program is distributed in the hope that it will be useful,", + "but WITHOUT ANY WARRANTY; without even the implied warranty of", + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", + "GNU General Public License for more details.", + "", + "You should have received a copy of the GNU General Public License", + "along with this program. If not, see ." + ], + } + ], +} \ No newline at end of file diff --git a/bricks/wyatt_package_template/__brick__/CHANGELOG.md b/bricks/wyatt_package_template/__brick__/CHANGELOG.md new file mode 100644 index 0000000..effe43c --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +- Initial version. diff --git a/bricks/wyatt_package_template/__brick__/README.md b/bricks/wyatt_package_template/__brick__/README.md new file mode 100644 index 0000000..754f2d7 --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/README.md @@ -0,0 +1,65 @@ + + +{{#flutter}} + +# Flutter - {{#titleCase}}{{package_name}}{{/titleCase}} + +

+ Style: Wyatt Analysis + SDK: Flutter +

+ +{{/flutter}} + +{{^flutter}} + +# Dart - {{#titleCase}}{{package_name}}{{/titleCase}} + +

+ Style: Wyatt Analysis + SDK: Dart & Flutter +

+ +{{/flutter}} + +{{#sentenceCase}}{{description}}{{/sentenceCase}} + +## Features + +TODO: List what your package can do. Maybe include images, gifs, or videos. + +## Getting started + +TODO: List prerequisites and provide or point to information on how to +start using the package. + +## Usage + +TODO: Include short and useful examples for package users. Add longer examples +to `/example` folder. + +```dart +const like = 'sample'; +``` + +## Additional information + +TODO: Tell users more about the package: where to find more information, how to +contribute to the package, how to file issues, what response they can expect +from the package authors, and more. diff --git a/bricks/wyatt_package_template/__brick__/analysis_options.yaml b/bricks/wyatt_package_template/__brick__/analysis_options.yaml new file mode 100644 index 0000000..405eea1 --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/analysis_options.yaml @@ -0,0 +1,10 @@ +{{#flutter}} +include: package:wyatt_analysis/analysis_options.flutter.yaml + +{{/flutter}} + +{{^flutter}} +include: package:wyatt_analysis/analysis_options.yaml + +{{/flutter}} + diff --git a/bricks/wyatt_package_template/__brick__/example/.gitignore b/bricks/wyatt_package_template/__brick__/example/.gitignore new file mode 100644 index 0000000..24476c5 --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/example/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/bricks/wyatt_package_template/__brick__/example/.metadata b/bricks/wyatt_package_template/__brick__/example/.metadata new file mode 100644 index 0000000..30e0d3c --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/example/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + channel: stable + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + - platform: web + create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/bricks/wyatt_package_template/__brick__/example/README.md b/bricks/wyatt_package_template/__brick__/example/README.md new file mode 100644 index 0000000..2b3fce4 --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/example/README.md @@ -0,0 +1,16 @@ +# example + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/bricks/wyatt_package_template/__brick__/example/analysis_options.yaml b/bricks/wyatt_package_template/__brick__/example/analysis_options.yaml new file mode 100644 index 0000000..405eea1 --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/example/analysis_options.yaml @@ -0,0 +1,10 @@ +{{#flutter}} +include: package:wyatt_analysis/analysis_options.flutter.yaml + +{{/flutter}} + +{{^flutter}} +include: package:wyatt_analysis/analysis_options.yaml + +{{/flutter}} + diff --git a/bricks/wyatt_package_template/__brick__/example/lib/main.dart b/bricks/wyatt_package_template/__brick__/example/lib/main.dart new file mode 100644 index 0000000..54165c0 --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/example/lib/main.dart @@ -0,0 +1,62 @@ +// Copyright (C) {{year}} WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +{{#flutter}} +import 'package:flutter/material.dart'; + + +{{/flutter}} + +import 'package:{{#snakeCase}}{{package_name}}{{/snakeCase}}/{{#snakeCase}}{{package_name}}{{/snakeCase}}.dart'; + +{{^flutter}} +class {{#pascalCase}}{{package_name}}{{/pascalCase}}Example { + static void run(List args) { + print({{#pascalCase}}{{package_name}}{{/pascalCase}}.testString); + } +} + + +{{/flutter}} + + +{{#flutter}} +void main(List args) { + runApp(const App()); +} + +class App extends StatelessWidget { + const App({super.key}); + + static const String title = '{{#titleCase}}{{package_name}}{{/titleCase}} Example'; + + @override + Widget build(BuildContext context) => MaterialApp( + title: title, + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Scaffold( + appBar: AppBar( + title: const Text(title), + ), + body: Center(child: Text({{#pascalCase}}{{package_name}}{{/pascalCase}}.testString)), + ), + ); +} + +{{/flutter}} + diff --git a/bricks/wyatt_package_template/__brick__/example/pubspec.yaml b/bricks/wyatt_package_template/__brick__/example/pubspec.yaml new file mode 100644 index 0000000..bc37e2a --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/example/pubspec.yaml @@ -0,0 +1,41 @@ +name: {{#snakeCase}}{{package_name}}{{/snakeCase}}_example +description: A new Flutter project. +version: 1.0.0 + +publish_to: 'none' + +environment: + sdk: ">=2.19.0 <3.0.0" + +dependencies: +{{#flutter}} + flutter: { sdk: flutter } + +{{/flutter}} + + + {{#snakeCase}}{{package_name}}{{/snakeCase}}: + path: "../" + +dev_dependencies: +{{#flutter}} + flutter_test: { sdk: flutter } + +{{/flutter}} + +{{^flutter}} + test: ^1.21.0 + +{{/flutter}} + + + wyatt_analysis: + hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub + version: ^2.3.0 + +{{#flutter}} +# The following section is specific to Flutter. +flutter: + uses-material-design: true + +{{/flutter}} diff --git a/bricks/wyatt_package_template/__brick__/example/test/widget_test.dart b/bricks/wyatt_package_template/__brick__/example/test/widget_test.dart new file mode 100644 index 0000000..e69de29 diff --git a/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/favicon.png b/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/favicon.png new file mode 100644 index 0000000..8aaa46a Binary files /dev/null and b/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/favicon.png differ diff --git a/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/icons/Icon-192.png b/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/icons/Icon-192.png new file mode 100644 index 0000000..b749bfe Binary files /dev/null and b/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/icons/Icon-192.png differ diff --git a/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/icons/Icon-512.png b/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/icons/Icon-512.png new file mode 100644 index 0000000..88cfd48 Binary files /dev/null and b/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/icons/Icon-512.png differ diff --git a/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/icons/Icon-maskable-192.png b/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/icons/Icon-maskable-192.png new file mode 100644 index 0000000..eb9b4d7 Binary files /dev/null and b/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/icons/Icon-maskable-192.png differ diff --git a/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/icons/Icon-maskable-512.png b/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/icons/Icon-maskable-512.png new file mode 100644 index 0000000..d69c566 Binary files /dev/null and b/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/icons/Icon-maskable-512.png differ diff --git a/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/index.html b/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/index.html new file mode 100644 index 0000000..be820e8 --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/index.html @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + example + + + + + + + + + + diff --git a/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/manifest.json b/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/manifest.json new file mode 100644 index 0000000..096edf8 --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/example/{{#flutter}}web{{/flutter}}/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "example", + "short_name": "example", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/bricks/wyatt_package_template/__brick__/example/{{^flutter}}bin{{/flutter}}/{{package_name.snakeCase()}}_example.dart b/bricks/wyatt_package_template/__brick__/example/{{^flutter}}bin{{/flutter}}/{{package_name.snakeCase()}}_example.dart new file mode 100644 index 0000000..979ae75 --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/example/{{^flutter}}bin{{/flutter}}/{{package_name.snakeCase()}}_example.dart @@ -0,0 +1,24 @@ +// Copyright (C) {{year}} WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:{{#snakeCase}}{{package_name}}{{/snakeCase}}_example/main.dart'; + +void main(List args) { + {{#pascalCase}}{{package_name}}{{/pascalCase}}Example.run(args); + exit(0); +} diff --git a/bricks/wyatt_package_template/__brick__/lib/src/{{package_name.snakeCase()}}.dart b/bricks/wyatt_package_template/__brick__/lib/src/{{package_name.snakeCase()}}.dart new file mode 100644 index 0000000..cdd5368 --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/lib/src/{{package_name.snakeCase()}}.dart @@ -0,0 +1,19 @@ +// Copyright (C) {{year}} WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +abstract class {{#pascalCase}}{{package_name}}{{/pascalCase}} { + static String get testString => 'Package: {{#titleCase}}{{package_name}}{{/titleCase}}'; +} diff --git a/bricks/wyatt_package_template/__brick__/lib/{{package_name.snakeCase()}}.dart b/bricks/wyatt_package_template/__brick__/lib/{{package_name.snakeCase()}}.dart new file mode 100644 index 0000000..708ca9c --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/lib/{{package_name.snakeCase()}}.dart @@ -0,0 +1,20 @@ +// Copyright (C) {{year}} WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +/// {{#sentenceCase}}{{description}}{{/sentenceCase}} +library {{#snakeCase}}{{package_name}}{{/snakeCase}}; + +export 'src/{{#snakeCase}}{{package_name}}{{/snakeCase}}.dart'; diff --git a/bricks/wyatt_package_template/__brick__/pubspec.yaml b/bricks/wyatt_package_template/__brick__/pubspec.yaml new file mode 100644 index 0000000..09ebfcb --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/pubspec.yaml @@ -0,0 +1,39 @@ +name: {{#snakeCase}}{{package_name}}{{/snakeCase}} +description: {{#sentenceCase}}{{description}}{{/sentenceCase}}. +repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/{{#snakeCase}}{{package_name}}{{/snakeCase}} +version: 1.0.0 + +environment: + sdk: ">=2.19.0 <3.0.0" + +dependencies: +{{#flutter}} + flutter: { sdk: flutter } + +{{/flutter}} + + path: ^1.8.0 + +dev_dependencies: +{{#flutter}} + flutter_test: { sdk: flutter } + +{{/flutter}} + + +{{^flutter}} + test: ^1.21.0 + +{{/flutter}} + + + wyatt_analysis: + hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub + version: ^2.3.0 + +{{#flutter}} +# The following section is specific to Flutter. +flutter: + uses-material-design: true + +{{/flutter}} diff --git a/bricks/wyatt_package_template/__brick__/test/{{package_name.snakeCase()}}_test.dart b/bricks/wyatt_package_template/__brick__/test/{{package_name.snakeCase()}}_test.dart new file mode 100644 index 0000000..771213c --- /dev/null +++ b/bricks/wyatt_package_template/__brick__/test/{{package_name.snakeCase()}}_test.dart @@ -0,0 +1 @@ +// TODO(wyatt): add some tests \ No newline at end of file diff --git a/bricks/wyatt_package_template/brick.yaml b/bricks/wyatt_package_template/brick.yaml new file mode 100644 index 0000000..7f9cdd1 --- /dev/null +++ b/bricks/wyatt_package_template/brick.yaml @@ -0,0 +1,24 @@ +name: wyatt_package_template +description: New package template for Wyatt Studio projects. + +version: 0.1.0 + +vars: + package_name: + type: string + description: The package name + default: package_name + prompt: What is the package name? + + description: + type: string + description: A short package description + default: A package by Wyatt Studio. + prompt: What is the package description? + + flutter: + type: boolean + description: Should generate a plugin (Flutter only) or a package (Dart and Flutter). + default: false + prompt: Should generate Flutter only plugin ? + diff --git a/bricks/wyatt_package_template/hooks/post_gen.dart b/bricks/wyatt_package_template/hooks/post_gen.dart new file mode 100644 index 0000000..babd1b7 --- /dev/null +++ b/bricks/wyatt_package_template/hooks/post_gen.dart @@ -0,0 +1,39 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:mason/mason.dart'; + +void removeGitKeepFiles(String targetPath) { + if (!FileSystemEntity.isDirectorySync(targetPath)) { + throw ArgumentError('Target must be a directory', 'targetPath'); + } + + Directory(targetPath) + .listSync(recursive: true) + .whereType() + .forEach((file) { + if (file.path.contains('.gitkeep')) { + file.deleteSync(recursive: true); + } + }); +} + +Future run(HookContext context) async { + final workingDirectory = Directory.current.path; + removeGitKeepFiles(workingDirectory); +} diff --git a/bricks/wyatt_package_template/hooks/pre_gen.dart b/bricks/wyatt_package_template/hooks/pre_gen.dart new file mode 100644 index 0000000..ea2f0c7 --- /dev/null +++ b/bricks/wyatt_package_template/hooks/pre_gen.dart @@ -0,0 +1,21 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:mason/mason.dart'; + +void run(HookContext context) { + context.vars = {...context.vars, 'year': DateTime.now().year.toString()}; +} \ No newline at end of file diff --git a/bricks/wyatt_package_template/hooks/pubspec.yaml b/bricks/wyatt_package_template/hooks/pubspec.yaml new file mode 100644 index 0000000..454f6df --- /dev/null +++ b/bricks/wyatt_package_template/hooks/pubspec.yaml @@ -0,0 +1,7 @@ +name: hooks + +environment: + sdk: ">=2.18.0 <3.0.0" + +dependencies: + mason: any \ No newline at end of file diff --git a/mason-lock.json b/mason-lock.json deleted file mode 100644 index 938c454..0000000 --- a/mason-lock.json +++ /dev/null @@ -1 +0,0 @@ -{"bricks":{"core_app_brick":{"path":"bricks/core_app_brick"},"wyatt_package":{"path":"bricks/wyatt_package"},"wyatt_clean_code":{"path":"bricks/wyatt_clean_code"}}} \ No newline at end of file diff --git a/mason.yaml b/mason.yaml index 8cfe754..c62a7fd 100644 --- a/mason.yaml +++ b/mason.yaml @@ -1,5 +1,3 @@ -# Register bricks which can be consumed via the Mason CLI. -# https://github.com/felangel/mason bricks: core_app_brick: path: bricks/core_app_brick @@ -9,3 +7,9 @@ bricks: path: bricks/wyatt_clean_code wyatt_feature_brick: path: bricks/wyatt_feature_brick + wyatt_brick_template: + path: bricks/wyatt_brick_template + wyatt_app_template: + path: bricks/wyatt_app_template + wyatt_package_template: + path: bricks/wyatt_package_template \ No newline at end of file diff --git a/tools/brick_generator/README.md b/tools/brick_generator/README.md index c8b20d0..ffcfb78 100644 --- a/tools/brick_generator/README.md +++ b/tools/brick_generator/README.md @@ -1,42 +1,384 @@ -A sample command-line application to generate which allows to generate the template of a brick from a project which compiles. with an entrypoint in `bin/`, library code -in `lib/`. +# Dart - Brick Generator -# How to use +A simple command-line application which allows to generate the template of a brick from a project which compiles. -- Add your app in `apps`. -- Add `brick_config.yaml` in you app folder and add this fields : +With an entrypoint in `bin/` , library code in `lib/` . + +## How to use + +* Add your app in `apps/`. +* Add `brickgen.yaml` in you app folder and add this fields: ```yaml -brick_name: wyatt_feature_brick +name: brick_name +description: An awesome brick -path_to_brickify: lib/feature_brick_folder +version: 0.1.0 -variables: - feature_brick: - variable_name: feature_brick +vars: + bundle_id: + compilable: io.wyattapp.new type: string - syntax: - camel_case: featureBrick - constant_case: FEATURE_BRICK - dot_case: feature.brick - header_case: Feature-Brick - lower_case: feature brick - pascal_case: FeatureBrick - param_case: feature-brick - sentence_case: Feature brick - snake_case: feature_brick - title_case: Feature Brick - upper_case: FEATURE BRICK - isBloc: - variable_name: bloc - type: bool + description: The bundle id used in Android and iOS + default: io.wyattapp.new + prompt: "What is the bundle id?" + + flutter: + type: boolean + description: If this app is a Flutter or Dart project. + default: false + prompt: "Is it Flutter app ?" + +brickgen: + path_to_brickify: brick_folder + ignore: + - .env + - node_modules/ + hooks: true + boolean_file_system: + flutter: + folders: + on_true: + - android + - ios + on_false: + - bin + files: + on_true: + - l10n.yaml + - trapeze.yaml + ``` -then run command with project path +Project structure must be like: + +``` +apps +├── brick_name +│ ├── brickgen.yaml +│ ├── hooks +│ │ └── pre_gen.dart +│ ├── brick_folder +│ │ └── ... compilable project +``` + +Then run command with project path ```sh -dart tools/brick_generator/bin/brick_generator.dart ./apps/wyatt_feature_brick +dart ./tools/brick_generator/bin/brickgen.dart ./apps/brick_name ./bricks/ ``` -# TODO -- Work on bool variables \ No newline at end of file +Available options: + +```text +-h, --help Show this help dialog +-v, --verbose Show additional diagnostic info +-r, --remove-empty Remove empty folders (if not it creates .gitkeep in each empty folders) +``` + +## TODO + +* [ ] hooks + - [x] post hooks + - [x] pre hooks + - [ ] add partial hooks +* [ ] bool variables + - [x] boolean file system + - [ ] boolean mapping +* [ ] enum variables +* [ ] array variables + +## Current specification + +### File Structure + +``` +apps +├── +│ ├── brickgen.yaml +│ ├── hooks +│ │ └── pre_gen.dart +│ ├── +│ │ └── ... compilable project +``` + +### Brick (Mason) + +```yaml +name: +description: + +version: 0.1.0 + +vars: + ... +``` + +- name: the brick name (will be in `brick.yaml`) +- description: the brick description (will be in `brick.yaml`) +- version: the brick version (will be in `brick.yaml`) +- vars: the brick variables (will be in `brick.yaml`) + +#### String variable + +```yaml +name: + compilable: + type: string + description: + default: + prompt: + formats: + - ... +``` + +- name: the variable name (will be in `brick.yaml`) + - compilable: the variable compilable name used in brickgen project + - type: variable type, here string, (will be in `brick.yaml`) + - default: default value (will be in `brick.yaml`) + - prompt: the displayed prompt at the brick generation (will be in `brick.yaml`) + - formats: optional list of formats that are detected. + - if no formats provided, all possible syntaxes are detected. + +#### Boolean variable + +```yaml +name: + type: boolean + description: + default: + prompt: +``` + +- name: the variable name (will be in `brick.yaml`) + - type: variable type, here string, (will be in `brick.yaml`) + - default: default value (will be in `brick.yaml`) + - prompt: the displayed prompt at the brick generation (will be in `brick.yaml`) + +> Identical to Mason + +### Brickgen + +```yaml +brickgen: + path_to_brickify: + ignore: + - ... + hooks: true + boolean_file_system: + ... +``` + +- path_to_brickify: the path of the compilable project that will be brickified +- ignore: list of the ignored files and folders. + - be sure to add an `/` at the end of the folders name. +- hooks: copy or not `hooks` folder +- boolean_file_system: list of the boolean file system variables + +#### Boolean File System + +```yaml +boolean_file_system: + boolean: + folders: + on_true: + - ... + on_false: + - ... + files: + on_true: + - ... + on_false: + - ... +``` + +- boolean: name of the `boolean` variable used. +- folders + - on_true: list of the folders includes if the variable is `true` + - on_true: list of the folders includes if the variable is `false` +- files + - on_true: list of the files includes if the variable is `true` + - on_true: list of the files includes if the variable is `false` + +> `on_true` and `on_false` are optionnal. (You are allowed to set one or two of them). + +## Specifications (WIP) + +File structure: + +``` +apps +├── +│ ├── brickgen.yaml +│ ├── hooks +│ │ └── pre_gen.dart +│ ├── +│ │ └── ... compilable project +``` + +Configuration: `brickgen.yaml` + +```yaml +name: +description: + +version: 0.1.0 + +vars: + display_name: + compilable: Display Name + type: string + description: The display name + default: Display Name + prompt: "What is the display name?" + formats: + - title_case + + project_name: + compilable: wyatt_app_template + type: string + description: The project name + default: wyatt_app + prompt: "What is the project name?" + formats: + - snake_case + + bundle_id: + compilable: io.wyattapp.new + type: string + description: The bundle id used in Android and iOS + default: io.wyattapp.new + prompt: "What is the bundle id?" + formats: + - dot_case + + flutter: + type: boolean + description: If this app is a Flutter or Dart project. + default: false + prompt: "Is it Flutter app ?" + +brickgen: + path_to_brickify: + ignore: + - .env + - node_modules/ + hooks: true + boolean_mapping: + flutter: + folders: + - "test": + on_true: "test" + on_false: "test_dart" + files: + - "pubspec.yaml": + on_true: pubspec.yaml + on_false: pubspec.dart.yaml + boolean_file_system: + flutter: + folders: + on_true: + - android + - ios + on_false: + - bin + files: + on_true: + - l10n.yaml + - trapeze.yaml +``` + +Will generate: + +``` +bricks +├── +│ ├── brick.yaml +│ ├── hooks +│ │ └── pre_gen.dart +│ ├── __brick__ +│ │ └── +``` + +> It creates a sub folder in __brick__ + + +### How copy works + +- Case 1 + +``` +apps +├── brick_1 +│ ├── brickgen.yaml +│ ├── hooks +│ │ └── pre_gen.dart +│ ├── brick_1 +│ │ ├── lib/ +│ │ └── pubspec.yaml +``` + +```yaml +... +name: awesome_brick_1 +brickgen: + path_to_brickify: brick_1 + hooks: true +... +``` + +```sh +dart ./tools/brick_generator/bin/brickgen.dart ./apps/brick_1 ./bricks/ +``` + +Will generate: + +``` +bricks +├── awesome_brick_1 +│ ├── brick.yaml +│ ├── hooks +│ │ └── pre_gen.dart +│ ├── __brick__ +│ │ ├── lib/ +│ │ └── pubspec.yaml +``` + +*** + +- Case 2 + +``` +apps +├── brick_2 +│ ├── brickgen.yaml +│ ├── hooks +│ │ └── pre_gen.dart +│ ├── brick_2 +│ │ ├── lib +│ │ │ └── widget.dart +│ │ └── pubspec.yaml +``` + +```yaml +... +name: awesome_brick_2 +brickgen: + path_to_brickify: brick_2/lib + hooks: false +... +``` + +```sh +dart ./tools/brick_generator/bin/brickgen.dart ./apps/brick_2 ./bricks/ +``` + +Will generate: + +``` +bricks +├── awesome_brick_2 +│ ├── brick.yaml +│ ├── __brick__ +│ │ └── widget.dart +``` \ No newline at end of file diff --git a/tools/brick_generator/bin/brick_generator.dart b/tools/brick_generator/bin/brick_generator.dart deleted file mode 100644 index b8d917e..0000000 --- a/tools/brick_generator/bin/brick_generator.dart +++ /dev/null @@ -1,71 +0,0 @@ -import 'dart:io'; - -import 'package:brick_generator/file_system_utils.dart'; -import 'package:brick_generator/models/brick_config.dart'; -import 'package:brick_generator/shell.dart'; -import 'package:brick_generator/yaml_reader.dart'; -import 'package:path/path.dart' as path; - -// Constants -const _bricks = 'bricks'; -const _brickFolderLabel = '__brick__'; -const _yamlFileName = 'brick_config.yaml'; - -Future main(List arguments) async { - try { - if (arguments.length != 1) { - throw ArgumentError('Please entry exemple project path'); - } - - final projectPath = arguments[0]; - - // Store options from yaml file - final configs = - YamlReader.readYamlFile(path.join(projectPath, _yamlFileName)); - final brickConfig = BrickConfig.from(configs); - stdout.writeln('🍺 config retrieved'); - - brickConfig?.checkFormat(); - - // Define paths - final sourcePath = path.join( - projectPath, - brickConfig!.pathToBrickify, - ); - final targetPath = path.join( - _bricks, - brickConfig.brickName, - _brickFolderLabel, - ); - stdout.writeln('🍺 path defined'); - - // Remove previously generated files - final targetDir = Directory(targetPath); - if (targetDir.existsSync()) { - await targetDir.delete(recursive: true); - } - - // create target folder - await Shell.mkdir(targetPath); - - // Copy project files - await Shell.cp(sourcePath, targetPath); - stdout.writeln('🍺 files copied'); - - // Convert values to variables - await FileSystemUtils.convertValuesToVariablesInFolder( - brickConfig, targetPath); - stdout.writeln('🍺 values converted into variables'); - - // Rename files and folders - await FileSystemUtils.renamePathsInFolder(brickConfig, targetPath); - stdout.writeln('🍺 folders and files renamed'); - - await FileSystemUtils.deleteEmptyFolders(targetPath); - stdout - ..writeln('🍺 empty folders removed') - ..writeln('✅ brick template available at $targetPath'); - } catch (_) { - stdout.writeln('❌ ${_.toString()}'); - } -} diff --git a/tools/brick_generator/bin/brickgen.dart b/tools/brick_generator/bin/brickgen.dart new file mode 100644 index 0000000..babd186 --- /dev/null +++ b/tools/brick_generator/bin/brickgen.dart @@ -0,0 +1,203 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:args/args.dart'; +import 'package:brick_generator/core/file_system.dart'; +import 'package:brick_generator/core/logger.dart'; +import 'package:brick_generator/models/brick_config.dart'; +import 'package:path/path.dart'; + +const _configurationFileName = 'brickgen.yaml'; +const _masonConfigurationFileName = 'brick.yaml'; +const _brickFolderName = '__brick__'; +const _hooksFolderName = 'hooks'; + +const _helpOption = 'help'; +const _verboseOption = 'verbose'; +const _removeEmptyOption = 'remove-empty'; + +class Brickgen { + final String brickPath; + final String outputPath; + final bool deleteEmptyFolders; + + late String configPath; + late String hooksInputPath; + + String? toBrickifyPath; + String? masonConfigPath; + String? targetPath; + String? hooksOutputPath; + + Brickgen({ + required this.brickPath, + required this.outputPath, + required this.deleteEmptyFolders, + }) { + configPath = join(brickPath, _configurationFileName); + hooksInputPath = join(brickPath, _hooksFolderName); + } + + Future run() async { + // Load config + final config = BrickConfig.fromFile(configPath); + Logger.debug('Read config: \n${config.toMason()}'); + Logger.info('Config retrieved.'); + + // Define paths + toBrickifyPath = FileSystem.joinExists( + brickPath, + config.brickgenConfig.pathToBrickify, + ); + Logger.debug('Define `toBrickifyPath`: $toBrickifyPath'); + + masonConfigPath = FileSystem.joinTouch( + outputPath, + config.name, + _masonConfigurationFileName, + ); + Logger.debug('Define `masonConfigPath`: $masonConfigPath'); + + hooksOutputPath = FileSystem.joinRecreate( + outputPath, + config.name, + _hooksFolderName, + ); + Logger.debug('Define `hooksOutputPath`: $hooksOutputPath'); + + targetPath = FileSystem.joinRecreate( + outputPath, + config.name, + _brickFolderName, + ); + Logger.debug('Define `targetPath`: $targetPath'); + + // Check paths + if (toBrickifyPath == null || + targetPath == null || + masonConfigPath == null || + hooksOutputPath == null) { + throw Exception('An error occures during path definition.'); + } + Logger.info('Paths defined.'); + + // Copy (and exclude from copy) project files + await FileSystem.copyFolder( + toBrickifyPath!, + targetPath!, + ignoreList: config.brickgenConfig.ignore, + ); + Logger.info('Project copied.'); + + // Take care of boolean mapping and boolean fs + FileSystem.applyBooleanFileSystem(config, targetPath!); + Logger.info('Boolean file system applied.'); + // TODO(wyatt): generate hook to handle boolean mapping. + + // Convert compilable values -> variables (in files) + FileSystem.convertCompilableVariablesInFolder(config, targetPath!); + FileSystem.convertBooleanVariablesInFolder(config, targetPath!); + Logger.info('Files content converted with variables.'); + + // Create `.gitkeep` in empty folders (to keep them in brick generation) + // Or remove them (depending of --remove option) + if (deleteEmptyFolders) { + FileSystem.removeEmptyFolders(targetPath!); + Logger.info('Empty folders removed.'); + } else { + FileSystem.createGitKeepInEmptyFolders(targetPath!); + Logger.info('Empty folders marked as to keep.'); + } + + // Convert compilable values -> variables (files/folder names) + FileSystem.renameCompilableFilesInFolder(config, targetPath!); + Logger.info('Files renamed with variables.'); + + // Clean empty folders created from copy/moves + FileSystem.removeEmptyFolders(targetPath!); + + // Create Mason config + FileSystem.writeFile(masonConfigPath!, config.toMason()); + Logger.info('Mason `brick.yaml` generated.'); + + // Copy hooks + await FileSystem.copyHooks(config, hooksInputPath, hooksOutputPath!); + + // Success! + Logger.success('Brick template available at $targetPath'); + } +} + +Future main(List args) async { + int exitCode = 0; + + final parser = ArgParser() + ..addFlag( + _helpOption, + negatable: false, + abbr: 'h', + help: 'Show this help dialog', + ) + ..addFlag( + _verboseOption, + negatable: false, + abbr: 'v', + help: 'Show additional diagnostic info', + ) + ..addFlag( + _removeEmptyOption, + negatable: false, + abbr: 'r', + help: 'Remove empty folders (if not it creates ' + '.gitkeep in each empty folders)', + ); + + final argResults = parser.parse(args); + + if (argResults[_helpOption] as bool? ?? false) { + Logger.info('Brickgen\n${parser.usage}'); + exit(0); + } + + if (argResults[_verboseOption] as bool? ?? false) { + Logger.setVerbose(); + } + + final paths = argResults.rest; + + if (paths.length < 2) { + Logger.error('Please provide input and output paths.'); + if (!(argResults[_helpOption] as bool? ?? false)) { + Logger.info('Brickgen\n${parser.usage}'); + } + exitCode = 1; + exit(exitCode); + } + + final brickPath = paths[0]; + final outputPath = paths[1]; + + await Brickgen( + brickPath: brickPath, + outputPath: outputPath, + deleteEmptyFolders: argResults[_removeEmptyOption] as bool? ?? false, + ).run(); + + exit(exitCode); +} diff --git a/tools/brick_generator/lib/core/file_system.dart b/tools/brick_generator/lib/core/file_system.dart new file mode 100644 index 0000000..f8288b9 --- /dev/null +++ b/tools/brick_generator/lib/core/file_system.dart @@ -0,0 +1,598 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:brick_generator/core/logger.dart'; +import 'package:brick_generator/core/shell.dart'; +import 'package:brick_generator/models/brick_config.dart'; +import 'package:brick_generator/models/brick_variable_boolean.dart'; +import 'package:brick_generator/models/brick_variable_string.dart'; +import 'package:brick_generator/models/ignore_list.dart'; +import 'package:path/path.dart'; + +abstract class FileSystem { + static void writeFile(String path, Object? content, {bool binary = false}) { + final file = File(join(path))..createSync(recursive: true); + + if (content == null) { + // Just create an empty file + return; + } + + try { + if (binary) { + file.writeAsBytesSync(content as List); + } else { + file.writeAsStringSync(content as String); + } + } catch (e) { + Logger.error(e); + } + } + + static Future copyFolder( + String from, + String to, { + IgnoreList? ignoreList, + }) async { + if (!FileSystemEntity.isDirectorySync(from)) { + throw ArgumentError('Path must be a directory', 'from'); + } + + Future cp(FileSystemEntity entity) async { + final absolutPath = entity.path; + final relativePath = absolutPath.replaceFirst(from, ''); + final newPath = ((to + relativePath).split('/')..removeLast()).join('/'); + + if (ignoreList != null && ignoreList.contains(from, absolutPath)) { + Logger.debug('Ignoring $absolutPath'); + } else { + Logger.debug('cp -Rf $absolutPath $newPath'); + await Shell.cp(absolutPath, newPath); + } + } + + // Copy folders + await Future.wait( + Directory(from) + .listSync(recursive: true) + .whereType() + .map((directory) async { + await cp(directory); + }), + ); + + // Copy root files + await Future.wait( + Directory(from).listSync().whereType().map((file) async { + await cp(file); + }), + ); + } + + static void makeDirectory(String path) { + final dir = Directory(path); + if (dir.existsSync()) { + dir.deleteSync(recursive: true); + } + dir.createSync(recursive: true); + } + + /// Join and verify if the joined path exists. + static String joinExists( + String part1, [ + String? part2, + String? part3, + String? part4, + String? part5, + String? part6, + String? part7, + String? part8, + ]) { + final path = join(part1, part2, part3, part4, part5, part6, part7, part8); + + if (FileSystemEntity.isDirectorySync(path)) { + Logger.debug('$path is a directory, and it exists.'); + return path; + } + + if (FileSystemEntity.isFileSync(path)) { + Logger.debug('$path is a file, and it exists.'); + return path; + } + + throw ArgumentError('Joined path is not existing.'); + } + + /// Join and verify if the joined path exists. If not, create it. + static String joinCreate( + String part1, [ + String? part2, + String? part3, + String? part4, + String? part5, + String? part6, + String? part7, + String? part8, + ]) { + final path = join(part1, part2, part3, part4, part5, part6, part7, part8); + + if (FileSystemEntity.isDirectorySync(path)) { + Logger.debug('$path is a directory, and it exists.'); + return path; + } + + if (FileSystemEntity.isFileSync(path)) { + Logger.debug('$path is a file, and it exists.'); + return path; + } + + makeDirectory(path); + Logger.debug('$path directory was created.'); + return path; + } + + /// Join and verify if the joined path exists. If yes, recreate it. + static String joinRecreate( + String part1, [ + String? part2, + String? part3, + String? part4, + String? part5, + String? part6, + String? part7, + String? part8, + ]) { + final path = join(part1, part2, part3, part4, part5, part6, part7, part8); + + if (FileSystemEntity.isDirectorySync(path)) { + makeDirectory(path); + Logger.debug('$path directory was recreated.'); + return path; + } + + if (FileSystemEntity.isFileSync(path)) { + Logger.debug('$path is a file ! No recreate it!'); + return path; + } + + makeDirectory(path); + Logger.debug('$path directory was created.'); + return path; + } + + /// Join and verify if the joined path exists. If yes, touch it. If not + /// create an empty file. + static String joinTouch( + String part1, [ + String? part2, + String? part3, + String? part4, + String? part5, + String? part6, + String? part7, + String? part8, + ]) { + final path = join(part1, part2, part3, part4, part5, part6, part7, part8); + + if (FileSystemEntity.isDirectorySync(path)) { + Logger.debug('$path is a directory ! No recreate it!'); + return path; + } + + if (FileSystemEntity.isFileSync(path)) { + writeFile(path, null); + Logger.debug('$path files was touched!'); + return path; + } + + writeFile(path, null); + Logger.debug('$path file was created.'); + return path; + } + + /// Transforms compilable variables: + /// For each String `vars` in config, search for compilable in code, then + /// convert it to his mustache format. + /// + /// Example: + /// ```yaml + /// bundle_id: + /// compilable: io.wyattapp.new + /// type: string + /// description: The bundle id used in Android and iOS + /// default: io.wyattapp.new + /// prompt: "What is the bundle id?" + /// ``` + /// + /// Search for `io.wyattapp.new` then converts + /// it to `{{#dotCase}}{{bundle_id}}{{/dotCase}}` + static void convertCompilableVariablesInFolder( + BrickConfig config, + String targetPath, + ) { + if (!FileSystemEntity.isDirectorySync(targetPath)) { + throw ArgumentError('Target must be a directory', 'targetPath'); + } + + Directory(targetPath) + .listSync(recursive: true) + .whereType() + .forEach((file) { + String? contents; + + try { + contents = file.readAsStringSync(); + } catch (e) { + // Ignore decode error + return; + } + + config.variables.whereType().forEach((variable) { + // Replace all string variables + for (final syntax in variable.formats) { + final toReplace = variable.syntaxes?[syntax.mapKey]; + if (toReplace != null && (contents?.contains(toReplace) ?? false)) { + contents = contents!.replaceAll( + toReplace, + '{{#${syntax.id}}}{{${variable.name}}}{{/${syntax.id}}}', + ); + Logger.debug( + 'Variable `${variable.name}` replaced ' + 'in ${file.path} by $toReplace', + ); + } + } + }); + + file.writeAsStringSync(contents!); + }); + } + + static void convertBooleanVariablesInFolder( + BrickConfig config, + String targetPath, + ) { + if (!FileSystemEntity.isDirectorySync(targetPath)) { + throw ArgumentError('Target must be a directory', 'targetPath'); + } + + Directory(targetPath) + .listSync(recursive: true) + .whereType() + .forEach((file) { + String? contents; + + try { + contents = file.readAsStringSync(); + } catch (e) { + // Ignore decode error + return; + } + + /// Defines differents prefixes used in comments in differents languages, + /// such as Dart, Yaml or Python for example. + final prefixes = [r'\/\/\/', '###']; + + config.variables.whereType().forEach((variable) { + for (final prefix in prefixes) { + final trueGroups = RegExp( + '^' + + prefix + + r'\s*{{#(.*)}}\n((?:.*\n)*?)' + + prefix + + r'\s*{{\/(.*)}}', + multiLine: true, + ); + final falseGroups = RegExp( + '^' + + prefix + + r'\s*{{\^(.*)}}\n((?:.*\n)*?)' + + prefix + + r'\s*{{\/(.*)}}', + multiLine: true, + ); + + final trueContents = contents?.replaceAllMapped(trueGroups, (match) { + if (match.group(1) == variable.name) { + // Match a bloc define by the variable + // Clean bloc content from his potential prefix + final cleaned = match.group(2)?.splitMapJoin( + '\n', + onMatch: (m) => '${m[0]}', + onNonMatch: (str) => str.replaceFirst(prefix, ''), + ) ?? + ''; + + Logger.debug( + 'Boolean section `${variable.name}` (true) ' + 'converted in ${file.path} (match: $trueGroups)', + ); + + return ''' +{{#${variable.name}}} +$cleaned +{{/${variable.name}}} +'''; + } else { + return match[0] ?? ''; + } + }); + + contents = trueContents; + + final falseContents = + contents?.replaceAllMapped(falseGroups, (match) { + if (match.group(1) == variable.name) { + // Match a bloc define by the variable + // Clean bloc content from his potential prefix + final cleaned = match.group(2)?.splitMapJoin( + '\n', + onMatch: (m) => '${m[0]}', + onNonMatch: (str) => str.replaceFirst(prefix, ''), + ) ?? + ''; + + Logger.debug( + 'Boolean section `${variable.name}` (false) ' + 'converted in ${file.path} (match: $falseGroups)', + ); + + return ''' +{{^${variable.name}}} +$cleaned +{{/${variable.name}}} +'''; + } else { + return match[0] ?? ''; + } + }); + + contents = falseContents; + } + }); + + file.writeAsStringSync(contents!); + }); + } + + static void createGitKeepInEmptyFolders(String targetPath) { + if (!FileSystemEntity.isDirectorySync(targetPath)) { + throw ArgumentError('Target must be a directory', 'targetPath'); + } + + Directory(targetPath) + .listSync(recursive: true) + .whereType() + .forEach((directory) { + if (directory.existsSync() && + directory.listSync(recursive: true).isEmpty) { + joinTouch(directory.path, '.gitkeep'); + Logger.debug('${directory.path} (empty) marked as to keep.'); + } + }); + } + + /// Removes empty folder dynamically: + /// + /// For example, for this structure: + /// ``` + /// ./brick/__brick__/folder/empty1/ + /// ./brick/__brick__/folder/empty2/ + /// ./brick/__brick__/dummy.txt + /// ``` + /// it will delete `empty1` and `empty2`...then it will delete `folder`, + /// because by deleting his subfolders he's now empty too. + /// + static void removeEmptyFolders(String targetPath) { + if (!FileSystemEntity.isDirectorySync(targetPath)) { + throw ArgumentError('Target must be a directory', 'targetPath'); + } + + bool containsEmptyFoldersFunction() => Directory(targetPath) + .listSync(recursive: true) + .whereType() + .any( + (directory) => + directory.existsSync() && + directory.listSync(recursive: true).isEmpty, + ); + + while (containsEmptyFoldersFunction()) { + Directory(targetPath) + .listSync(recursive: true) + .whereType() + .forEach((directory) { + if (directory.existsSync() && + directory.listSync(recursive: true).isEmpty) { + directory.deleteSync(recursive: true); + Logger.debug('${directory.path} (empty) deleted.'); + } + }); + } + } + + /// Transforms compilable file/folder names: + /// For each String `vars` in config, search for compilable in code, then + /// convert it to his mustache format. + /// + /// Example: + /// ```yaml + /// project_name: + /// compilable: wyatt_app_template + /// type: string + /// description: The project name + /// default: wyatt_app + /// prompt: "What is the project name?" + /// ``` + /// + /// Search for `wyatt_app_template` files and folders then converts + /// it to `{{project_name.snakeCase()}}` + static void renameCompilableFilesInFolder( + BrickConfig config, + String targetPath, + ) { + if (!FileSystemEntity.isDirectorySync(targetPath)) { + throw ArgumentError('Target must be a directory', 'targetPath'); + } + + Directory(targetPath) + .listSync(recursive: true) + .whereType() + .forEach((file) { + config.variables.whereType().forEach((variable) { + // Replace all string variables + for (final syntax in variable.formats) { + final toReplace = variable.syntaxes?[syntax.mapKey]; + if (toReplace != null && file.path.contains(toReplace)) { + final newPath = file.path.replaceAll( + toReplace, + '{{${variable.name}.${syntax.id}()}}', + ); + + File(newPath).createSync(recursive: true); + file.renameSync(newPath); + Logger.debug( + '${file.path} renamed with variable ' + '`${variable.name}` using $syntax', + ); + } + } + }); + }); + } + + static Future copyHooks( + BrickConfig config, + String source, + String targetPath, + ) async { + if (!config.brickgenConfig.hooks) { + Logger.debug('Ignore hooks'); + return; + } + + if (!FileSystemEntity.isDirectorySync(source)) { + throw ArgumentError('Source must be a directory', 'source'); + } + + if (!FileSystemEntity.isDirectorySync(targetPath)) { + throw ArgumentError('Target must be a directory', 'targetPath'); + } + + await copyFolder(source, targetPath); + Logger.info('Hooks copied.'); + } + + /// Apply boolean file system: create or not folders/files depending of + /// a boolean variable. + /// + /// Example + /// ```yaml + /// boolean_file_system: + /// flutter: + /// folders: + /// on_true: + /// - android + /// - ios + /// - assets + /// on_false: + /// - bin + /// files: + /// on_true: + /// - l10n.yaml + /// - trapeze.yaml + /// ``` + /// + /// Creates some folders and files depending of `flutter` variable. + static void applyBooleanFileSystem( + BrickConfig config, + String targetPath, + ) { + for (final variable in config.brickgenConfig.booleanFileSystem) { + final boolean = variable.booleanName; + + String rename( + String boolean, + FileSystemEntity entity, { + bool? onValue, + }) { + final entityPath = entity.path; + final entityPathSplitted = + (entityPath.split('/')..removeWhere((element) => element.isEmpty)); + final entityRenamed = + '{{${(onValue ?? true) ? "#" : "^"}$boolean}}${entityPathSplitted.last}{{/$boolean}}'; + final entityNewPath = + ((entityPathSplitted..removeLast())..add(entityRenamed)).join('/'); + + Logger.debug('Apply boolean file system on $entityPath'); + + return entityNewPath; + } + + // Rename folders + for (final folder in variable.folders.onTrueNames) { + final directory = Directory(join(targetPath, folder)); + final newPath = rename( + boolean, + directory, + onValue: true, + ); + + Directory(newPath).createSync(recursive: true); + directory.renameSync(newPath); + } + + for (final folder in variable.folders.onFalseNames) { + final directory = Directory(join(targetPath, folder)); + final newPath = rename( + boolean, + directory, + onValue: false, + ); + + Directory(newPath).createSync(recursive: true); + directory.renameSync(newPath); + } + + // Rename files + for (final path in variable.files.onTrueNames) { + final file = File(join(targetPath, path)); + final newPath = rename( + boolean, + file, + onValue: true, + ); + + File(newPath).createSync(recursive: true); + file.renameSync(newPath); + } + + for (final path in variable.files.onFalseNames) { + final file = File(join(targetPath, path)); + final newPath = rename( + boolean, + file, + onValue: false, + ); + + File(newPath).createSync(recursive: true); + file.renameSync(newPath); + } + } + } +} diff --git a/tools/brick_generator/lib/core/logger.dart b/tools/brick_generator/lib/core/logger.dart new file mode 100644 index 0000000..5176418 --- /dev/null +++ b/tools/brick_generator/lib/core/logger.dart @@ -0,0 +1,59 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:brick_generator/models/log_level.dart'; + +class Logger { + static bool verbose = false; + + static void setVerbose() => verbose = true; + + static void log(Object? message, {LogLevel level = LogLevel.info}) { + stdout.writeln('${level.prefix} ${message.toString()}'); + } + + static void debug(Object? message) { + if (verbose) { + log(message, level: LogLevel.debug); + } + } + + static void info(Object? message) { + log(message); + } + + static void error(Object? message) { + log(message, level: LogLevel.error); + } + + static void success(Object? message) { + log(message, level: LogLevel.success); + } + + static void throwError(Object error, [Object? message]) { + assert( + error is Exception || error is Exception, + 'Only throw instances of classes extending either Exception or Error;', + ); + if (message != null) { + Logger.error(message); + } + // ignore: only_throw_errors + throw error; + } +} diff --git a/tools/brick_generator/lib/core/reader.dart b/tools/brick_generator/lib/core/reader.dart new file mode 100644 index 0000000..a91d5a6 --- /dev/null +++ b/tools/brick_generator/lib/core/reader.dart @@ -0,0 +1,26 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:yaml/yaml.dart'; + +abstract class Reader {} + +class YamlReader extends Reader { + static YamlMap read(String path) => + loadYaml(File(path).readAsStringSync()) as YamlMap; +} diff --git a/tools/brick_generator/lib/core/shell.dart b/tools/brick_generator/lib/core/shell.dart new file mode 100644 index 0000000..ad5a92e --- /dev/null +++ b/tools/brick_generator/lib/core/shell.dart @@ -0,0 +1,78 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:brick_generator/core/logger.dart'; + +abstract class Shell { + static Future cp(String source, String destination) => + _Cmd.run('cp', ['-Rf', source, destination]); + + static Future mkdir(String destination) => + _Cmd.run('mkdir', ['-p', destination]); + + static Future rm(String target, {bool recursive = false}) => + _Cmd.run('rm', ['-f${recursive ? "r" : ""}', target]); +} + +abstract class _Cmd { + static Future run( + String cmd, + List args, { + bool throwOnError = true, + String? processWorkingDir, + }) async { + final result = await Process.run( + cmd, + args, + workingDirectory: processWorkingDir, + runInShell: true, + ); + + if (throwOnError) { + _throwIfProcessFailed(result, cmd, args); + } + return result; + } + + static void _throwIfProcessFailed( + ProcessResult pr, + String process, + List args, + ) { + if (pr.exitCode != 0) { + final values = { + 'Standard out': pr.stdout.toString().trim(), + 'Standard error': pr.stderr.toString().trim() + }..removeWhere((k, v) => v.isEmpty); + + String message; + if (values.isEmpty) { + message = 'Unknown error'; + } else if (values.length == 1) { + message = values.values.single; + } else { + message = values.entries.map((e) => '${e.key}\n${e.value}').join('\n'); + } + + Logger.throwError( + ProcessException(process, args, message, pr.exitCode), + message, + ); + } + } +} diff --git a/tools/brick_generator/lib/core/string_extension.dart b/tools/brick_generator/lib/core/string_extension.dart new file mode 100644 index 0000000..4edff8e --- /dev/null +++ b/tools/brick_generator/lib/core/string_extension.dart @@ -0,0 +1,311 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +extension StringExtension on String { + static final RegExp _defaultMatcher = RegExp(r'\s+|-+|_+|\.+'); + + Map get syntaxes => { + 'camel_case': camel(), + 'constant_case': constant(), + 'dot_case': dot(), + 'header_case': header(), + 'lower_case': lower(), + 'pascal_case': pascal(), + 'param_case': param(), + 'sentence_case': sentence(), + 'title_case': title(), + 'upper_case': upper(), + 'snake_case': snake(), + 'mustache_case': mustache(), + 'path_case': path(), + }; + + /// ```dart + /// print('abcd'.capitalize()) // Abcd + /// print('Abcd'.capitalize()) // Abcd + /// ``` + String capitalize() { + switch (length) { + case 0: + return this; + case 1: + return toUpperCase(); + default: + return substring(0, 1).toUpperCase() + substring(1); + } + } + + /// ```dart + /// print('abcd'.decapitalize()) // abcd + /// print('Abcd'.decapitalize()) // abcd + /// ``` + String decapitalize() { + switch (length) { + case 0: + return this; + case 1: + return toLowerCase(); + default: + return substring(0, 1).toLowerCase() + substring(1); + } + } + + /// ```dart + /// print('Hello-world'.camel()) // helloWorld + /// print('hello_World'.camel()) // helloWorld + /// print('Hello World'.camel()) // helloWorld + /// print('helloWorld'.camel()) // helloWorld + /// print('long space'.camel()) // longSpace + /// ``` + String camel() { + if (length > 0) { + return pascal().decapitalize(); + } else { + return this; + } + } + + /// ```dart + /// print('Hello World'.pascal()) // HelloWorld + /// print('helloWorld'.pascal()) // HelloWorld + /// print('long space'.pascal()) // LongSpace + /// ``` + String pascal() { + switch (length) { + case 0: + return this; + case 1: + return toUpperCase(); + default: + return splitMapJoin( + _defaultMatcher, + onMatch: (m) => '', + onNonMatch: (n) => n.capitalize(), + ); + } + } + + /// ```dart + /// print('Hello World'.constant()) // HELLO_WORLD + /// print('helloWorld'.constant()) // HELLO_WORLD + /// print('long space'.constant()) // LONG_SPACE + /// ``` + String constant() { + switch (length) { + case 0: + return this; + case 1: + return toUpperCase(); + default: + return splitMapJoin( + RegExp('[A-Z]'), + onMatch: (m) => ' ${m[0]}', + onNonMatch: (n) => n, + ).trim().splitMapJoin( + _defaultMatcher, + onMatch: (m) => '_', + onNonMatch: (n) => n.toUpperCase(), + ); + } + } + + /// ```dart + /// print('Hello World'.dot()) // hello.world + /// print('helloWorld'.dot()) // hello.world + /// print('long space'.dot()) // long.space + /// ``` + String dot() { + switch (length) { + case 0: + return this; + case 1: + return toLowerCase(); + default: + return splitMapJoin( + RegExp('[A-Z]'), + onMatch: (m) => ' ${m[0]}', + onNonMatch: (n) => n, + ).trim().splitMapJoin( + _defaultMatcher, + onMatch: (m) => '.', + onNonMatch: (n) => n.toLowerCase(), + ); + } + } + + /// ```dart + /// print('Hello World'.header()) // Hello-World + /// print('helloWorld'.header()) // Hello-World + /// ``` + String header() { + switch (length) { + case 0: + return this; + case 1: + return toUpperCase(); + default: + return splitMapJoin( + RegExp('[A-Z]'), + onMatch: (m) => ' ${m[0]}', + onNonMatch: (n) => n.toLowerCase(), + ).trim().splitMapJoin( + _defaultMatcher, + onMatch: (m) => '-', + onNonMatch: (n) => n.capitalize(), + ); + } + } + + /// ```dart + /// print('Hello World'.lower()) // hello world + /// print('helloWorld'.lower()) // hello world + /// ``` + String lower() { + switch (length) { + case 0: + return this; + case 1: + return toLowerCase(); + default: + return splitMapJoin( + RegExp('[A-Z]'), + onMatch: (m) => ' ${m[0]}', + onNonMatch: (n) => n, + ).trim().splitMapJoin( + _defaultMatcher, + onMatch: (m) => ' ', + onNonMatch: (n) => n.toLowerCase(), + ); + } + } + + /// ```dart + /// print('Hello World'.param()) // hello-world + /// print('helloWorld'.param()) // hello-world + /// print('long space'.param()) // long-space + /// ``` + String param() { + switch (length) { + case 0: + return this; + case 1: + return toLowerCase(); + default: + return splitMapJoin( + RegExp('[A-Z]'), + onMatch: (m) => ' ${m[0]}', + onNonMatch: (n) => n, + ).trim().splitMapJoin( + _defaultMatcher, + onMatch: (m) => '-', + onNonMatch: (n) => n.toLowerCase(), + ); + } + } + + /// ```dart + /// print('Hello World'.path()) // hello/world + /// print('helloWorld'.path()) // hello/world + /// print('long space'.path()) // long/space + /// ``` + String path() { + switch (length) { + case 0: + return this; + case 1: + return toLowerCase(); + default: + return splitMapJoin( + RegExp('[A-Z]'), + onMatch: (m) => ' ${m[0]}', + onNonMatch: (n) => n, + ).trim().splitMapJoin( + _defaultMatcher, + onMatch: (m) => '/', + onNonMatch: (n) => n.toLowerCase(), + ); + } + } + + /// ```dart + /// print('Hello World'.upper()) // HELLO WORLD + /// print('helloWorld'.upper()) // HELLO WORLD + /// ``` + String upper() { + switch (length) { + case 0: + return this; + case 1: + return toUpperCase(); + default: + return splitMapJoin( + RegExp('[A-Z]'), + onMatch: (m) => ' ${m[0]}', + onNonMatch: (n) => n, + ).trim().splitMapJoin( + _defaultMatcher, + onMatch: (m) => ' ', + onNonMatch: (n) => n.toUpperCase(), + ); + } + } + + /// ```dart + /// print('Hello World'.snake()) // hello_world + /// print('helloWorld'.snake()) // hello_world + /// print('long space'.snake()) // long_space + /// ``` + String snake() { + switch (length) { + case 0: + return this; + case 1: + return toLowerCase(); + default: + return splitMapJoin( + RegExp('[A-Z]'), + onMatch: (m) => ' ${m[0]}', + onNonMatch: (n) => n, + ).trim().splitMapJoin( + _defaultMatcher, + onMatch: (m) => '_', + onNonMatch: (n) => n.toLowerCase(), + ); + } + } + + /// ```dart + /// print('Hello World'.sentence()) // Hello world + /// print('helloWorld'.sentence()) // Hello world + /// ``` + String sentence() => lower().capitalize(); + + /// ```dart + /// print('Hello World'.title()) // Hello World + /// print('helloWorld'.title()) // Hello World + /// ``` + String title() => header().splitMapJoin( + _defaultMatcher, + onMatch: (m) => ' ', + onNonMatch: (n) => n, + ); + + /// ```dart + /// print('Hello World'.mustache()) // {{ Hello World }} + /// print('helloWorld'.mustache()) // {{ Hello World }} + /// ``` + String mustache() => '{{ ${title()} }}'; +} diff --git a/tools/brick_generator/lib/file_system_utils.dart b/tools/brick_generator/lib/file_system_utils.dart deleted file mode 100644 index e768a4f..0000000 --- a/tools/brick_generator/lib/file_system_utils.dart +++ /dev/null @@ -1,89 +0,0 @@ -import 'dart:io'; - -import 'package:brick_generator/models/brick_config.dart'; -import 'package:brick_generator/models/variable_string_syntax.dart'; -import 'package:brick_generator/models/variable_type.dart'; - -class FileSystemUtils { - static Future convertValuesToVariablesInFolder( - BrickConfig brickConfig, - String path, - ) async { - await Future.wait( - Directory(path) - .listSync(recursive: true) - .whereType() - .map((_) async { - var file = _; - - var contents = await file.readAsString(); - - // Transform all values in variables - if (brickConfig.variables != null) { - for (final variable in brickConfig.variables!) { - // Replace all string variables - if (variable?.type == VariabelType.string) { - for (final syntax in VariableStringSyntax.values) { - final toReplace = variable?.syntax?[syntax.mapKey] as String?; - if (toReplace != null) { - contents = contents.replaceAll( - toReplace, - '{{#${syntax.id}}}{{${variable?.name}}}{{/${syntax.id}}}', - ); - } - } - } - stdout.writeln( - '🍺 variables ${variable?.name} added in ${file.path}', - ); - } - } - - // Replace content - file = await file.writeAsString(contents); - }), - ); - } - - static Future renamePathsInFolder( - BrickConfig brickConfig, - String path, - ) async { - await Future.wait( - Directory(path) - .listSync(recursive: true) - .whereType() - .map((_) async { - final file = _; - - // Rename file if needed - if (brickConfig.variables != null) { - for (final variable in brickConfig.variables!) { - if (variable?.type == VariabelType.string && - variable?.syntax?[VariableStringSyntax.snakeCase.mapKey] != - null) { - final newPath = file.path.replaceAll( - variable!.syntax![VariableStringSyntax.snakeCase.mapKey] - as String, - '{{${variable.name}.snakeCase()}}', - ); - - await File(newPath).create(recursive: true); - await file.rename(newPath); - } - } - } - }), - ); - } - - static Future deleteEmptyFolders(String path) async { - for (final dir in Directory(path).listSync(recursive: true).reversed) { - if (dir is Directory) { - if (await dir.exists() && await dir.list().isEmpty) { - await dir.delete(recursive: true); - } - } - } - } -} diff --git a/tools/brick_generator/lib/models/boolean_file_system.dart b/tools/brick_generator/lib/models/boolean_file_system.dart new file mode 100644 index 0000000..1af3c71 --- /dev/null +++ b/tools/brick_generator/lib/models/boolean_file_system.dart @@ -0,0 +1,77 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:brick_generator/models/boolean_file_system_variable.dart'; +import 'package:yaml/yaml.dart'; + +const _foldersKey = 'folders'; +const _filesKey = 'files'; + +class BooleanFileSystem { + BooleanFileSystem({ + required this.booleanName, + required this.folders, + required this.files, + }); + + factory BooleanFileSystem.fromYaml(String key, YamlMap? source) { + if (source == null) { + throw ArgumentError.notNull('source'); + } + + final variableName = key; + + final foldersMap = source.nodes[_foldersKey] as YamlMap?; + final folders = (foldersMap != null) + ? BooleanFileSystemVariable.fromYaml( + source.nodes[_foldersKey] as YamlMap?, + ) + : BooleanFileSystemVariable.empty(); + + final filesMap = source.nodes[_filesKey] as YamlMap?; + final files = (filesMap != null) + ? BooleanFileSystemVariable.fromYaml( + source.nodes[_filesKey] as YamlMap?, + ) + : BooleanFileSystemVariable.empty(); + + return BooleanFileSystem( + booleanName: variableName, + folders: folders, + files: files, + ); + } + + String booleanName; + BooleanFileSystemVariable folders; + BooleanFileSystemVariable files; + + BooleanFileSystem copyWith({ + String? booleanName, + BooleanFileSystemVariable? folders, + BooleanFileSystemVariable? files, + }) => + BooleanFileSystem( + booleanName: booleanName ?? this.booleanName, + folders: folders ?? this.folders, + files: files ?? this.files, + ); + + @override + String toString() => 'BooleanFileSystem(booleanName: $booleanName, ' + 'folders: $folders, files: $files)'; +} diff --git a/tools/brick_generator/lib/models/boolean_file_system_variable.dart b/tools/brick_generator/lib/models/boolean_file_system_variable.dart new file mode 100644 index 0000000..2772edf --- /dev/null +++ b/tools/brick_generator/lib/models/boolean_file_system_variable.dart @@ -0,0 +1,66 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:yaml/yaml.dart'; + +const _onTrueKey = 'on_true'; +const _onFalseKey = 'on_false'; + +class BooleanFileSystemVariable { + BooleanFileSystemVariable({ + required this.onTrueNames, + required this.onFalseNames, + }); + + factory BooleanFileSystemVariable.fromYaml(YamlMap? source) { + if (source == null) { + throw ArgumentError.notNull('source'); + } + + final onTrueNames = (source[_onTrueKey] as YamlList?) + ?.map((element) => element as String) + .toList(); + final onFalseNames = (source[_onFalseKey] as YamlList?) + ?.map((element) => element as String) + .toList(); + + return BooleanFileSystemVariable( + onTrueNames: onTrueNames ?? [], + onFalseNames: onFalseNames ?? [], + ); + } + + factory BooleanFileSystemVariable.empty() => BooleanFileSystemVariable( + onTrueNames: [], + onFalseNames: [], + ); + + final List onTrueNames; + final List onFalseNames; + + BooleanFileSystemVariable copyWith({ + List? onTrueNames, + List? onFalseNames, + }) => + BooleanFileSystemVariable( + onTrueNames: onTrueNames ?? this.onTrueNames, + onFalseNames: onFalseNames ?? this.onFalseNames, + ); + + @override + String toString() => 'BooleanFileSystemVariable(onTrueNames: $onTrueNames, ' + 'onFalseNames: $onFalseNames)'; +} diff --git a/tools/brick_generator/lib/models/boolean_mapping.dart b/tools/brick_generator/lib/models/boolean_mapping.dart new file mode 100644 index 0000000..28e413f --- /dev/null +++ b/tools/brick_generator/lib/models/boolean_mapping.dart @@ -0,0 +1,77 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:brick_generator/models/boolean_name_single_mapping.dart'; +import 'package:yaml/yaml.dart'; + +const _foldersKey = 'folders'; +const _filesKey = 'files'; + +class BooleanMapping { + BooleanMapping({ + required this.booleanName, + required this.folders, + required this.files, + }); + + factory BooleanMapping.fromYaml(String key, YamlMap? source) { + if (source == null) { + throw ArgumentError.notNull('source'); + } + + final variableName = key; + final folders = (source.nodes[_foldersKey] as YamlList?) + ?.map( + (element) => + BooleanNameSingleMapping.fromYaml(element as YamlMap?), + ) + .toList() ?? + []; + final files = (source.nodes[_filesKey] as YamlList?) + ?.map( + (element) => + BooleanNameSingleMapping.fromYaml(element as YamlMap?), + ) + .toList() ?? + []; + + return BooleanMapping( + booleanName: variableName, + folders: folders, + files: files, + ); + } + + String booleanName; + List folders; + List files; + + BooleanMapping copyWith({ + String? booleanName, + List? folders, + List? files, + }) => + BooleanMapping( + booleanName: booleanName ?? this.booleanName, + folders: folders ?? this.folders, + files: files ?? this.files, + ); + + @override + String toString() => 'BooleanMapping(booleanName: $booleanName, ' + 'folders: $folders, files: $files)'; +} diff --git a/tools/brick_generator/lib/models/boolean_name_list_mapping.dart b/tools/brick_generator/lib/models/boolean_name_list_mapping.dart new file mode 100644 index 0000000..164621e --- /dev/null +++ b/tools/brick_generator/lib/models/boolean_name_list_mapping.dart @@ -0,0 +1,78 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:brick_generator/models/boolean_name_mapping.dart'; +import 'package:yaml/yaml.dart'; + +const _onTrueKey = 'on_true'; +const _onFalseKey = 'on_false'; + +class BooleanNameListMapping extends BooleanNameMapping { + BooleanNameListMapping({ + required this.fileSystemEntityName, + required this.onTrueNames, + required this.onFalseNames, + }); + + factory BooleanNameListMapping.fromYaml(YamlMap? source) { + if (source == null) { + throw ArgumentError.notNull('source'); + } + + final fsEntityName = source.keys.first as String; + final onTrueNames = + ((source.values.first as YamlMap?)?[_onTrueKey] as YamlList?) + ?.map((element) => element as String) + .toList(); + final onFalseNames = + ((source.values.first as YamlMap?)?[_onFalseKey] as YamlList?) + ?.map((element) => element as String) + .toList(); + + return BooleanNameListMapping( + fileSystemEntityName: fsEntityName, + onTrueNames: onTrueNames ?? [], + onFalseNames: onFalseNames ?? [], + ); + } + + @override + final String fileSystemEntityName; + final List onTrueNames; + final List onFalseNames; + + BooleanNameListMapping copyWith({ + String? fileSystemEntityName, + List? onTrueNames, + List? onFalseNames, + }) => + BooleanNameListMapping( + fileSystemEntityName: fileSystemEntityName ?? this.fileSystemEntityName, + onTrueNames: onTrueNames ?? this.onTrueNames, + onFalseNames: onFalseNames ?? this.onFalseNames, + ); + + @override + String get onFalseName => onFalseNames.first; + + @override + String get onTrueName => onTrueNames.first; + + @override + String toString() => + 'BooleanNameListMapping(fileSystemEntityName: $fileSystemEntityName, ' + 'onTrueNames: $onTrueNames, onFalseNames: $onFalseNames)'; +} diff --git a/tools/brick_generator/lib/models/boolean_name_mapping.dart b/tools/brick_generator/lib/models/boolean_name_mapping.dart new file mode 100644 index 0000000..0a8858f --- /dev/null +++ b/tools/brick_generator/lib/models/boolean_name_mapping.dart @@ -0,0 +1,21 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +abstract class BooleanNameMapping { + String get fileSystemEntityName; + String get onTrueName; + String get onFalseName; +} diff --git a/tools/brick_generator/lib/models/boolean_name_single_mapping.dart b/tools/brick_generator/lib/models/boolean_name_single_mapping.dart new file mode 100644 index 0000000..1dfb068 --- /dev/null +++ b/tools/brick_generator/lib/models/boolean_name_single_mapping.dart @@ -0,0 +1,70 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:brick_generator/models/boolean_name_mapping.dart'; +import 'package:yaml/yaml.dart'; + +const _onTrueKey = 'on_true'; +const _onFalseKey = 'on_false'; + +class BooleanNameSingleMapping extends BooleanNameMapping { + BooleanNameSingleMapping({ + required this.fileSystemEntityName, + required this.onTrueName, + required this.onFalseName, + }); + + factory BooleanNameSingleMapping.fromYaml(YamlMap? source) { + if (source == null) { + throw ArgumentError.notNull('source'); + } + + final fsEntityName = source.keys.first as String; + final onTrueName = + (source.values.first as YamlMap?)?[_onTrueKey] as String?; + final onFalseName = + (source.values.first as YamlMap?)?[_onFalseKey] as String?; + + return BooleanNameSingleMapping( + fileSystemEntityName: fsEntityName, + onTrueName: onTrueName ?? fsEntityName, + onFalseName: onFalseName ?? fsEntityName, + ); + } + + @override + final String fileSystemEntityName; + @override + final String onTrueName; + @override + final String onFalseName; + + BooleanNameSingleMapping copyWith({ + String? fileSystemEntityName, + String? onTrueName, + String? onFalseName, + }) => + BooleanNameSingleMapping( + fileSystemEntityName: fileSystemEntityName ?? this.fileSystemEntityName, + onTrueName: onTrueName ?? this.onTrueName, + onFalseName: onFalseName ?? this.onFalseName, + ); + + @override + String toString() => + 'BooleanNameSingleMapping(fileSystemEntityName: $fileSystemEntityName, ' + 'onTrueName: $onTrueName, onFalseName: $onFalseName)'; +} diff --git a/tools/brick_generator/lib/models/brick_config.dart b/tools/brick_generator/lib/models/brick_config.dart index e1ce248..6711a93 100644 --- a/tools/brick_generator/lib/models/brick_config.dart +++ b/tools/brick_generator/lib/models/brick_config.dart @@ -1,51 +1,99 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:brick_generator/core/reader.dart'; import 'package:brick_generator/models/brick_variable.dart'; +import 'package:brick_generator/models/brickgen_config.dart'; import 'package:yaml/yaml.dart'; -const _brickNameKey = 'brick_name'; -const _pathToBrickifyKey = 'path_to_brickify'; -const _variablesKey = 'variables'; +const _nameKey = 'name'; +const _descriptionKey = 'description'; +const _versionKey = 'version'; +const _varsKey = 'vars'; +const _brickgenKey = 'brickgen'; class BrickConfig { - String? brickName; - String? pathToBrickify; - List? variables; - BrickConfig({ - required this.brickName, - required this.pathToBrickify, + required this.name, + required this.description, + required this.version, required this.variables, + required this.brickgenConfig, }); - BrickConfig._(); - factory BrickConfig.parser() => BrickConfig._(); - - static BrickConfig? from(YamlMap? data) => data != null - ? BrickConfig( - brickName: data[_brickNameKey] as String?, - pathToBrickify: data[_pathToBrickifyKey] as String?, - variables: (data[_variablesKey] as YamlMap?) - ?.map( - (dynamic key, dynamic value) => - MapEntry( - key, - BrickVariable.from(value as YamlMap?), - ), - ) - .values - .toList(), - ) - : null; - - void checkFormat() { - if (brickName == null || pathToBrickify == null) { - throw ArgumentError( - 'Yaml file is not conform', - ); + factory BrickConfig.parse(YamlMap? data) { + if (data == null) { + throw ArgumentError.notNull('data'); } - if (variables != null) { - for (final variable in variables!) { - variable?.checkFormat(); + + final variables = (data[_varsKey] as YamlMap?) + ?.entries + .map( + (e) => BrickVariable.fromYaml(e.key as String, e.value as YamlMap?), + ) + .toList(); + + final config = BrickConfig( + name: data[_nameKey] as String? ?? '', + description: data[_descriptionKey] as String? ?? '', + version: data[_versionKey] as String? ?? '', + variables: variables ?? [], + brickgenConfig: BrickgenConfig.parse(data[_brickgenKey] as YamlMap?), + ); + + return config; + } + + factory BrickConfig.fromFile(String? path) { + if (path == null) { + throw ArgumentError.notNull('path'); + } + + final config = YamlReader.read(path); + + return BrickConfig.parse(config); + } + + String name; + String description; + String version; + List> variables; + BrickgenConfig brickgenConfig; + + String toMason() { + final content = StringBuffer(''' +name: $name +description: $description + +version: $version + +'''); + + if (variables.isNotEmpty) { + content.writeln('vars:'); + for (final variable in variables) { + content.writeln(variable.toMason()); } } + + return content.toString(); } + + @override + String toString() => 'BrickConfig(name: $name, ' + 'description: $description, version: $version, variables: $variables, ' + 'brickgenConfig: $brickgenConfig)'; } diff --git a/tools/brick_generator/lib/models/brick_variable.dart b/tools/brick_generator/lib/models/brick_variable.dart index a34e704..23827e8 100644 --- a/tools/brick_generator/lib/models/brick_variable.dart +++ b/tools/brick_generator/lib/models/brick_variable.dart @@ -1,38 +1,59 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:brick_generator/models/brick_variable_boolean.dart'; +import 'package:brick_generator/models/brick_variable_string.dart'; import 'package:brick_generator/models/variable_type.dart'; import 'package:yaml/yaml.dart'; -const _variableNameKey = 'variable_name'; const _typeKey = 'type'; -const _syntaxKey = 'syntax'; - -class BrickVariable { - String? name; - VariabelType? type; - YamlMap? syntax; +abstract class BrickVariable { BrickVariable({ - required this.name, required this.type, - required this.syntax, + required this.name, + required this.description, + required this.defaultValue, + required this.prompt, }); - BrickVariable._(); + String name; + VariableType type; + String description; + T defaultValue; + String prompt; - factory BrickVariable.parser() => BrickVariable._(); - - static BrickVariable? from(YamlMap? data) => data != null - ? BrickVariable( - name: data[_variableNameKey] as String?, - type: VariabelType.stringToEnum(data[_typeKey] as String?), - syntax: data[_syntaxKey] as YamlMap?, - ) - : null; - - void checkFormat() { - if (name == null || type == null) { - throw ArgumentError( - 'Yaml file is not conform', - ); + static BrickVariable fromYaml(String key, YamlMap? source) { + final type = VariableType.fromString(source?[_typeKey] as String?); + switch (type) { + case VariableType.string: + return BrickVariableString.fromYaml(key, source); + case VariableType.boolean: + return BrickVariableBoolean.fromYaml(key, source); + case VariableType.none: + throw ArgumentError('Invalid variable type', 'type'); } } + + // TODO(wyatt): use `yaml_writer` to dumps YAML properly. + String toMason() => ''' + $name: + type: $type + description: $description + default: $defaultValue + prompt: $prompt +'''; } diff --git a/tools/brick_generator/lib/models/brick_variable_boolean.dart b/tools/brick_generator/lib/models/brick_variable_boolean.dart new file mode 100644 index 0000000..f545192 --- /dev/null +++ b/tools/brick_generator/lib/models/brick_variable_boolean.dart @@ -0,0 +1,55 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:brick_generator/models/brick_variable.dart'; +import 'package:brick_generator/models/variable_type.dart'; +import 'package:yaml/yaml.dart'; + +const _typeKey = 'type'; +const _descriptionKey = 'description'; +const _defaultKey = 'default'; +const _promptKey = 'prompt'; + +class BrickVariableBoolean extends BrickVariable { + BrickVariableBoolean({ + required super.type, + required super.name, + required super.description, + required super.defaultValue, + required super.prompt, + }); + + factory BrickVariableBoolean.fromYaml(String key, YamlMap? source) { + if (source == null) { + throw ArgumentError.notNull('source'); + } + + final type = VariableType.fromString(source[_typeKey] as String?); + + return BrickVariableBoolean( + type: type, + name: key, + description: source[_descriptionKey] as String? ?? '', + defaultValue: source[_defaultKey] as bool? ?? false, + prompt: source[_promptKey] as String? ?? '', + ); + } + + @override + String toString() => 'BrickVariableBoolean(name: $name, ' + 'description: $description, defaultValue: $defaultValue, ' + 'prompt: $prompt,)'; +} diff --git a/tools/brick_generator/lib/models/brick_variable_string.dart b/tools/brick_generator/lib/models/brick_variable_string.dart new file mode 100644 index 0000000..abfbefc --- /dev/null +++ b/tools/brick_generator/lib/models/brick_variable_string.dart @@ -0,0 +1,76 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:brick_generator/core/string_extension.dart'; +import 'package:brick_generator/models/brick_variable.dart'; +import 'package:brick_generator/models/variable_string_syntax.dart'; +import 'package:brick_generator/models/variable_type.dart'; +import 'package:yaml/yaml.dart'; + +const _compilableKey = 'compilable'; +const _formatsKey = 'formats'; +const _typeKey = 'type'; +const _descriptionKey = 'description'; +const _defaultKey = 'default'; +const _promptKey = 'prompt'; + +class BrickVariableString extends BrickVariable { + BrickVariableString({ + required this.compilable, + required this.formats, + required this.syntaxes, + required super.type, + required super.name, + required super.description, + required super.defaultValue, + required super.prompt, + }); + + factory BrickVariableString.fromYaml(String key, YamlMap? source) { + if (source == null) { + throw ArgumentError.notNull('source'); + } + + final type = VariableType.fromString(source[_typeKey] as String?); + + final formats = (source[_formatsKey] as YamlList?) + ?.map((element) => element as String) + .map(VariableStringSyntax.fromString) ?? + VariableStringSyntax.values; + + final syntaxes = (source[_compilableKey] as String?)?.syntaxes ?? {}; + + return BrickVariableString( + compilable: source[_compilableKey] as String? ?? '', + type: type, + syntaxes: syntaxes, + name: key, + description: source[_descriptionKey] as String? ?? '', + defaultValue: source[_defaultKey] as String? ?? '', + prompt: source[_promptKey] as String? ?? '', + formats: formats.toList(), + ); + } + + String compilable; + Map? syntaxes; + List formats; + + @override + String toString() => 'BrickVariableString(name: $name, ' + 'description: $description, compilable: $compilable, ' + 'defaultValue: $defaultValue, prompt: $prompt,)'; +} diff --git a/tools/brick_generator/lib/models/brickgen_config.dart b/tools/brick_generator/lib/models/brickgen_config.dart new file mode 100644 index 0000000..271dff9 --- /dev/null +++ b/tools/brick_generator/lib/models/brickgen_config.dart @@ -0,0 +1,84 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:brick_generator/models/boolean_file_system.dart'; +import 'package:brick_generator/models/boolean_mapping.dart'; +import 'package:brick_generator/models/ignore_list.dart'; +import 'package:yaml/yaml.dart'; + +const _pathToBrickifyKey = 'path_to_brickify'; +const _ignoreKey = 'ignore'; +const _hooksKey = 'hooks'; +const _booleanMappingKey = 'boolean_mapping'; +const _booleanFileSystemKey = 'boolean_file_system'; + +class BrickgenConfig { + final String pathToBrickify; + final IgnoreList ignore; + final bool hooks; + final List booleanMapping; + final List booleanFileSystem; + + BrickgenConfig({ + required this.pathToBrickify, + required this.ignore, + required this.hooks, + required this.booleanMapping, + required this.booleanFileSystem, + }); + + factory BrickgenConfig.parse(YamlMap? data) { + if (data == null) { + throw ArgumentError.notNull('data'); + } + + final booleanMapping = (data[_booleanMappingKey] as YamlMap?) + ?.entries + .map( + (e) => + BooleanMapping.fromYaml(e.key as String, e.value as YamlMap?), + ) + .toList() ?? + []; + + final booleanFileSystem = (data[_booleanFileSystemKey] as YamlMap?) + ?.entries + .map( + (e) => BooleanFileSystem.fromYaml( + e.key as String, + e.value as YamlMap?, + ), + ) + .toList() ?? + []; + + final config = BrickgenConfig( + pathToBrickify: data[_pathToBrickifyKey] as String? ?? '', + ignore: IgnoreList.fromConfig(data[_ignoreKey] as YamlList?), + hooks: data[_hooksKey] as bool? ?? false, + booleanMapping: booleanMapping, + booleanFileSystem: booleanFileSystem, + ); + + return config; + } + + @override + String toString() => 'BrickgenConfig(pathToBrickify: $pathToBrickify, ' + 'ignore: $ignore, hooks: $hooks, booleanMapping: $booleanMapping, ' + 'booleanFileSystem: $booleanFileSystem)'; +} diff --git a/tools/brick_generator/lib/models/ignore_list.dart b/tools/brick_generator/lib/models/ignore_list.dart new file mode 100644 index 0000000..5121d63 --- /dev/null +++ b/tools/brick_generator/lib/models/ignore_list.dart @@ -0,0 +1,108 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'dart:io'; + +import 'package:path/path.dart'; +import 'package:yaml/yaml.dart'; + +class IgnoreList { + final List ignoredFiles; + final List ignoredFolders; + + IgnoreList({ + required this.ignoredFiles, + required this.ignoredFolders, + }); + + /// Only parse files an folders (no glob) + /// - file <- file + /// - folder/ <- folder, ends with "/" + /// - infolder/file <- file + /// - sub/folder/ <- folder, ends with "/" + factory IgnoreList.fromConfig(YamlList? list) { + final List ignoredFiles = []; + final List ignoredFolders = []; + + final ignored = + list?.map((element) => element as String).toList() ?? []; + + for (final element in ignored) { + if (element.endsWith('/')) { + // This is a folder + ignoredFolders.add(element.substring(0, element.length - 1)); + } else { + // This is a file + ignoredFiles.add(element); + } + } + + return IgnoreList( + ignoredFiles: ignoredFiles, + ignoredFolders: ignoredFolders, + ); + } + + factory IgnoreList.fromBrickIgnoreFile() { + throw UnimplementedError('.brickignore is not yet supported'); + } + + bool contains(String root, String path) { + final FileSystemEntityType type = FileSystemEntity.typeSync(path); + + // Check if file/folder is an ignored folder (or any subtree of it) + for (final element in ignoredFolders) { + final ignoredPath = join(root, element); + if (path.startsWith(ignoredPath)) { + return true; + } + } + + switch (type) { + case FileSystemEntityType.file: + for (final element in ignoredFiles) { + final ignoredPath = join(root, element); + if (ignoredPath == path) { + return true; + } + } + return false; + case FileSystemEntityType.directory: + for (final element in ignoredFolders) { + final ignoredPath = join(root, element); + if (ignoredPath == path) { + return true; + } + } + return false; + case FileSystemEntityType.link: + case FileSystemEntityType.notFound: + case FileSystemEntityType.pipe: + case FileSystemEntityType.unixDomainSock: + throw ArgumentError( + 'This file system entity type is not supported', + 'from', + ); + } + + return false; + } + + @override + String toString() => 'IgnoreList(ignoredFiles: $ignoredFiles, ' + 'ignoredFolders: $ignoredFolders)'; +} diff --git a/tools/brick_generator/lib/models/log_level.dart b/tools/brick_generator/lib/models/log_level.dart new file mode 100644 index 0000000..113a169 --- /dev/null +++ b/tools/brick_generator/lib/models/log_level.dart @@ -0,0 +1,26 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +enum LogLevel { + debug('💡'), + info('🍺'), + success('✅'), + error('❌'); + + const LogLevel(this.prefix); + + final String prefix; +} diff --git a/tools/brick_generator/lib/models/variable_string_syntax.dart b/tools/brick_generator/lib/models/variable_string_syntax.dart index 053bace..55829c8 100644 --- a/tools/brick_generator/lib/models/variable_string_syntax.dart +++ b/tools/brick_generator/lib/models/variable_string_syntax.dart @@ -1,4 +1,21 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + enum VariableStringSyntax { + none('ERROR', 'ERROR'), snakeCase('snake_case', 'snakeCase'), camelCase('camel_case', 'camelCase'), constantCase('constant_case', 'constantCase'), @@ -9,10 +26,21 @@ enum VariableStringSyntax { paramCase('param_case', 'paramCase'), sentenceCase('sentence_case', 'sentenceCase'), titleCase('title_case', 'titleCase'), - upperCase('upper_case', 'upperCase'); + upperCase('upper_case', 'upperCase'), + pathCase('path_case', 'pathCase'), + mustacheCase('mustache_case', 'mustacheCase'); + + const VariableStringSyntax(this.mapKey, this.id); + + factory VariableStringSyntax.fromString(String? source) { + for (final element in values) { + if (element.mapKey == source || element.id == source) { + return element; + } + } + return VariableStringSyntax.none; + } final String mapKey; final String id; - - const VariableStringSyntax(this.mapKey, this.id); } diff --git a/tools/brick_generator/lib/models/variable_type.dart b/tools/brick_generator/lib/models/variable_type.dart index db6aef6..da0af3b 100644 --- a/tools/brick_generator/lib/models/variable_type.dart +++ b/tools/brick_generator/lib/models/variable_type.dart @@ -1,16 +1,33 @@ -enum VariabelType { +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +enum VariableType { none, string, - bool; + boolean; - static VariabelType stringToEnum(String? type) { - switch (type) { - case 'string': - return string; - case 'bool': - return bool; - default: - return none; + factory VariableType.fromString(String? source) { + for (final element in values) { + if (element.name == source || element.name == source) { + return element; + } } + return VariableType.none; } + + @override + String toString() => name; } diff --git a/tools/brick_generator/lib/shell.dart b/tools/brick_generator/lib/shell.dart deleted file mode 100644 index e16b30f..0000000 --- a/tools/brick_generator/lib/shell.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'dart:io'; - -class Shell { - static Future cp(String source, String destination) { - return _Cmd.run('cp', ['-Rf', source, destination]); - } - - static Future mkdir(String destination) { - return _Cmd.run('mkdir', ['-p', destination]); - } -} - -class _Cmd { - static Future run( - String cmd, - List args, { - bool throwOnError = true, - String? processWorkingDir, - }) async { - final result = await Process.run( - cmd, - args, - workingDirectory: processWorkingDir, - runInShell: true, - ); - - if (throwOnError) { - _throwIfProcessFailed(result, cmd, args); - } - return result; - } - - static void _throwIfProcessFailed( - ProcessResult pr, - String process, - List args, - ) { - if (pr.exitCode != 0) { - final values = { - 'Standard out': pr.stdout.toString().trim(), - 'Standard error': pr.stderr.toString().trim() - }..removeWhere((k, v) => v.isEmpty); - - String message; - if (values.isEmpty) { - message = 'Unknown error'; - } else if (values.length == 1) { - message = values.values.single; - } else { - message = values.entries.map((e) => '${e.key}\n${e.value}').join('\n'); - } - - throw ProcessException(process, args, message, pr.exitCode); - } - } -} diff --git a/tools/brick_generator/lib/yaml_reader.dart b/tools/brick_generator/lib/yaml_reader.dart deleted file mode 100644 index a7bdf15..0000000 --- a/tools/brick_generator/lib/yaml_reader.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'dart:io'; -import 'package:yaml/yaml.dart'; - -class YamlReader { - static YamlMap readYamlFile(String path) => - loadYaml(File(path).readAsStringSync()) as YamlMap; -} diff --git a/tools/brick_generator/pubspec.yaml b/tools/brick_generator/pubspec.yaml index 3ecdbc3..bccc5e3 100644 --- a/tools/brick_generator/pubspec.yaml +++ b/tools/brick_generator/pubspec.yaml @@ -8,12 +8,14 @@ environment: sdk: ">=2.17.0 <3.0.0" dependencies: + args: ^2.3.2 path: ^1.8.2 yaml: ^3.1.1 dev_dependencies: + test: ^1.22.2 wyatt_analysis: - git: - url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages - ref: wyatt_analysis-v2.1.0 - path: packages/wyatt_analysis + hosted: + url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ + name: wyatt_analysis + version: 2.3.0 diff --git a/tools/brick_generator/test/string_test.dart b/tools/brick_generator/test/string_test.dart new file mode 100644 index 0000000..7d0d637 --- /dev/null +++ b/tools/brick_generator/test/string_test.dart @@ -0,0 +1,53 @@ +// Copyright (C) 2023 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:brick_generator/core/string_extension.dart'; +import 'package:test/test.dart'; + +void main() { + final expected = { + 'camel_case': 'featureName', + 'constant_case': 'FEATURE_NAME', + 'dot_case': 'feature.name', + 'header_case': 'Feature-Name', + 'lower_case': 'feature name', + 'pascal_case': 'FeatureName', + 'param_case': 'feature-name', + 'sentence_case': 'Feature name', + 'title_case': 'Feature Name', + 'upper_case': 'FEATURE NAME', + 'snake_case': 'feature_name', + }; + test('transforms `feature_name`', () { + const name = 'feature_name'; + expect(name.syntaxes, equals(expected)); + }); + + test('transforms `featureName`', () { + const name = 'feature_name'; + expect(name.syntaxes, equals(expected)); + }); + + test('transforms `feature-Name`', () { + const name = 'feature_name'; + expect(name.syntaxes, equals(expected)); + }); + + test('transforms `Feature Name`', () { + const name = 'feature_name'; + expect(name.syntaxes, equals(expected)); + }); +}