Compare commits

...

40 Commits

Author SHA1 Message Date
Miroslav Bajtoš 2746bf5bde
2.27.1
* Upgrade lodash from 3.x to 4.x (Miroslav Bajtoš)
2018-02-26 16:52:59 +01:00
Miroslav Bajtoš 17cbdf58f1
Merge pull request #278 from strongloop/upgrade-lodash
Upgrade lodash from 3.x to 4.x
2018-02-26 16:52:25 +01:00
Miroslav Bajtoš 81cdf6b42d
Upgrade lodash from 3.x to 4.x 2018-02-19 11:52:33 +01:00
Miroslav Bajtoš 5060032d26
2.27.0
* Drop support for Node.js versions 0.10 and 0.12 (Miroslav Bajtoš)
 * CODEOWNERS: move @lehni to Alumni section (Miroslav Bajtoš)
 * CODEOWNERS: add zbarbuto (Miroslav Bajtoš)
 * Add CODEOWNERS file (Miroslav Bajtoš)
2017-10-23 09:28:19 +02:00
Miroslav Bajtoš 11058e9afa Merge pull request #272 from strongloop/drop-support-node-0.x
Drop support for Node.js versions 0.10 and 0.12
2017-10-23 09:27:52 +02:00
Miroslav Bajtoš b0408f250d
Drop support for Node.js versions 0.10 and 0.12
Some of our dependencies are no longer supporting pre-4.0 versions of
Node.js. As a result, our CI builds are failing on these platforms.

This pull request removes 0.10 and 0.12 from our Travis CI build matrix
and also adds "engines" field to package.json to tell our internal
Jenkins CI to stop testing 0.10 and 0.12 versions too.
2017-10-19 10:57:06 +02:00
Miroslav Bajtoš 7156baa2d0 Merge pull request #270 from strongloop/good-bye-lehni-2x
Good bye lehni 2x
2017-10-19 10:51:36 +02:00
Miroslav Bajtoš ff5db9696b
CODEOWNERS: move @lehni to Alumni section 2017-10-19 10:50:31 +02:00
Miroslav Bajtoš 223a2668a8 Merge pull request #267 from strongloop/welcome-zbarbuto-2x
CODEOWNERS: add zbarbuto
2017-09-27 11:12:03 +02:00
Miroslav Bajtoš cb5651c584 CODEOWNERS: add zbarbuto 2017-09-25 09:56:54 +02:00
Miroslav Bajtoš 0038e4c939 Merge pull request #265 from strongloop/chore/add-codeowners-2.x
Add CODEOWNERS to 2.x branch
2017-09-20 10:05:41 +02:00
Miroslav Bajtoš b668116fab
2.26.2
* Ignore js sourcemap files from boot (Zak Barbuto)
2017-09-15 10:43:45 +02:00
Miroslav Bajtoš 35e668318b Merge pull request #263 from NextFaze/fix/ignore-maps
Ignore js sourcemap files from boot
2017-09-15 10:43:03 +02:00
Zak Barbuto 3d3609defe Ignore js sourcemap files from boot 2017-09-15 09:46:20 +09:30
Miroslav Bajtoš e81e1952b5
Add CODEOWNERS file 2017-09-14 11:16:43 +02:00
Miroslav Bajtoš cdab45d40e
2.26.1
* Do not call callbacks twice in async boot scripts (Jürg Lehni)
2017-08-17 09:58:23 +02:00
Miroslav Bajtoš ded190ee8a Merge pull request #260 from lehni/feature/async-boot-scripts-2.x
Do not call callbacks twice in async boot scripts
2017-08-17 09:57:42 +02:00
Jürg Lehni c9a1e0cc69 Do not call callbacks twice in async boot scripts
See #252 for details
2017-08-16 20:32:06 +02:00
Miroslav Bajtoš fa656e4bee
2.26.0
* Add support for ES6 style async boot scripts (Jürg Lehni)
 * Update Italian translated strings Q2 2017 (Allen Boone)
 * Update translated strings Q2 2017 (Allen Boone)
2017-07-31 17:34:06 +02:00
Miroslav Bajtoš 7f34b0dff6 Merge pull request #252 from lehni/feature/async-boot-scripts-2.x
Add support for ES6 style async boot scripts
2017-07-31 17:33:34 +02:00
Jürg Lehni 51326091b2
Add support for ES6 style async boot scripts 2017-07-31 16:11:22 +02:00
Diana Lau 39b885f9fb Merge pull request #251 from strongloop/update-translations-2.x-backport
Update translations 2.x backport
2017-06-26 09:09:35 -04:00
Miroslav Bajtoš 6db7cadc9b
2.25.0
* Support es2015 module exports (Babel, TypeScript) (John McLaughlin)
2017-06-26 15:04:00 +02:00
Miroslav Bajtoš 06855c1fcd Merge pull request #250 from zamb3zi/2.x
Support for Typescript/Babel emitted ES2015 modules
2017-06-26 15:03:22 +02:00
John McLaughlin 2b596c8c8b
Support es2015 module exports (Babel, TypeScript)
Detect when a script file is an es2015 module created by
a transpiler like Babel or TypeScript and use the `default`
export instead of `module.exports` in such case.

The following artefacts support the new syntax now:

  - boot scripts
  - components
  - middleware
  - model scripts
2017-06-26 14:35:43 +02:00
Allen Boone 4f91a4f78e Update Italian translated strings Q2 2017 2017-06-23 16:16:16 -04:00
Allen Boone b607f969b8 Update translated strings Q2 2017 2017-06-22 10:23:58 -04:00
Miroslav Bajtoš e5224368d4
2.24.1
* add support for absolute middleware paths on win32 (Benjamin Kroeger)
2017-06-07 14:08:51 +02:00
Miroslav Bajtoš b076286235 Merge pull request #233 from benkroeger/2.x
adds support for absolute middleware paths on win32
2017-06-07 14:07:52 +02:00
Miroslav Bajtoš 7f14a24ed2
2.24.0
* Provide options.scriptExtensions (Supasate Choochaisri)
 * Fix browser tests on Node.js 0.10 (Miroslav Bajtoš)
2017-04-03 15:14:51 +02:00
Miroslav Bajtoš 440a75d6f5 Merge pull request #242 from supasate/2.x
Provide options.scriptExtensions for 2.x
2017-04-03 15:13:49 +02:00
Supasate Choochaisri 95e5201255 Provide options.scriptExtensions 2017-04-01 02:10:31 +07:00
Miroslav Bajtoš cda21ea481 Merge pull request #244 from strongloop/fix/node-0.10-ci
Fix browser tests on Node.js 0.10
2017-03-24 12:22:09 +01:00
Miroslav Bajtoš 67c4f1e1a3
Fix browser tests on Node.js 0.10 2017-03-24 12:04:25 +01:00
Benjamin Kroeger 49016b4e66 add support for absolute middleware paths on win32
uses simple regex check to test if a path matches NTFS notation
2016-11-29 11:03:09 +01:00
Miroslav Bajtoš 9cb3d0648b 2.23.0
* Fix resolution of middleware modules (Miroslav Bajtoš)
 * Normalize line endings to support both LF and CRLF (Miroslav Bajtoš)
2016-10-13 10:15:17 +02:00
David Cheung d9e744a6a7 Merge pull request #222 from strongloop/fix/middleware-outside-node-modules-2x
Fix resolution of middleware modules [2.x]
2016-10-12 14:20:47 -04:00
Miroslav Bajtoš d2d9e8789e Fix resolution of middleware modules
Fix the code loading "loopback#errorhandler" (for example) to correctly
look up the "loopback" module in node_modules of the bootstrapped
application, instead of looking it up in node_modules of loopback-boot.
2016-10-12 14:38:37 +02:00
Miroslav Bajtoš eeea74e0f7 Merge pull request #217 from strongloop/fix-ci-windows
Normalize line endings to support both LF and CRLF [2.x]
2016-09-23 15:55:29 +02:00
Miroslav Bajtoš efea20feb5 Normalize line endings to support both LF and CRLF
This should fix build failures on Windows caused by line-ending
mismatch.
2016-09-23 12:42:56 +02:00
38 changed files with 714 additions and 105 deletions

