keycloakify 10.0.0-rc.17 → 10.0.0-rc.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PUBLIC_URL.js.map +1 -1
- package/account/Template.js +5 -5
- package/account/Template.js.map +1 -1
- package/account/i18n/i18n.js +37 -29
- package/account/i18n/i18n.js.map +1 -1
- package/account/kcContext/KcContext.js.map +1 -1
- package/account/kcContext/createGetKcContext.js +20 -15
- package/account/kcContext/createGetKcContext.js.map +1 -1
- package/account/kcContext/getKcContext.js.map +1 -1
- package/account/kcContext/getKcContextFromWindow.d.ts +3 -1
- package/account/kcContext/getKcContextFromWindow.js.map +1 -1
- package/account/kcContext/kcContextMocks.js +148 -144
- package/account/kcContext/kcContextMocks.js.map +1 -1
- package/account/lib/useGetClassName.js +14 -14
- package/account/lib/useGetClassName.js.map +1 -1
- package/account/pages/Account.js +1 -1
- package/account/pages/Account.js.map +1 -1
- package/account/pages/Password.js +7 -7
- package/account/pages/Password.js.map +1 -1
- package/account/pages/Totp.js +4 -4
- package/account/pages/Totp.js.map +1 -1
- package/bin/main.js +2066 -2165
- package/bin/shared/constants.d.ts +1 -0
- package/bin/shared/constants.js +4 -3
- package/bin/shared/constants.js.map +1 -1
- package/lib/isStorybook.js +2 -1
- package/lib/isStorybook.js.map +1 -1
- package/lib/useGetClassName.js.map +1 -1
- package/login/Template.js +13 -13
- package/login/Template.js.map +1 -1
- package/login/UserProfileFormFields.js +43 -41
- package/login/UserProfileFormFields.js.map +1 -1
- package/login/i18n/baseMessages/ca.d.ts +1 -1
- package/login/i18n/baseMessages/ca.js +1 -1
- package/login/i18n/baseMessages/el.d.ts +0 -1
- package/login/i18n/baseMessages/el.js +0 -1
- package/login/i18n/baseMessages/el.js.map +1 -1
- package/login/i18n/baseMessages/en.d.ts +1 -1
- package/login/i18n/baseMessages/en.js +1 -1
- package/login/i18n/baseMessages/es.d.ts +1 -1
- package/login/i18n/baseMessages/es.js +1 -1
- package/login/i18n/baseMessages/fa.d.ts +0 -1
- package/login/i18n/baseMessages/fa.js +0 -1
- package/login/i18n/baseMessages/fa.js.map +1 -1
- package/login/i18n/baseMessages/hu.d.ts +1 -1
- package/login/i18n/baseMessages/hu.js +1 -1
- package/login/i18n/baseMessages/index.d.ts +1 -2
- package/login/i18n/baseMessages/zh-CN.d.ts +1 -1
- package/login/i18n/baseMessages/zh-CN.js +1 -1
- package/login/i18n/i18n.js +39 -31
- package/login/i18n/i18n.js.map +1 -1
- package/login/kcContext/KcContext.js.map +1 -1
- package/login/kcContext/createGetKcContext.js +30 -22
- package/login/kcContext/createGetKcContext.js.map +1 -1
- package/login/kcContext/getKcContext.js.map +1 -1
- package/login/kcContext/getKcContextFromWindow.d.ts +3 -1
- package/login/kcContext/getKcContextFromWindow.js.map +1 -1
- package/login/kcContext/kcContextMocks.js +233 -231
- package/login/kcContext/kcContextMocks.js.map +1 -1
- package/login/lib/useDownloadTerms.js.map +1 -1
- package/login/lib/useGetClassName.js +112 -112
- package/login/lib/useGetClassName.js.map +1 -1
- package/login/lib/useUserProfileForm.js +181 -181
- package/login/lib/useUserProfileForm.js.map +1 -1
- package/login/pages/DeleteAccountConfirm.js +5 -1
- package/login/pages/DeleteAccountConfirm.js.map +1 -1
- package/login/pages/FrontchannelLogout.js +1 -1
- package/login/pages/FrontchannelLogout.js.map +1 -1
- package/login/pages/Login.js.map +1 -1
- package/login/pages/LoginRecoveryAuthnCodeConfig.js +3 -3
- package/login/pages/LoginRecoveryAuthnCodeConfig.js.map +1 -1
- package/login/pages/LoginResetPassword.js.map +1 -1
- package/login/pages/LoginUsername.js.map +1 -1
- package/login/pages/WebauthnAuthenticate.js +11 -8
- package/login/pages/WebauthnAuthenticate.js.map +1 -1
- package/login/pages/WebauthnRegister.js +7 -7
- package/login/pages/WebauthnRegister.js.map +1 -1
- package/package.json +230 -226
- package/src/PUBLIC_URL.ts +4 -1
- package/src/account/Template.tsx +5 -5
- package/src/account/TemplateProps.ts +4 -1
- package/src/account/i18n/i18n.tsx +40 -30
- package/src/account/kcContext/KcContext.ts +4 -1
- package/src/account/kcContext/createGetKcContext.ts +48 -22
- package/src/account/kcContext/getKcContext.ts +3 -1
- package/src/account/kcContext/getKcContextFromWindow.ts +6 -2
- package/src/account/kcContext/kcContextMocks.ts +164 -160
- package/src/account/lib/useGetClassName.ts +15 -14
- package/src/account/pages/Account.tsx +2 -2
- package/src/account/pages/Password.tsx +8 -8
- package/src/account/pages/Totp.tsx +4 -6
- package/src/bin/copy-keycloak-resources-to-public.ts +2 -2
- package/src/bin/download-keycloak-default-theme.ts +30 -8
- package/src/bin/eject-page.ts +48 -11
- package/src/bin/initialize-email-theme.ts +25 -17
- package/src/bin/keycloakify/buildJars/buildJar.ts +179 -104
- package/src/bin/keycloakify/buildJars/buildJars.ts +35 -16
- package/src/bin/keycloakify/buildJars/extensionVersions.ts +2 -1
- package/src/bin/keycloakify/buildJars/generatePom.ts +11 -3
- package/src/bin/keycloakify/buildJars/getKeycloakVersionRangeForJar.ts +33 -8
- package/src/bin/keycloakify/generateFtl/generateFtl.ts +49 -12
- package/src/bin/keycloakify/generateSrcMainResources/bringInAccountV1.ts +29 -18
- package/src/bin/keycloakify/generateSrcMainResources/generateMessageProperties.ts +35 -12
- package/src/bin/keycloakify/generateSrcMainResources/generateSrcMainResources.ts +3 -1
- package/src/bin/keycloakify/generateSrcMainResources/generateSrcMainResourcesForMainTheme.ts +86 -41
- package/src/bin/keycloakify/generateSrcMainResources/generateSrcMainResourcesForThemeVariant.ts +39 -15
- package/src/bin/keycloakify/generateSrcMainResources/readExtraPageNames.ts +21 -7
- package/src/bin/keycloakify/generateSrcMainResources/readFieldNameUsage.ts +34 -7
- package/src/bin/keycloakify/generateStartKeycloakTestingContainer.ts +19 -5
- package/src/bin/keycloakify/keycloakify.ts +28 -9
- package/src/bin/keycloakify/replacers/replaceImportsInCssCode.ts +24 -5
- package/src/bin/keycloakify/replacers/replaceImportsInInlineCssCode.ts +6 -2
- package/src/bin/keycloakify/replacers/replaceImportsInJsCode/replaceImportsInJsCode.ts +6 -3
- package/src/bin/keycloakify/replacers/replaceImportsInJsCode/vite.ts +24 -6
- package/src/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.ts +49 -11
- package/src/bin/main.ts +78 -41
- package/src/bin/shared/KeycloakVersionRange.ts +3 -1
- package/src/bin/shared/buildOptions.ts +70 -43
- package/src/bin/shared/constants.ts +4 -2
- package/src/bin/shared/copyKeycloakResourcesToPublic.ts +27 -13
- package/src/bin/shared/downloadKeycloakDefaultTheme.ts +161 -218
- package/src/bin/shared/downloadKeycloakStaticResources.ts +25 -21
- package/src/bin/shared/getJarFileBasename.ts +3 -1
- package/src/bin/shared/getThemeSrcDirPath.ts +5 -2
- package/src/bin/shared/metaInfKeycloakThemes.ts +35 -8
- package/src/bin/shared/promptKeycloakVersion.ts +33 -14
- package/src/bin/start-keycloak/index.ts +1 -0
- package/src/bin/start-keycloak/myrealm-realm-23.json +2142 -0
- package/src/bin/start-keycloak/myrealm-realm-24.json +2318 -0
- package/src/bin/start-keycloak/start-keycloak.ts +467 -0
- package/src/bin/tools/SemVer.ts +32 -13
- package/src/bin/tools/String.prototype.replaceAll.ts +9 -2
- package/src/bin/tools/crawl.ts +4 -1
- package/src/bin/tools/crc32.ts +42 -24
- package/src/bin/tools/downloadAndExtractArchive/downloadAndExtractArchive.ts +262 -0
- package/src/bin/tools/downloadAndExtractArchive/fetchProxyOptions.ts +96 -0
- package/src/bin/tools/downloadAndExtractArchive/index.ts +1 -0
- package/src/bin/tools/extractArchive.ts +120 -0
- package/src/bin/tools/fetchProxyOptions.ts +31 -8
- package/src/bin/tools/getAbsoluteAndInOsFormatPath.ts +10 -2
- package/src/bin/tools/getNpmWorkspaceRootDirPath.ts +18 -5
- package/src/bin/tools/octokit-addons/getLatestsSemVersionedTag.ts +8 -2
- package/src/bin/tools/octokit-addons/listTags.ts +15 -4
- package/src/bin/tools/partitionPromiseSettledResults.ts +12 -3
- package/src/bin/tools/readThisNpmPackageVersion.ts +5 -1
- package/src/bin/tools/transformCodebase.ts +29 -10
- package/src/bin/tools/trimIndent.ts +4 -1
- package/src/lib/isStorybook.ts +3 -1
- package/src/lib/useGetClassName.ts +12 -3
- package/src/login/Template.tsx +14 -14
- package/src/login/TemplateProps.ts +4 -1
- package/src/login/UserProfileFormFields.tsx +44 -42
- package/src/login/i18n/baseMessages/ca.ts +1 -1
- package/src/login/i18n/baseMessages/el.ts +0 -1
- package/src/login/i18n/baseMessages/en.ts +1 -1
- package/src/login/i18n/baseMessages/es.ts +1 -1
- package/src/login/i18n/baseMessages/fa.ts +0 -1
- package/src/login/i18n/baseMessages/hu.ts +1 -1
- package/src/login/i18n/baseMessages/zh-CN.ts +1 -1
- package/src/login/i18n/i18n.tsx +42 -32
- package/src/login/kcContext/KcContext.ts +8 -2
- package/src/login/kcContext/createGetKcContext.ts +84 -37
- package/src/login/kcContext/getKcContext.ts +3 -1
- package/src/login/kcContext/getKcContextFromWindow.ts +6 -2
- package/src/login/kcContext/kcContextMocks.ts +339 -325
- package/src/login/lib/useDownloadTerms.ts +6 -4
- package/src/login/lib/useGetClassName.ts +119 -112
- package/src/login/lib/useUserProfileForm.tsx +219 -205
- package/src/login/pages/DeleteAccountConfirm.tsx +9 -3
- package/src/login/pages/FrontchannelLogout.tsx +1 -1
- package/src/login/pages/Login.tsx +2 -2
- package/src/login/pages/LoginRecoveryAuthnCodeConfig.tsx +3 -3
- package/src/login/pages/LoginResetPassword.tsx +2 -2
- package/src/login/pages/LoginUsername.tsx +2 -2
- package/src/login/pages/WebauthnAuthenticate.tsx +11 -8
- package/src/login/pages/WebauthnRegister.tsx +7 -7
- package/src/tools/AndByDiscriminatingKey.ts +12 -6
- package/src/tools/Array.prototype.every.ts +4 -1
- package/src/tools/LazyOrNot.ts +3 -1
- package/src/tools/clsx.ts +7 -1
- package/src/tools/deepAssign.ts +15 -8
- package/src/tools/deepClone.ts +3 -1
- package/src/tools/formatNumber.ts +4 -1
- package/src/tools/useConstCallback.ts +3 -1
- package/src/tools/useInsertLinkTags.ts +20 -7
- package/src/tools/useInsertScriptTags.ts +7 -2
- package/src/tools/useSetClassName.ts +4 -1
- package/src/vite-plugin/vite-plugin.ts +45 -21
- package/tools/Array.prototype.every.js +2 -1
- package/tools/Array.prototype.every.js.map +1 -1
- package/tools/clsx.js.map +1 -1
- package/tools/deepAssign.js +9 -7
- package/tools/deepAssign.js.map +1 -1
- package/tools/deepClone.js.map +1 -1
- package/tools/formatNumber.js.map +1 -1
- package/tools/useConstCallback.js.map +1 -1
- package/tools/useInsertLinkTags.js +5 -4
- package/tools/useInsertLinkTags.js.map +1 -1
- package/tools/useInsertScriptTags.js +5 -2
- package/tools/useInsertScriptTags.js.map +1 -1
- package/tools/useSetClassName.js.map +1 -1
- package/vite-plugin/index.js +975 -1651
- package/src/bin/shared/downloadAndUnzip.ts +0 -203
- package/src/bin/start-keycloak.ts +0 -309
- package/src/bin/tools/unzip.ts +0 -141
package/src/bin/tools/crc32.ts
CHANGED
@@ -1,27 +1,42 @@
|
|
1
1
|
import { Readable } from "stream";
|
2
2
|
|
3
3
|
const crc32tab = [
|
4
|
-
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535,
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
4
|
+
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535,
|
5
|
+
0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd,
|
6
|
+
0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d,
|
7
|
+
0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
|
8
|
+
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
|
9
|
+
0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
10
|
+
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac,
|
11
|
+
0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
12
|
+
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab,
|
13
|
+
0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
|
14
|
+
0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb,
|
15
|
+
0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
16
|
+
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea,
|
17
|
+
0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce,
|
18
|
+
0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
|
19
|
+
0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
20
|
+
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409,
|
21
|
+
0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
22
|
+
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739,
|
23
|
+
0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
24
|
+
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268,
|
25
|
+
0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0,
|
26
|
+
0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8,
|
27
|
+
0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
28
|
+
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
|
29
|
+
0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703,
|
30
|
+
0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7,
|
31
|
+
0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
|
32
|
+
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae,
|
33
|
+
0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
34
|
+
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6,
|
35
|
+
0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
36
|
+
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d,
|
37
|
+
0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5,
|
38
|
+
0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
|
39
|
+
0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
25
40
|
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
26
41
|
];
|
27
42
|
|
@@ -33,11 +48,13 @@ const crc32tab = [
|
|
33
48
|
export function crc32(input: Readable | String | Buffer): Promise<number> {
|
34
49
|
if (typeof input === "string") {
|
35
50
|
let crc = ~0;
|
36
|
-
for (let i = 0; i < input.length; i++)
|
51
|
+
for (let i = 0; i < input.length; i++)
|
52
|
+
crc = (crc >>> 8) ^ crc32tab[(crc ^ input.charCodeAt(i)) & 0xff];
|
37
53
|
return Promise.resolve((crc ^ -1) >>> 0);
|
38
54
|
} else if (input instanceof Buffer) {
|
39
55
|
let crc = ~0;
|
40
|
-
for (let i = 0; i < input.length; i++)
|
56
|
+
for (let i = 0; i < input.length; i++)
|
57
|
+
crc = (crc >>> 8) ^ crc32tab[(crc ^ input[i]) & 0xff];
|
41
58
|
return Promise.resolve((crc ^ -1) >>> 0);
|
42
59
|
} else if (input instanceof Readable) {
|
43
60
|
return new Promise<number>((resolve, reject) => {
|
@@ -46,7 +63,8 @@ export function crc32(input: Readable | String | Buffer): Promise<number> {
|
|
46
63
|
input.on("end", () => resolve((crc ^ -1) >>> 0));
|
47
64
|
input.on("error", e => reject(e));
|
48
65
|
input.on("data", (chunk: Buffer) => {
|
49
|
-
for (let i = 0; i < chunk.length; i++)
|
66
|
+
for (let i = 0; i < chunk.length; i++)
|
67
|
+
crc = (crc >>> 8) ^ crc32tab[(crc ^ chunk[i]) & 0xff];
|
50
68
|
});
|
51
69
|
});
|
52
70
|
} else {
|
@@ -0,0 +1,262 @@
|
|
1
|
+
import fetch from "make-fetch-happen";
|
2
|
+
import { mkdir, unlink, writeFile, readdir, readFile } from "fs/promises";
|
3
|
+
import { dirname as pathDirname, join as pathJoin } from "path";
|
4
|
+
import { assert } from "tsafe/assert";
|
5
|
+
import { extractArchive } from "../extractArchive";
|
6
|
+
import { existsAsync } from "../fs.existsAsync";
|
7
|
+
import { getProxyFetchOptions } from "./fetchProxyOptions";
|
8
|
+
import * as crypto from "crypto";
|
9
|
+
import { rm } from "../fs.rm";
|
10
|
+
|
11
|
+
export async function downloadAndExtractArchive(params: {
|
12
|
+
url: string;
|
13
|
+
uniqueIdOfOnOnArchiveFile: string;
|
14
|
+
onArchiveFile: (params: {
|
15
|
+
fileRelativePath: string;
|
16
|
+
readFile: () => Promise<Buffer>;
|
17
|
+
writeFile: (params: {
|
18
|
+
fileRelativePath: string;
|
19
|
+
modifiedData?: Buffer;
|
20
|
+
}) => Promise<void>;
|
21
|
+
}) => Promise<void>;
|
22
|
+
cacheDirPath: string;
|
23
|
+
npmWorkspaceRootDirPath: string;
|
24
|
+
}): Promise<{ extractedDirPath: string }> {
|
25
|
+
const {
|
26
|
+
url,
|
27
|
+
uniqueIdOfOnOnArchiveFile,
|
28
|
+
onArchiveFile,
|
29
|
+
cacheDirPath,
|
30
|
+
npmWorkspaceRootDirPath
|
31
|
+
} = params;
|
32
|
+
|
33
|
+
const archiveFileBasename = url.split("?")[0].split("/").reverse()[0];
|
34
|
+
|
35
|
+
const archiveFilePath = pathJoin(cacheDirPath, archiveFileBasename);
|
36
|
+
|
37
|
+
download: {
|
38
|
+
if (await existsAsync(archiveFilePath)) {
|
39
|
+
const isDownloaded = await SuccessTracker.getIsDownloaded({
|
40
|
+
cacheDirPath,
|
41
|
+
archiveFileBasename
|
42
|
+
});
|
43
|
+
|
44
|
+
if (isDownloaded) {
|
45
|
+
break download;
|
46
|
+
}
|
47
|
+
|
48
|
+
await unlink(archiveFilePath);
|
49
|
+
|
50
|
+
await SuccessTracker.removeFromDownloaded({
|
51
|
+
cacheDirPath,
|
52
|
+
archiveFileBasename
|
53
|
+
});
|
54
|
+
}
|
55
|
+
|
56
|
+
await mkdir(pathDirname(archiveFilePath), { recursive: true });
|
57
|
+
|
58
|
+
const response = await fetch(
|
59
|
+
url,
|
60
|
+
await getProxyFetchOptions({ npmWorkspaceRootDirPath })
|
61
|
+
);
|
62
|
+
|
63
|
+
response.body?.setMaxListeners(Number.MAX_VALUE);
|
64
|
+
assert(typeof response.body !== "undefined" && response.body != null);
|
65
|
+
|
66
|
+
await writeFile(archiveFilePath, response.body);
|
67
|
+
|
68
|
+
await SuccessTracker.markAsDownloaded({
|
69
|
+
cacheDirPath,
|
70
|
+
archiveFileBasename
|
71
|
+
});
|
72
|
+
}
|
73
|
+
|
74
|
+
const extractDirBasename = `${archiveFileBasename.split(".")[0]}_${uniqueIdOfOnOnArchiveFile}_${crypto
|
75
|
+
.createHash("sha256")
|
76
|
+
.update(onArchiveFile.toString())
|
77
|
+
.digest("hex")
|
78
|
+
.substring(0, 5)}`;
|
79
|
+
|
80
|
+
await Promise.all(
|
81
|
+
(await readdir(cacheDirPath))
|
82
|
+
.filter(
|
83
|
+
(() => {
|
84
|
+
const prefix = extractDirBasename
|
85
|
+
.split("_")
|
86
|
+
.reverse()
|
87
|
+
.slice(1)
|
88
|
+
.reverse()
|
89
|
+
.join("_");
|
90
|
+
|
91
|
+
return basename =>
|
92
|
+
basename !== extractDirBasename && basename.startsWith(prefix);
|
93
|
+
})()
|
94
|
+
)
|
95
|
+
.map(async extractDirBasename => {
|
96
|
+
await rm(pathJoin(cacheDirPath, extractDirBasename), { recursive: true });
|
97
|
+
await SuccessTracker.removeFromExtracted({
|
98
|
+
cacheDirPath,
|
99
|
+
extractDirBasename
|
100
|
+
});
|
101
|
+
})
|
102
|
+
);
|
103
|
+
|
104
|
+
const extractedDirPath = pathJoin(cacheDirPath, extractDirBasename);
|
105
|
+
|
106
|
+
extract_and_transform: {
|
107
|
+
if (await existsAsync(extractedDirPath)) {
|
108
|
+
const isExtracted = await SuccessTracker.getIsExtracted({
|
109
|
+
cacheDirPath,
|
110
|
+
extractDirBasename
|
111
|
+
});
|
112
|
+
|
113
|
+
if (isExtracted) {
|
114
|
+
break extract_and_transform;
|
115
|
+
}
|
116
|
+
|
117
|
+
await rm(extractedDirPath, { recursive: true });
|
118
|
+
|
119
|
+
await SuccessTracker.removeFromExtracted({
|
120
|
+
cacheDirPath,
|
121
|
+
extractDirBasename
|
122
|
+
});
|
123
|
+
}
|
124
|
+
|
125
|
+
await extractArchive({
|
126
|
+
archiveFilePath,
|
127
|
+
onArchiveFile: async ({ relativeFilePathInArchive, readFile, writeFile }) =>
|
128
|
+
onArchiveFile({
|
129
|
+
fileRelativePath: relativeFilePathInArchive,
|
130
|
+
readFile,
|
131
|
+
writeFile: ({ fileRelativePath, modifiedData }) =>
|
132
|
+
writeFile({
|
133
|
+
filePath: pathJoin(extractedDirPath, fileRelativePath),
|
134
|
+
modifiedData
|
135
|
+
})
|
136
|
+
})
|
137
|
+
});
|
138
|
+
|
139
|
+
await SuccessTracker.markAsExtracted({
|
140
|
+
cacheDirPath,
|
141
|
+
extractDirBasename
|
142
|
+
});
|
143
|
+
}
|
144
|
+
|
145
|
+
return { extractedDirPath };
|
146
|
+
}
|
147
|
+
|
148
|
+
type SuccessTracker = {
|
149
|
+
archiveFileBasenames: string[];
|
150
|
+
extractDirBasenames: string[];
|
151
|
+
};
|
152
|
+
|
153
|
+
namespace SuccessTracker {
|
154
|
+
async function read(params: { cacheDirPath: string }): Promise<SuccessTracker> {
|
155
|
+
const { cacheDirPath } = params;
|
156
|
+
|
157
|
+
const filePath = pathJoin(cacheDirPath, "downloadAndExtractArchive.json");
|
158
|
+
|
159
|
+
if (!(await existsAsync(filePath))) {
|
160
|
+
return { archiveFileBasenames: [], extractDirBasenames: [] };
|
161
|
+
}
|
162
|
+
|
163
|
+
return JSON.parse((await readFile(filePath)).toString("utf8"));
|
164
|
+
}
|
165
|
+
|
166
|
+
async function write(params: {
|
167
|
+
cacheDirPath: string;
|
168
|
+
successTracker: SuccessTracker;
|
169
|
+
}) {
|
170
|
+
const { cacheDirPath, successTracker } = params;
|
171
|
+
|
172
|
+
const filePath = pathJoin(cacheDirPath, "downloadAndExtractArchive.json");
|
173
|
+
|
174
|
+
{
|
175
|
+
const dirPath = pathDirname(filePath);
|
176
|
+
|
177
|
+
if (!(await existsAsync(dirPath))) {
|
178
|
+
await mkdir(dirPath, { recursive: true });
|
179
|
+
}
|
180
|
+
}
|
181
|
+
|
182
|
+
await writeFile(filePath, JSON.stringify(successTracker));
|
183
|
+
}
|
184
|
+
|
185
|
+
export async function markAsDownloaded(params: {
|
186
|
+
cacheDirPath: string;
|
187
|
+
archiveFileBasename: string;
|
188
|
+
}) {
|
189
|
+
const { cacheDirPath, archiveFileBasename } = params;
|
190
|
+
|
191
|
+
const successTracker = await read({ cacheDirPath });
|
192
|
+
|
193
|
+
successTracker.archiveFileBasenames.push(archiveFileBasename);
|
194
|
+
|
195
|
+
await write({ cacheDirPath, successTracker });
|
196
|
+
}
|
197
|
+
|
198
|
+
export async function getIsDownloaded(params: {
|
199
|
+
cacheDirPath: string;
|
200
|
+
archiveFileBasename: string;
|
201
|
+
}): Promise<boolean> {
|
202
|
+
const { cacheDirPath, archiveFileBasename } = params;
|
203
|
+
|
204
|
+
const successTracker = await read({ cacheDirPath });
|
205
|
+
|
206
|
+
return successTracker.archiveFileBasenames.includes(archiveFileBasename);
|
207
|
+
}
|
208
|
+
|
209
|
+
export async function removeFromDownloaded(params: {
|
210
|
+
cacheDirPath: string;
|
211
|
+
archiveFileBasename: string;
|
212
|
+
}) {
|
213
|
+
const { cacheDirPath, archiveFileBasename } = params;
|
214
|
+
|
215
|
+
const successTracker = await read({ cacheDirPath });
|
216
|
+
|
217
|
+
successTracker.archiveFileBasenames = successTracker.archiveFileBasenames.filter(
|
218
|
+
basename => basename !== archiveFileBasename
|
219
|
+
);
|
220
|
+
|
221
|
+
await write({ cacheDirPath, successTracker });
|
222
|
+
}
|
223
|
+
|
224
|
+
export async function markAsExtracted(params: {
|
225
|
+
cacheDirPath: string;
|
226
|
+
extractDirBasename: string;
|
227
|
+
}) {
|
228
|
+
const { cacheDirPath, extractDirBasename } = params;
|
229
|
+
|
230
|
+
const successTracker = await read({ cacheDirPath });
|
231
|
+
|
232
|
+
successTracker.extractDirBasenames.push(extractDirBasename);
|
233
|
+
|
234
|
+
await write({ cacheDirPath, successTracker });
|
235
|
+
}
|
236
|
+
|
237
|
+
export async function getIsExtracted(params: {
|
238
|
+
cacheDirPath: string;
|
239
|
+
extractDirBasename: string;
|
240
|
+
}): Promise<boolean> {
|
241
|
+
const { cacheDirPath, extractDirBasename } = params;
|
242
|
+
|
243
|
+
const successTracker = await read({ cacheDirPath });
|
244
|
+
|
245
|
+
return successTracker.extractDirBasenames.includes(extractDirBasename);
|
246
|
+
}
|
247
|
+
|
248
|
+
export async function removeFromExtracted(params: {
|
249
|
+
cacheDirPath: string;
|
250
|
+
extractDirBasename: string;
|
251
|
+
}) {
|
252
|
+
const { cacheDirPath, extractDirBasename } = params;
|
253
|
+
|
254
|
+
const successTracker = await read({ cacheDirPath });
|
255
|
+
|
256
|
+
successTracker.extractDirBasenames = successTracker.extractDirBasenames.filter(
|
257
|
+
basename => basename !== extractDirBasename
|
258
|
+
);
|
259
|
+
|
260
|
+
await write({ cacheDirPath, successTracker });
|
261
|
+
}
|
262
|
+
}
|
@@ -0,0 +1,96 @@
|
|
1
|
+
import { exec as execCallback } from "child_process";
|
2
|
+
import { readFile } from "fs/promises";
|
3
|
+
import { type FetchOptions } from "make-fetch-happen";
|
4
|
+
import { promisify } from "util";
|
5
|
+
|
6
|
+
function ensureArray<T>(arg0: T | T[]) {
|
7
|
+
return Array.isArray(arg0) ? arg0 : typeof arg0 === "undefined" ? [] : [arg0];
|
8
|
+
}
|
9
|
+
|
10
|
+
function ensureSingleOrNone<T>(arg0: T | T[]) {
|
11
|
+
if (!Array.isArray(arg0)) return arg0;
|
12
|
+
if (arg0.length === 0) return undefined;
|
13
|
+
if (arg0.length === 1) return arg0[0];
|
14
|
+
throw new Error(
|
15
|
+
"Illegal configuration, expected a single value but found multiple: " +
|
16
|
+
arg0.map(String).join(", ")
|
17
|
+
);
|
18
|
+
}
|
19
|
+
|
20
|
+
type NPMConfig = Record<string, string | string[]>;
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Get npm configuration as map
|
24
|
+
*/
|
25
|
+
async function getNmpConfig(params: { npmWorkspaceRootDirPath: string }) {
|
26
|
+
const { npmWorkspaceRootDirPath } = params;
|
27
|
+
|
28
|
+
const exec = promisify(execCallback);
|
29
|
+
|
30
|
+
const stdout = await exec("npm config get", {
|
31
|
+
encoding: "utf8",
|
32
|
+
cwd: npmWorkspaceRootDirPath
|
33
|
+
}).then(({ stdout }) => stdout);
|
34
|
+
|
35
|
+
const npmConfigReducer = (cfg: NPMConfig, [key, value]: [string, string]) =>
|
36
|
+
key in cfg
|
37
|
+
? { ...cfg, [key]: [...ensureArray(cfg[key]), value] }
|
38
|
+
: { ...cfg, [key]: value };
|
39
|
+
|
40
|
+
return stdout
|
41
|
+
.split("\n")
|
42
|
+
.filter(line => !line.startsWith(";"))
|
43
|
+
.map(line => line.trim())
|
44
|
+
.map(line => line.split("=", 2) as [string, string])
|
45
|
+
.reduce(npmConfigReducer, {} as NPMConfig);
|
46
|
+
}
|
47
|
+
|
48
|
+
export type ProxyFetchOptions = Pick<
|
49
|
+
FetchOptions,
|
50
|
+
"proxy" | "noProxy" | "strictSSL" | "cert" | "ca"
|
51
|
+
>;
|
52
|
+
|
53
|
+
export async function getProxyFetchOptions(params: {
|
54
|
+
npmWorkspaceRootDirPath: string;
|
55
|
+
}): Promise<ProxyFetchOptions> {
|
56
|
+
const { npmWorkspaceRootDirPath } = params;
|
57
|
+
|
58
|
+
const cfg = await getNmpConfig({ npmWorkspaceRootDirPath });
|
59
|
+
|
60
|
+
const proxy = ensureSingleOrNone(cfg["https-proxy"] ?? cfg["proxy"]);
|
61
|
+
const noProxy = cfg["noproxy"] ?? cfg["no-proxy"];
|
62
|
+
|
63
|
+
function maybeBoolean(arg0: string | undefined) {
|
64
|
+
return typeof arg0 === "undefined" ? undefined : Boolean(arg0);
|
65
|
+
}
|
66
|
+
|
67
|
+
const strictSSL = maybeBoolean(ensureSingleOrNone(cfg["strict-ssl"]));
|
68
|
+
const cert = cfg["cert"];
|
69
|
+
const ca = ensureArray(cfg["ca"] ?? cfg["ca[]"]);
|
70
|
+
const cafile = ensureSingleOrNone(cfg["cafile"]);
|
71
|
+
|
72
|
+
if (typeof cafile !== "undefined" && cafile !== "null") {
|
73
|
+
ca.push(
|
74
|
+
...(await (async () => {
|
75
|
+
function chunks<T>(arr: T[], size: number = 2) {
|
76
|
+
return arr
|
77
|
+
.map((_, i) => i % size == 0 && arr.slice(i, i + size))
|
78
|
+
.filter(Boolean) as T[][];
|
79
|
+
}
|
80
|
+
|
81
|
+
const cafileContent = await readFile(cafile, "utf-8");
|
82
|
+
return chunks(cafileContent.split(/(-----END CERTIFICATE-----)/), 2).map(
|
83
|
+
ca => ca.join("").replace(/^\n/, "").replace(/\n/g, "\\n")
|
84
|
+
);
|
85
|
+
})())
|
86
|
+
);
|
87
|
+
}
|
88
|
+
|
89
|
+
return {
|
90
|
+
proxy,
|
91
|
+
noProxy,
|
92
|
+
strictSSL,
|
93
|
+
cert,
|
94
|
+
ca: ca.length === 0 ? undefined : ca
|
95
|
+
};
|
96
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from "./downloadAndExtractArchive";
|
@@ -0,0 +1,120 @@
|
|
1
|
+
import fs from "fs/promises";
|
2
|
+
import fsSync from "fs";
|
3
|
+
import yauzl from "yauzl";
|
4
|
+
import stream from "stream";
|
5
|
+
import { Deferred } from "evt/tools/Deferred";
|
6
|
+
import { dirname as pathDirname, sep as pathSep } from "path";
|
7
|
+
|
8
|
+
export async function extractArchive(params: {
|
9
|
+
archiveFilePath: string;
|
10
|
+
onArchiveFile: (params: {
|
11
|
+
relativeFilePathInArchive: string;
|
12
|
+
readFile: () => Promise<Buffer>;
|
13
|
+
writeFile: (params: { filePath: string; modifiedData?: Buffer }) => Promise<void>;
|
14
|
+
}) => Promise<void>;
|
15
|
+
}) {
|
16
|
+
const { archiveFilePath, onArchiveFile } = params;
|
17
|
+
|
18
|
+
const zipFile = await new Promise<yauzl.ZipFile>((resolve, reject) => {
|
19
|
+
yauzl.open(archiveFilePath, { lazyEntries: true }, async (error, zipFile) => {
|
20
|
+
if (error) {
|
21
|
+
reject(error);
|
22
|
+
return;
|
23
|
+
}
|
24
|
+
resolve(zipFile);
|
25
|
+
});
|
26
|
+
});
|
27
|
+
|
28
|
+
const dDone = new Deferred<void>();
|
29
|
+
|
30
|
+
zipFile.once("end", () => {
|
31
|
+
zipFile.close();
|
32
|
+
dDone.resolve();
|
33
|
+
});
|
34
|
+
|
35
|
+
const writeFile = async (
|
36
|
+
entry: yauzl.Entry,
|
37
|
+
params: {
|
38
|
+
filePath: string;
|
39
|
+
modifiedData?: Buffer;
|
40
|
+
}
|
41
|
+
): Promise<void> => {
|
42
|
+
const { filePath, modifiedData } = params;
|
43
|
+
|
44
|
+
await fs.mkdir(pathDirname(filePath), { recursive: true });
|
45
|
+
|
46
|
+
if (modifiedData !== undefined) {
|
47
|
+
await fs.writeFile(filePath, modifiedData);
|
48
|
+
return;
|
49
|
+
}
|
50
|
+
|
51
|
+
const readStream = await new Promise<stream.Readable>(resolve =>
|
52
|
+
zipFile.openReadStream(entry, async (error, readStream) => {
|
53
|
+
if (error) {
|
54
|
+
dDone.reject(error);
|
55
|
+
return;
|
56
|
+
}
|
57
|
+
|
58
|
+
resolve(readStream);
|
59
|
+
})
|
60
|
+
);
|
61
|
+
|
62
|
+
const dDoneWithFile = new Deferred<void>();
|
63
|
+
|
64
|
+
stream.pipeline(readStream, fsSync.createWriteStream(filePath), error => {
|
65
|
+
if (error) {
|
66
|
+
dDone.reject(error);
|
67
|
+
return;
|
68
|
+
}
|
69
|
+
|
70
|
+
dDoneWithFile.resolve();
|
71
|
+
});
|
72
|
+
|
73
|
+
await dDoneWithFile.pr;
|
74
|
+
};
|
75
|
+
|
76
|
+
const readFile = (entry: yauzl.Entry) =>
|
77
|
+
new Promise<Buffer>(resolve =>
|
78
|
+
zipFile.openReadStream(entry, async (error, readStream) => {
|
79
|
+
if (error) {
|
80
|
+
dDone.reject(error);
|
81
|
+
return;
|
82
|
+
}
|
83
|
+
|
84
|
+
const chunks: Buffer[] = [];
|
85
|
+
|
86
|
+
readStream.on("data", chunk => {
|
87
|
+
chunks.push(chunk);
|
88
|
+
});
|
89
|
+
|
90
|
+
readStream.on("end", () => {
|
91
|
+
resolve(Buffer.concat(chunks));
|
92
|
+
});
|
93
|
+
|
94
|
+
readStream.on("error", error => {
|
95
|
+
dDone.reject(error);
|
96
|
+
});
|
97
|
+
})
|
98
|
+
);
|
99
|
+
|
100
|
+
zipFile.on("entry", async (entry: yauzl.Entry) => {
|
101
|
+
handle_file: {
|
102
|
+
// NOTE: Skip directories
|
103
|
+
if (entry.fileName.endsWith(pathSep)) {
|
104
|
+
break handle_file;
|
105
|
+
}
|
106
|
+
|
107
|
+
await onArchiveFile({
|
108
|
+
relativeFilePathInArchive: entry.fileName.split("/").join(pathSep),
|
109
|
+
readFile: () => readFile(entry),
|
110
|
+
writeFile: params => writeFile(entry, params)
|
111
|
+
});
|
112
|
+
}
|
113
|
+
|
114
|
+
zipFile.readEntry();
|
115
|
+
});
|
116
|
+
|
117
|
+
zipFile.readEntry();
|
118
|
+
|
119
|
+
await dDone.pr;
|
120
|
+
}
|
@@ -11,7 +11,10 @@ function ensureSingleOrNone<T>(arg0: T | T[]) {
|
|
11
11
|
if (!Array.isArray(arg0)) return arg0;
|
12
12
|
if (arg0.length === 0) return undefined;
|
13
13
|
if (arg0.length === 1) return arg0[0];
|
14
|
-
throw new Error(
|
14
|
+
throw new Error(
|
15
|
+
"Illegal configuration, expected a single value but found multiple: " +
|
16
|
+
arg0.map(String).join(", ")
|
17
|
+
);
|
15
18
|
}
|
16
19
|
|
17
20
|
type NPMConfig = Record<string, string | string[]>;
|
@@ -24,10 +27,15 @@ async function getNmpConfig(params: { npmWorkspaceRootDirPath: string }) {
|
|
24
27
|
|
25
28
|
const exec = promisify(execCallback);
|
26
29
|
|
27
|
-
const stdout = await exec("npm config get", {
|
30
|
+
const stdout = await exec("npm config get", {
|
31
|
+
encoding: "utf8",
|
32
|
+
cwd: npmWorkspaceRootDirPath
|
33
|
+
}).then(({ stdout }) => stdout);
|
28
34
|
|
29
35
|
const npmConfigReducer = (cfg: NPMConfig, [key, value]: [string, string]) =>
|
30
|
-
key in cfg
|
36
|
+
key in cfg
|
37
|
+
? { ...cfg, [key]: [...ensureArray(cfg[key]), value] }
|
38
|
+
: { ...cfg, [key]: value };
|
31
39
|
|
32
40
|
return stdout
|
33
41
|
.split("\n")
|
@@ -37,9 +45,14 @@ async function getNmpConfig(params: { npmWorkspaceRootDirPath: string }) {
|
|
37
45
|
.reduce(npmConfigReducer, {} as NPMConfig);
|
38
46
|
}
|
39
47
|
|
40
|
-
export type ProxyFetchOptions = Pick<
|
48
|
+
export type ProxyFetchOptions = Pick<
|
49
|
+
FetchOptions,
|
50
|
+
"proxy" | "noProxy" | "strictSSL" | "cert" | "ca"
|
51
|
+
>;
|
41
52
|
|
42
|
-
export async function getProxyFetchOptions(params: {
|
53
|
+
export async function getProxyFetchOptions(params: {
|
54
|
+
npmWorkspaceRootDirPath: string;
|
55
|
+
}): Promise<ProxyFetchOptions> {
|
43
56
|
const { npmWorkspaceRootDirPath } = params;
|
44
57
|
|
45
58
|
const cfg = await getNmpConfig({ npmWorkspaceRootDirPath });
|
@@ -60,14 +73,24 @@ export async function getProxyFetchOptions(params: { npmWorkspaceRootDirPath: st
|
|
60
73
|
ca.push(
|
61
74
|
...(await (async () => {
|
62
75
|
function chunks<T>(arr: T[], size: number = 2) {
|
63
|
-
return arr
|
76
|
+
return arr
|
77
|
+
.map((_, i) => i % size == 0 && arr.slice(i, i + size))
|
78
|
+
.filter(Boolean) as T[][];
|
64
79
|
}
|
65
80
|
|
66
81
|
const cafileContent = await readFile(cafile, "utf-8");
|
67
|
-
return chunks(cafileContent.split(/(-----END CERTIFICATE-----)/), 2).map(
|
82
|
+
return chunks(cafileContent.split(/(-----END CERTIFICATE-----)/), 2).map(
|
83
|
+
ca => ca.join("").replace(/^\n/, "").replace(/\n/g, "\\n")
|
84
|
+
);
|
68
85
|
})())
|
69
86
|
);
|
70
87
|
}
|
71
88
|
|
72
|
-
return {
|
89
|
+
return {
|
90
|
+
proxy,
|
91
|
+
noProxy,
|
92
|
+
strictSSL,
|
93
|
+
cert,
|
94
|
+
ca: ca.length === 0 ? undefined : ca
|
95
|
+
};
|
73
96
|
}
|
@@ -1,7 +1,15 @@
|
|
1
|
-
import {
|
1
|
+
import {
|
2
|
+
isAbsolute as pathIsAbsolute,
|
3
|
+
sep as pathSep,
|
4
|
+
join as pathJoin,
|
5
|
+
resolve as pathResolve
|
6
|
+
} from "path";
|
2
7
|
import * as os from "os";
|
3
8
|
|
4
|
-
export function getAbsoluteAndInOsFormatPath(params: {
|
9
|
+
export function getAbsoluteAndInOsFormatPath(params: {
|
10
|
+
pathIsh: string;
|
11
|
+
cwd: string;
|
12
|
+
}): string {
|
5
13
|
const { pathIsh, cwd } = params;
|
6
14
|
|
7
15
|
let pathOut = pathIsh;
|