keycloakify 10.0.0-rc.118 → 10.0.0-rc.119

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 (48) hide show
  1. package/bin/{490.index.js → 246.index.js} +20 -2
  2. package/bin/31.index.js +151 -159
  3. package/bin/440.index.js +27 -22
  4. package/bin/526.index.js +168 -56
  5. package/bin/599.index.js +560 -0
  6. package/bin/622.index.js +4 -2
  7. package/bin/{36.index.js → 678.index.js} +577 -71
  8. package/bin/{180.index.js → 697.index.js} +611 -526
  9. package/bin/743.index.js +70 -0
  10. package/bin/780.index.js +729 -0
  11. package/bin/932.index.js +725 -48
  12. package/bin/{966.index.js → 941.index.js} +2 -19
  13. package/bin/main.js +19 -7
  14. package/bin/shared/buildContext.d.ts +28 -19
  15. package/bin/shared/buildContext.js.map +1 -1
  16. package/bin/shared/getLatestsSemVersionedTag.d.ts +10 -0
  17. package/bin/shared/getLatestsSemVersionedTag.js.map +1 -0
  18. package/bin/shared/promptKeycloakVersion.js.map +1 -1
  19. package/package.json +24 -5
  20. package/src/bin/initialize-account-theme/copyBoilerplate.ts +32 -0
  21. package/src/bin/initialize-account-theme/index.ts +1 -0
  22. package/src/bin/initialize-account-theme/initialize-account-theme.ts +95 -0
  23. package/src/bin/initialize-account-theme/initializeAccountTheme_multiPage.ts +21 -0
  24. package/src/bin/initialize-account-theme/initializeAccountTheme_singlePage.ts +150 -0
  25. package/src/bin/initialize-account-theme/src/multi-page/KcContext.ts +12 -0
  26. package/src/bin/initialize-account-theme/src/multi-page/KcPage.tsx +25 -0
  27. package/src/bin/initialize-account-theme/src/multi-page/KcPageStory.tsx +38 -0
  28. package/src/bin/initialize-account-theme/src/multi-page/i18n.ts +5 -0
  29. package/src/bin/initialize-account-theme/src/single-page/KcContext.ts +7 -0
  30. package/src/bin/initialize-account-theme/src/single-page/KcPage.tsx +11 -0
  31. package/src/bin/initialize-account-theme/updateAccountThemeImplementationInConfig.ts +92 -0
  32. package/src/bin/keycloakify/buildJars/buildJar.ts +2 -2
  33. package/src/bin/keycloakify/buildJars/buildJars.ts +3 -4
  34. package/src/bin/keycloakify/generateResources/generateResourcesForMainTheme.ts +26 -20
  35. package/src/bin/keycloakify/keycloakify.ts +1 -1
  36. package/src/bin/keycloakify/replacers/replaceImportsInJsCode/replaceImportsInJsCode.ts +2 -2
  37. package/src/bin/main.ts +14 -0
  38. package/src/bin/shared/buildContext.ts +246 -225
  39. package/src/bin/shared/getLatestsSemVersionedTag.ts +180 -0
  40. package/src/bin/shared/promptKeycloakVersion.ts +8 -77
  41. package/src/bin/start-keycloak/appBuild.ts +13 -9
  42. package/src/bin/tools/downloadAndExtractArchive.ts +4 -2
  43. package/src/bin/tools/npmInstall.ts +63 -0
  44. package/src/bin/tools/octokit-addons/getLatestsSemVersionedTag.ts +3 -2
  45. package/src/bin/tsconfig.json +3 -1
  46. package/src/vite-plugin/vite-plugin.ts +7 -5
  47. package/vite-plugin/index.js +156 -180
  48. package/vite-plugin/vite-plugin.d.ts +6 -4