View File

@ -1,8 +1,7 @@
sudo: false
language: node_js
node_js:
- "0.10"
- "0.12"
- "4"
- "6"
- "8"

View File

@ -1,3 +1,71 @@
2018-02-26, Version 2.27.1
==========================
* Upgrade lodash from 3.x to 4.x (Miroslav Bajtoš)
2017-10-23, Version 2.27.0
==========================
* Drop support for Node.js versions 0.10 and 0.12 (Miroslav Bajtoš)
* CODEOWNERS: move @lehni to Alumni section (Miroslav Bajtoš)
* CODEOWNERS: add zbarbuto (Miroslav Bajtoš)
* Add CODEOWNERS file (Miroslav Bajtoš)
2017-09-15, Version 2.26.2
==========================
* Ignore js sourcemap files from boot (Zak Barbuto)
2017-08-17, Version 2.26.1
==========================
* Do not call callbacks twice in async boot scripts (Jürg Lehni)
2017-07-31, Version 2.26.0
==========================
* Add support for ES6 style async boot scripts (Jürg Lehni)
* Update Italian translated strings Q2 2017 (Allen Boone)
* Update translated strings Q2 2017 (Allen Boone)
2017-06-26, Version 2.25.0
==========================
* Support es2015 module exports (Babel, TypeScript) (John McLaughlin)
2017-06-07, Version 2.24.1
==========================
* add support for absolute middleware paths on win32 (Benjamin Kroeger)
2017-04-03, Version 2.24.0
==========================
* Provide options.scriptExtensions (Supasate Choochaisri)
* Fix browser tests on Node.js 0.10 (Miroslav Bajtoš)
2016-10-13, Version 2.23.0
==========================
* Fix resolution of middleware modules (Miroslav Bajtoš)
* Normalize line endings to support both LF and CRLF (Miroslav Bajtoš)
2016-09-05, Version 2.22.0
==========================

11
CODEOWNERS Normal file
View File

@ -0,0 +1,11 @@
# Lines starting with '#' are comments.
# Each line is a file pattern followed by one or more owners,
# the last matching pattern has the most precendence.
# Current maintainers
* @bajtos @zbarbuto
# Alumni
#
# @lehni

17
intl/de/messages.json Normal file
View File

@ -0,0 +1,17 @@
{
"1e5fea50eef843cbffd1d438494912c8": "Pfad \"{0}\" kann nicht aufgelöst werden",
"34319676975b1abf107da7a056abb434": "Ungültiges Normalisierungsformat - \"{0}\"",
"3a7049e42006e8bc19e0f4fc8df63b6b": "Die `app` wird von einer nicht kompatiblen Loopback-Version {0} betrieben. Unterstützte Versionen: {1}",
"3f93b626dd9a1c33d67490f6e71018b5": "WARNUNG: Hauptkonfigurationsdatei \"{0}{{.json}}\" fehlt",
"4d052d84c8620730afd4a30832f11724": "Unbekanntes Modell {0} kann nicht konfiguriert werden",
"4ed668e9187650d898acf97707df445a": "Die {{phase}} \"{0}\" ist in der Hauptkonfiguration nicht definiert.",
"6447e6b342a2c51ab0bc53b3cbdf3742": "Sortierungskonflikt: \"{0}\" kann nicht nach \"{1}\" hinzugefügt werden, da die entgegengesetzte Reihenfolge bereits angegeben wurde",
"70654dc6eb565613a33344efed3de998": "Laden von Boot-Script fehlgeschlagen: {0}\n{1}",
"7f7bdcadb75abfef1bd8a126d547dd6d": "{0} wird nicht in einen gültigen Wert aufgelöst; zurückgegeben als {1}. \"{2}\" muss in der Umgebungsvariable oder über {{app.get()}} auflösbar sein.",
"91a742b7c3568cf6b6755741a70b3c52": "Die {{middleware}} \"{0}\" in {{phase}} \"{1}\" ist in der Hauptkonfiguration nicht definiert.",
"a3aa22086ae4976cd013065c9a3ff81c": "{0} kann nicht angewendet werden: ",
"be2cf2868ba54624fe38e9908dde5e9e": "Die Daten in {{model-config.json}} haben das nicht unterstützte {{1.x}}-Format.",
"ec551b6f2fafd8d40af801ebe5bb09f6": "{{middleware}}-Anweisungen werden verworfen, {{loopback}}-Client unterstützt {{middleware}} nicht.",
"fdc23df1bd0fe55fe3faabcc89ff60f3": "Middleware \"{0}\" nicht gefunden: {1}"
}

17
intl/es/messages.json Normal file
View File

@ -0,0 +1,17 @@
{
"1e5fea50eef843cbffd1d438494912c8": "No se puede resolver la vía de acceso \"{0}\"",
"34319676975b1abf107da7a056abb434": "Formato de normalización no válido - \"{0}\"",
"3a7049e42006e8bc19e0f4fc8df63b6b": "La `app` está basada en una versión de loopback incompatible {0}. Versiones soportadas: {1}",
"3f93b626dd9a1c33d67490f6e71018b5": "AVISO: falta el archivo de configuración principal \"{0}{{.json}}\"",
"4d052d84c8620730afd4a30832f11724": "No se puede configurar el modelo desconocido {0}",
"4ed668e9187650d898acf97707df445a": "La {{phase}} \"{0}\" no está definida en la configuración principal.",
"6447e6b342a2c51ab0bc53b3cbdf3742": "Conflicto de orden: no se puede añadir \"{0}\" después de \"{1}\", porque ya se ha especificado el orden inverso.",
"70654dc6eb565613a33344efed3de998": "No se ha podido cargar el script de arranque: {0}\n{1}",
"7f7bdcadb75abfef1bd8a126d547dd6d": "{0} no se resuelve como un valor válido, se ha devuelto como {1}. \"{2}\" debe poder resolverse en la variable de entorno o por medio de {{app.get()}}.",
"91a742b7c3568cf6b6755741a70b3c52": "El {{middleware}} \"{0}\" en la {{phase}} \"{1}\" no está definido en la configuración principal.",
"a3aa22086ae4976cd013065c9a3ff81c": "No se puede aplicar {0}: ",
"be2cf2868ba54624fe38e9908dde5e9e": "Los datos de {{model-config.json}} están en un formato {{1.x}} no soportado.",
"ec551b6f2fafd8d40af801ebe5bb09f6": "Descartando instrucciones de {{middleware}}, el cliente de {{loopback}} no da soporte a {{middleware}}.",
"fdc23df1bd0fe55fe3faabcc89ff60f3": "Middleware \"{0}\" no encontrado: {1}"
}

17
intl/fr/messages.json Normal file
View File

@ -0,0 +1,17 @@
{
"1e5fea50eef843cbffd1d438494912c8": "Impossible de résoudre le chemin \"{0}\"",
"34319676975b1abf107da7a056abb434": "Format de normalisation non valide - \"{0}\"",
"3a7049e42006e8bc19e0f4fc8df63b6b": "L'application `app` est basée sur une version loopback {0} incompatible. Versions prises en charge : {1}",
"3f93b626dd9a1c33d67490f6e71018b5": "AVERTISSEMENT : le fichier de configuration principal \"{0}{{.json}}\" est manquant",
"4d052d84c8620730afd4a30832f11724": "Impossible de configurer le modèle inconnu {0}",
"4ed668e9187650d898acf97707df445a": "{{phase}} \"{0}\" n'est pas défini dans la configuration principale.",
"6447e6b342a2c51ab0bc53b3cbdf3742": "Conflit concernant l'ordre : impossible d'ajouter \"{0}\" après \"{1}\" car l'ordre opposé à déjà été spécifié",
"70654dc6eb565613a33344efed3de998": "Echec du chargement du script d'amorçage : {0}\n{1}",
"7f7bdcadb75abfef1bd8a126d547dd6d": "{0} n'est pas résolu en une valeur valide, renvoyé sous forme de {1}. \"{2}\" doit pouvoir être résolu dans la variable d'environnement ou par {{app.get()}}.",
"91a742b7c3568cf6b6755741a70b3c52": "Le {{middleware}} \"{0}\" dans {{phase}} \"{1}\" n'est pas défini dans la configuration principale.",
"a3aa22086ae4976cd013065c9a3ff81c": "Impossible d'appliquer {0} : ",
"be2cf2868ba54624fe38e9908dde5e9e": "Les données contenues dans {{model-config.json}} sont au format {{1.x}} qui n'est pas pris en charge.",
"ec551b6f2fafd8d40af801ebe5bb09f6": "Les instructions {{middleware}} sont ignorées ; le client {{loopback}} ne prend pas en charge {{middleware}}.",
"fdc23df1bd0fe55fe3faabcc89ff60f3": "Middleware \"{0}\" introuvable : {1}"
}

