keycloakify 11.8.46 → 11.8.47-rc.2

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.
Files changed (43) hide show
  1. package/bin/254.index.js +283 -0
  2. package/bin/30.index.js +25 -0
  3. package/bin/{864.index.js → 309.index.js} +6944 -28439
  4. package/bin/311.index.js +198 -0
  5. package/bin/{313.index.js → 355.index.js} +148 -172
  6. package/bin/{84.index.js → 502.index.js} +151 -103
  7. package/bin/626.index.js +216 -0
  8. package/bin/656.index.js +274 -0
  9. package/bin/675.index.js +177 -0
  10. package/bin/69.index.js +1 -1
  11. package/bin/762.index.js +1475 -0
  12. package/bin/780.index.js +4 -2
  13. package/bin/786.index.js +115 -0
  14. package/bin/895.index.js +21501 -0
  15. package/bin/{618.index.js → 932.index.js} +117 -163
  16. package/bin/949.index.js +1 -1
  17. package/bin/97.index.js +539 -4
  18. package/bin/init/index.d.ts +1 -0
  19. package/bin/init/init.d.ts +3 -0
  20. package/bin/init/setupEslint.d.ts +4 -0
  21. package/bin/init/setupVitePluginIfNeeded.d.ts +4 -0
  22. package/bin/initialize-login-theme.d.ts +4 -0
  23. package/bin/main.js +42 -49
  24. package/bin/shared/customHandler.d.ts +1 -1
  25. package/bin/shared/customHandler.js.map +1 -1
  26. package/package.json +23 -7
  27. package/src/bin/init/index.ts +1 -0
  28. package/src/bin/init/init.ts +354 -0
  29. package/src/bin/init/setupEslint.ts +80 -0
  30. package/src/bin/init/setupVitePluginIfNeeded.ts +143 -0
  31. package/src/bin/initialize-account-theme/initialize-account-theme.ts +4 -0
  32. package/src/bin/initialize-login-theme.ts +323 -0
  33. package/src/bin/main.ts +14 -0
  34. package/src/bin/shared/buildContext.ts +28 -59
  35. package/src/bin/shared/customHandler.ts +3 -1
  36. package/src/bin/shared/initializeSpa.ts +28 -0
  37. package/src/bin/sync-extensions/extensionModuleMeta.ts +89 -73
  38. package/src/bin/sync-extensions/managedGitignoreFiles.ts +32 -2
  39. package/src/bin/tools/fetchProxyOptions.ts +2 -1
  40. package/src/bin/tools/npmInstall.ts +13 -6
  41. package/vite-plugin/index.js +24 -43
  42. package/bin/433.index.js +0 -140
  43. package/bin/698.index.js +0 -298
@@ -2,7 +2,6 @@ import { parse as urlParse } from "url";
2
2
  import {
3
3
  join as pathJoin,
4
4
  sep as pathSep,
5
- relative as pathRelative,
6
5
  resolve as pathResolve,
7
6
  dirname as pathDirname
8
7
  } from "path";
@@ -13,8 +12,7 @@ import { assert, type Equals, is } from "tsafe/assert";
13
12
  import * as child_process from "child_process";
14
13
  import {
15
14
  VITE_PLUGIN_SUB_SCRIPTS_ENV_NAMES,
16
- BUILD_FOR_KEYCLOAK_MAJOR_VERSION_ENV_NAME,
17
- THEME_TYPES
15
+ BUILD_FOR_KEYCLOAK_MAJOR_VERSION_ENV_NAME
18
16
  } from "./constants";
19
17
  import type { KeycloakVersionRange } from "./KeycloakVersionRange";
20
18
  import { exclude } from "tsafe";