@@ -0,0 +1,180 @@
1
+ import { getLatestsSemVersionedTagFactory } from "../tools/octokit-addons/getLatestsSemVersionedTag";
2
+ import { Octokit } from "@octokit/rest";
3
+ import type { ReturnType } from "tsafe";
4
+ import type { Param0 } from "tsafe";
5
+ import { join as pathJoin, dirname as pathDirname } from "path";
6
+ import * as fs from "fs";
7
+ import { z } from "zod";
8
+ import { assert, type Equals } from "tsafe/assert";
9
+ import { id } from "tsafe/id";
10
+ import type { SemVer } from "../tools/SemVer";
11
+ import { same } from "evt/tools/inDepth/same";
12
+
13
+ type GetLatestsSemVersionedTag = ReturnType<
14
+ typeof getLatestsSemVersionedTagFactory
15
+ >["getLatestsSemVersionedTag"];
16
+
17
+ type Params = Param0<GetLatestsSemVersionedTag>;
18
+ type R = ReturnType<GetLatestsSemVersionedTag>;
19
+
20
+ let getLatestsSemVersionedTag_stateless: GetLatestsSemVersionedTag | undefined =
21
+ undefined;
22
+
23
+ const CACHE_VERSION = 1;
24
+
25
+ type Cache = {
26
+ version: typeof CACHE_VERSION;
27
+ entries: {
28
+ time: number;
29
+ params: Params;
30
+ result: R;
31
+ }[];
32
+ };
33
+
34
+ export async function getLatestsSemVersionedTag({
35
+ cacheDirPath,
36
+ ...params
37
+ }: Params & { cacheDirPath: string }): Promise<R> {
38
+ const cacheFilePath = pathJoin(cacheDirPath, "latest-sem-versioned-tags.json");
39
+
40
+ const cacheLookupResult = (() => {
41
+ const getResult_currentCache = (currentCacheEntries: Cache["entries"]) => ({
42
+ hasCachedResult: false as const,
43
+ currentCache: {
44
+ version: CACHE_VERSION,
45
+ entries: currentCacheEntries
46
+ }
47
+ });
48
+
49
+ if (!fs.existsSync(cacheFilePath)) {
50
+ return getResult_currentCache([]);
51
+ }
52
+
53
+ let cache_json;
54
+
55
+ try {
56
+ cache_json = fs.readFileSync(cacheFilePath).toString("utf8");
57
+ } catch {
58
+ return getResult_currentCache([]);
59
+ }
60
+
61
+ let cache_json_parsed: unknown;
62
+
63
+ try {
64
+ cache_json_parsed = JSON.parse(cache_json);
65
+ } catch {
66
+ return getResult_currentCache([]);
67
+ }
68
+
69
+ const zSemVer = (() => {
70
+ type TargetType = SemVer;
71
+
72
+ const zTargetType = z.object({
73
+ major: z.number(),
74
+ minor: z.number(),
75
+ patch: z.number(),
76
+ rc: z.number().optional(),
77
+ parsedFrom: z.string()
78
+ });
79
+
80
+ assert<Equals<z.infer<typeof zTargetType>, TargetType>>();
81
+
82
+ return id<z.ZodType<TargetType>>(zTargetType);
83
+ })();
84
+
85
+ const zCache = (() => {
86
+ type TargetType = Cache;
87
+
88
+ const zTargetType = z.object({
89
+ version: z.literal(CACHE_VERSION),
90
+ entries: z.array(
91
+ z.object({
92
+ time: z.number(),
93
+ params: z.object({
94
+ owner: z.string(),
95
+ repo: z.string(),
96
+ count: z.number(),
97
+ doIgnoreReleaseCandidates: z.boolean()
98
+ }),
99
+ result: z.array(
100
+ z.object({
101
+ tag: z.string(),
102
+ version: zSemVer
103
+ })
104
+ )
105
+ })
106
+ )
107
+ });
108
+
109
+ assert<Equals<z.infer<typeof zTargetType>, TargetType>>();
110
+
111
+ return id<z.ZodType<TargetType>>(zTargetType);
112
+ })();
113
+
114
+ let cache: Cache;
115
+
116
+ try {
117
+ cache = zCache.parse(cache_json_parsed);
118
+ } catch {
119
+ return getResult_currentCache([]);
120
+ }
121
+
122
+ const cacheEntry = cache.entries.find(e => same(e.params, params));
123
+
124
+ if (cacheEntry === undefined) {
125
+ return getResult_currentCache(cache.entries);
126
+ }
127
+
128
+ if (Date.now() - cacheEntry.time > 3_600_000) {
129
+ return getResult_currentCache(cache.entries.filter(e => e !== cacheEntry));
130
+ }
131
+ return {
132
+ hasCachedResult: true as const,
133
+ cachedResult: cacheEntry.result
134
+ };
135
+ })();
136
+
137
+ if (cacheLookupResult.hasCachedResult) {
138
+ return cacheLookupResult.cachedResult;
139
+ }
140
+
141
+ const { currentCache } = cacheLookupResult;
142
+
143
+ getLatestsSemVersionedTag_stateless ??= (() => {
144
+ const octokit = (() => {
145
+ const githubToken = process.env.GITHUB_TOKEN;
146
+
147
+ const octokit = new Octokit(
148
+ githubToken === undefined ? undefined : { auth: githubToken }
149
+ );
150
+
151
+ return octokit;
152
+ })();
153
+
154
+ const { getLatestsSemVersionedTag } = getLatestsSemVersionedTagFactory({
155
+ octokit
156
+ });
157
+
158
+ return getLatestsSemVersionedTag;
159
+ })();
160
+
161
+ const result = await getLatestsSemVersionedTag_stateless(params);
162
+
163
+ currentCache.entries.push({
164
+ time: Date.now(),
165
+ params,
166
+ result
167
+ });
168
+
169
+ {
170
+ const dirPath = pathDirname(cacheFilePath);
171
+
172
+ if (!fs.existsSync(dirPath)) {
173
+ fs.mkdirSync(dirPath, { recursive: true });
174
+ }
175
+ }
176
+
177
+ fs.writeFileSync(cacheFilePath, JSON.stringify(currentCache, null, 2));
178
+
179
+ return result;
180
+ }
@@ -1,11 +1,6 @@
1
- import { getLatestsSemVersionedTagFactory } from "../tools/octokit-addons/getLatestsSemVersionedTag";
2
- import { Octokit } from "@octokit/rest";
1
+ import { getLatestsSemVersionedTag } from "./getLatestsSemVersionedTag";
3
2
  import cliSelect from "cli-select";