17
intl/it/messages.json Normal file
View File

@ -0,0 +1,17 @@
{
"1e5fea50eef843cbffd1d438494912c8": "Impossibile risolvere il percorso \"{0}\"",
"34319676975b1abf107da7a056abb434": "Formato di normalizzazione non valido - \"{0}\"",
"3a7049e42006e8bc19e0f4fc8df63b6b": "La `app` si basa su una versione loopback non compatibile {0}. Versioni supportate: {1}",
"3f93b626dd9a1c33d67490f6e71018b5": "AVVERTENZA: file di configurazione principale \"{0}{{.json}}\" mancante",
"4d052d84c8620730afd4a30832f11724": "Impossibile configurare il modello {0} sconosciuto",
"4ed668e9187650d898acf97707df445a": "{{phase}} \"{0}\" non definita nella configurazione principale.",
"6447e6b342a2c51ab0bc53b3cbdf3742": "Conflitto di ordinamento: impossibile aggiungere \"{0}\" dopo \"{1}\", perché è già stato specificato l'ordine opposto",
"70654dc6eb565613a33344efed3de998": "Caricamento dello script di boot non riuscito: {0}\n{1}",
"7f7bdcadb75abfef1bd8a126d547dd6d": "{0} non viene risolto in un valore valido, restituito come {1}. \"{2}\" deve essere risolto in una variabile di ambiente o da {{app.get()}}.",
"91a742b7c3568cf6b6755741a70b3c52": "{{middleware}} \"{0}\" in {{phase}} \"{1}\" non definito nella configurazione principale.",
"a3aa22086ae4976cd013065c9a3ff81c": "Impossibile applicare {0}: ",
"be2cf2868ba54624fe38e9908dde5e9e": "I dati in {{model-config.json}} sono nel formato {{1.x}} non supportato.",
"ec551b6f2fafd8d40af801ebe5bb09f6": "Eliminazione delle istruzioni {{middleware}}, il client {{loopback}} non supporta {{middleware}}.",
"fdc23df1bd0fe55fe3faabcc89ff60f3": "Middleware \"{0}\" non trovato: {1}"
}

17
intl/ja/messages.json Normal file
View File

@ -0,0 +1,17 @@
{
"1e5fea50eef843cbffd1d438494912c8": "パス \"{0}\" を解決できません",
"34319676975b1abf107da7a056abb434": "無効な正規化形式 - \"{0}\"",
"3a7049e42006e8bc19e0f4fc8df63b6b": "「アプリケーション」は、互換性のない loopback バージョン {0} を使用しています。サポートされるバージョン: {1}",
"3f93b626dd9a1c33d67490f6e71018b5": "警告: メイン構成ファイル \"{0}{{.json}}\" が欠落しています",
"4d052d84c8620730afd4a30832f11724": "不明なモデル {0} を構成できません",
"4ed668e9187650d898acf97707df445a": "メイン構成内に {{phase}} \"{0}\" が定義されていません。",
"6447e6b342a2c51ab0bc53b3cbdf3742": "順序付けの競合: \"{0}\" を \"{1}\" の後に追加することはできません。既に逆の順序が指定されています",
"70654dc6eb565613a33344efed3de998": "ブート・スクリプトのロードに失敗しました: {0}\n{1}",
"7f7bdcadb75abfef1bd8a126d547dd6d": "{0} は有効な値に解決されず、{1} として返されました。 \"{2}\" は環境変数または {{app.get()}} で解決できなければなりません。",
"91a742b7c3568cf6b6755741a70b3c52": "{{phase}} \"{1}\" の {{middleware}} \"{0}\" がメイン構成内に定義されていません。",
"a3aa22086ae4976cd013065c9a3ff81c": "{0} を適用できません: ",
"be2cf2868ba54624fe38e9908dde5e9e": "{{model-config.json}} のデータが、サポートされていない {{1.x}} 形式になっています。",
"ec551b6f2fafd8d40af801ebe5bb09f6": "{{middleware}} 命令を破棄します。{{loopback}} クライアントでは {{middleware}} はサポートされません。",
"fdc23df1bd0fe55fe3faabcc89ff60f3": "ミドルウェア \"{0}\" が見つかりません: {1}"
}

17
intl/ko/messages.json Normal file
View File

@ -0,0 +1,17 @@
{
"1e5fea50eef843cbffd1d438494912c8": "\"{0}\" 경로를 해석할 수 없음",
"34319676975b1abf107da7a056abb434": "올바르지 않은 정규화 형식 - \"{0}\"",
"3a7049e42006e8bc19e0f4fc8df63b6b": "`앱`이 호환되지 않는 루프백 버전 {0}을(를) 기반으로 합니다. 지원되는 버전: {1}",
"3f93b626dd9a1c33d67490f6e71018b5": "경고: 기본 구성 파일 \"{0}{{.json}}\"이(가) 누락됨",
"4d052d84c8620730afd4a30832f11724": "알 수 없는 모델 {0}을(를) 구성할 수 없음",
"4ed668e9187650d898acf97707df445a": "{{phase}} \"{0}\"이(가) 기본 구성에 정의되어 있지 않습니다.",
"6447e6b342a2c51ab0bc53b3cbdf3742": "순서 지정 충돌: 반대 순서로 이미 지정되어서 \"{1}\" 뒤에 \"{0}\"을(를) 추가할 수 없음",
"70654dc6eb565613a33344efed3de998": "부트 스크립트를 로드하는 데 실패함: {0}\n{1}",
"7f7bdcadb75abfef1bd8a126d547dd6d": "{0}이(가) 올바른 값으로 해석되지 않아서 {1}(으)로 리턴되었습니다. \"{2}\"은(는) 환경 변수에서 또는 {{app.get()}}에 의해 해석 가능해야 합니다. ",
"91a742b7c3568cf6b6755741a70b3c52": "{{phase}} \"{1}\"의 {{middleware}} \"{0}\"이(가) 기본 구성에 정의되어 있지 않습니다. ",
"a3aa22086ae4976cd013065c9a3ff81c": "{0}을(를) 적용할 수 없음: ",
"be2cf2868ba54624fe38e9908dde5e9e": "{{model-config.json}}의 데이터가 지원되지 않는 {{1.x}} 형식입니다. ",
"ec551b6f2fafd8d40af801ebe5bb09f6": "{{middleware}} 지시사항을 버리십시오. {{loopback}} 클라이언트가 {{middleware}}을(를) 지원하지 않습니다.",
"fdc23df1bd0fe55fe3faabcc89ff60f3": "미들웨어 \"{0}\"을(를) 찾을 수 없음: {1}"
}

17
intl/nl/messages.json Normal file
View File

