keycloakify 11.8.36-rc.1 → 11.8.37-rc.1

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.
@@ -0,0 +1,189 @@
1
+ import * as fsPr from "fs/promises";
2
+ import {
3
+ join as pathJoin,
4
+ sep as pathSep,
5
+ dirname as pathDirname,
6
+ relative as pathRelative
7
+ } from "path";
8
+ import { assert } from "tsafe/assert";
9
+ import type { BuildContext } from "../shared/buildContext";
10
+ import type { ExtensionModuleMeta } from "./extensionModuleMeta";
11
+ import { existsAsync } from "../tools/fs.existsAsync";
12
+ import { getAbsoluteAndInOsFormatPath } from "../tools/getAbsoluteAndInOsFormatPath";
13
+ import { KEYCLOAK_THEME } from "../shared/constants";
14
+
15
+ export type BuildContextLike = {
16
+ themeSrcDirPath: string;
17
+ publicDirPath: string;
18
+ };
19
+
20
+ assert<BuildContext extends BuildContextLike ? true : false>();
21
+
22
+ type ExtensionModuleMetaLike = {
23
+ moduleName: string;
24
+ version: string;
25
+ files: {
26
+ isPublic: boolean;
27
+ fileRelativePath: string;
28
+ }[];
29
+ };
30
+
31
+ assert<ExtensionModuleMeta extends ExtensionModuleMetaLike ? true : false>();
32
+
33
+ const DELIMITER_START = `# === Owned files start ===`;
34
+ const DELIMITER_END = `# === Owned files end =====`;
35
+
36
+ export async function writeManagedGitignoreFiles(params: {
37
+ buildContext: BuildContextLike;
38
+ extensionModuleMetas: ExtensionModuleMetaLike[];
39
+ ownedFilesRelativePaths: { isPublic: boolean; fileRelativePath: string }[];
40
+ }): Promise<void> {
41
+ const { buildContext } = params;
42
+
43
+ for (const isPublicIteration of [false, true] as const) {
44
+ const extensionModuleMetas_ctx = params.extensionModuleMetas
45
+ .map(extensionModuleMeta => ({
46
+ ...extensionModuleMeta,
47
+ files: extensionModuleMeta.files.filter(
48
+ ({ isPublic }) => isPublic === isPublicIteration
49
+ )
50
+ }))
51
+ .filter(extensionModuleMeta => extensionModuleMeta.files.length !== 0);
52
+
53
+ if (extensionModuleMetas_ctx.length === 0) {
54
+ continue;
55
+ }
56
+
57
+ const ownedFilesRelativePaths_ctx = params.ownedFilesRelativePaths.filter(
58
+ ({ isPublic }) => isPublic === isPublicIteration
59
+ );
60
+
61
+ const filePath = pathJoin(
62
+ isPublicIteration
63
+ ? pathJoin(buildContext.publicDirPath, KEYCLOAK_THEME)
64
+ : buildContext.themeSrcDirPath,
65
+ ".gitignore"
66
+ );
67
+
68
+ const content_new = Buffer.from(
69
+ [
70
+ `# This file is managed by Keycloakify, do not edit it manually.`,
71
+ ``,
72
+ DELIMITER_START,
73
+ ...ownedFilesRelativePaths_ctx
74
+ .map(({ fileRelativePath }) => fileRelativePath)
75
+ .map(fileRelativePath => fileRelativePath.split(pathSep).join("/"))
76
+ .map(line => `# ${line}`),
77
+ DELIMITER_END,
78
+ ``,
79
+ ...extensionModuleMetas_ctx
80
+ .map(extensionModuleMeta => [
81
+ `# === ${extensionModuleMeta.moduleName} v${extensionModuleMeta.version} ===`,
82
+ ...extensionModuleMeta.files
83
+ .map(({ fileRelativePath }) => fileRelativePath)
84
+ .filter(
85
+ fileRelativePath =>
86
+ !ownedFilesRelativePaths_ctx
87
+ .map(({ fileRelativePath }) => fileRelativePath)
88
+ .includes(fileRelativePath)
89
+ )
90
+ .map(
91
+ fileRelativePath =>
92
+ `/${fileRelativePath.split(pathSep).join("/").replace(/^\.\//, "")}`
93
+ ),
94
+
95
+ ``
96
+ ])
97
+ .flat()
98
+ ].join("\n"),
99
+ "utf8"
100
+ );
101
+
102
+ const content_current = await (async () => {
103
+ if (!(await existsAsync(filePath))) {
104
+ return undefined;
105
+ }
106
+
107
+ return await fsPr.readFile(filePath);
108
+ })();
109
+
110
+ if (content_current !== undefined && content_current.equals(content_new)) {
111
+ continue;
112
+ }
113
+
114
+ create_dir: {
115
+ const dirPath = pathDirname(filePath);
116
+
117
+ if (await existsAsync(dirPath)) {
118
+ break create_dir;
119
+ }
120
+
121
+ await fsPr.mkdir(dirPath, { recursive: true });
122
+ }
123
+
124
+ await fsPr.writeFile(filePath, content_new);
125
+ }
126
+ }
127
+
128
+ export async function readManagedGitignoresFile(params: {
129
+ buildContext: BuildContextLike;
130
+ }): Promise<{
131
+ ownedFilesRelativePaths: { isPublic: boolean; fileRelativePath: string }[];
132
+ }> {
133
+ const { buildContext } = params;
134
+
135
+ const ownedFilesRelativePaths: { isPublic: boolean; fileRelativePath: string }[] = [];
136
+
137
+ for (const isPublicIteration of [false, true] as const) {
138
+ const filePath = pathJoin(
139
+ isPublicIteration
140
+ ? pathJoin(buildContext.publicDirPath, KEYCLOAK_THEME)
141
+ : buildContext.themeSrcDirPath,
142
+ ".gitignore"
143
+ );
144
+
145
+ if (!(await existsAsync(filePath))) {
146
+ continue;
147
+ }
148
+
149
+ const contentStr = (await fsPr.readFile(filePath)).toString("utf8");
150
+
151
+ const payload = (() => {
152
+ const index_start = contentStr.indexOf(DELIMITER_START);
153
+ const index_end = contentStr.indexOf(DELIMITER_END);
154
+
155
+ if (index_start === -1 || index_end === -1) {
156
+ return undefined;
157
+ }
158
+
159
+ return contentStr
160
+ .slice(index_start + DELIMITER_START.length, index_end)
161
+ .trim();
162
+ })();
163
+
164
+ if (payload === undefined) {
165
+ continue;
166
+ }
167
+
168
+ payload
169
+ .split("\n")
170
+ .map(line => line.trim())
171
+ .map(line => line.replace(/^# /, ""))
172
+ .filter(line => line !== "")
173
+ .map(line =>
174
+ getAbsoluteAndInOsFormatPath({
175
+ cwd: buildContext.themeSrcDirPath,
176
+ pathIsh: line
177
+ })
178
+ )
179
+ .map(filePath => pathRelative(buildContext.themeSrcDirPath, filePath))
180
+ .forEach(fileRelativePath =>
181
+ ownedFilesRelativePaths.push({
182
+ isPublic: isPublicIteration,
183
+ fileRelativePath
184
+ })
185
+ );
186
+ }
187
+
188
+ return { ownedFilesRelativePaths };
189
+ }
@@ -2,9 +2,9 @@ import type { BuildContext } from "../shared/buildContext";
2
2
  import { getExtensionModuleMetas, computeHash } from "./extensionModuleMeta";
3
3
  import { installExtensionModulesPeerDependencies } from "./installExtensionModulesPeerDependencies";
4
4
  import {
5
- readManagedGitignoreFile,
6
- writeManagedGitignoreFile
7
- } from "./managedGitignoreFile";
5
+ readManagedGitignoresFile,
6
+ writeManagedGitignoreFiles
7
+ } from "./managedGitignoreFiles";
8
8
  import { dirname as pathDirname } from "path";
9
9
  import { join as pathJoin } from "path";
10
10
  import { existsAsync } from "../tools/fs.existsAsync";
@@ -12,6 +12,8 @@ import * as fsPr from "fs/promises";
12
12
  import { getIsKnownByGit, untrackFromGit } from "../tools/gitUtils";
13
13
  import { command as updateKcGenCommand } from "../update-kc-gen";
14
14
  import { getBuildContext } from "../shared/buildContext";
15
+ import { KEYCLOAK_THEME } from "../shared/constants";
16
+ import { same } from "evt/tools/inDepth/same";
15
17
 
16
18
  export async function command(params: { buildContext: BuildContext }) {
17
19
  const { buildContext } = params;
@@ -23,11 +25,11 @@ export async function command(params: { buildContext: BuildContext }) {
23
25
  extensionModuleMetas
24
26
  });
25
27
 
26
- const { ownedFilesRelativePaths } = await readManagedGitignoreFile({
28
+ const { ownedFilesRelativePaths } = await readManagedGitignoresFile({
27
29
  buildContext
28
30
  });
29
31
 
30
- await writeManagedGitignoreFile({
32
+ await writeManagedGitignoreFiles({
31
33
  buildContext,
32
34
  ownedFilesRelativePaths,
33
35
  extensionModuleMetas
@@ -38,13 +40,24 @@ export async function command(params: { buildContext: BuildContext }) {
38
40
  .map(extensionModuleMeta =>
39
41
  Promise.all(
40
42
  extensionModuleMeta.files.map(
41
- async ({ fileRelativePath, copyableFilePath, hash }) => {
42
- if (ownedFilesRelativePaths.includes(fileRelativePath)) {
43
+ async ({
44
+ isPublic,
45
+ fileRelativePath,
46
+ copyableFilePath,
47
+ hash
48
+ }) => {
49
+ if (
50
+ ownedFilesRelativePaths.some(entry =>
51
+ same(entry, { isPublic, fileRelativePath })
52
+ )
53
+ ) {
43
54
  return;
44
55
  }
45
56
 
46
57
  const destFilePath = pathJoin(
47
- buildContext.themeSrcDirPath,
58
+ isPublic
59
+ ? pathJoin(buildContext.publicDirPath, KEYCLOAK_THEME)
60
+ : buildContext.themeSrcDirPath,
48
61
  fileRelativePath
49
62
  );
50
63
 
@@ -2,7 +2,8 @@ import { join as pathJoin, relative as pathRelative, sep as pathSep } from "path
2
2
  import type { Plugin } from "vite";
3
3
  import {
4
4
  WELL_KNOWN_DIRECTORY_BASE_NAME,
5
- VITE_PLUGIN_SUB_SCRIPTS_ENV_NAMES
5
+ VITE_PLUGIN_SUB_SCRIPTS_ENV_NAMES,
6
+ KEYCLOAK_THEME
6
7
  } from "../bin/shared/constants";
7
8
  import { id } from "tsafe/id";
8
9
  import { rm } from "../bin/tools/fs.rm";
@@ -203,6 +204,7 @@ export function keycloakify(params: keycloakify.Params) {
203
204
 
204
205
  assert(buildDirPath !== undefined);
205
206
 
207
+ // NOTE: This is legacy and should eventually be removed
206
208
  await rm(
207
209
  pathJoin(
208
210
  buildDirPath,
@@ -213,6 +215,11 @@ export function keycloakify(params: keycloakify.Params) {
213
215
  force: true
214
216
  }
215
217
  );
218
+
219
+ await rm(pathJoin(buildDirPath, KEYCLOAK_THEME), {
220
+ recursive: true,
221
+ force: true
222
+ });
216
223
  },
217
224
  transformIndexHtml: html => {
218
225
  const doReadKcContextFromUrl =
@@ -2118,10 +2118,15 @@ function keycloakify(params) {
2118
2118
  return;
2119
2119
  }
2120
2120
  (0, assert_1.assert)(buildDirPath !== undefined);
2121
+ // NOTE: This is legacy and should eventually be removed
2121
2122
  await (0, fs_rm_1.rm)((0, path_1.join)(buildDirPath, constants_1.WELL_KNOWN_DIRECTORY_BASE_NAME.KEYCLOAKIFY_DEV_RESOURCES), {
2122
2123
  recursive: true,
2123
2124
  force: true
2124
2125
  });
2126
+ await (0, fs_rm_1.rm)((0, path_1.join)(buildDirPath, constants_1.KEYCLOAK_THEME), {
2127
+ recursive: true,
2128
+ force: true
2129
+ });
2125
2130
  },
2126
2131
  transformIndexHtml: html => {
2127
2132
  const doReadKcContextFromUrl = process.env.NODE_ENV === "development" &&
@@ -1,14 +0,0 @@
1
- import type { ExtensionModuleMeta } from "./extensionModuleMeta";
2
- export type BuildContextLike = {
3
- themeSrcDirPath: string;
4
- };
5
- export declare function writeManagedGitignoreFile(params: {
6
- buildContext: BuildContextLike;
7
- extensionModuleMetas: ExtensionModuleMeta[];
8
- ownedFilesRelativePaths: string[];
9
- }): Promise<void>;
10
- export declare function readManagedGitignoreFile(params: {
11
- buildContext: BuildContextLike;
12
- }): Promise<{
13
- ownedFilesRelativePaths: string[];
14
- }>;
@@ -1,136 +0,0 @@
1
- import * as fsPr from "fs/promises";
2
- import {
3
- join as pathJoin,
4
- sep as pathSep,
5
- dirname as pathDirname,
6
- relative as pathRelative
7
- } from "path";
8
- import { assert } from "tsafe/assert";
9
- import type { BuildContext } from "../shared/buildContext";
10
- import type { ExtensionModuleMeta } from "./extensionModuleMeta";
11
- import { existsAsync } from "../tools/fs.existsAsync";
12
- import { getAbsoluteAndInOsFormatPath } from "../tools/getAbsoluteAndInOsFormatPath";
13
-
14
- export type BuildContextLike = {
15
- themeSrcDirPath: string;
16
- };
17
-
18
- assert<BuildContext extends BuildContextLike ? true : false>();
19
-
20
- const DELIMITER_START = `# === Owned files start ===`;
21
- const DELIMITER_END = `# === Owned files end =====`;
22
-
23
- export async function writeManagedGitignoreFile(params: {
24
- buildContext: BuildContextLike;
25
- extensionModuleMetas: ExtensionModuleMeta[];
26
- ownedFilesRelativePaths: string[];
27
- }): Promise<void> {
28
- const { buildContext, extensionModuleMetas, ownedFilesRelativePaths } = params;
29
-
30
- if (extensionModuleMetas.length === 0) {
31
- return;
32
- }
33
-
34
- const filePath = pathJoin(buildContext.themeSrcDirPath, ".gitignore");
35
-
36
- const content_new = Buffer.from(
37
- [
38
- `# This file is managed by Keycloakify, do not edit it manually.`,
39
- ``,
40
- DELIMITER_START,
41
- ...ownedFilesRelativePaths
42
- .map(fileRelativePath => fileRelativePath.split(pathSep).join("/"))
43
- .map(line => `# ${line}`),
44
- DELIMITER_END,
45
- ``,
46
- ...extensionModuleMetas
47
- .map(extensionModuleMeta => [
48
- `# === ${extensionModuleMeta.moduleName} v${extensionModuleMeta.version} ===`,
49
- ...extensionModuleMeta.files
50
- .map(({ fileRelativePath }) => fileRelativePath)
51
- .filter(
52
- fileRelativePath =>
53
- !ownedFilesRelativePaths.includes(fileRelativePath)
54
- )
55
- .map(
56
- fileRelativePath =>
57
- `/${fileRelativePath.split(pathSep).join("/").replace(/^\.\//, "")}`
58
- ),
59
-
60
- ``
61
- ])
62
- .flat()
63
- ].join("\n"),
64
- "utf8"
65
- );
66
-
67
- const content_current = await (async () => {
68
- if (!(await existsAsync(filePath))) {
69
- return undefined;
70
- }
71
-
72
- return await fsPr.readFile(filePath);
73
- })();
74
-
75
- if (content_current !== undefined && content_current.equals(content_new)) {
76
- return;
77
- }
78
-
79
- create_dir: {
80
- const dirPath = pathDirname(filePath);
81
-
82
- if (await existsAsync(dirPath)) {
83
- break create_dir;
84
- }
85
-
86
- await fsPr.mkdir(dirPath, { recursive: true });
87
- }
88
-
89
- await fsPr.writeFile(filePath, content_new);
90
- }
91
-
92
- export async function readManagedGitignoreFile(params: {
93
- buildContext: BuildContextLike;
94
- }): Promise<{
95
- ownedFilesRelativePaths: string[];
96
- }> {
97
- const { buildContext } = params;
98
-
99
- const filePath = pathJoin(buildContext.themeSrcDirPath, ".gitignore");
100
-
101
- if (!(await existsAsync(filePath))) {
102
- return { ownedFilesRelativePaths: [] };
103
- }
104
-
105
- const contentStr = (await fsPr.readFile(filePath)).toString("utf8");
106
-
107
- const payload = (() => {
108
- const index_start = contentStr.indexOf(DELIMITER_START);
109
- const index_end = contentStr.indexOf(DELIMITER_END);
110
-
111
- if (index_start === -1 || index_end === -1) {
112
- return undefined;
113
- }
114
-
115
- return contentStr.slice(index_start + DELIMITER_START.length, index_end).trim();
116
- })();
117
-
118
- if (payload === undefined) {
119
- return { ownedFilesRelativePaths: [] };
120
- }
121
-
122
- const ownedFilesRelativePaths = payload
123
- .split("\n")
124
- .map(line => line.trim())
125
- .map(line => line.replace(/^# /, ""))
126
- .filter(line => line !== "")
127
- .map(line =>
128
- getAbsoluteAndInOsFormatPath({
129
- cwd: buildContext.themeSrcDirPath,
130
- pathIsh: line
131
- })
132
- )
133
- .map(filePath => pathRelative(buildContext.themeSrcDirPath, filePath));
134
-
135
- return { ownedFilesRelativePaths };
136
- }