@@ -167,40 +165,7 @@ export function getBuildContext(params: {
167
165
  return { themeSrcDirPath };
168
166
  }
169
167
 
170
- {
171
- const basenames = fs.readdirSync(srcDirPath);
172
-
173
- for (const basename of basenames) {
174
- const path = pathJoin(srcDirPath, basename);
175
-
176
- if (!fs.statSync(path).isFile()) {
177
- continue;
178
- }
179
-
180
- if (fs.readFileSync(path).toString("utf8").includes("./kc.gen")) {
181
- return { themeSrcDirPath: srcDirPath };
182
- }
183
- }
184
- }
185
-
186
- for (const themeType of [...THEME_TYPES, "email"]) {
187
- if (!fs.existsSync(pathJoin(srcDirPath, themeType))) {
188
- continue;
189
- }
190
- return { themeSrcDirPath: srcDirPath };
191
- }
192
-
193
- console.log(
194
- chalk.red(
195
- [
196
- `Can't locate your Keycloak theme source directory in .${pathSep}${pathRelative(process.cwd(), srcDirPath)}`,
197
- `Make sure to either use the Keycloakify CLI in the root of your Keycloakify project or use the --project CLI option`,
198
- `If you are collocating your Keycloak theme with your app you must have a directory named '${KEYCLOAK_THEME}' or '${KEYCLOAK_THEME.replace(/-/g, "_")}' in your 'src' directory`
199
- ].join("\n")
200
- )
201
- );
202
-
203
- process.exit(1);
168
+ return { themeSrcDirPath: srcDirPath };
204
169
  })();
205
170
 