@ -0,0 +1,17 @@
{
"1e5fea50eef843cbffd1d438494912c8": "Pad \"{0}\" kan niet worden omgezet.",
"34319676975b1abf107da7a056abb434": "Ongeldige normalisatie-indeling - \"{0}\"",
"3a7049e42006e8bc19e0f4fc8df63b6b": "De 'app' wordt aangestuurd door een incompatibele versie van loopback, {0}. Ondersteunde versies: {1}",
"3f93b626dd9a1c33d67490f6e71018b5": "WAARSCHUWING: Hoofdconfiguratiebestand \"{0}{{.json}}\" ontbreekt.",
"4d052d84c8620730afd4a30832f11724": "Configuratie van onbekend model {0} kan niet ongedaan worden gemaakt",
"4ed668e9187650d898acf97707df445a": "De {{phase}} \"{0}\" is niet gedefinieerd in de hoofdconfiguratie.",
"6447e6b342a2c51ab0bc53b3cbdf3742": "Volgordeconflict: \"{0}\" kan niet worden toegevoegd na \"{1}\", omdat de omgekeerde volgorde al is opgegeven.",
"70654dc6eb565613a33344efed3de998": "Laden van opstartscript is mislukt: {0}\n{1}",
"7f7bdcadb75abfef1bd8a126d547dd6d": "{0} wordt niet omgezet in een geldige waarde; wordt geretourneerd als {1}. \"{2}\" moet omgezet kunnen worden in een omgevingsvariabele of door {{app.get()}}.",
"91a742b7c3568cf6b6755741a70b3c52": "De {{middleware}} \"{0}\" in {{phase}} \"{1}\" is niet gedefinieerd in de hoofdconfiguratie.",
"a3aa22086ae4976cd013065c9a3ff81c": "{0} kan niet worden toegepast: ",
"be2cf2868ba54624fe38e9908dde5e9e": "De gegevens in {{model-config.json}} hebben de niet ondersteunde indeling {{1.x}}.",
"ec551b6f2fafd8d40af801ebe5bb09f6": "{{middleware}} instructies worden verwijderd, {{loopback}}-client ondersteunt geen {{middleware}}.",
"fdc23df1bd0fe55fe3faabcc89ff60f3": "Middleware \"{0}\" is niet gevonden: {1}"
}

17
intl/pt/messages.json Normal file
View File

@ -0,0 +1,17 @@
{
"1e5fea50eef843cbffd1d438494912c8": "Não é possível resolver caminho \"{0}\"",
"34319676975b1abf107da7a056abb434": "Formato de normalização inválido - \"{0}\"",
"3a7049e42006e8bc19e0f4fc8df63b6b": "O `app` é desenvolvido com uma versão de loopback incompatível {0}. Versões suportadas: {1}",
"3f93b626dd9a1c33d67490f6e71018b5": "AVISO: o arquivo de configuração principal \"{0}{{.json}}\" está ausente",
"4d052d84c8620730afd4a30832f11724": "Não é possível configurar modelo desconhecido {0}",
"4ed668e9187650d898acf97707df445a": "A {{phase}} \"{0}\" não foi definida na configuração principal.",
"6447e6b342a2c51ab0bc53b3cbdf3742": "Conflito de ordem: não é possível incluir \"{0}\" após \"{1}\", porque a ordem oposta já foi especificada",
"70654dc6eb565613a33344efed3de998": "Falha ao carregar script de inicialização: {0}\n{1}",
"7f7bdcadb75abfef1bd8a126d547dd6d": "{0} não resolve para um valor válido, retornado como {1}. \"{2}\" deve ser resolvível na variável de ambiente ou pelo {{app.get()}}.",
"91a742b7c3568cf6b6755741a70b3c52": "O {{middleware}} \"{0}\" em {{phase}} \"{1}\" não é definido na configuração principal.",
"a3aa22086ae4976cd013065c9a3ff81c": "Não é possível aplicar {0}: ",
"be2cf2868ba54624fe38e9908dde5e9e": "Os dados em {{model-config.json}} estão no formato não suportado {{1.x}}.",
"ec551b6f2fafd8d40af801ebe5bb09f6": "Descartando instruções de {{middleware}}, cliente de {{loopback}} não suporta {{middleware}}.",
"fdc23df1bd0fe55fe3faabcc89ff60f3": "Middleware \"{0}\" não localizado: {1}"
}

17
intl/tr/messages.json Normal file
View File

@ -0,0 +1,17 @@
{
"1e5fea50eef843cbffd1d438494912c8": "\"{0}\" yolu çözülemiyor",
"34319676975b1abf107da7a056abb434": "Geçersiz normalleştirme biçimi - \"{0}\"",
"3a7049e42006e8bc19e0f4fc8df63b6b": "`app` uyumsuz olan geri döngü {0} sürümüyle güçlendirilmiş. Desteklenen sürümler: {1}",
"3f93b626dd9a1c33d67490f6e71018b5": "UYARI: Ana yapılandırma dosyası \"{0}{{.json}}\" eksik",
"4d052d84c8620730afd4a30832f11724": "Bilinmeyen {0} modeli yapılandırılamıyor",
"4ed668e9187650d898acf97707df445a": "{{phase}} \"{0}\", ana yapılandırmada tanımlı değil",
"6447e6b342a2c51ab0bc53b3cbdf3742": "Sıralama çakışması: \"{0}\", \"{1}\" sonrasına eklenemez; karşıt sıra belirtilmiş",
"70654dc6eb565613a33344efed3de998": "Önyükleme komut dosyasının yüklenmesi başarısız oldu: {0}\n{1}",
"7f7bdcadb75abfef1bd8a126d547dd6d": "{0} geçerli bir değere çözülmüyor, {1} olarak döndürüldü. \"{2}\" ortam değişkeninde ya da {{app.get()}} ile çözülebilir olmalıdır.",
"91a742b7c3568cf6b6755741a70b3c52": "{{phase}} \"{1}\" aşamasındaki {{middleware}} \"{0}\" ana yapılandırmada tanımlı değil.",
"a3aa22086ae4976cd013065c9a3ff81c": "{0} uygulanamıyor: ",
"be2cf2868ba54624fe38e9908dde5e9e": "{{model-config.json}} içindeki verileri desteklenmeyen {{1.x}} biçiminde.",
"ec551b6f2fafd8d40af801ebe5bb09f6": "{{middleware}} yönergeleri atılıyor, {{middleware}}, {{loopback}} istemcisi tarafından desteklenmiyor.",
"fdc23df1bd0fe55fe3faabcc89ff60f3": "Ara katman \"{0}\" bulunamadı: {1}"
}

View File

@ -0,0 +1,17 @@
{
"1e5fea50eef843cbffd1d438494912c8": "无法解析路径“{0}”",
"34319676975b1abf107da7a056abb434": "标准化格式无效 -“{0}”",
"3a7049e42006e8bc19e0f4fc8df63b6b": "应用程序由不兼容的回环版本 {0} 支持。受支持的版本:{1}",
"3f93b626dd9a1c33d67490f6e71018b5": "警告:缺失主要配置文件“{0}{{.json}}”",
"4d052d84c8620730afd4a30832f11724": "无法配置未知的模型 {0}",
"4ed668e9187650d898acf97707df445a": "未在主配置中定义 {{phase}}“{0}”。",
"6447e6b342a2c51ab0bc53b3cbdf3742": "顺序冲突:不能在“{1}”之后添加“{0}”,因为已指定相反顺序",
"70654dc6eb565613a33344efed3de998": "无法装入引导脚本:{0}\n{1}",
"7f7bdcadb75abfef1bd8a126d547dd6d": "{0} 未解析为有效值,返回为 {1}。“{2}”必须可在环境变量中解析或由 {{app.get()}} 解析。",
"91a742b7c3568cf6b6755741a70b3c52": "未在主配置中定义 {{phase}}“{1}”中的 {{middleware}}“{0}”。",
"a3aa22086ae4976cd013065c9a3ff81c": "无法应用 {0}",
"be2cf2868ba54624fe38e9908dde5e9e": "{{model-config.json}} 中的数据不是受支持的 {{1.x}} 格式。",
"ec551b6f2fafd8d40af801ebe5bb09f6": "正在丢弃 {{middleware}} 指示信息,{{loopback}} 客户机不支持 {{middleware}}。",
"fdc23df1bd0fe55fe3faabcc89ff60f3": "找不到中间件“{0}”:{1}"
}

View File