4
3
  import { SemVer } from "../tools/SemVer";
5
- import { join as pathJoin, dirname as pathDirname } from "path";
6
- import * as fs from "fs";
7
- import type { ReturnType } from "tsafe";
8
- import { id } from "tsafe/id";
9
4
 
10
5
  export async function promptKeycloakVersion(params: {
11
6
  startingFromMajor: number | undefined;
@@ -14,79 +9,15 @@ export async function promptKeycloakVersion(params: {
14
9
  }) {
15
10
  const { startingFromMajor, excludeMajorVersions, cacheDirPath } = params;
16
11
 
17
- const { getLatestsSemVersionedTag } = (() => {
18
- const { octokit } = (() => {
19
- const githubToken = process.env.GITHUB_TOKEN;
20
-
21
- const octokit = new Octokit(
22
- githubToken === undefined ? undefined : { auth: githubToken }
23
- );
24
-
25
- return { octokit };
26
- })();
27
-
28
- const { getLatestsSemVersionedTag } = getLatestsSemVersionedTagFactory({
29
- octokit
30
- });
31
-
32
- return { getLatestsSemVersionedTag };
33
- })();
34
-
35
12
  const semVersionedTagByMajor = new Map<number, { tag: string; version: SemVer }>();
36
13
 
37
- const semVersionedTags = await (async () => {
38
- const cacheFilePath = pathJoin(cacheDirPath, "keycloak-versions.json");
39
-
40
- type Cache = {
41
- time: number;
42
- semVersionedTags: ReturnType<typeof getLatestsSemVersionedTag>;
43
- };
44
-
45
- use_cache: {
46
- if (!fs.existsSync(cacheFilePath)) {
47
- break use_cache;
48
- }
49
-
50
- const cache: Cache = JSON.parse(
51
- fs.readFileSync(cacheFilePath).toString("utf8")
52
- );
53
-
54
- if (Date.now() - cache.time > 3_600_000) {
55
- fs.unlinkSync(cacheFilePath);
56
- break use_cache;
57
- }
58
-
59
- return cache.semVersionedTags;
60
- }
61
-
62
- const semVersionedTags = await getLatestsSemVersionedTag({
63
- count: 50,
64
- owner: "keycloak",
65
- repo: "keycloak"
66
- });
67
-
68
- {
69
- const dirPath = pathDirname(cacheFilePath);
70
-
71
- if (!fs.existsSync(dirPath)) {
72
- fs.mkdirSync(dirPath, { recursive: true });
73
- }
74
- }
75
-
76
- fs.writeFileSync(
77
- cacheFilePath,
78
- JSON.stringify(
79
- id<Cache>({
80
- time: Date.now(),
81
- semVersionedTags
82
- }),
83
- null,
84
- 2
85
- )
86
- );
87
-
88
- return semVersionedTags;
89
- })();
14
+ const semVersionedTags = await getLatestsSemVersionedTag({
15
+ cacheDirPath,
16
+ count: 50,
17
+ owner: "keycloak",
18
+ repo: "keycloak",
19
+ doIgnoreReleaseCandidates: true
20
+ });
90
21
 
91
22
  semVersionedTags.forEach(semVersionedTag => {
92
23
  if (
@@ -5,12 +5,15 @@ import type { BuildContext } from "../shared/buildContext";
5
5
  import chalk from "chalk";
6
6
  import { sep as pathSep, join as pathJoin } from "path";
7
7
  import { getAbsoluteAndInOsFormatPath } from "../tools/getAbsoluteAndInOsFormatPath";
8
+ import * as fs from "fs";
9
+ import { dirname as pathDirname, relative as pathRelative } from "path";
8
10
 
9
11
  export type BuildContextLike = {
10
12
  projectDirPath: string;
11
13
  keycloakifyBuildDirPath: string;
12
14
  bundler: BuildContext["bundler"];
13
15
  projectBuildDirPath: string;
16
+ packageJsonFilePath: string;
14
17
  };
15
18
 
16
19
  assert<BuildContext extends BuildContextLike ? true : false>();
@@ -20,7 +23,7 @@ export async function appBuild(params: {
20
23
  }): Promise<{ isAppBuildSuccess: boolean }> {
21
24
  const { buildContext } = params;
22
25
 
23
- switch (buildContext.bundler.type) {
26
+ switch (buildContext.bundler) {
24
27
  case "vite":
25
28
  return appBuild_vite({ buildContext });
26
29
  case "webpack":
@@ -33,7 +36,7 @@ async function appBuild_vite(params: {
33
36
  }): Promise<{ isAppBuildSuccess: boolean }> {
34
37
  const { buildContext } = params;
35
38
 
36
- assert(buildContext.bundler.type === "vite");
39
+ assert(buildContext.bundler === "vite");
37
40
 
38
41
  const dIsSuccess = new Deferred<boolean>();
39
42
 
@@ -66,17 +69,18 @@ async function appBuild_webpack(params: {
66
69
  }): Promise<{ isAppBuildSuccess: boolean }> {
67
70
  const { buildContext } = params;
68
71
 
69
- assert(buildContext.bundler.type === "webpack");
72
+ assert(buildContext.bundler === "webpack");
70
73
 
71
- const entries = Object.entries(buildContext.bundler.packageJsonScripts).filter(
72
- ([, scriptCommand]) => scriptCommand.includes("keycloakify build")
73
- );
74
+ const entries = Object.entries(
75
+ (JSON.parse(fs.readFileSync(buildContext.packageJsonFilePath).toString("utf8"))
76
+ .scripts ?? {}) as Record<string, string>
77
+ ).filter(([, scriptCommand]) => scriptCommand.includes("keycloakify build"));
74
78
 
75
79
  if (entries.length === 0) {
76
80
  console.log(
77
81
  chalk.red(
78
82
  [
79
- `You should have a script in your package.json at ${buildContext.bundler.packageJsonDirPath}`,
83
+ `You should have a script in your package.json at ${pathRelative(process.cwd(), pathDirname(buildContext.packageJsonFilePath))}`,
80
84
  `that includes the 'keycloakify build' command`
81
85
  ].join(" ")
82
86
  )
@@ -123,7 +127,7 @@ async function appBuild_webpack(params: {
123
127
  process.exit(-1);
124
128
  }
125
129
 
126
- let commandCwd = buildContext.bundler.packageJsonDirPath;
130
+ let commandCwd = pathDirname(buildContext.packageJsonFilePath);
127
131
 
128
132
  for (const subCommand of appBuildSubCommands) {
129
133
  const dIsSuccess = new Deferred<boolean>();
@@ -152,7 +156,7 @@ async function appBuild_webpack(params: {
152
156
 
153
157
  return [
154
158
  pathJoin(
155
- buildContext.bundler.packageJsonDirPath,
159
+ pathDirname(buildContext.packageJsonFilePath),
156
160
  "node_modules",
157
161
  ".bin"
158
162
  ),
@@ -63,7 +63,7 @@ export async function downloadAndExtractArchive(params: {
63
63
  });
64
64
  }
65
65
 
66
- const extractDirBasename = `${archiveFileBasename.split(".")[0]}_${uniqueIdOfOnArchiveFile}_${crypto
66
+ const extractDirBasename = `${archiveFileBasename.replace(/\.([^.]+)$/, (...[, ext]) => `_${ext}`)}_${uniqueIdOfOnArchiveFile}_${crypto
67
67
  .createHash("sha256")
68
68
  .update(onArchiveFile.toString())
69
69
  .digest("hex")
@@ -85,7 +85,9 @@ export async function downloadAndExtractArchive(params: {
85
85
  })()
86
86
  )
87
87
  .map(async extractDirBasename => {
88
- await rm(pathJoin(cacheDirPath, extractDirBasename), { recursive: true });
88
+ await rm(pathJoin(cacheDirPath, extractDirBasename), {
89
+ recursive: true
90
+ });
89
91
  await SuccessTracker.removeFromExtracted({
90
92
  cacheDirPath,
91
93
  extractDirBasename
@@ -0,0 +1,63 @@
1
+ import * as fs from "fs";
2
+ import { join as pathJoin } from "path";
3
+ import * as child_process from "child_process";
4
+ import chalk from "chalk";
5
+
6
+ export function npmInstall(params: { packageJsonDirPath: string }) {
7
+ const { packageJsonDirPath } = params;
8
+
9
+ const packageManagerBinName = (() => {
10
+ const packageMangers = [
11
+ {
12
+ binName: "yarn",
13
+ lockFileBasename: "yarn.lock"
14
+ },
15
+ {
16
+ binName: "npm",
17
+ lockFileBasename: "package-lock.json"
18
+ },
19
+ {
20
+ binName: "pnpm",
21
+ lockFileBasename: "pnpm-lock.yaml"
22
+ },
23
+ {
24
+ binName: "bun",
25
+ lockFileBasename: "bun.lockdb"
26
+ }
27
+ ] as const;
28
+
29
+ for (const packageManager of packageMangers) {
30
+ if (
31
+ fs.existsSync(
32
+ pathJoin(packageJsonDirPath, packageManager.lockFileBasename)
33
+ ) ||
34
+ fs.existsSync(pathJoin(process.cwd(), packageManager.lockFileBasename))
35
+ ) {
36
+ return packageManager.binName;
37
+ }
38
+ }
39
+
40
+ return undefined;
41
+ })();
42
+
43
+ install_dependencies: {
44
+ if (packageManagerBinName === undefined) {
45
+ break install_dependencies;
46
+ }
47
+
48
+ console.log(`Installing the new dependencies...`);
49
+
50
+ try {
51
+ child_process.execSync(`${packageManagerBinName} install`, {
52
+ cwd: packageJsonDirPath,
53
+ stdio: "inherit"
54
+ });
55
+ } catch {
56
+ console.log(
57
+ chalk.yellow(
58
+ `\`${packageManagerBinName} install\` failed, continuing anyway...`
59
+ )
60
+ );
61
+ }
62
+ }
63
+ }
@@ -9,13 +9,14 @@ export function getLatestsSemVersionedTagFactory(params: { octokit: Octokit }) {
9
9
  owner: string;
10
10
  repo: string;
11
11
  count: number;
12
+ doIgnoreReleaseCandidates: boolean;
12
13
  }): Promise<
13
14
  {
14
15
  tag: string;
15
16
  version: SemVer;
16
17
  }[]
17
18
  > {
18
- const { owner, repo, count } = params;
19
+ const { owner, repo, count, doIgnoreReleaseCandidates } = params;
19
20
 
20
21
  const semVersionedTags: { tag: string; version: SemVer }[] = [];
21
22
 
@@ -30,7 +31,7 @@ export function getLatestsSemVersionedTagFactory(params: { octokit: Octokit }) {
30
31
  continue;
31
32
  }
32
33
 
33
- if (version.rc !== undefined) {
34
+ if (doIgnoreReleaseCandidates && version.rc !== undefined) {
34
35
  continue;
35
36
  }
36
37
 
@@ -8,5 +8,7 @@
8
8
  "moduleResolution": "node",
9
9
  "outDir": "../../dist/bin",
10
10
  "rootDir": "."
11
- }
11
+ },
12
+ "include": ["**/*.ts", "**/*.tsx"],
13
+ "exclude": ["initialize-account-theme/src"]
12
14
  }
@@ -18,12 +18,14 @@ import {
18
18
  import MagicString from "magic-string";
19
19
  import { generateKcGenTs } from "../bin/shared/generateKcGenTs";
20
20
 
21
- export type Params = BuildOptions & {
22
- postBuild?: (buildContext: Omit<BuildContext, "bundler">) => Promise<void>;
23
- };
21
+ export namespace keycloakify {
22
+ export type Params = BuildOptions & {
23
+ postBuild?: (buildContext: Omit<BuildContext, "bundler">) => Promise<void>;
24
+ };
25
+ }
24
26
 
25
- export function keycloakify(params?: Params) {
26
- const { postBuild, ...buildOptions } = params ?? {};
27
+ export function keycloakify(params: keycloakify.Params) {
28
+ const { postBuild, ...buildOptions } = params;
27
29
 
28
30
  let projectDirPath: string | undefined = undefined;
29
31
  let urlPathname: string | undefined = undefined;