From ef09b9775be322ee27213b63561acdfaeae8678c Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 14:03:07 +0800 Subject: [PATCH 01/16] chore: reference https://www.prisma.io/docs/reference/api-reference/environment-variables-reference --- lib/src/configure/prisma_environment.dart | 58 +++++++++++++++++++++++ lib/src/configure/query_engine_type.dart | 5 ++ 2 files changed, 63 insertions(+) create mode 100644 lib/src/configure/prisma_environment.dart create mode 100644 lib/src/configure/query_engine_type.dart diff --git a/lib/src/configure/prisma_environment.dart b/lib/src/configure/prisma_environment.dart new file mode 100644 index 00000000..4fe5ba39 --- /dev/null +++ b/lib/src/configure/prisma_environment.dart @@ -0,0 +1,58 @@ +// ignore_for_file: non_constant_identifier_names + +import 'query_engine_type.dart'; + +/// See https://www.prisma.io/docs/reference/api-reference/environment-variables-reference +class PrismaEnvironment { + const PrismaEnvironment({ + this.DATABASE_URL, + this.DEBUG, + this.NO_COLOR, + this.BROWSER, + this.PRISMA_CLI_QUERY_ENGINE_TYPE = QueryEngineType.binary, + this.PRISMA_CLIENT_ENGINE_TYPE = QueryEngineType.binary, + this.PRISMA_ENGINES_MIRROR = r'https://binaries.prisma.sh', + this.PRISMA_QUERY_ENGINE_BINARY, + this.PRISMA_QUERY_ENGINE_LIBRARY, + this.PRISMA_MIGRATION_ENGINE_BINARY, + this.PRISMA_INTROSPECTION_ENGINE_BINARY, + this.PRISMA_FMT_BINARY, + }); + + /// Database URL + final String? DATABASE_URL; + + /// Debugging + final String? DEBUG; + + /// NO_COLOR + final String? NO_COLOR; + + /// BROWSER is for Prisma Studio to force which browser it should be open in, if not set it will open in the default browser. It's also used as a flag when starting the studio from the CLI. + /// BROWSER=firefox prisma studio --port 5555 + final String? BROWSER; + + /// PRISMA_CLI_QUERY_ENGINE_TYPE is used to define the query engine type Prisma CLI downloads and uses. Defaults to library, but can be set to binary + final QueryEngineType PRISMA_CLI_QUERY_ENGINE_TYPE; + + /// PRISMA_CLIENT_ENGINE_TYPE is used to define the query engine type Prisma Client downloads and uses. Defaults to library, but can be set to binary + final QueryEngineType PRISMA_CLIENT_ENGINE_TYPE; + + /// PRISMA_ENGINES_MIRROR can be used to specify a custom CDN (or server) endpoint to download the engines files for the CLI/Client. The default value is https://binaries.prisma.sh, where Prisma hosts the engine files + final String PRISMA_ENGINES_MIRROR; + + /// PRISMA_QUERY_ENGINE_BINARY is used to set a custom location for your own query engine binary. + final String? PRISMA_QUERY_ENGINE_BINARY; + + /// PRISMA_QUERY_ENGINE_LIBRARY is used to set a custom location for your own query engine library. + final String? PRISMA_QUERY_ENGINE_LIBRARY; + + /// PRISMA_MIGRATION_ENGINE_BINARY is used to set a custom location for your own migration engine binary. + final String? PRISMA_MIGRATION_ENGINE_BINARY; + + /// PRISMA_INTROSPECTION_ENGINE_BINARY is used to set a custom location for your own introspection engine binary. + final String? PRISMA_INTROSPECTION_ENGINE_BINARY; + + /// PRISMA_FMT_BINARY is used to set a custom location for your own format engine binary. + final String? PRISMA_FMT_BINARY; +} diff --git a/lib/src/configure/query_engine_type.dart b/lib/src/configure/query_engine_type.dart new file mode 100644 index 00000000..a801b567 --- /dev/null +++ b/lib/src/configure/query_engine_type.dart @@ -0,0 +1,5 @@ +/// Prisma query engine type. +enum QueryEngineType { + binary, + library, +} From 12f39cefab6093c690909092bec251a081cba691 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 16:03:32 +0800 Subject: [PATCH 02/16] refactor(configure): Add new prisma env --- lib/configure.dart | 8 +- lib/src/configure/configure.dart | 26 +----- lib/src/configure/configure_io.dart | 94 ------------------- lib/src/configure/configure_web.dart | 9 -- lib/src/configure/environment.dart | 107 ++++++++++++++++++++++ lib/src/configure/io/configure.dart | 1 + lib/src/configure/prisma_environment.dart | 58 ------------ lib/src/configure/web/configure.dart | 9 ++ pubspec.yaml | 1 + 9 files changed, 126 insertions(+), 187 deletions(-) delete mode 100644 lib/src/configure/configure_io.dart delete mode 100644 lib/src/configure/configure_web.dart create mode 100644 lib/src/configure/environment.dart create mode 100644 lib/src/configure/io/configure.dart delete mode 100644 lib/src/configure/prisma_environment.dart create mode 100644 lib/src/configure/web/configure.dart diff --git a/lib/configure.dart b/lib/configure.dart index a9c9e9b9..356a20e9 100644 --- a/lib/configure.dart +++ b/lib/configure.dart @@ -1,3 +1,5 @@ -export 'src/configure/configure.dart'; -export 'src/configure/configure_web.dart' - if (dart.library.io) 'src/configure/configure_io.dart'; +export 'src/configure/configure.dart' + if (dart.library.html) 'src/configure/web/configure.dart' + if (dart.library.io) 'src/configure/io/configure.dart'; +export 'src/configure/environment.dart'; +export 'src/configure/query_engine_type.dart'; diff --git a/lib/src/configure/configure.dart b/lib/src/configure/configure.dart index 6d5a7140..a6846fae 100644 --- a/lib/src/configure/configure.dart +++ b/lib/src/configure/configure.dart @@ -1,24 +1,4 @@ -/// Prisma configuration. -/// -/// E.g: -/// ```dart -/// final value = configure('key'); -/// final environment = configure.environment; -/// final envValue = configure.env('key'); -/// ``` -abstract class Configure { - /// Get all configuration. - Map get all; +import 'environment.dart'; - /// Call getter. - dynamic call(String name, [dynamic defaultValue]) => - all.containsKey(name.toLowerCase()) - ? all[name.toLowerCase()] - : defaultValue; - - /// Environments. - Map get environment => call('environment') ?? {}; - - /// Get environment variable. - String? env(String name) => environment[name]; -} +/// Prisma configuration environment variables. +external final Environment environment; diff --git a/lib/src/configure/configure_io.dart b/lib/src/configure/configure_io.dart deleted file mode 100644 index 6d9c9c62..00000000 --- a/lib/src/configure/configure_io.dart +++ /dev/null @@ -1,94 +0,0 @@ -import 'dart:io'; -import 'package:path/path.dart' as path; -import 'package:yaml/yaml.dart'; - -import 'configure.dart'; - -class _IO$Configure extends Configure { - /// Create IO configure. - _IO$Configure() { - _load(); - } - - /// Loaded document. - late final Map _document; - - @override - Map get all => _document; - - /// Load `prisma.yaml` file. - void _load() { - // Get current directory. - final Directory currentDirectory = Directory.current; - - // Build path to `prisma.yaml`. - final String configFilePath = - path.join(currentDirectory.path, 'prisma.yaml'); - - // Create prisma config file. - final File configFile = File(configFilePath); - - // If file does not exist. - if (!configFile.existsSync()) { - _document = const {}; - return; - } - - // Load YAML. - final Map yaml = - loadYaml(configFile.readAsStringSync(), sourceUrl: configFile.uri); - - // Parse YAML to Map. - _parseYamlToMap(yaml, root: true); - } - - /// Parse YAML to Map. - void _parseYamlToMap(Map yaml, {bool root = false}) { - _document = {}; - for (final MapEntry entity in yaml.entries) { - if (entity.key == 'environment' && root) { - _document['environment'] = _mergeEnvironment(entity.value); - continue; - } - - _document[entity.key.toString().toLowerCase()] = - _parseMapItem(entity.value); - } - } - - /// Merge Environment. - Map _mergeEnvironment(dynamic environment) { - if (environment is! Map) return Platform.environment; - final Map result = {}; - for (final MapEntry entity in environment.entries) { - if (entity.value != null) { - if (entity.value is String) { - result[entity.key.toString().toUpperCase()] = entity.value; - } - - result[entity.key.toString().toUpperCase()] = entity.value.toString(); - } - } - - return { - ...Platform.environment, - ...result, - }; - } - - /// Parse Map item. - dynamic _parseMapItem(dynamic item) { - if (item is Map) { - return _parseYamlToMap(item); - } - - if (item is List) { - return item.map((dynamic i) => _parseMapItem(i)).toList(); - } - - return item; - } -} - -/// Create IO configure instance. -Configure get configure => _IO$Configure(); diff --git a/lib/src/configure/configure_web.dart b/lib/src/configure/configure_web.dart deleted file mode 100644 index f2590efe..00000000 --- a/lib/src/configure/configure_web.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'configure.dart'; - -class _Web$Configure extends Configure { - @override - Map get all => const {}; -} - -/// Create web configure instance. -Configure get configure => _Web$Configure(); diff --git a/lib/src/configure/environment.dart b/lib/src/configure/environment.dart new file mode 100644 index 00000000..83cd89ba --- /dev/null +++ b/lib/src/configure/environment.dart @@ -0,0 +1,107 @@ +// ignore_for_file: non_constant_identifier_names + +import 'package:rc/rc.dart'; + +import 'query_engine_type.dart'; + +/// See https://www.prisma.io/docs/reference/api-reference/environment-variables-reference +class Environment { + /// Create a new [Environment] from [RuntimeConfiguration]. + const Environment(RuntimeConfiguration prismarc) : _prismarc = prismarc; + + /// Current [RuntimeConfiguration]. + final RuntimeConfiguration _prismarc; + + /// Get all environment variables + Map get all => + _prismarc.all.map((key, value) => MapEntry(key, value.toString())); + + /// Merge [Environment] with [other]. + void merge({ + String? DATABASE_URL, + String? DEBUG, + String? NO_COLOR, + String? BROWSER, + QueryEngineType? PRISMA_CLI_QUERY_ENGINE_TYPE, + QueryEngineType? PRISMA_CLIENT_ENGINE_TYPE, + String? PRISMA_ENGINES_MIRROR, + String? PRISMA_QUERY_ENGINE_BINARY, + String? PRISMA_QUERY_ENGINE_LIBRARY, + String? PRISMA_MIGRATION_ENGINE_BINARY, + String? PRISMA_INTROSPECTION_ENGINE_BINARY, + String? PRISMA_FMT_BINARY, + }) { + final Map configuration = { + 'DATABASE_URL': DATABASE_URL, + 'DEBUG': DEBUG, + 'NO_COLOR': NO_COLOR, + 'BROWSER': BROWSER, + 'PRISMA_CLI_QUERY_ENGINE_TYPE': PRISMA_CLI_QUERY_ENGINE_TYPE?.name, + 'PRISMA_CLIENT_ENGINE_TYPE': PRISMA_CLIENT_ENGINE_TYPE?.name, + 'PRISMA_ENGINES_MIRROR': PRISMA_ENGINES_MIRROR, + 'PRISMA_QUERY_ENGINE_BINARY': PRISMA_QUERY_ENGINE_BINARY, + 'PRISMA_QUERY_ENGINE_LIBRARY': PRISMA_QUERY_ENGINE_LIBRARY, + 'PRISMA_MIGRATION_ENGINE_BINARY': PRISMA_MIGRATION_ENGINE_BINARY, + 'PRISMA_INTROSPECTION_ENGINE_BINARY': PRISMA_INTROSPECTION_ENGINE_BINARY, + 'PRISMA_FMT_BINARY': PRISMA_FMT_BINARY, + }; + + for (final MapEntry entry in configuration.entries) { + if (entry.value != null && entry.value?.isNotEmpty == true) { + _prismarc.context.configuration[entry.key] = entry.value; + } + } + } + + /// Database URL + String? get DATABASE_URL => all['DATABASE_URL']; + + /// Debugging + String? get DEBUG => all['DEBUG']; + + /// NO_COLOR + String? get NO_COLOR => all['NO_COLOR']; + + /// BROWSER is for Prisma Studio to force which browser it should be open in, if not set it will open in the default browser. It's also used as a flag when starting the studio from the CLI. + /// BROWSER=firefox prisma studio --port 5555 + String? get BROWSER => all['BROWSER']; + + /// PRISMA_CLI_QUERY_ENGINE_TYPE is used to define the query engine type Prisma CLI downloads and uses. Defaults to library, but can be set to binary + QueryEngineType get PRISMA_CLI_QUERY_ENGINE_TYPE => + QueryEngineType.values.firstWhere( + (element) => + element.name == + all['PRISMA_CLI_QUERY_ENGINE_TYPE']?.trim().toLowerCase(), + orElse: () => QueryEngineType.library, + ); + + /// PRISMA_CLIENT_ENGINE_TYPE is used to define the query engine type Prisma Client downloads and uses. Defaults to library, but can be set to binary + QueryEngineType get PRISMA_CLIENT_ENGINE_TYPE => + QueryEngineType.values.firstWhere( + (element) => + element.name == + all['PRISMA_CLIENT_ENGINE_TYPE']?.trim().toLowerCase(), + orElse: () => QueryEngineType.library, + ); + + /// PRISMA_ENGINES_MIRROR can be used to specify a custom CDN (or server) endpoint to download the engines files for the CLI/Client. The default value is https://binaries.prisma.sh, where Prisma hosts the engine files + String get PRISMA_ENGINES_MIRROR => + all['PRISMA_ENGINES_MIRROR'] ?? 'https://binaries.prisma.sh'; + + /// PRISMA_QUERY_ENGINE_BINARY is used to set a custom location for your own query engine binary. + String? get PRISMA_QUERY_ENGINE_BINARY => all['PRISMA_QUERY_ENGINE_BINARY']; + + /// PRISMA_QUERY_ENGINE_LIBRARY is used to set a custom location for your own query engine library. + String? get PRISMA_QUERY_ENGINE_LIBRARY => all['PRISMA_QUERY_ENGINE_LIBRARY']; + + /// PRISMA_MIGRATION_ENGINE_BINARY is used to set a custom location for your own migration engine binary. + String? get PRISMA_MIGRATION_ENGINE_BINARY => + all['PRISMA_MIGRATION_ENGINE_BINARY']; + + /// PRISMA_INTROSPECTION_ENGINE_BINARY is used to set a custom location for your own introspection engine binary. + String? get PRISMA_INTROSPECTION_ENGINE_BINARY => + all['PRISMA_INTROSPECTION_ENGINE_BINARY']; + + /// PRISMA_FMT_BINARY is used to set a custom location for your own format engine binary. + String? get PRISMA_FMT_BINARY => all['PRISMA_FMT_BINARY']; +} diff --git a/lib/src/configure/io/configure.dart b/lib/src/configure/io/configure.dart new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/lib/src/configure/io/configure.dart @@ -0,0 +1 @@ + diff --git a/lib/src/configure/prisma_environment.dart b/lib/src/configure/prisma_environment.dart deleted file mode 100644 index 4fe5ba39..00000000 --- a/lib/src/configure/prisma_environment.dart +++ /dev/null @@ -1,58 +0,0 @@ -// ignore_for_file: non_constant_identifier_names - -import 'query_engine_type.dart'; - -/// See https://www.prisma.io/docs/reference/api-reference/environment-variables-reference -class PrismaEnvironment { - const PrismaEnvironment({ - this.DATABASE_URL, - this.DEBUG, - this.NO_COLOR, - this.BROWSER, - this.PRISMA_CLI_QUERY_ENGINE_TYPE = QueryEngineType.binary, - this.PRISMA_CLIENT_ENGINE_TYPE = QueryEngineType.binary, - this.PRISMA_ENGINES_MIRROR = r'https://binaries.prisma.sh', - this.PRISMA_QUERY_ENGINE_BINARY, - this.PRISMA_QUERY_ENGINE_LIBRARY, - this.PRISMA_MIGRATION_ENGINE_BINARY, - this.PRISMA_INTROSPECTION_ENGINE_BINARY, - this.PRISMA_FMT_BINARY, - }); - - /// Database URL - final String? DATABASE_URL; - - /// Debugging - final String? DEBUG; - - /// NO_COLOR - final String? NO_COLOR; - - /// BROWSER is for Prisma Studio to force which browser it should be open in, if not set it will open in the default browser. It's also used as a flag when starting the studio from the CLI. - /// BROWSER=firefox prisma studio --port 5555 - final String? BROWSER; - - /// PRISMA_CLI_QUERY_ENGINE_TYPE is used to define the query engine type Prisma CLI downloads and uses. Defaults to library, but can be set to binary - final QueryEngineType PRISMA_CLI_QUERY_ENGINE_TYPE; - - /// PRISMA_CLIENT_ENGINE_TYPE is used to define the query engine type Prisma Client downloads and uses. Defaults to library, but can be set to binary - final QueryEngineType PRISMA_CLIENT_ENGINE_TYPE; - - /// PRISMA_ENGINES_MIRROR can be used to specify a custom CDN (or server) endpoint to download the engines files for the CLI/Client. The default value is https://binaries.prisma.sh, where Prisma hosts the engine files - final String PRISMA_ENGINES_MIRROR; - - /// PRISMA_QUERY_ENGINE_BINARY is used to set a custom location for your own query engine binary. - final String? PRISMA_QUERY_ENGINE_BINARY; - - /// PRISMA_QUERY_ENGINE_LIBRARY is used to set a custom location for your own query engine library. - final String? PRISMA_QUERY_ENGINE_LIBRARY; - - /// PRISMA_MIGRATION_ENGINE_BINARY is used to set a custom location for your own migration engine binary. - final String? PRISMA_MIGRATION_ENGINE_BINARY; - - /// PRISMA_INTROSPECTION_ENGINE_BINARY is used to set a custom location for your own introspection engine binary. - final String? PRISMA_INTROSPECTION_ENGINE_BINARY; - - /// PRISMA_FMT_BINARY is used to set a custom location for your own format engine binary. - final String? PRISMA_FMT_BINARY; -} diff --git a/lib/src/configure/web/configure.dart b/lib/src/configure/web/configure.dart new file mode 100644 index 00000000..2474d2e4 --- /dev/null +++ b/lib/src/configure/web/configure.dart @@ -0,0 +1,9 @@ +import 'package:rc/rc.dart'; + +import '../environment.dart'; + +/// Create a [RuntimeConfiguration]. +final _prismarc = RuntimeConfiguration(contents: r''); + +/// Create a new [Environment] from [RuntimeConfiguration]. +final Environment environment = Environment(_prismarc); diff --git a/pubspec.yaml b/pubspec.yaml index 389bdecb..e667d369 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,6 +16,7 @@ dependencies: http: ^0.13.5 json_annotation: ^4.6.0 path: ^1.8.2 + rc: ^0.1.0 retry: ^3.1.0 yaml: ^3.1.1 From 701b999fa20054be92abcb14ca12f71d8f7d1ebe Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 17:16:36 +0800 Subject: [PATCH 03/16] feat(runtime): Load runtime configuration file - #15 --- example/.prismarc | 1 + example/lib/src/generated/prisma_client.dart | 2 +- example/prisma.yaml | 2 - lib/src/configure/io/configure.dart | 48 ++++++++ lib/src/configure/io/finder.dart | 112 +++++++++++++++++++ lib/src/configure/web/configure.dart | 2 +- 6 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 example/.prismarc delete mode 100644 example/prisma.yaml create mode 100644 lib/src/configure/io/finder.dart diff --git a/example/.prismarc b/example/.prismarc new file mode 100644 index 00000000..771fc1c7 --- /dev/null +++ b/example/.prismarc @@ -0,0 +1 @@ +DATABASE_URL = "postgres://seven@localhost:5432/demo?schema=public" diff --git a/example/lib/src/generated/prisma_client.dart b/example/lib/src/generated/prisma_client.dart index ff25827f..782a0b3c 100644 --- a/example/lib/src/generated/prisma_client.dart +++ b/example/lib/src/generated/prisma_client.dart @@ -3432,7 +3432,7 @@ class PrismaClient { datasources?.toOverwrites() ?? const {}, dmmf: _dmmf, schema: _schema, - environment: configure.environment, + environment: environment.all, executable: _executable, ); diff --git a/example/prisma.yaml b/example/prisma.yaml deleted file mode 100644 index dd57f16b..00000000 --- a/example/prisma.yaml +++ /dev/null @@ -1,2 +0,0 @@ -environment: - DATABASE_URL: "postgres://seven@localhost:5432/demo?schema=public" diff --git a/lib/src/configure/io/configure.dart b/lib/src/configure/io/configure.dart index 8b137891..ea1458b3 100644 --- a/lib/src/configure/io/configure.dart +++ b/lib/src/configure/io/configure.dart @@ -1 +1,49 @@ +// Create a [RuntimeConfiguration] with dotenv. +import 'dart:io'; +import 'package:rc/rc.dart'; + +import '../environment.dart'; +import 'finder.dart'; + +/// Create a [RuntimeConfiguration] with `prismarc` and `dotenv`. +RuntimeConfiguration get _prismarc { + /// Create a [RuntimeConfiguration] with `dotenv`. + final RuntimeConfiguration dotenv = + prismaConifgurationResult.dotenv?.isNotEmpty == true + ? RuntimeConfiguration.from( + prismaConifgurationResult.dotenv!, + includeEnvironment: true, + ) + : RuntimeConfiguration(contents: ""); + + /// Create a [RuntimeConfiguration] with `prismarc`. + final RuntimeConfiguration prismarc = + prismaConifgurationResult.prismarc?.isNotEmpty == true + ? RuntimeConfiguration.from( + prismaConifgurationResult.prismarc!, + includeEnvironment: true, + ) + : RuntimeConfiguration(contents: ""); + + /// Create a [RuntimeConfiguration] container + final RuntimeConfiguration container = RuntimeConfiguration( + contents: "", + environment: Platform.environment, + ); + + // Merge [dotenv] to [container]. + for (final MapEntry item in dotenv.all.entries) { + container.context.configuration[item.key] = item.value; + } + + // Merge [prismarc] to [container]. + for (final MapEntry item in prismarc.all.entries) { + container.context.configuration[item.key] = item.value; + } + + return container; +} + +/// Create a new [Environment] from [RuntimeConfiguration]. +final Environment environment = Environment(_prismarc); diff --git a/lib/src/configure/io/finder.dart b/lib/src/configure/io/finder.dart new file mode 100644 index 00000000..a5c6f63b --- /dev/null +++ b/lib/src/configure/io/finder.dart @@ -0,0 +1,112 @@ +import 'dart:io'; + +import 'package:path/path.dart' as path; +import 'package:yaml/yaml.dart'; + +class FindPrismaConfigurationResult { + const FindPrismaConfigurationResult({ + this.prismarc, + this.dotenv, + this.schema, + }); + + /// The prisma runtime configuration file path. + final String? prismarc; + + /// The dotenv file path. + final String? dotenv; + + /// Custom schema path. + final String? schema; +} + +/// Get search paths. +List get _searchPaths => { + ..._buildSearchPaths(Directory.current.path), + ..._buildSearchPaths(path.dirname(Platform.script.path)), + ..._buildSearchPaths(path.dirname(Platform.resolvedExecutable)), + ..._buildSearchPaths(path.dirname(Platform.executable)), + }.toList(); + +/// Build search paths for [base]. +List _buildSearchPaths(String base) => [ + base, + path.join(base, 'prisma'), + path.join(base, '.dart_tool', 'prisma'), + ]; + +/// Find a file in [searchPaths]. +File? _findFile(String filename) { + for (final String searchPath in _searchPaths) { + final File file = File(path.join(searchPath, filename)); + if (file.existsSync()) { + return file; + } + } + + return null; +} + +/// Read `pubspec.yaml` in [searchPaths]. +Map? readPubspec(File? pubspec) { + if (pubspec == null) return null; + + final dynamic yaml = loadYaml( + pubspec.readAsStringSync(), + sourceUrl: pubspec.uri, + ); + + if (yaml is YamlMap) { + return yaml + .map((key, value) => MapEntry(key.toString(), value)); + } + + return null; +} + +/// Relative a [path] by [directory], default using find in [searchPaths]. +File? _relativeOrFind({ + required String filename, + String? directory, + String? name, +}) { + if (name != null) { + assert(directory == null, 'Cannot use both directory and path'); + + final File file = File(path.join(directory!, name)); + if (file.existsSync()) return file; + } + + final File? file = _findFile(filename); + if (file != null) return file; + + return null; +} + +// Find prisma configuration result. +FindPrismaConfigurationResult get prismaConifgurationResult { + final File? pubspec = _findFile('pubspec.yaml'); + final Map? pubspecDocument = readPubspec(pubspec); + + final File? prismarc = _relativeOrFind( + name: pubspecDocument?['prisma']?['prismarc']?.toString(), + directory: pubspec?.parent.path, + filename: '.prismarc', + ); + final File? dotenv = _relativeOrFind( + name: pubspecDocument?['prisma']?['env']?.toString(), + directory: pubspec?.parent.path, + filename: '.env', + ); + final File? schema = _relativeOrFind( + name: pubspecDocument?['prisma']?['schema']?.toString(), + directory: pubspec?.parent.path, + filename: 'schema.prisma', + ); + + return FindPrismaConfigurationResult( + prismarc: prismarc?.path, + dotenv: dotenv?.path, + schema: schema?.path ?? path.join('prisma', 'schema.prisma'), + ); +} diff --git a/lib/src/configure/web/configure.dart b/lib/src/configure/web/configure.dart index 2474d2e4..3de7438e 100644 --- a/lib/src/configure/web/configure.dart +++ b/lib/src/configure/web/configure.dart @@ -3,7 +3,7 @@ import 'package:rc/rc.dart'; import '../environment.dart'; /// Create a [RuntimeConfiguration]. -final _prismarc = RuntimeConfiguration(contents: r''); +final RuntimeConfiguration _prismarc = RuntimeConfiguration(contents: r''); /// Create a new [Environment] from [RuntimeConfiguration]. final Environment environment = Environment(_prismarc); From 0e3d7e0fef3b04d93c1b87a576d524469b83f6c8 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 17:26:49 +0800 Subject: [PATCH 04/16] feat(cli): Debug print with environment --- bin/orm.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/orm.dart b/bin/orm.dart index 36b5ce39..a12134f7 100644 --- a/bin/orm.dart +++ b/bin/orm.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:args/args.dart'; import 'package:args/command_runner.dart'; +import 'package:orm/configure.dart'; import 'package:orm/version.dart'; import 'src/commands/db/db_command.dart'; @@ -44,7 +45,7 @@ void main(List args) async { try { await runner.runCommand(results); } catch (error, stackTrace) { - if (!results.wasParsed('debug')) { + if (!results.wasParsed('debug') || environment.DEBUG != null) { print(error); print(stackTrace); exit(1); From 912943146ef14a9ba3a4855739f1114e200ecb09 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 17:27:38 +0800 Subject: [PATCH 05/16] chore(cli): CLI binary engine environment with configure namespace --- bin/src/binary_engine/binary_engine.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/src/binary_engine/binary_engine.dart b/bin/src/binary_engine/binary_engine.dart index 350261e9..2795d069 100644 --- a/bin/src/binary_engine/binary_engine.dart +++ b/bin/src/binary_engine/binary_engine.dart @@ -4,7 +4,7 @@ import 'dart:isolate'; import 'package:archive/archive_io.dart'; import 'package:http/http.dart'; -import 'package:orm/configure.dart'; +import 'package:orm/configure.dart' as configure; import '../utils/chmod.dart'; import '../utils/find_project.dart'; @@ -64,7 +64,7 @@ class BinaryEngine { workingDirectory: projectDirectory, includeParentEnvironment: false, environment: { - ...configure.environment, + ...configure.environment.all, ...environment, }, ); @@ -75,7 +75,7 @@ class BinaryEngine { arguments, workingDirectory: projectDirectory, includeParentEnvironment: false, - environment: configure.environment, + environment: configure.environment.all, ); /// Download the binary engine. From af566d6f960ea68627c35c650f567134430aeabb Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 17:38:08 +0800 Subject: [PATCH 06/16] feat(runtime): Configure define schema path --- lib/src/configure/configure.dart | 3 +++ lib/src/configure/io/configure.dart | 4 ++++ lib/src/configure/web/configure.dart | 3 +++ 3 files changed, 10 insertions(+) diff --git a/lib/src/configure/configure.dart b/lib/src/configure/configure.dart index a6846fae..ca69256a 100644 --- a/lib/src/configure/configure.dart +++ b/lib/src/configure/configure.dart @@ -2,3 +2,6 @@ import 'environment.dart'; /// Prisma configuration environment variables. external final Environment environment; + +/// Prisma schema path +final String schema = 'prisma/schema.prisma'; diff --git a/lib/src/configure/io/configure.dart b/lib/src/configure/io/configure.dart index ea1458b3..daf955cc 100644 --- a/lib/src/configure/io/configure.dart +++ b/lib/src/configure/io/configure.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:rc/rc.dart'; import '../environment.dart'; +import '../configure.dart' as internal; import 'finder.dart'; /// Create a [RuntimeConfiguration] with `prismarc` and `dotenv`. @@ -47,3 +48,6 @@ RuntimeConfiguration get _prismarc { /// Create a new [Environment] from [RuntimeConfiguration]. final Environment environment = Environment(_prismarc); + +/// Prisma schema path +String get schema => prismaConifgurationResult.schema ?? internal.schema; diff --git a/lib/src/configure/web/configure.dart b/lib/src/configure/web/configure.dart index 3de7438e..7cb77ae1 100644 --- a/lib/src/configure/web/configure.dart +++ b/lib/src/configure/web/configure.dart @@ -7,3 +7,6 @@ final RuntimeConfiguration _prismarc = RuntimeConfiguration(contents: r''); /// Create a new [Environment] from [RuntimeConfiguration]. final Environment environment = Environment(_prismarc); + +/// Current platform not supported. +String get schema => throw UnsupportedError('Platform not supported'); From 3d644f784aaca461b402bc8274369a4ab6274b3c Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 17:38:46 +0800 Subject: [PATCH 07/16] chore(CLI): Commands default schema using by `configure.schema` --- bin/src/commands/db/subs/db_pull_sub_command.dart | 6 ++---- bin/src/commands/db/subs/db_push_sub_command.dart | 6 ++---- bin/src/commands/format_command.dart | 5 ++--- bin/src/commands/generate_command.dart | 5 ++--- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/bin/src/commands/db/subs/db_pull_sub_command.dart b/bin/src/commands/db/subs/db_pull_sub_command.dart index 7e80e2d6..9e6b267e 100644 --- a/bin/src/commands/db/subs/db_pull_sub_command.dart +++ b/bin/src/commands/db/subs/db_pull_sub_command.dart @@ -1,7 +1,7 @@ import 'dart:io'; import 'package:args/command_runner.dart'; -import 'package:orm/configure.dart'; +import 'package:orm/configure.dart' as configure; import 'package:orm/version.dart'; import '../../../binary_engine/binary_engine.dart'; @@ -10,7 +10,6 @@ import '../../../binary_engine/binray_engine_type.dart'; import '../../../internal/introspection_engine.dart'; import '../../../internal/json_rpc.dart'; import '../../../utils/ansi_progress.dart'; -import '../../../utils/find_project.dart'; class DbPullSubCommand extends Command { @override @@ -28,8 +27,7 @@ class DbPullSubCommand extends Command { 'schema', help: 'Custom path to your Prisma schema', valueHelp: 'path', - defaultsTo: - configure('schema', joinRelativePaths(['prisma', 'schema.prisma'])), + defaultsTo: configure.schema, ); argParser.addOption( 'composite-type-depth', diff --git a/bin/src/commands/db/subs/db_push_sub_command.dart b/bin/src/commands/db/subs/db_push_sub_command.dart index 63f01544..b56b353c 100644 --- a/bin/src/commands/db/subs/db_push_sub_command.dart +++ b/bin/src/commands/db/subs/db_push_sub_command.dart @@ -1,7 +1,7 @@ import 'dart:io'; import 'package:args/command_runner.dart'; -import 'package:orm/configure.dart'; +import 'package:orm/configure.dart' as configure; import 'package:orm/version.dart'; import '../../../binary_engine/binary_engine.dart'; @@ -10,7 +10,6 @@ import '../../../binary_engine/binray_engine_type.dart'; import '../../../internal/json_rpc.dart'; import '../../../internal/migrate_engine.dart'; import '../../../utils/ansi_progress.dart'; -import '../../../utils/find_project.dart'; class DbPushSubCommand extends Command { @override @@ -29,8 +28,7 @@ class DbPushSubCommand extends Command { 'schema', help: 'Schema file path.', valueHelp: 'path', - defaultsTo: - configure('schema', joinRelativePaths(['prisma', 'schema.prisma'])), + defaultsTo: configure.schema, ); } diff --git a/bin/src/commands/format_command.dart b/bin/src/commands/format_command.dart index 46a4af83..d1003141 100644 --- a/bin/src/commands/format_command.dart +++ b/bin/src/commands/format_command.dart @@ -1,7 +1,7 @@ import 'dart:io'; import 'package:args/command_runner.dart'; -import 'package:orm/configure.dart'; +import 'package:orm/configure.dart' as configure; import 'package:orm/version.dart'; import '../binary_engine/binary_engine.dart'; @@ -16,8 +16,7 @@ class FormatCommand extends Command { 'schema', help: 'Schema file path.', valueHelp: 'path', - defaultsTo: - configure('schema', joinRelativePaths(['prisma', 'schema.prisma'])), + defaultsTo: configure.schema, ); } diff --git a/bin/src/commands/generate_command.dart b/bin/src/commands/generate_command.dart index 6ee63a7b..0ec8d463 100644 --- a/bin/src/commands/generate_command.dart +++ b/bin/src/commands/generate_command.dart @@ -2,7 +2,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:args/command_runner.dart'; -import 'package:orm/configure.dart'; +import 'package:orm/configure.dart' as configure; import 'package:orm/dmmf.dart'; import 'package:orm/generator_helper.dart'; import 'package:orm/orm.dart'; @@ -28,8 +28,7 @@ class GenerateCommand extends Command { 'schema', help: 'Custom path to your Prisma schema', valueHelp: 'path', - defaultsTo: - configure('schema', joinRelativePaths(['prisma', 'schema.prisma'])), + defaultsTo: configure.schema, ); } From 474830773356872ffb3c10e5bff9b6fae35e6dd9 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 17:42:42 +0800 Subject: [PATCH 08/16] feat(CLI): generate import show names --- bin/src/generator/imports_generator.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/src/generator/imports_generator.dart b/bin/src/generator/imports_generator.dart index b733256b..d5991d7c 100644 --- a/bin/src/generator/imports_generator.dart +++ b/bin/src/generator/imports_generator.dart @@ -16,7 +16,7 @@ const List<_Import> _imports = <_Import>[ alias: 'convert', show: ['json'], ), - _Import('package:orm/configure.dart'), + _Import('package:orm/configure.dart', alias: 'configure'), _Import('package:orm/orm.dart', alias: 'runtime'), _Import('package:orm/dmmf.dart', alias: 'dmmf'), _Import('package:json_annotation/json_annotation.dart'), @@ -29,9 +29,9 @@ Future importsGenerator() async { if (element.alias != null) { imports.write(' as ${element.alias}'); } - // if (element.show.isNotEmpty) { - // imports.write(' show ${element.show.join(', ')}'); - // } + if (element.show.isNotEmpty) { + imports.write(' show ${element.show.join(', ')}'); + } imports.writeln(';'); } From 1e306b50cc3d3346c72ee331a7b41734569c0645 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 17:43:23 +0800 Subject: [PATCH 09/16] chore(cli): generate prisma client environment using `configure.environment` --- bin/src/generator/client_builder.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/src/generator/client_builder.dart b/bin/src/generator/client_builder.dart index ea818ffb..23cd2f65 100644 --- a/bin/src/generator/client_builder.dart +++ b/bin/src/generator/client_builder.dart @@ -38,7 +38,7 @@ class PrismaClient { datasources: datasources?.toOverwrites() ?? const {}, dmmf: _dmmf, schema: _schema, - environment: configure.environment, + environment: configure.environment.all, executable: _executable, ); From f81a15ca663c55e08b2c9c856c88481d33148b75 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 17:43:40 +0800 Subject: [PATCH 10/16] chore: Update example generated prisma client --- example/lib/src/generated/prisma_client.dart | 208 +++++++++---------- 1 file changed, 95 insertions(+), 113 deletions(-) diff --git a/example/lib/src/generated/prisma_client.dart b/example/lib/src/generated/prisma_client.dart index 782a0b3c..c0f62850 100644 --- a/example/lib/src/generated/prisma_client.dart +++ b/example/lib/src/generated/prisma_client.dart @@ -1,11 +1,11 @@ // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: camel_case_types, constant_identifier_names, depend_on_referenced_packages, non_constant_identifier_names -import 'dart:convert' as convert; -import 'package:orm/configure.dart'; +import 'dart:convert' as convert show json; +import 'package:orm/configure.dart' as configure; import 'package:orm/orm.dart' as runtime; import 'package:orm/dmmf.dart' as dmmf; -import 'package:json_annotation/json_annotation.dart' as json_annotation; +import 'package:json_annotation/json_annotation.dart'; export 'package:orm/orm.dart' show Datasource, PrismaNull, PrismaUnion, TransactionIsolationLevel; @@ -2095,8 +2095,7 @@ class PostUncheckedUpdateManyWithoutPostsInput }; } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class AggregateUser { const AggregateUser({ this.$avg, @@ -2108,23 +2107,22 @@ class AggregateUser { factory AggregateUser.fromJson(Map json) => _$AggregateUserFromJson(json); - @json_annotation.JsonKey(name: '_avg') + @JsonKey(name: '_avg') final UserAvgAggregateOutputType? $avg; - @json_annotation.JsonKey(name: '_sum') + @JsonKey(name: '_sum') final UserSumAggregateOutputType? $sum; - @json_annotation.JsonKey(name: '_min') + @JsonKey(name: '_min') final UserMinAggregateOutputType? $min; - @json_annotation.JsonKey(name: '_max') + @JsonKey(name: '_max') final UserMaxAggregateOutputType? $max; Map toJson() => _$AggregateUserToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class UserGroupByOutputType { const UserGroupByOutputType({ required this.id, @@ -2139,32 +2137,31 @@ class UserGroupByOutputType { factory UserGroupByOutputType.fromJson(Map json) => _$UserGroupByOutputTypeFromJson(json); - @json_annotation.JsonKey(name: 'id') + @JsonKey(name: 'id') final int id; - @json_annotation.JsonKey(name: 'name') + @JsonKey(name: 'name') final String name; - @json_annotation.JsonKey(name: 'createdAt') + @JsonKey(name: 'createdAt') final DateTime createdAt; - @json_annotation.JsonKey(name: '_avg') + @JsonKey(name: '_avg') final UserAvgAggregateOutputType? $avg; - @json_annotation.JsonKey(name: '_sum') + @JsonKey(name: '_sum') final UserSumAggregateOutputType? $sum; - @json_annotation.JsonKey(name: '_min') + @JsonKey(name: '_min') final UserMinAggregateOutputType? $min; - @json_annotation.JsonKey(name: '_max') + @JsonKey(name: '_max') final UserMaxAggregateOutputType? $max; Map toJson() => _$UserGroupByOutputTypeToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class AggregatePost { const AggregatePost({ this.$avg, @@ -2176,23 +2173,22 @@ class AggregatePost { factory AggregatePost.fromJson(Map json) => _$AggregatePostFromJson(json); - @json_annotation.JsonKey(name: '_avg') + @JsonKey(name: '_avg') final PostAvgAggregateOutputType? $avg; - @json_annotation.JsonKey(name: '_sum') + @JsonKey(name: '_sum') final PostSumAggregateOutputType? $sum; - @json_annotation.JsonKey(name: '_min') + @JsonKey(name: '_min') final PostMinAggregateOutputType? $min; - @json_annotation.JsonKey(name: '_max') + @JsonKey(name: '_max') final PostMaxAggregateOutputType? $max; Map toJson() => _$AggregatePostToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class PostGroupByOutputType { const PostGroupByOutputType({ required this.id, @@ -2210,41 +2206,40 @@ class PostGroupByOutputType { factory PostGroupByOutputType.fromJson(Map json) => _$PostGroupByOutputTypeFromJson(json); - @json_annotation.JsonKey(name: 'id') + @JsonKey(name: 'id') final int id; - @json_annotation.JsonKey(name: 'title') + @JsonKey(name: 'title') final String title; - @json_annotation.JsonKey(name: 'authorId') + @JsonKey(name: 'authorId') final int authorId; - @json_annotation.JsonKey(name: 'content') + @JsonKey(name: 'content') final String content; - @json_annotation.JsonKey(name: 'published') + @JsonKey(name: 'published') final bool published; - @json_annotation.JsonKey(name: 'created_at') + @JsonKey(name: 'created_at') final DateTime created_at; - @json_annotation.JsonKey(name: '_avg') + @JsonKey(name: '_avg') final PostAvgAggregateOutputType? $avg; - @json_annotation.JsonKey(name: '_sum') + @JsonKey(name: '_sum') final PostSumAggregateOutputType? $sum; - @json_annotation.JsonKey(name: '_min') + @JsonKey(name: '_min') final PostMinAggregateOutputType? $min; - @json_annotation.JsonKey(name: '_max') + @JsonKey(name: '_max') final PostMaxAggregateOutputType? $max; Map toJson() => _$PostGroupByOutputTypeToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class AffectedRowsOutput { const AffectedRowsOutput({ required this.count, @@ -2253,14 +2248,13 @@ class AffectedRowsOutput { factory AffectedRowsOutput.fromJson(Map json) => _$AffectedRowsOutputFromJson(json); - @json_annotation.JsonKey(name: 'count') + @JsonKey(name: 'count') final int count; Map toJson() => _$AffectedRowsOutputToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class UserCountOutputType { const UserCountOutputType({ required this.posts, @@ -2269,14 +2263,13 @@ class UserCountOutputType { factory UserCountOutputType.fromJson(Map json) => _$UserCountOutputTypeFromJson(json); - @json_annotation.JsonKey(name: 'posts') + @JsonKey(name: 'posts') final int posts; Map toJson() => _$UserCountOutputTypeToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class UserCountAggregateOutputType { const UserCountAggregateOutputType({ required this.id, @@ -2288,23 +2281,22 @@ class UserCountAggregateOutputType { factory UserCountAggregateOutputType.fromJson(Map json) => _$UserCountAggregateOutputTypeFromJson(json); - @json_annotation.JsonKey(name: 'id') + @JsonKey(name: 'id') final int id; - @json_annotation.JsonKey(name: 'name') + @JsonKey(name: 'name') final int name; - @json_annotation.JsonKey(name: 'createdAt') + @JsonKey(name: 'createdAt') final int createdAt; - @json_annotation.JsonKey(name: '_all') + @JsonKey(name: '_all') final int $all; Map toJson() => _$UserCountAggregateOutputTypeToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class UserAvgAggregateOutputType { const UserAvgAggregateOutputType({ this.id, @@ -2313,14 +2305,13 @@ class UserAvgAggregateOutputType { factory UserAvgAggregateOutputType.fromJson(Map json) => _$UserAvgAggregateOutputTypeFromJson(json); - @json_annotation.JsonKey(name: 'id') + @JsonKey(name: 'id') final double? id; Map toJson() => _$UserAvgAggregateOutputTypeToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class UserSumAggregateOutputType { const UserSumAggregateOutputType({ this.id, @@ -2329,14 +2320,13 @@ class UserSumAggregateOutputType { factory UserSumAggregateOutputType.fromJson(Map json) => _$UserSumAggregateOutputTypeFromJson(json); - @json_annotation.JsonKey(name: 'id') + @JsonKey(name: 'id') final int? id; Map toJson() => _$UserSumAggregateOutputTypeToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class UserMinAggregateOutputType { const UserMinAggregateOutputType({ this.id, @@ -2347,20 +2337,19 @@ class UserMinAggregateOutputType { factory UserMinAggregateOutputType.fromJson(Map json) => _$UserMinAggregateOutputTypeFromJson(json); - @json_annotation.JsonKey(name: 'id') + @JsonKey(name: 'id') final int? id; - @json_annotation.JsonKey(name: 'name') + @JsonKey(name: 'name') final String? name; - @json_annotation.JsonKey(name: 'createdAt') + @JsonKey(name: 'createdAt') final DateTime? createdAt; Map toJson() => _$UserMinAggregateOutputTypeToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class UserMaxAggregateOutputType { const UserMaxAggregateOutputType({ this.id, @@ -2371,20 +2360,19 @@ class UserMaxAggregateOutputType { factory UserMaxAggregateOutputType.fromJson(Map json) => _$UserMaxAggregateOutputTypeFromJson(json); - @json_annotation.JsonKey(name: 'id') + @JsonKey(name: 'id') final int? id; - @json_annotation.JsonKey(name: 'name') + @JsonKey(name: 'name') final String? name; - @json_annotation.JsonKey(name: 'createdAt') + @JsonKey(name: 'createdAt') final DateTime? createdAt; Map toJson() => _$UserMaxAggregateOutputTypeToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class PostCountAggregateOutputType { const PostCountAggregateOutputType({ required this.id, @@ -2399,32 +2387,31 @@ class PostCountAggregateOutputType { factory PostCountAggregateOutputType.fromJson(Map json) => _$PostCountAggregateOutputTypeFromJson(json); - @json_annotation.JsonKey(name: 'id') + @JsonKey(name: 'id') final int id; - @json_annotation.JsonKey(name: 'title') + @JsonKey(name: 'title') final int title; - @json_annotation.JsonKey(name: 'authorId') + @JsonKey(name: 'authorId') final int authorId; - @json_annotation.JsonKey(name: 'content') + @JsonKey(name: 'content') final int content; - @json_annotation.JsonKey(name: 'published') + @JsonKey(name: 'published') final int published; - @json_annotation.JsonKey(name: 'created_at') + @JsonKey(name: 'created_at') final int created_at; - @json_annotation.JsonKey(name: '_all') + @JsonKey(name: '_all') final int $all; Map toJson() => _$PostCountAggregateOutputTypeToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class PostAvgAggregateOutputType { const PostAvgAggregateOutputType({ this.id, @@ -2434,17 +2421,16 @@ class PostAvgAggregateOutputType { factory PostAvgAggregateOutputType.fromJson(Map json) => _$PostAvgAggregateOutputTypeFromJson(json); - @json_annotation.JsonKey(name: 'id') + @JsonKey(name: 'id') final double? id; - @json_annotation.JsonKey(name: 'authorId') + @JsonKey(name: 'authorId') final double? authorId; Map toJson() => _$PostAvgAggregateOutputTypeToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class PostSumAggregateOutputType { const PostSumAggregateOutputType({ this.id, @@ -2454,17 +2440,16 @@ class PostSumAggregateOutputType { factory PostSumAggregateOutputType.fromJson(Map json) => _$PostSumAggregateOutputTypeFromJson(json); - @json_annotation.JsonKey(name: 'id') + @JsonKey(name: 'id') final int? id; - @json_annotation.JsonKey(name: 'authorId') + @JsonKey(name: 'authorId') final int? authorId; Map toJson() => _$PostSumAggregateOutputTypeToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class PostMinAggregateOutputType { const PostMinAggregateOutputType({ this.id, @@ -2478,29 +2463,28 @@ class PostMinAggregateOutputType { factory PostMinAggregateOutputType.fromJson(Map json) => _$PostMinAggregateOutputTypeFromJson(json); - @json_annotation.JsonKey(name: 'id') + @JsonKey(name: 'id') final int? id; - @json_annotation.JsonKey(name: 'title') + @JsonKey(name: 'title') final String? title; - @json_annotation.JsonKey(name: 'authorId') + @JsonKey(name: 'authorId') final int? authorId; - @json_annotation.JsonKey(name: 'content') + @JsonKey(name: 'content') final String? content; - @json_annotation.JsonKey(name: 'published') + @JsonKey(name: 'published') final bool? published; - @json_annotation.JsonKey(name: 'created_at') + @JsonKey(name: 'created_at') final DateTime? created_at; Map toJson() => _$PostMinAggregateOutputTypeToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class PostMaxAggregateOutputType { const PostMaxAggregateOutputType({ this.id, @@ -2514,29 +2498,28 @@ class PostMaxAggregateOutputType { factory PostMaxAggregateOutputType.fromJson(Map json) => _$PostMaxAggregateOutputTypeFromJson(json); - @json_annotation.JsonKey(name: 'id') + @JsonKey(name: 'id') final int? id; - @json_annotation.JsonKey(name: 'title') + @JsonKey(name: 'title') final String? title; - @json_annotation.JsonKey(name: 'authorId') + @JsonKey(name: 'authorId') final int? authorId; - @json_annotation.JsonKey(name: 'content') + @JsonKey(name: 'content') final String? content; - @json_annotation.JsonKey(name: 'published') + @JsonKey(name: 'published') final bool? published; - @json_annotation.JsonKey(name: 'created_at') + @JsonKey(name: 'created_at') final DateTime? created_at; Map toJson() => _$PostMaxAggregateOutputTypeToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class User { const User({ required this.id, @@ -2547,23 +2530,22 @@ class User { factory User.fromJson(Map json) => _$UserFromJson(json); - @json_annotation.JsonKey(name: 'id') + @JsonKey(name: 'id') final int id; - @json_annotation.JsonKey(name: 'name') + @JsonKey(name: 'name') final String name; - @json_annotation.JsonKey(name: 'createdAt') + @JsonKey(name: 'createdAt') final DateTime createdAt; - @json_annotation.JsonKey(name: 'posts') + @JsonKey(name: 'posts') final List? posts; Map toJson() => _$UserToJson(this); } -@json_annotation.JsonSerializable( - createFactory: true, createToJson: true, explicitToJson: true) +@JsonSerializable(createFactory: true, createToJson: true, explicitToJson: true) class Post { const Post({ required this.id, @@ -2577,25 +2559,25 @@ class Post { factory Post.fromJson(Map json) => _$PostFromJson(json); - @json_annotation.JsonKey(name: 'id') + @JsonKey(name: 'id') final int id; - @json_annotation.JsonKey(name: 'title') + @JsonKey(name: 'title') final String title; - @json_annotation.JsonKey(name: 'authorId') + @JsonKey(name: 'authorId') final int authorId; - @json_annotation.JsonKey(name: 'content') + @JsonKey(name: 'content') final String content; - @json_annotation.JsonKey(name: 'published') + @JsonKey(name: 'published') final bool published; - @json_annotation.JsonKey(name: 'created_at') + @JsonKey(name: 'created_at') final DateTime created_at; - @json_annotation.JsonKey(name: 'author') + @JsonKey(name: 'author') final User? author; Map toJson() => _$PostToJson(this); @@ -3432,7 +3414,7 @@ class PrismaClient { datasources?.toOverwrites() ?? const {}, dmmf: _dmmf, schema: _schema, - environment: environment.all, + environment: configure.environment.all, executable: _executable, ); From 3d7108c362dab920a5ca0e5dea52c1b5b9623361 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 18:02:41 +0800 Subject: [PATCH 11/16] chore(cli): `init` command generate runtime configuration --- bin/src/commands/init_command.dart | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/bin/src/commands/init_command.dart b/bin/src/commands/init_command.dart index 8cda4f34..bb23bf0d 100644 --- a/bin/src/commands/init_command.dart +++ b/bin/src/commands/init_command.dart @@ -51,17 +51,12 @@ class InitCommand extends Command { /// Create prisma config file. void createPrismaConfigFile(Uri uri) { - final File config = File(joinPaths(['prisma.yaml'])); + final File config = File(joinPaths(['.prismarc'])); if (!config.existsSync()) { config.createSync(recursive: true); } - final String template = r''' -environment: - DATABASE_URL: {url} -'''; - final String content = template.replaceAll('{url}', uri.toString()); - config.writeAsStringSync(content); + config.writeAsStringSync('DATABASE_URL = ${uri.toString()}'); } /// Create prisma schema file. From 835453583f26aadac9d47036855886bbd831c02a Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 18:03:22 +0800 Subject: [PATCH 12/16] feat(cli): Download engines using environment --- bin/src/binary_engine/binary_engine.dart | 34 +++++++++++++++++++----- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/bin/src/binary_engine/binary_engine.dart b/bin/src/binary_engine/binary_engine.dart index 2795d069..e4492562 100644 --- a/bin/src/binary_engine/binary_engine.dart +++ b/bin/src/binary_engine/binary_engine.dart @@ -26,14 +26,33 @@ class BinaryEngine { String get _archiveExtension => platform == BinaryEnginePlatform.windows ? '.exe.gz' : '.gz'; - /// archive file name. - String get _archiveBasename => type.value + _archiveExtension; - /// Archive file path. - String get _archive => joinPaths(['.dart_tool', 'prisma', _archiveBasename]); + String get _archive => executable + _archiveExtension; /// Executable file path. - String get executable => joinPaths(['.dart_tool', 'prisma', type.value]); + String get executable { + switch (type) { + case BinaryEngineType.query: + return configure.environment.PRISMA_QUERY_ENGINE_BINARY ?? + _defaultEnginePathBuilder('query-engine'); + case BinaryEngineType.migration: + return configure.environment.PRISMA_MIGRATION_ENGINE_BINARY ?? + _defaultEnginePathBuilder('migration-engine'); + case BinaryEngineType.introspection: + return configure.environment.PRISMA_INTROSPECTION_ENGINE_BINARY ?? + _defaultEnginePathBuilder('introspection-engine'); + case BinaryEngineType.format: + return configure.environment.PRISMA_FMT_BINARY ?? + _defaultEnginePathBuilder('prisma-fmt'); + } + } + + /// Default engine path builder. + String _defaultEnginePathBuilder(String name) => joinPaths([ + '.dart_tool', + 'prisma', + '${platform.name}-$name', + ]); /// Has the binary engine been downloaded. Future get hasDownloaded async { @@ -90,12 +109,13 @@ class BinaryEngine { await _clean(); // Create download url. - final Uri url = Uri.parse('https://binaries.prisma.sh').replace( + final Uri url = + Uri.parse(configure.environment.PRISMA_ENGINES_MIRROR).replace( pathSegments: [ 'all_commits', version, platform.value, - _archiveBasename, + type.value + _archiveExtension, ], ); From 48201788c002d106d3a7013ee23226cd32275e84 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 18:03:41 +0800 Subject: [PATCH 13/16] chore: Rebuild example prisma client --- example/lib/src/generated/prisma_client.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/lib/src/generated/prisma_client.dart b/example/lib/src/generated/prisma_client.dart index c0f62850..55cd7cee 100644 --- a/example/lib/src/generated/prisma_client.dart +++ b/example/lib/src/generated/prisma_client.dart @@ -3375,7 +3375,7 @@ final dmmf.Document _dmmf = /// Prisma query engine executable. const String _executable = - '/Users/seven/workspace/prisma/example/.dart_tool/prisma/query-engine'; + '/Users/seven/workspace/prisma/example/.dart_tool/prisma/darwin-query-engine'; /// Prisma schema as string. final String _schema = From 9b7ed6ed3efa08984cca6ed9bfa8252302c042ff Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 18:05:36 +0800 Subject: [PATCH 14/16] chore: Fix typo --- bin/src/commands/generate_command.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/src/commands/generate_command.dart b/bin/src/commands/generate_command.dart index 0ec8d463..349ac5e7 100644 --- a/bin/src/commands/generate_command.dart +++ b/bin/src/commands/generate_command.dart @@ -14,7 +14,6 @@ import '../binary_engine/binray_engine_type.dart'; import '../generator/generator.dart'; import '../generator/generator_options.dart'; import '../utils/ansi_progress.dart'; -import '../utils/find_project.dart'; class GenerateCommand extends Command { @override From 2ac1d7a3b646ec98aba7a804d17f376db4f463b9 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 18:09:28 +0800 Subject: [PATCH 15/16] chore(cli): fix default engine name --- bin/src/binary_engine/binary_engine.dart | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/bin/src/binary_engine/binary_engine.dart b/bin/src/binary_engine/binary_engine.dart index e4492562..180154f0 100644 --- a/bin/src/binary_engine/binary_engine.dart +++ b/bin/src/binary_engine/binary_engine.dart @@ -48,11 +48,8 @@ class BinaryEngine { } /// Default engine path builder. - String _defaultEnginePathBuilder(String name) => joinPaths([ - '.dart_tool', - 'prisma', - '${platform.name}-$name', - ]); + String _defaultEnginePathBuilder(String name) => + joinPaths(['.dart_tool', 'prisma', name]); /// Has the binary engine been downloaded. Future get hasDownloaded async { From 08966b61c49f767a1a12c7fcf79984a61ee6861b Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Sep 2022 18:37:49 +0800 Subject: [PATCH 16/16] chore(version): pre-written 2.1.0 --- CHANGELOG.md | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++ pubspec.yaml | 2 +- 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0370ca5..c5562379 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,108 @@ +## 2.1.0 + +🌟 Help us spread the word about [Prisma ORM for Dart](https://github.com/odroe/prisma-dart) by starring the repo or [Tweeting](https://twitter.com/intent/tweet?text=Check%20out%20the%20latest%20Prisma%20ORM%20for%20Dart%20release%20v2.0.0🚀%0D%0A%0D%0Ahttps://github.com/odroe/prisma-dart/releases/tag/2.1.0) about the release. 🌟 + +### Major improvements: + +#### Runtime configuration + +Previously, use `prisma.yaml` to configure Prisma: +```yaml +environment: + DATABASE_URL: postgres://user:password@localhost:5432/mydb +``` + +Now, we have introduced a new configuration method, **Runtime Configuration** compatible with dotenv format: +``` +# .prismarc +DATABASE_URL=postgres://user:password@localhost:5432/mydb + +# Database host +DATABASE_HOST=postgres://user:password@localhost:5432 +DATABASE_URL=${DATABASE_HOST}/mydb +``` + +If you have dotenv in mind, you just need to add the database URL configuration to `.env`: +```dotenv +DATABASE_URL=postgres://user:password@localhost:5432/mydb +``` + +For more usage of runtime configuration, please see 👉 https://pub.dev/packages/rc + +#### Custom configuration + +Now, you can customize your prisma project configuration in `pubspec.yaml`: +```yaml +... +prisma: + prismarc: path/a/b/c/custom.prismarc + dotenv: path/a/b/c/custom.env + schema: path/a/b/c/custom.prisma +... +``` + +| Parameter | Description | Default | +| --- | --- | --- | +| `prismarc` | Custom runtime configuration path | `.prismarc` | +| `dotenv` | Custom dotenv path | `.env` | +| `schema` | Custom Prisma schema path | `prisma/schema.prisma` | + +#### Custom engine path + +Previously, the Prisma engine was downloaded into the `.dart_tool/prisma` directory, now you can customize it. + +##### Custom engines path with runtime configuration + +``` +# Query binary engine +PRISMA_QUERY_ENGINE_BINARY(path) = custom-engines/query-engine + +# Migration binary engine +PRISMA_MIGRATION_ENGINE_BINARY(path) = custom-engines/migration-engine + +# Introspection binary engine +PRISMA_INTROSPECTION_ENGINE_BINARY(path) = custom-engines/introspection-engine + +# Format binary engine +PRISMA_FMT_BINARY(path) = custom-engines/prisma-fmt +``` + +##### Custom engines path with dotenv + +``` +PRISMA_QUERY_ENGINE_BINARY=path/to/custom-engines/query-engine +PRISMA_MIGRATION_ENGINE_BINARY=path/to/custom-engines/migration-engine +PRISMA_INTROSPECTION_ENGINE_BINARY=path/to/custom-engines/introspection-engine +PRISMA_FMT_BINARY=path/to/custom-engines/prisma-fmt +``` + +#### Refactored `package:orm/configure.dart` + +Previously, we have `package:orm/configure.dart` to configure Prisma, now we have refactored it to `package:orm/prisma.dart`: +```dart +import 'package:orm/configure.dart'; + +print(configure('DATABASE_URL')); +``` + +Now, you can use `package:orm/configure.dart` to configure Prisma: +```dart +import 'package:orm/configure.dart'; + +print(environment.DATABASE_URL); +``` + +### Bug fixes: + +1. Fix map and throws binary errors - [#16](https://github.com/odroe/prisma-dart/pull/16) +2. Problems using Model with relation - [#14](https://github.com/odroe/prisma-dart/pull/14) + +### Features: + +1. Generator generate import support show. +2. Prisma CLI debug allow set to dotenv or runtime configuration. +3. Prisma CLI debug print stack trace. + ## 2.0.1 ### CLI diff --git a/pubspec.yaml b/pubspec.yaml index e667d369..99c65c78 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: orm description: ◭ Next-generation ORM for Dart Navtive & Flutter | PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, MongoDB and CockroachDB. -version: 2.0.1 +version: 2.1.0 homepage: https://prisma.pub repository: https://github.com/odroe/prisma-dart