@ -0,0 +1,17 @@
{
"1e5fea50eef843cbffd1d438494912c8": "無法解析路徑 \"{0}\"",
"34319676975b1abf107da7a056abb434": "無效的正規化格式 - \"{0}\"",
"3a7049e42006e8bc19e0f4fc8df63b6b": "'app' 採用不相容的 LoopBack 版本 {0}。支援的版本:{1}",
"3f93b626dd9a1c33d67490f6e71018b5": "警告:遺漏主要配置檔 \"{0}{{.json}}\"",
"4d052d84c8620730afd4a30832f11724": "無法配置不明模型 {0}",
"4ed668e9187650d898acf97707df445a": "主要配置中未定義 {{phase}} \"{0}\"。",
"6447e6b342a2c51ab0bc53b3cbdf3742": "排序衝突:不能將 \"{0}\" 新增至 \"{1}\" 後面,因為已指定相反順序",
"70654dc6eb565613a33344efed3de998": "載入啟動 Script 時失敗:{0}\n{1}",
"7f7bdcadb75abfef1bd8a126d547dd6d": "{0} 未解析成有效的值,傳回 {1}。\"{2}\" 必須可在環境變數中解析或由 {{app.get()}} 解析。",
"91a742b7c3568cf6b6755741a70b3c52": "主要配置中未定義 {{phase}} \"{1}\" 中的 {{middleware}} \"{0}\"。",
"a3aa22086ae4976cd013065c9a3ff81c": "無法套用 {0}",
"be2cf2868ba54624fe38e9908dde5e9e": "{{model-config.json}} 中的資料採用不受支援的 {{1.x}} 格式。",
"ec551b6f2fafd8d40af801ebe5bb09f6": "正在捨棄 {{middleware}} 指令,{{loopback}} 用戶端不支援 {{middleware}}。",
"fdc23df1bd0fe55fe3faabcc89ff60f3": "找不到中介軟體 \"{0}\"{1}"
}

View File