206
171
  const { resolvedViteConfig } = (() => {
@@ -216,6 +181,7 @@ export function getBuildContext(params: {
216
181
  const output = child_process
217
182
  .execSync("npx vite", {
218
183
  cwd: projectDirPath,
184
+ stdio: ["pipe", "pipe", "ignore"],
219
185
  env: {
220
186
  ...process.env,
221
187
  [VITE_PLUGIN_SUB_SCRIPTS_ENV_NAMES.RESOLVE_VITE_CONFIG]: "true"
@@ -770,33 +736,36 @@ export function getBuildContext(params: {
770
736
  environmentVariables: buildOptions.environmentVariables ?? [],
771
737
  implementedThemeTypes,
772
738
  themeSrcDirPath,
773
- fetchOptions: getProxyFetchOptions({
774
- npmConfigGetCwd: (function callee(upCount: number): string {
775
- const dirPath = pathResolve(
776
- pathJoin(...[projectDirPath, ...Array(upCount).fill("..")])
777
- );
739
+ get fetchOptions() {
740
+ return getProxyFetchOptions({
741
+ npmConfigGetCwd: (function callee(upCount: number): string {
742
+ const dirPath = pathResolve(
743
+ pathJoin(...[projectDirPath, ...Array(upCount).fill("..")])
744
+ );
778
745
 
779
- assert(
780
- dirPath !== pathSep,
781
- "Couldn't find a place to run 'npm config get'"
782
- );
746
+ assert(
747
+ dirPath !== pathSep,
748
+ "Couldn't find a place to run 'npm config get'"
749
+ );
783
750
 
784
- try {
785
- child_process.execSync("npm config get", {
786
- cwd: dirPath,
787
- stdio: "pipe"
788
- });
789
- } catch (error) {
790
- if (String(error).includes("ENOWORKSPACES")) {
791
- return callee(upCount + 1);
751
+ try {
752
+ child_process.execSync("npm config get", {
753
+ cwd: dirPath,
754
+ stdio: "pipe"
755
+ });
756
+ } catch (error) {
757
+ if (String(error).includes("ENOWORKSPACES")) {
758
+ return callee(upCount + 1);
759
+ }
760
+
761
+ throw error;
792
762
  }
793
763
 
794
- throw error;
795
- }
764
+ return dirPath;
765
+ })(0)
766
+ });
767
+ },
796
768
 
797
- return dirPath;
798
- })(0)
799
- }),
800
769
  jarTargets: (() => {
801
770
  const getDefaultJarFileBasename = (range: string) =>
802
771
  `keycloak-theme-for-kc-${range}.jar`;
@@ -10,11 +10,13 @@ export type CommandName =
10
10
  | "update-kc-gen"
11
11
  | "eject-page"
12
12
  | "add-story"
13
+ | "initialize-login-theme"
13
14
  | "initialize-account-theme"
14
15
  | "initialize-admin-theme"
15
16
  | "initialize-admin-theme"
16
17
  | "initialize-email-theme"
17
- | "copy-keycloak-resources-to-public";
18
+ | "copy-keycloak-resources-to-public"
19
+ | "init";
18
20
 
19
21
  export type ApiVersion = "v1";
20
22
 
@@ -1,6 +1,7 @@
1
1
  import { dirname as pathDirname, join as pathJoin, relative as pathRelative } from "path";
2
2
  import type { BuildContext } from "./buildContext";
3
3
  import * as fs from "fs";
4
+ import * as fsPr from "fs/promises";
4
5
  import { assert, is, type Equals } from "tsafe/assert";
5
6
  import { id } from "tsafe/id";
6
7
  import {
@@ -12,6 +13,7 @@ import { npmInstall } from "../tools/npmInstall";
12
13
  import * as child_process from "child_process";
13
14
  import { z } from "zod";
14
15
  import chalk from "chalk";
16
+ import { existsAsync } from "../tools/fs.existsAsync";
15
17
 
16
18
  export type BuildContextLike = BuildContextLike_addSyncExtensionsToPostinstallScript & {
17
19
  themeSrcDirPath: string;
@@ -82,6 +84,10 @@ export async function initializeSpa(params: {
82
84
  buildContext
83
85
  });
84
86
 
87
+ await disableVerbatimModuleSyntax({
88
+ projectDirPath: buildContext.projectDirPath
89
+ });
90
+
85
91
  const uiSharedMajor = (() => {
86
92
  const dependencies = {
87
93
  ...parsedPackageJson.devDependencies,
@@ -154,3 +160,25 @@ export async function initializeSpa(params: {
154
160
  packageJsonDirPath: pathDirname(buildContext.packageJsonFilePath)
155
161
  });
156
162
  }
163
+
164
+ async function disableVerbatimModuleSyntax(params: { projectDirPath: string }) {
165
+ const { projectDirPath } = params;
166
+
167
+ const filePath = pathJoin(projectDirPath, "tsconfig.app.json");
168
+
169
+ if (!(await existsAsync(filePath))) {
170
+ return;
171
+ }
172
+
173
+ let content = (await fsPr.readFile(filePath)).toString("utf8");
174
+
175
+ const regExp = /"verbatimModuleSyntax"\s*:\s*true\s*(,?)/m;
176
+
177
+ if (!regExp.test(content)) {
178
+ return;
179
+ }
180
+
181
+ content = content.replace(regExp, `"verbatimModuleSyntax": false$1`);
182
+
183
+ await fsPr.writeFile(filePath, Buffer.from(content, "utf8"));
184
+ }
@@ -206,92 +206,108 @@ export async function getExtensionModuleMetas(params: {
206
206
  })();
207
207
 
208
208
  const extensionModuleMetas = await Promise.all(
209
- installedExtensionModules.map(
210
- async ({
211
- moduleName,
212
- version,
213
- peerDependencies,
214
- dirPath
215
- }): Promise<ExtensionModuleMeta> => {
216
- use_cache: {
217
- const extensionModuleMeta_cache =
218
- extensionModuleMetas_cacheUpToDate.find(
219
- extensionModuleMeta =>
220
- extensionModuleMeta.moduleName === moduleName
221
- );
222
-
223
- if (extensionModuleMeta_cache === undefined) {
224
- break use_cache;
225
- }
226
-
227
- return extensionModuleMeta_cache;
228
- }
209
+ [...installedExtensionModules]
210
+ .sort((a, b) => a.moduleName.localeCompare(b.moduleName))
211
+ .map(
212
+ async ({
213
+ moduleName,
214
+ version,
215
+ peerDependencies,
216
+ dirPath
217
+ }): Promise<ExtensionModuleMeta> => {
218
+ use_cache: {
219
+ const extensionModuleMeta_cache =
220
+ extensionModuleMetas_cacheUpToDate.find(
221
+ extensionModuleMeta =>
222
+ extensionModuleMeta.moduleName === moduleName
223
+ );
224
+
225
+ if (extensionModuleMeta_cache === undefined) {
226
+ break use_cache;
227
+ }
229
228
 
230
- const files: ExtensionModuleMeta["files"] = [];
229
+ return extensionModuleMeta_cache;
230
+ }
231
231
 
232
- await crawlAsync({
233
- dirPath: pathJoin(dirPath, KEYCLOAK_THEME),
234
- returnedPathsType: "relative to dirPath",
235
- onFileFound: async fileRelativePath_fromReservedDir => {
236
- const isPublic = fileRelativePath_fromReservedDir.startsWith(
237
- `public${pathSep}`
238
- );
232
+ const files: ExtensionModuleMeta["files"] = [];
233
+
234
+ await crawlAsync({
235
+ dirPath: pathJoin(dirPath, KEYCLOAK_THEME),
236
+ returnedPathsType: "relative to dirPath",
237
+ onFileFound: async fileRelativePath_fromReservedDir => {
238
+ const isPublic = fileRelativePath_fromReservedDir.startsWith(
239
+ `public${pathSep}`
240
+ );
241
+
242
+ const fileRelativePath = isPublic
243
+ ? pathRelative("public", fileRelativePath_fromReservedDir)
244
+ : fileRelativePath_fromReservedDir;
245
+
246
+ const sourceCode =
247
+ await getExtensionModuleFileSourceCodeReadyToBeCopied({
248
+ buildContext,
249
+ isPublic,
250
+ fileRelativePath,
251
+ isOwnershipAction: false,
252
+ extensionModuleDirPath: dirPath,
253
+ extensionModuleName: moduleName,
254
+ extensionModuleVersion: version
255
+ });
256
+
257
+ const hash = computeHash(sourceCode);
258
+
259
+ const copyableFilePath = pathJoin(
260
+ pathDirname(cacheFilePath),
261
+ KEYCLOAK_THEME,
262
+ fileRelativePath_fromReservedDir
263
+ );
264
+
265
+ {
266
+ const dirPath = pathDirname(copyableFilePath);
267
+
268
+ if (!(await existsAsync(dirPath))) {
269
+ await fsPr.mkdir(dirPath, { recursive: true });
270
+ }
271
+ }
239
272
 
240
- const fileRelativePath = isPublic
241
- ? pathRelative("public", fileRelativePath_fromReservedDir)
242
- : fileRelativePath_fromReservedDir;
273
+ fsPr.writeFile(copyableFilePath, sourceCode);
243
274
 
244
- const sourceCode =
245
- await getExtensionModuleFileSourceCodeReadyToBeCopied({
246
- buildContext,
275
+ files.push({
247
276
  isPublic,
248
277
  fileRelativePath,
249
- isOwnershipAction: false,
250
- extensionModuleDirPath: dirPath,
251
- extensionModuleName: moduleName,
252
- extensionModuleVersion: version
278
+ hash,
279
+ copyableFilePath
253
280
  });
254
-
255
- const hash = computeHash(sourceCode);
256
-
257
- const copyableFilePath = pathJoin(
258
- pathDirname(cacheFilePath),
259
- KEYCLOAK_THEME,
260
- fileRelativePath_fromReservedDir
261
- );
262
-
263
- {
264
- const dirPath = pathDirname(copyableFilePath);
265
-
266
- if (!(await existsAsync(dirPath))) {
267
- await fsPr.mkdir(dirPath, { recursive: true });
268
- }
269
281
  }
282
+ });
270
283
 
271
- fsPr.writeFile(copyableFilePath, sourceCode);
284
+ {
285
+ const getId = (file: {
286
+ isPublic: boolean;
287
+ fileRelativePath: string;
288
+ }) =>
289
+ `${file.isPublic ? "public" : "src"} - ${file.fileRelativePath}`;
272
290
 
273
- files.push({
274
- isPublic,
275
- fileRelativePath,
276
- hash,
277
- copyableFilePath
278
- });
291
+ files.sort((a, b) => getId(a).localeCompare(getId(b)));
279
292
  }
280
- });
281
293
 
282
- return id<ExtensionModuleMeta>({
283
- moduleName,
284
- version,
285
- files,
286
- peerDependencies: Object.fromEntries(
287
- Object.entries(peerDependencies).filter(
288
- ([moduleName]) =>
289
- !isAmong(["react", "@types/react"], moduleName)
294
+ return id<ExtensionModuleMeta>({
295
+ moduleName,
296
+ version,
297
+ files,
298
+ peerDependencies: Object.fromEntries(
299
+ Object.entries(peerDependencies)
300
+ .filter(
301
+ ([moduleName]) =>
302
+ !isAmong(["react", "@types/react"], moduleName)
303
+ )
304
+ .sort(([moduleName_a], [moduleName_b]) =>
305
+ moduleName_a.localeCompare(moduleName_b)
306
+ )
290
307
  )
291
- )
292
- });
293
- }
294
- )
308
+ });
309
+ }
310
+ )
295
311
  );
296
312
 
297
313
  update_cache: {
@@ -73,10 +73,16 @@ export async function writeManagedGitignoreFiles(params: {
73
73
  ...ownedFilesRelativePaths_ctx
74
74
  .map(({ fileRelativePath }) => fileRelativePath)
75
75
  .map(fileRelativePath => fileRelativePath.split(pathSep).join("/"))
76
+ .sort(posixPathCompareFn)
76
77
  .map(line => `# ${line}`),
77
78
  DELIMITER_END,
78
79
  ``,
79
- ...extensionModuleMetas_ctx
80
+ ...[...extensionModuleMetas_ctx]
81
+ .sort((a, b) => {
82
+ const n = a.moduleName.length - b.moduleName.length;
83
+
84
+ return n !== 0 ? n : a.moduleName.localeCompare(b.moduleName);
85
+ })
80
86
  .map(extensionModuleMeta => [
81
87
  `# === ${extensionModuleMeta.moduleName} v${extensionModuleMeta.version} ===`,
82
88
  ...extensionModuleMeta.files
@@ -90,7 +96,8 @@ export async function writeManagedGitignoreFiles(params: {
90
96
  .map(
91
97
  fileRelativePath =>
92
98
  `/${fileRelativePath.split(pathSep).join("/").replace(/^\.\//, "")}`
93
- ),
99
+ )
100
+ .sort(posixPathCompareFn),
94
101
 
95
102
  ``
96
103
  ])
@@ -187,3 +194,26 @@ export async function readManagedGitignoresFile(params: {
187
194
 
188
195
  return { ownedFilesRelativePaths };
189
196
  }
197
+
198
+ function posixPathCompareFn(a: string, b: string) {
199
+ const aParts = a.split("/");
200
+ const bParts = b.split("/");
201
+
202
+ const diff = aParts.length - bParts.length;
203
+
204
+ if (diff !== 0) {
205
+ return diff;
206
+ }
207
+
208
+ const len = Math.min(aParts.length, bParts.length);
209
+
210
+ for (let i = 0; i < len; i++) {
211
+ const cmp = aParts[i].localeCompare(bParts[i], undefined, {
212
+ numeric: true,
213
+ sensitivity: "base"
214
+ });
215
+ if (cmp !== 0) return cmp;
216
+ }
217
+
218
+ return 0;
219
+ }
@@ -18,7 +18,8 @@ export function getProxyFetchOptions(params: {
18
18
  const cfg = (() => {
19
19
  const output = child_process
20
20
  .execSync("npm config get", {
21
- cwd: npmConfigGetCwd
21
+ cwd: npmConfigGetCwd,
22
+ stdio: ["pipe", "pipe", "ignore"]
22
23
  })
23
24
  .toString("utf8");
24
25
 
@@ -99,24 +99,31 @@ async function runPackageManagerInstall(params: {
99
99
 
100
100
  const dCompleted = new Deferred<void>();
101
101
 
102
- const child = child_process.spawn(packageManagerBinName, ["install"], {
103
- cwd,
104
- env: process.env,
105
- shell: true
106
- });
102
+ const child = child_process.spawn(
103
+ packageManagerBinName,
104
+ ["install", ...(packageManagerBinName !== "npm" ? [] : ["--force"])],
105
+ {
106
+ cwd,
107
+ env: process.env,
108
+ shell: true
109
+ }
110
+ );
107
111
 
108
112
  child.stdout.on("data", data => process.stdout.write(data));
109
113
 
114
+ let errorLog = "";
115
+
110
116
  child.stderr.on("data", data => {
111
117
  if (data.toString("utf8").includes("peer dependency")) {
112
118
  return;
113
119
  }
114
120
 
115
- process.stderr.write(data);
121
+ errorLog += data.toString("utf8");
116
122
  });
117
123
 
118
124
  child.on("exit", code => {
119
125
  if (code !== 0) {
126
+ console.log(errorLog);
120
127
  dCompleted.reject(new Error(`Failed with code ${code}`));
121
128
  return;
122
129
  }
@@ -287,7 +287,8 @@ function getProxyFetchOptions(params) {
287
287
  const { npmConfigGetCwd } = params;
288
288
  const cfg = (() => {
289
289
  const output = external_child_process_.execSync("npm config get", {
290
- cwd: npmConfigGetCwd
290
+ cwd: npmConfigGetCwd,
291
+ stdio: ["pipe", "pipe", "ignore"]
291
292
  })
292
293
  .toString("utf8");
293
294
  return output
@@ -408,30 +409,7 @@ function getBuildContext(params) {
408
409
  if (themeSrcDirPath !== undefined) {
409
410
  return { themeSrcDirPath };
410
411
  }
411
- {
412
- const basenames = external_fs_.readdirSync(srcDirPath);
413
- for (const basename of basenames) {
414
- const path = (0,external_path_.join)(srcDirPath, basename);
415
- if (!external_fs_.statSync(path).isFile()) {
416
- continue;
417
- }
418
- if (external_fs_.readFileSync(path).toString("utf8").includes("./kc.gen")) {
419
- return { themeSrcDirPath: srcDirPath };
420
- }
421
- }
422
- }
423
- for (const themeType of [...constants.THEME_TYPES, "email"]) {
424
- if (!external_fs_.existsSync((0,external_path_.join)(srcDirPath, themeType))) {
425
- continue;
426
- }
427
- return { themeSrcDirPath: srcDirPath };
428
- }
429
- console.log(source_default().red([
430
- `Can't locate your Keycloak theme source directory in .${external_path_.sep}${(0,external_path_.relative)(process.cwd(), srcDirPath)}`,
431
- `Make sure to either use the Keycloakify CLI in the root of your Keycloakify project or use the --project CLI option`,
432
- `If you are collocating your Keycloak theme with your app you must have a directory named '${constants.KEYCLOAK_THEME}' or '${constants.KEYCLOAK_THEME.replace(/-/g, "_")}' in your 'src' directory`
433
- ].join("\n")));
434
- process.exit(1);
412
+ return { themeSrcDirPath: srcDirPath };
435
413
  })();
436
414
  const { resolvedViteConfig } = (() => {
437
415
  if (external_fs_.readdirSync(projectDirPath)
@@ -441,6 +419,7 @@ function getBuildContext(params) {
441
419
  }
442
420
  const output = external_child_process_.execSync("npx vite", {
443
421
  cwd: projectDirPath,
422
+ stdio: ["pipe", "pipe", "ignore"],
444
423
  env: Object.assign(Object.assign({}, process.env), { [constants.VITE_PLUGIN_SUB_SCRIPTS_ENV_NAMES.RESOLVE_VITE_CONFIG]: "true" })
445
424
  })
446
425
  .toString("utf8");
@@ -814,25 +793,27 @@ function getBuildContext(params) {
814
793
  environmentVariables: (_e = buildOptions.environmentVariables) !== null && _e !== void 0 ? _e : [],
815
794
  implementedThemeTypes,
816
795
  themeSrcDirPath,
817
- fetchOptions: getProxyFetchOptions({
818
- npmConfigGetCwd: (function callee(upCount) {
819
- const dirPath = (0,external_path_.resolve)((0,external_path_.join)(...[projectDirPath, ...Array(upCount).fill("..")]));
820
- (0,assert/* assert */.h)(dirPath !== external_path_.sep, "Couldn't find a place to run 'npm config get'");
821
- try {
822
- external_child_process_.execSync("npm config get", {
823
- cwd: dirPath,
824
- stdio: "pipe"
825
- });
826
- }
827
- catch (error) {
828
- if (String(error).includes("ENOWORKSPACES")) {
829
- return callee(upCount + 1);
796
+ get fetchOptions() {
797
+ return getProxyFetchOptions({
798
+ npmConfigGetCwd: (function callee(upCount) {
799
+ const dirPath = (0,external_path_.resolve)((0,external_path_.join)(...[projectDirPath, ...Array(upCount).fill("..")]));
800
+ (0,assert/* assert */.h)(dirPath !== external_path_.sep, "Couldn't find a place to run 'npm config get'");
801
+ try {
802
+ external_child_process_.execSync("npm config get", {
803
+ cwd: dirPath,
804
+ stdio: "pipe"
805
+ });
830
806
  }
831
- throw error;
832
- }
833
- return dirPath;
834
- })(0)
835
- }),
807
+ catch (error) {
808
+ if (String(error).includes("ENOWORKSPACES")) {
809
+ return callee(upCount + 1);
810
+ }
811
+ throw error;
812
+ }
813
+ return dirPath;
814
+ })(0)
815
+ });
816
+ },
836
817
  jarTargets: (() => {
837
818
  const getDefaultJarFileBasename = (range) => `keycloak-theme-for-kc-${range}.jar`;
838
819
  build_for_specific_keycloak_major_version: {