@ -14,9 +14,17 @@ var debug = require('debug')('loopback:boot:compiler');
var Module = require('module');
var _ = require('lodash');
var g = require('strong-globalize')();
var requireNodeOrEsModule = require('./require');
var FILE_EXTENSION_JSON = '.json';
function arrayToObject(array) {
return array.reduce(function(obj, val) {
obj[val] = val;
return obj;
}, {});
}
/**
* Gather all bootstrap-related configuration data and compile it into
* a single object containing instruction for `boot.execute`.
@ -36,8 +44,14 @@ module.exports = function compile(options) {
options = { appRootDir: options };
}
// For setting properties without modifying the original object
options = Object.create(options);
var appRootDir = options.appRootDir = options.appRootDir || process.cwd();
var env = options.env || process.env.NODE_ENV || 'development';
var scriptExtensions = options.scriptExtensions ?
arrayToObject(options.scriptExtensions) :
require.extensions;
var appConfigRootDir = options.appConfigRootDir || appRootDir;
var appConfig = options.config ||
@ -76,9 +90,9 @@ module.exports = function compile(options) {
resolveRelativePaths(bootScripts, appRootDir);
bootDirs.forEach(function(dir) {
bootScripts = bootScripts.concat(findScripts(dir));
bootScripts = bootScripts.concat(findScripts(dir, scriptExtensions));
var envdir = dir + '/' + env;
bootScripts = bootScripts.concat(findScripts(envdir));
bootScripts = bootScripts.concat(findScripts(envdir, scriptExtensions));
});
// de-dedup boot scripts -ERS
@ -90,12 +104,12 @@ module.exports = function compile(options) {
var modelSources = options.modelSources || modelsMeta.sources || ['./models'];
var modelInstructions = buildAllModelInstructions(
modelsRootDir, modelsConfig, modelSources, options.modelDefinitions);
modelsRootDir, modelsConfig, modelSources, options.modelDefinitions,
scriptExtensions);
var mixinDirs = options.mixinDirs || [];
var mixinSources = options.mixinSources || modelsMeta.mixins || ['./mixins'];
var mixinInstructions = buildAllMixinInstructions(
appRootDir, mixinDirs, mixinSources, options, modelInstructions);
appRootDir, options, mixinSources, scriptExtensions, modelInstructions);
// When executor passes the instruction to loopback methods,
// loopback modifies the data. Since we are loading the data using `require`,
@ -151,11 +165,11 @@ function assertIsValidModelConfig(config) {
* @private
*/
function findScripts(dir, extensions) {
function findScripts(dir, scriptExtensions) {
assert(dir, g.f('cannot require directory contents without directory name'));
var files = tryReadDir(dir);
extensions = extensions || _.keys(require.extensions);
scriptExtensions = scriptExtensions || require.extensions;
// sort files in lowercase alpha for linux
files.sort(function(a, b) {
@ -181,9 +195,9 @@ function findScripts(dir, extensions) {
var filepath = path.resolve(path.join(dir, filename));
var stats = fs.statSync(filepath);
// only require files supported by require.extensions (.txt .md etc.)
// only require files supported by specified extensions
if (stats.isFile()) {
if (isPreferredExtension(filename))
if (scriptExtensions && isPreferredExtension(filename, scriptExtensions))
results.push(filepath);
else
debug('Skipping file %s - unknown extension', filepath);
@ -204,9 +218,12 @@ function tryReadDir() {
}
function buildAllModelInstructions(rootDir, modelsConfig, sources,
modelDefinitions) {
var registry = verifyModelDefinitions(rootDir, modelDefinitions) ||
findModelDefinitions(rootDir, sources);
modelDefinitions, scriptExtensions) {
var registry = verifyModelDefinitions(rootDir, modelDefinitions,
scriptExtensions);
if (!registry) {
registry = findModelDefinitions(rootDir, sources, scriptExtensions);
}
var modelNamesToBuild = addAllBaseModels(registry, Object.keys(modelsConfig));
@ -287,7 +304,7 @@ function sortByInheritance(instructions) {
});
}
function verifyModelDefinitions(rootDir, modelDefinitions) {
function verifyModelDefinitions(rootDir, modelDefinitions, scriptExtensions) {
if (!modelDefinitions || modelDefinitions.length < 1) {
return undefined;
}
@ -299,7 +316,7 @@ function verifyModelDefinitions(rootDir, modelDefinitions) {
definition.sourceFile = fixFileExtension(
fullPath,
tryReadDir(path.dirname(fullPath)),
true);
scriptExtensions);
if (!definition.sourceFile) {
debug('Model source code not found: %s - %s', definition.sourceFile);
}
@ -325,7 +342,7 @@ function verifyModelDefinitions(rootDir, modelDefinitions) {
return registry;
}
function findModelDefinitions(rootDir, sources) {
function findModelDefinitions(rootDir, sources, scriptExtensions) {
var registry = {};
sources.forEach(function(src) {
@ -343,7 +360,8 @@ function findModelDefinitions(rootDir, sources) {
})
.forEach(function(f) {
var fullPath = path.resolve(srcDir, f);
var entry = loadModelDefinition(rootDir, fullPath, files);
var entry = loadModelDefinition(rootDir, fullPath, files,
scriptExtensions);
var modelName = entry.definition.name;
if (!modelName) {
debug('Skipping model definition without Model name: %s',
@ -381,7 +399,10 @@ function tryResolveAppPath(rootDir, relativePath, resolveOptions) {
resolveOptions = resolveOptions || { strict: true };
var isModuleRelative = false;
if (relativePath[0] === '/') {
// would love to use `path.isAbsolute(relativePath)` from node's core module `path`
// but unfortunately that is not available in node v0.10.x
// https://nodejs.org/dist/latest-v6.x/docs/api/path.html#path_path_isabsolute_path
if (relativePath[0] === '/' || /^[a-zA-Z]:[\\]{1,2}/.test(relativePath)) {
fullPath = relativePath;
} else if (start === './' || start === '..') {
fullPath = path.resolve(rootDir, relativePath);
@ -445,13 +466,13 @@ function tryResolveAppPath(rootDir, relativePath, resolveOptions) {
return undefined;
}
function loadModelDefinition(rootDir, jsonFile, allFiles) {
function loadModelDefinition(rootDir, jsonFile, allFiles, scriptExtensions) {
var definition = require(jsonFile);
var basename = path.basename(jsonFile, path.extname(jsonFile));
definition.name = definition.name || _.capitalize(_.camelCase(basename));
definition.name = definition.name || _.upperFirst(_.camelCase(basename));
// find a matching file with a supported extension like `.js` or `.coffee`
var sourceFile = fixFileExtension(jsonFile, allFiles, true);
var sourceFile = fixFileExtension(jsonFile, allFiles, scriptExtensions);
if (sourceFile === undefined) {
debug('Model source code not found: %s', sourceFile);
@ -569,7 +590,7 @@ function resolveMiddlewarePath(rootDir, middleware, config) {
// Try to require the module and check if <module>.<fragment> is a valid
// function
var m = require(pathName);
var m = requireNodeOrEsModule(sourceFile);
if (typeof m[fragment] === 'function') {
resolved.sourceFile = sourceFile;
return resolved;
@ -605,7 +626,7 @@ function resolveMiddlewarePath(rootDir, middleware, config) {
var MIDDLEWARE_PATH_PARAM_REGEX = /^\$!(\.\/|\.\.\/)/;
function resolveMiddlewareParams(rootDir, params) {
return cloneDeep(params, function resolvePathParam(value) {
return _.cloneDeepWith(params, function resolvePathParam(value) {
if (typeof value === 'string' && MIDDLEWARE_PATH_PARAM_REGEX.test(value)) {
return path.resolve(rootDir, value.slice(2));
} else {
@ -640,23 +661,31 @@ function resolveRelativePaths(relativePaths, appRootDir) {
function getExcludedExtensions() {
return {
'.json': '.json',
/**
* This is a temporary workaround for #246
* See discussion here for full description of the underlying issue
* https://github.com/strongloop/loopback-boot/pull/245#issuecomment-311052798
*/
'.map': '.map',
'.node': 'node',
};
}
function isPreferredExtension(filename) {
var includeExtensions = require.extensions;
function isPreferredExtension(filename, includeExtensions) {
assert(!!includeExtensions, '"includeExtensions" argument is required');
var ext = path.extname(filename);
return (ext in includeExtensions) && !(ext in getExcludedExtensions());
}
function fixFileExtension(filepath, files, onlyScriptsExportingFunction) {
function fixFileExtension(filepath, files, scriptExtensions) {
var results = [];
var otherFile;
/* Prefer coffee scripts over json */
if (isPreferredExtension(filepath)) return filepath;
if (scriptExtensions && isPreferredExtension(filepath, scriptExtensions)) {
return filepath;
}
var basename = path.basename(filepath, FILE_EXTENSION_JSON);
var sourceDir = path.dirname(filepath);
@ -670,10 +699,7 @@ function fixFileExtension(filepath, files, onlyScriptsExportingFunction) {
if (!(otherFileExtension in getExcludedExtensions()) &&
path.basename(f, otherFileExtension) == basename) {
if (!onlyScriptsExportingFunction)
results.push(otherFile);
else if (onlyScriptsExportingFunction &&
(typeof require.extensions[otherFileExtension]) === 'function') {
if (!scriptExtensions || otherFileExtension in scriptExtensions) {
results.push(otherFile);
}
}
@ -689,32 +715,33 @@ function resolveAppScriptPath(rootDir, relativePath, resolveOptions) {
}
var sourceDir = path.dirname(resolvedPath);
var files = tryReadDir(sourceDir);
var fixedFile = fixFileExtension(resolvedPath, files, false);
var fixedFile = fixFileExtension(resolvedPath, files);
return (fixedFile === undefined ? resolvedPath : fixedFile);
}
function buildAllMixinInstructions(appRootDir, mixinDirs, mixinSources, options,
modelInstructions) {
var extensions = _.without(_.keys(require.extensions),
_.keys(getExcludedExtensions()));
function buildAllMixinInstructions(appRootDir, options, mixinSources,
scriptExtensions, modelInstructions) {
// load mixins from `options.mixins`
var sourceFiles = options.mixins || [];
var instructionsFromMixins = loadMixins(sourceFiles, options);
var mixinDirs = options.mixinDirs || [];
var instructionsFromMixins = loadMixins(sourceFiles, options.normalization);
// load mixins from `options.mixinDirs`
sourceFiles = findMixinDefinitions(appRootDir, mixinDirs, extensions);
sourceFiles = findMixinDefinitions(appRootDir, mixinDirs, scriptExtensions);
if (sourceFiles === undefined) return;
var instructionsFromMixinDirs = loadMixins(sourceFiles, options);
var instructionsFromMixinDirs = loadMixins(sourceFiles,
options.normalization);
/* If `mixinDirs` and `mixinSources` have any directories in common,
* then remove the common directories from `mixinSources` */
mixinSources = _.difference(mixinSources, mixinDirs);
// load mixins from `options.mixinSources`
sourceFiles = findMixinDefinitions(appRootDir, mixinSources, extensions);
sourceFiles = findMixinDefinitions(appRootDir, mixinSources,
scriptExtensions);
if (sourceFiles === undefined) return;
var instructionsFromMixinSources = loadMixins(sourceFiles, options);
var instructionsFromMixinSources = loadMixins(sourceFiles,
options.normalization);
// Fetch unique list of mixin names, used in models
var modelMixins = fetchMixinNamesUsedInModelInstructions(modelInstructions);
@ -732,7 +759,7 @@ function buildAllMixinInstructions(appRootDir, mixinDirs, mixinSources, options,
return _.values(mixins);
}
function findMixinDefinitions(appRootDir, sourceDirs, extensions) {
function findMixinDefinitions(appRootDir, sourceDirs, scriptExtensions) {
var files = [];
sourceDirs.forEach(function(dir) {
var path = tryResolveAppPath(appRootDir, dir);
@ -740,12 +767,12 @@ function findMixinDefinitions(appRootDir, sourceDirs, extensions) {
debug('Skipping unknown module source dir %j', dir);
return;
}
files = files.concat(findScripts(path, extensions));
files = files.concat(findScripts(path, scriptExtensions));
});
return files;
}
function loadMixins(sourceFiles, options) {
function loadMixins(sourceFiles, normalization) {
var mixinInstructions = {};
sourceFiles.forEach(function(filepath) {
var dir = path.dirname(filepath);
@ -753,12 +780,12 @@ function loadMixins(sourceFiles, options) {
var name = path.basename(filepath, ext);
var metafile = path.join(dir, name + FILE_EXTENSION_JSON);
name = normalizeMixinName(name, options);
name = normalizeMixinName(name, normalization);
var meta = {};
meta.name = name;
if (utils.fileExistsSync(metafile)) {
// May overwrite name, not sourceFile
_.extend(meta, require(metafile));
_.extend(meta, requireNodeOrEsModule(metafile));
}
meta.sourceFile = filepath;
mixinInstructions[meta.name] = meta;
@ -788,8 +815,7 @@ function filterMixinInstructionsUsingWhitelist(instructions, includeMixins) {
return filteredInstructions;
}
function normalizeMixinName(str, options) {
var normalization = options.normalization;
function normalizeMixinName(str, normalization) {
switch (normalization) {
case false:
case 'none': return str;

View File

@ -10,6 +10,7 @@ var async = require('async');
var path = require('path');
var format = require('util').format;
var g = require('strong-globalize')();
var requireNodeOrEsModule = require('./require');
/**
* Execute bootstrap instructions gathered by `boot.compile`.
@ -211,7 +212,7 @@ function defineMixins(app, instructions) {
if (!modelBuilder.mixins || !mixins.length) return;
mixins.forEach(function(obj) {
var mixin = require(obj.sourceFile);
var mixin = requireNodeOrEsModule(obj.sourceFile);
if (typeof mixin === 'function' || mixin.prototype instanceof BaseClass) {
debug('Defining mixin %s', obj.name);
@ -244,7 +245,7 @@ function defineModels(app, instructions) {
model = registry.createModel(data.definition);
if (data.sourceFile) {
debug('Loading customization script %s', data.sourceFile);
var code = require(data.sourceFile);
var code = requireNodeOrEsModule(data.sourceFile);
if (typeof code === 'function') {
debug('Customizing model %s', name);
code(model);
@ -288,12 +289,12 @@ function runScripts(app, list, callback) {
list.forEach(function(filepath) {
debug('Requiring script %s', filepath);
try {
var exports = require(filepath);
if (typeof exports === 'function') {
var bootFn = requireNodeOrEsModule(filepath);
if (typeof bootFn === 'function') {
debug('Exported function detected %s', filepath);
functions.push({
path: filepath,
func: exports,
func: bootFn,
});
}
} catch (err) {
@ -304,17 +305,24 @@ function runScripts(app, list, callback) {
async.eachSeries(functions, function(f, done) {
debug('Running script %s', f.path);
if (f.func.length >= 2) {
debug('Starting async function %s', f.path);
f.func(app, function(err) {
debug('Async function finished %s', f.path);
done(err);
});
} else {
debug('Starting sync function %s', f.path);
f.func(app);
debug('Sync function finished %s', f.path);
done();
var cb = function(err) {
debug('Async function %s %s', err ? 'failed' : 'finished', f.path);
done(err);
// Make sure done() isn't called twice, e.g. if a script returns a
// thenable object and also calls the passed callback.
cb = function() {};
};
try {
var result = f.func(app, cb);
if (result && typeof result.then === 'function') {
result.then(function() { cb(); }, cb);
} else if (f.func.length < 2) {
debug('Sync function finished %s', f.path);
done();
}
} catch (err) {
debug('Sync function failed %s', f.path, err);
done(err);
}
}, callback);
}
@ -340,7 +348,7 @@ function setupMiddleware(app, instructions) {
middleware.forEach(function(data) {
debug('Configuring middleware %j%s', data.sourceFile,
data.fragment ? ('#' + data.fragment) : '');
var factory = require(data.sourceFile);
var factory = requireNodeOrEsModule(data.sourceFile);
if (data.fragment) {
factory = factory[data.fragment].bind(factory);
}
@ -429,7 +437,7 @@ function getUpdatedConfigObject(app, config, opts) {
function setupComponents(app, instructions) {
instructions.components.forEach(function(data) {
debug('Configuring component %j', data.sourceFile);
var configFn = require(data.sourceFile);
var configFn = requireNodeOrEsModule(data.sourceFile);
var opts = {
useEnvVars: true,
};

9
lib/require.js Normal file
View File

@ -0,0 +1,9 @@
// Copyright IBM Corp. 2015,2017. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
module.exports = function requireNodeOrEsModule(sourceFile) {
var exports = require(sourceFile);
return exports && exports.__esModule ? exports.default : exports;
};

View File

@ -1,6 +1,6 @@
{
"name": "loopback-boot",
"version": "2.22.0",
"version": "2.27.1",
"description": "Convention-based bootstrapper for LoopBack applications",
"keywords": [
"StrongLoop",
@ -19,18 +19,22 @@
"posttest": "npm run lint",
"lint": "eslint ."
},
"engines": {
"node": ">=4"
},
"license": "MIT",
"dependencies": {
"async": "~0.9.0",
"commondir": "0.0.1",
"debug": "^2.0.0",
"lodash": "^3.6.0",
"lodash": "^4.17.5",
"semver": "^4.1.0",
"strong-globalize": "^2.6.2",
"toposort": "^0.2.10"
},
"devDependencies": {
"browserify": "^4.1.8",
"bluebird": "^3.1.1",
"chai": "^1.10.0",
"coffee-script": "^1.8.0",
"coffeeify": "^0.7.0",

View File

@ -57,10 +57,15 @@ describe('browser support', function() {
expect(Object.keys(app.models)).to.include('Customer');
expect(app.models.Customer.settings)
.to.have.property('_customized', 'Customer');
expect(Object.keys(app.models)).to.include('ProductUmd');
expect(app.models.ProductUmd.settings)
.to.have.property('_customized', 'UMD');
// configured in fixtures/browser-app/component-config.json
// and fixtures/browser-app/components/dummy-component.js
// configured in fixtures/browser-app/component-config.json,
// fixtures/browser-app/components/dummy-component.js and
// fixtures/browser-app/components/dummy-component-umd.js
expect(app.dummyComponentOptions).to.eql({ option: 'value' });
expect(app.dummyComponentUmdOptions).to.eql({ option: 'valueUmd' });
done();
});
@ -79,8 +84,9 @@ describe('browser support', function() {
var modelBuilder = app.registry.modelBuilder;
var registry = modelBuilder.mixins.mixins;
expect(Object.keys(registry)).to.eql(['TimeStamps']);
expect(Object.keys(registry)).to.eql(['AuditedUmd', 'TimeStamps']);
expect(app.models.Customer.timeStampsMixin).to.eql(true);
expect(app.models.ProductUmd.auditedMixin).to.eql(true);
done();
});

View File

@ -2016,6 +2016,22 @@ describe('compiler', function() {
.to.equal(require.resolve('loopback/server/middleware/url-not-found'));
});
it('supports absolute paths notation', function() {
var middlewarePath =
path.resolve(__dirname, './fixtures/simple-middleware.js');
var routes = {};
routes[middlewarePath] = {};
appdir.writeConfigFileSync('middleware.json', {
'routes': routes,
});
var instructions = boot.compile(appdir.PATH);
expect(instructions.middleware.middleware[0].sourceFile)
.to.equal(path.resolve(appdir.PATH,
middlewarePath));
});
it('supports shorthand notation for relative paths', function() {
appdir.writeConfigFileSync('middleware.json', {
'routes': {
@ -2171,6 +2187,24 @@ describe('compiler', function() {
'sourceFile', coffee);
});
it('ignores sourcmap files when loading middleware',
function() {
var middleware = appdir.writeFileSync('my-middleware.js',
'// I am the middleware');
var sourcemap = appdir.writeFileSync('my-middleware.js.map',
'// I am a sourcemap');
appdir.writeConfigFileSync('middleware.json', {
'routes': {
'./my-middleware': {},
},
});
var instructions = boot.compile(appdir.PATH);
expect(instructions.middleware.middleware[0]).have.property(
'sourceFile', middleware);
});
describe('config with relative paths in params', function() {
var RELATIVE_PATH_PARAMS = [
'$!./here',

View File

@ -265,6 +265,8 @@ describe('executor', function() {
'barLoaded',
'barSyncLoaded',
'fooLoaded',
'promiseLoaded',
'thenableLoaded',
'barStarted',
]);
@ -275,9 +277,16 @@ describe('executor', function() {
'barLoaded',
'barSyncLoaded',
'fooLoaded',
'promiseLoaded',
'thenableLoaded',
'barStarted',
'barFinished',
'barSyncExecuted',
'promiseStarted',
'promiseFinished',
'thenableStarted',
'thenableFinished',
'umdLoaded',
]);
done();
}, 10);
@ -291,51 +300,132 @@ describe('executor', function() {
'barLoaded',
'barSyncLoaded',
'fooLoaded',
'promiseLoaded',
'thenableLoaded',
'barStarted',
'barFinished',
'barSyncExecuted',
'promiseStarted',
'promiseFinished',
'thenableStarted',
'thenableFinished',
'umdLoaded',
]);
done();
});
});
describe('for mixins', function() {
var options;
beforeEach(function() {
appdir.writeFileSync('custom-mixins/example.js',
'module.exports = ' +
'function(Model, options) {}');
it('searches boot file extensions specified in options.scriptExtensions',
function(done) {
var options = {
app: app,
appRootDir: SIMPLE_APP,
scriptExtensions: ['.customjs', '.customjs2'],
};
boot.execute(app, boot.compile(options), function(err) {
if (err) return done(err);
expect(process.bootFlags, 'process: bootFlags').to.eql([
'customjs',
'customjs2',
]);
done();
});
});
});
appdir.writeFileSync('custom-mixins/time-stamps.js',
'module.exports = ' +
'function(Model, options) {}');
describe('with boot script returning a rejected promise', function() {
before(function() {
// Tell simple-app/boot/reject.js to return a rejected promise
process.rejectPromise = true;
});
appdir.writeConfigFileSync('custom-mixins/time-stamps.json', {
name: 'Timestamping',
});
after(function() {
delete process.rejectPromise;
});
options = {
appRootDir: appdir.PATH,
};
it('receives rejected promise as callback error',
function(done) {
boot.execute(app, simpleAppInstructions(), function(err) {
expect(err).to.exist.and.be.an.instanceOf(Error)
.with.property('message', 'reject');
done();
});
});
});
describe('with boot script throwing an error', function() {
before(function() {
// Tell simple-app/boot/throw.js to throw an error
process.throwError = true;
});
after(function() {
delete process.throwError;
});
it('receives thrown error as callback errors',
function(done) {
boot.execute(app, simpleAppInstructions(), function(err) {
expect(err).to.exist.and.be.an.instanceOf(Error)
.with.property('message', 'throw');
done();
});
});
});
describe('with boot script returning a promise and calling callback',
function() {
before(function() {
process.promiseAndCallback = true;
});
it('defines mixins from instructions - using `mixinDirs`', function() {
options.mixinDirs = ['./custom-mixins'];
boot(app, options);
var modelBuilder = app.registry.modelBuilder;
var registry = modelBuilder.mixins.mixins;
expect(Object.keys(registry)).to.eql(['Example', 'Timestamping']);
after(function() {
delete process.promiseAndCallback;
});
it('defines mixins from instructions - using `mixinSources`', function() {
options.mixinSources = ['./custom-mixins'];
boot(app, options);
var modelBuilder = app.registry.modelBuilder;
var registry = modelBuilder.mixins.mixins;
expect(Object.keys(registry)).to.eql(['Example', 'Timestamping']);
it('should only call the callback once', function(done) {
// Note: Mocha will fail this test if done() is called twice
boot.execute(app, simpleAppInstructions(), done);
});
}
);
describe('for mixins', function() {
var options;
beforeEach(function() {
appdir.writeFileSync('custom-mixins/example.js',
'module.exports = ' +
'function(Model, options) {}');
appdir.writeFileSync('custom-mixins/time-stamps.js',
'module.exports = ' +
'function(Model, options) {}');
appdir.writeConfigFileSync('custom-mixins/time-stamps.json', {
name: 'Timestamping',
});
options = {
appRootDir: appdir.PATH,
};
});
it('defines mixins from instructions - using `mixinDirs`', function() {
options.mixinDirs = ['./custom-mixins'];
boot(app, options);
var modelBuilder = app.registry.modelBuilder;
var registry = modelBuilder.mixins.mixins;
expect(Object.keys(registry)).to.eql(['Example', 'Timestamping']);
});
it('defines mixins from instructions - using `mixinSources`', function() {
options.mixinSources = ['./custom-mixins'];
boot(app, options);
var modelBuilder = app.registry.modelBuilder;
var registry = modelBuilder.mixins.mixins;
expect(Object.keys(registry)).to.eql(['Example', 'Timestamping']);
});
});
@ -804,10 +894,11 @@ describe('executor', function() {
.get('/')
.end(function(err, res) {
if (err) return done(err);
expect(res.text).to.eql(('<!DOCTYPE html>\n<html>\n<head lang="en">\n' +
var EXPECTED_TEXT = '<!DOCTYPE html>\n<html>\n<head lang="en">\n' +
' <meta charset="UTF-8">\n <title>simple-app</title>\n' +
'</head>\n<body>\n<h1>simple-app</h1>\n' +
'</body>\n</html>').replace(/\n/g, os.EOL));
'</body>\n</html>';
expect(normalizeEols(res.text)).to.eql(normalizeEols(EXPECTED_TEXT));
done();
});
});
@ -820,6 +911,7 @@ describe('executor', function() {
.end(function(err, res) {
if (err) return done(err);
expect(res.headers.names).to.equal('custom-middleware');
expect(res.headers.umd).to.equal('success');
done();
});
});
@ -1129,3 +1221,7 @@ function envAppInstructions() {
env: 'test',
});
}
function normalizeEols(str) {
return str.replace(/\r\n/g, '\n');
}

View File

@ -1,5 +1,8 @@
{
"./components/dummy-component": {
"option": "value"
},
"./components/dummy-component-umd": {
"option": "valueUmd"
}
}

View File

@ -0,0 +1,11 @@
// Copyright IBM Corp. 2015,2017. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
module.exports = {
default: function(app, options) {
app.dummyComponentUmdOptions = options;
},
};
Object.defineProperty(module.exports, '__esModule', { value: true });

View File

@ -0,0 +1,11 @@
// Copyright IBM Corp. 2014,2017. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
module.exports = {
default: function(Model, options) {
Model.auditedMixin = true;
},
};
Object.defineProperty(module.exports, '__esModule', { value: true });

View File

@ -7,5 +7,8 @@
},
"Customer": {
"dataSource": "db"
},
"ProductUmd": {
"dataSource": "db"
}
}

View File

@ -0,0 +1,11 @@
// Copyright IBM Corp. 2014,2017. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
module.exports = {
default: function(ProductUmd) {
ProductUmd.settings._customized = 'UMD';
},
};
Object.defineProperty(module.exports, '__esModule', { value: true });

View File

@ -0,0 +1,5 @@
{
"name": "ProductUmd",
"base": "User",
"mixins": {"AuditedUmd": {} }
}

View File

@ -0,0 +1,6 @@
'use strict';
module.exports = function(app, callback) {
process.bootFlags.push('customjs');
callback();
};

View File

@ -0,0 +1,6 @@
'use strict';
module.exports = function(app, callback) {
process.bootFlags.push('customjs2');
callback();
};

View File

@ -0,0 +1,13 @@
// Copyright IBM Corp. 2017. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
var Promise = require('bluebird');
module.exports = function(app, callback) {
callback();
if (process.promiseAndCallback) {
return Promise.reject();
}
};

View File

@ -0,0 +1,19 @@
// Copyright IBM Corp. 2017. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
var Promise = require('bluebird');
process.bootFlags.push('promiseLoaded');
module.exports = function(app) {
process.bootFlags.push('promiseStarted');
return Promise.resolve({
then: function(onFulfill, onReject) {
process.nextTick(function() {
process.bootFlags.push('promiseFinished');
onFulfill();
});
},
});
};

12
test/fixtures/simple-app/boot/reject.js vendored Normal file
View File

@ -0,0 +1,12 @@
// Copyright IBM Corp. 2017. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
var Promise = require('bluebird');
module.exports = function(app) {
if (process.rejectPromise) {
return Promise.reject(new Error('reject'));
}
};

View File

@ -0,0 +1,17 @@
// Copyright IBM Corp. 2017. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
process.bootFlags.push('thenableLoaded');
module.exports = function(app) {
process.bootFlags.push('thenableStarted');
return {
then: function(onFulfill, onReject) {
process.nextTick(function() {
process.bootFlags.push('thenableFinished');
onFulfill();
});
},
};
};

10
test/fixtures/simple-app/boot/throw.js vendored Normal file
View File

@ -0,0 +1,10 @@
// Copyright IBM Corp. 2017. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
module.exports = function(app) {
if (process.throwError) {
throw new Error('throw');
}
};

11
test/fixtures/simple-app/boot/umd.js vendored Normal file
View File

@ -0,0 +1,11 @@
// Copyright IBM Corp. 2014,2017. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
module.exports = {
default: function(app) {
process.bootFlags.push('umdLoaded');
},
};
Object.defineProperty(module.exports, '__esModule', { value: true });

View File

@ -2,6 +2,9 @@
"initial": {
"../../helpers/push-name-middleware": {
"params": "custom-middleware"
}
},
"../../helpers/set-umd-middleware": {
"params": "success"
}
}
}

View File

@ -63,6 +63,12 @@ function createContext() {
// `window` is used by loopback to detect browser runtime
context.window = context;
// In Node.js 0.10, the Uint8Array is provided by Node.js glue,
// it's not available in the V8 runtime itself
if (/^v0\.10/.test(process.version)) {
context.Uint8Array = Uint8Array;
}
return vm.createContext(context);
}
exports.createContext = createContext;

View File

@ -0,0 +1,14 @@
// Copyright IBM Corp. 2017. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
module.exports = {
default: function(value) {
return function(req, res, next) {
res.setHeader('umd', value);
next();
};
},
};
Object.defineProperty(module.exports, '__esModule', { value: true });