keycloakify 11.6.0 → 11.6.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 (49) hide show
  1. package/bin/{805.index.js → 174.index.js} +111 -2
  2. package/bin/363.index.js +1528 -0
  3. package/bin/453.index.js +1 -1
  4. package/bin/{33.index.js → 568.index.js} +2 -113
  5. package/bin/735.index.js +53 -24
  6. package/bin/{653.index.js → 840.index.js} +387 -213
  7. package/bin/921.index.js +1 -1
  8. package/bin/930.index.js +165 -0
  9. package/bin/946.index.js +20 -0
  10. package/bin/initialize-admin-theme.d.ts +4 -0
  11. package/bin/main.js +72 -18
  12. package/bin/{eject-file.d.ts → own.d.ts} +2 -1
  13. package/bin/shared/addSyncExtensionsToPostinstallScript.d.ts +10 -0
  14. package/bin/shared/customHandler.d.ts +1 -1
  15. package/bin/shared/customHandler.js.map +1 -1
  16. package/bin/{postinstall/uiModuleMeta.d.ts → sync-extensions/extensionModuleMeta.d.ts} +5 -5
  17. package/bin/sync-extensions/getExtensionModuleFileSourceCodeReadyToBeCopied.d.ts +12 -0
  18. package/bin/sync-extensions/index.d.ts +1 -0
  19. package/bin/{postinstall/installUiModulesPeerDependencies.d.ts → sync-extensions/installExtensionModulesPeerDependencies.d.ts} +3 -3
  20. package/bin/{postinstall → sync-extensions}/managedGitignoreFile.d.ts +4 -4
  21. package/bin/tools/isKnownByGit.d.ts +3 -0
  22. package/bin/tools/npmInstall.d.ts +1 -1
  23. package/package.json +27 -22
  24. package/src/bin/eject-page.ts +1 -3
  25. package/src/bin/initialize-account-theme/initializeAccountTheme_singlePage.ts +3 -1
  26. package/src/bin/initialize-admin-theme.ts +146 -0
  27. package/src/bin/main.ts +76 -17
  28. package/src/bin/own.ts +209 -0
  29. package/src/bin/shared/addSyncExtensionsToPostinstallScript.ts +70 -0
  30. package/src/bin/shared/customHandler.ts +1 -0
  31. package/src/bin/{postinstall/uiModuleMeta.ts → sync-extensions/extensionModuleMeta.ts} +55 -43
  32. package/src/bin/{postinstall/getUiModuleFileSourceCodeReadyToBeCopied.ts → sync-extensions/getExtensionModuleFileSourceCodeReadyToBeCopied.ts} +32 -21
  33. package/src/bin/sync-extensions/index.ts +1 -0
  34. package/src/bin/{postinstall/installUiModulesPeerDependencies.ts → sync-extensions/installExtensionModulesPeerDependencies.ts} +16 -14
  35. package/src/bin/{postinstall → sync-extensions}/managedGitignoreFile.ts +18 -18
  36. package/src/bin/{postinstall/postinstall.ts → sync-extensions/sync-extension.ts} +14 -26
  37. package/src/bin/tools/isKnownByGit.ts +45 -0
  38. package/src/bin/tools/listInstalledModules.ts +2 -2
  39. package/src/bin/tools/npmInstall.ts +46 -9
  40. package/src/bin/tools/untrackFromGit.ts +19 -3
  41. package/bin/356.index.js +0 -755
  42. package/bin/854.index.js +0 -68
  43. package/bin/postinstall/getUiModuleFileSourceCodeReadyToBeCopied.d.ts +0 -12
  44. package/bin/postinstall/index.d.ts +0 -1
  45. package/bin/tools/isTrackedByGit.d.ts +0 -3
  46. package/src/bin/eject-file.ts +0 -68
  47. package/src/bin/postinstall/index.ts +0 -1
  48. package/src/bin/tools/isTrackedByGit.ts +0 -29
  49. /package/bin/{postinstall/postinstall.d.ts → sync-extensions/sync-extension.d.ts} +0 -0
@@ -10,14 +10,15 @@ import { crawlAsync } from "../tools/crawlAsync";
10
10
  import { getIsPrettierAvailable, getPrettier } from "../tools/runPrettier";
11
11
  import { readThisNpmPackageVersion } from "../tools/readThisNpmPackageVersion";
12
12
  import {
13
- getUiModuleFileSourceCodeReadyToBeCopied,
14
- type BuildContextLike as BuildContextLike_getUiModuleFileSourceCodeReadyToBeCopied
15
- } from "./getUiModuleFileSourceCodeReadyToBeCopied";
13
+ getExtensionModuleFileSourceCodeReadyToBeCopied,
14
+ type BuildContextLike as BuildContextLike_getExtensionModuleFileSourceCodeReadyToBeCopied
15
+ } from "./getExtensionModuleFileSourceCodeReadyToBeCopied";
16
16
  import * as crypto from "crypto";
17
17
  import { KEYCLOAK_THEME } from "../shared/constants";
18
18
  import { exclude } from "tsafe/exclude";
19
+ import { isAmong } from "tsafe/isAmong";
19
20
 
20
- export type UiModuleMeta = {
21
+ export type ExtensionModuleMeta = {
21
22
  moduleName: string;
22
23
  version: string;
23
24
  files: {
@@ -28,8 +29,8 @@ export type UiModuleMeta = {
28
29
  peerDependencies: Record<string, string>;
29
30
  };
30
31
 
31
- const zUiModuleMeta = (() => {
32
- type ExpectedType = UiModuleMeta;
32
+ const zExtensionModuleMeta = (() => {
33
+ type ExpectedType = ExtensionModuleMeta;
33
34
 
34
35
  const zTargetType = z.object({
35
36
  moduleName: z.string(),
@@ -55,7 +56,7 @@ type ParsedCacheFile = {
55
56
  keycloakifyVersion: string;
56
57
  prettierConfigHash: string | null;
57
58
  thisFilePath: string;
58
- uiModuleMetas: UiModuleMeta[];
59
+ extensionModuleMetas: ExtensionModuleMeta[];
59
60
  };
60
61
 
61
62
  const zParsedCacheFile = (() => {
@@ -65,7 +66,7 @@ const zParsedCacheFile = (() => {
65
66
  keycloakifyVersion: z.string(),
66
67
  prettierConfigHash: z.union([z.string(), z.null()]),
67
68
  thisFilePath: z.string(),
68
- uiModuleMetas: z.array(zUiModuleMeta)
69
+ extensionModuleMetas: z.array(zExtensionModuleMeta)
69
70
  });
70
71
 
71
72
  type InferredType = z.infer<typeof zTargetType>;
@@ -75,10 +76,10 @@ const zParsedCacheFile = (() => {
75
76
  return id<z.ZodType<ExpectedType>>(zTargetType);
76
77
  })();
77
78
 
78
- const CACHE_FILE_RELATIVE_PATH = pathJoin("ui-modules", "cache.json");
79
+ const CACHE_FILE_RELATIVE_PATH = pathJoin("extension-modules", "cache.json");
79
80
 
80
81
  export type BuildContextLike =
81
- BuildContextLike_getUiModuleFileSourceCodeReadyToBeCopied & {
82
+ BuildContextLike_getExtensionModuleFileSourceCodeReadyToBeCopied & {
82
83
  cacheDirPath: string;
83
84
  packageJsonFilePath: string;
84
85
  projectDirPath: string;
@@ -86,9 +87,9 @@ export type BuildContextLike =
86
87
 
87
88
  assert<BuildContext extends BuildContextLike ? true : false>();
88
89
 
89
- export async function getUiModuleMetas(params: {
90
+ export async function getExtensionModuleMetas(params: {
90
91
  buildContext: BuildContextLike;
91
- }): Promise<UiModuleMeta[]> {
92
+ }): Promise<ExtensionModuleMeta[]> {
92
93
  const { buildContext } = params;
93
94
 
94
95
  const cacheFilePath = pathJoin(buildContext.cacheDirPath, CACHE_FILE_RELATIVE_PATH);
@@ -105,7 +106,7 @@ export async function getUiModuleMetas(params: {
105
106
  return configHash;
106
107
  })();
107
108
 
108
- const installedUiModules = await (async () => {
109
+ const installedExtensionModules = await (async () => {
109
110
  const installedModulesWithKeycloakifyInTheName = await listInstalledModules({
110
111
  packageJsonFilePath: buildContext.packageJsonFilePath,
111
112
  projectDirPath: buildContext.packageJsonFilePath,
@@ -133,7 +134,7 @@ export async function getUiModuleMetas(params: {
133
134
  return await fsPr.readFile(cacheFilePath);
134
135
  })();
135
136
 
136
- const uiModuleMetas_cacheUpToDate: UiModuleMeta[] = await (async () => {
137
+ const extensionModuleMetas_cacheUpToDate: ExtensionModuleMeta[] = await (async () => {
137
138
  const parsedCacheFile: ParsedCacheFile | undefined = await (async () => {
138
139
  if (cacheContent === undefined) {
139
140
  return undefined;
@@ -176,45 +177,51 @@ export async function getUiModuleMetas(params: {
176
177
  return [];
177
178
  }
178
179
 
179
- const uiModuleMetas_cacheUpToDate = parsedCacheFile.uiModuleMetas.filter(
180
- uiModuleMeta => {
181
- const correspondingInstalledUiModule = installedUiModules.find(
182
- installedUiModule =>
183
- installedUiModule.moduleName === uiModuleMeta.moduleName
184
- );
180
+ const extensionModuleMetas_cacheUpToDate =
181
+ parsedCacheFile.extensionModuleMetas.filter(extensionModuleMeta => {
182
+ const correspondingInstalledExtensionModule =
183
+ installedExtensionModules.find(
184
+ installedExtensionModule =>
185
+ installedExtensionModule.moduleName ===
186
+ extensionModuleMeta.moduleName
187
+ );
185
188
 
186
- if (correspondingInstalledUiModule === undefined) {
189
+ if (correspondingInstalledExtensionModule === undefined) {
187
190
  return false;
188
191
  }
189
192
 
190
- return correspondingInstalledUiModule.version === uiModuleMeta.version;
191
- }
192
- );
193
+ return (
194
+ correspondingInstalledExtensionModule.version ===
195
+ extensionModuleMeta.version
196
+ );
197
+ });
193
198
 
194
- return uiModuleMetas_cacheUpToDate;
199
+ return extensionModuleMetas_cacheUpToDate;
195
200
  })();
196
201
 
197
- const uiModuleMetas = await Promise.all(
198
- installedUiModules.map(
202
+ const extensionModuleMetas = await Promise.all(
203
+ installedExtensionModules.map(
199
204
  async ({
200
205
  moduleName,
201
206
  version,
202
207
  peerDependencies,
203
208
  dirPath
204
- }): Promise<UiModuleMeta> => {
209
+ }): Promise<ExtensionModuleMeta> => {
205
210
  use_cache: {
206
- const uiModuleMeta_cache = uiModuleMetas_cacheUpToDate.find(
207
- uiModuleMeta => uiModuleMeta.moduleName === moduleName
208
- );
211
+ const extensionModuleMeta_cache =
212
+ extensionModuleMetas_cacheUpToDate.find(
213
+ extensionModuleMeta =>
214
+ extensionModuleMeta.moduleName === moduleName
215
+ );
209
216
 
210
- if (uiModuleMeta_cache === undefined) {
217
+ if (extensionModuleMeta_cache === undefined) {
211
218
  break use_cache;
212
219
  }
213
220
 
214
- return uiModuleMeta_cache;
221
+ return extensionModuleMeta_cache;
215
222
  }
216
223
 
217
- const files: UiModuleMeta["files"] = [];
224
+ const files: ExtensionModuleMeta["files"] = [];
218
225
 
219
226
  {
220
227
  const srcDirPath = pathJoin(dirPath, KEYCLOAK_THEME);
@@ -224,13 +231,13 @@ export async function getUiModuleMetas(params: {
224
231
  returnedPathsType: "relative to dirPath",
225
232
  onFileFound: async fileRelativePath => {
226
233
  const sourceCode =
227
- await getUiModuleFileSourceCodeReadyToBeCopied({
234
+ await getExtensionModuleFileSourceCodeReadyToBeCopied({
228
235
  buildContext,
229
236
  fileRelativePath,
230
- isForEjection: false,
231
- uiModuleDirPath: dirPath,
232
- uiModuleName: moduleName,
233
- uiModuleVersion: version
237
+ isOwnershipAction: false,
238
+ extensionModuleDirPath: dirPath,
239
+ extensionModuleName: moduleName,
240
+ extensionModuleVersion: version
234
241
  });
235
242
 
236
243
  const hash = computeHash(sourceCode);
@@ -260,11 +267,16 @@ export async function getUiModuleMetas(params: {
260
267
  });
261
268
  }
262
269
 
263
- return id<UiModuleMeta>({
270
+ return id<ExtensionModuleMeta>({
264
271
  moduleName,
265
272
  version,
266
273
  files,
267
- peerDependencies
274
+ peerDependencies: Object.fromEntries(
275
+ Object.entries(peerDependencies).filter(
276
+ ([moduleName]) =>
277
+ !isAmong(["react", "@types/react"], moduleName)
278
+ )
279
+ )
268
280
  });
269
281
  }
270
282
  )
@@ -275,7 +287,7 @@ export async function getUiModuleMetas(params: {
275
287
  keycloakifyVersion,
276
288
  prettierConfigHash,
277
289
  thisFilePath: cacheFilePath,
278
- uiModuleMetas
290
+ extensionModuleMetas
279
291
  });
280
292
 
281
293
  const cacheContent_new = Buffer.from(
@@ -300,7 +312,7 @@ export async function getUiModuleMetas(params: {
300
312
  await fsPr.writeFile(cacheFilePath, cacheContent_new);
301
313
  }
302
314
 
303
- return uiModuleMetas;
315
+ return extensionModuleMetas;
304
316
  }
305
317
 
306
318
  export function computeHash(data: Buffer) {
@@ -11,40 +11,51 @@ export type BuildContextLike = {
11
11
 
12
12
  assert<BuildContext extends BuildContextLike ? true : false>();
13
13
 
14
- export async function getUiModuleFileSourceCodeReadyToBeCopied(params: {
14
+ export async function getExtensionModuleFileSourceCodeReadyToBeCopied(params: {
15
15
  buildContext: BuildContextLike;
16
16
  fileRelativePath: string;
17
- isForEjection: boolean;
18
- uiModuleDirPath: string;
19
- uiModuleName: string;
20
- uiModuleVersion: string;
17
+ isOwnershipAction: boolean;
18
+ extensionModuleDirPath: string;
19
+ extensionModuleName: string;
20
+ extensionModuleVersion: string;
21
21
  }): Promise<Buffer> {
22
22
  const {
23
23
  buildContext,
24
- uiModuleDirPath,
24
+ extensionModuleDirPath,
25
25
  fileRelativePath,
26
- isForEjection,
27
- uiModuleName,
28
- uiModuleVersion
26
+ isOwnershipAction,
27
+ extensionModuleName,
28
+ extensionModuleVersion
29
29
  } = params;
30
30
 
31
31
  let sourceCode = (
32
- await fsPr.readFile(pathJoin(uiModuleDirPath, KEYCLOAK_THEME, fileRelativePath))
32
+ await fsPr.readFile(
33
+ pathJoin(extensionModuleDirPath, KEYCLOAK_THEME, fileRelativePath)
34
+ )
33
35
  ).toString("utf8");
34
36
 
35
37
  sourceCode = addCommentToSourceCode({
36
38
  sourceCode,
37
39
  fileRelativePath,
38
- commentLines: isForEjection
39
- ? [`This file was ejected from ${uiModuleName} version ${uiModuleVersion}.`]
40
- : [
41
- `WARNING: Before modifying this file run the following command:`,
42
- ``,
43
- `$ npx keycloakify eject-file --file '${fileRelativePath.split(pathSep).join("/")}'`,
44
- ``,
45
- `This file comes from ${uiModuleName} version ${uiModuleVersion}.`,
46
- `This file has been copied over to your repo by your postinstall script: \`npx keycloakify postinstall\``
47
- ]
40
+ commentLines: (() => {
41
+ const path = fileRelativePath.split(pathSep).join("/");
42
+
43
+ return isOwnershipAction
44
+ ? [
45
+ `This file has been claimed for ownership from ${extensionModuleName} version ${extensionModuleVersion}.`,
46
+ `To relinquish ownership and restore this file to its original content, run the following command:`,
47
+ ``,
48
+ `$ npx keycloakify own --path '${path}' --revert`
49
+ ]
50
+ : [
51
+ `WARNING: Before modifying this file, run the following command:`,
52
+ ``,
53
+ `$ npx keycloakify own --path '${path}'`,
54
+ ``,
55
+ `This file is provided by ${extensionModuleName} version ${extensionModuleVersion}.`,
56
+ `It was copied into your repository by the postinstall script: \`keycloakify sync-extensions\`.`
57
+ ];
58
+ })()
48
59
  });
49
60
 
50
61
  const destFilePath = pathJoin(buildContext.themeSrcDirPath, fileRelativePath);
@@ -93,7 +104,7 @@ function addCommentToSourceCode(params: {
93
104
  `<!--`,
94
105
  ...commentLines.map(
95
106
  line =>
96
- ` ${line.replace("--file", "-f").replace("Before modifying", "Before modifying or replacing")}`
107
+ ` ${line.replace("--path", "-p").replace("Before modifying", "Before modifying or replacing")}`
97
108
  ),
98
109
  `-->`
99
110
  ].join("\n");
@@ -0,0 +1 @@
1
+ export * from "./sync-extension";
@@ -1,6 +1,6 @@
1
1
  import { assert, type Equals, is } from "tsafe/assert";
2
2
  import type { BuildContext } from "../shared/buildContext";
3
- import type { UiModuleMeta } from "./uiModuleMeta";
3
+ import type { ExtensionModuleMeta } from "./extensionModuleMeta";
4
4
  import { z } from "zod";
5
5
  import { id } from "tsafe/id";
6
6
  import * as fsPr from "fs/promises";
@@ -16,29 +16,29 @@ export type BuildContextLike = {
16
16
 
17
17
  assert<BuildContext extends BuildContextLike ? true : false>();
18
18
 
19
- export type UiModuleMetaLike = {
19
+ export type ExtensionModuleMetaLike = {
20
20
  moduleName: string;
21
21
  peerDependencies: Record<string, string>;
22
22
  };
23
23
 
24
- assert<UiModuleMeta extends UiModuleMetaLike ? true : false>();
24
+ assert<ExtensionModuleMeta extends ExtensionModuleMetaLike ? true : false>();
25
25
 
26
- export async function installUiModulesPeerDependencies(params: {
26
+ export async function installExtensionModulesPeerDependencies(params: {
27
27
  buildContext: BuildContextLike;
28
- uiModuleMetas: UiModuleMetaLike[];
28
+ extensionModuleMetas: ExtensionModuleMetaLike[];
29
29
  }): Promise<void | never> {
30
- const { buildContext, uiModuleMetas } = params;
30
+ const { buildContext, extensionModuleMetas } = params;
31
31
 
32
- const { uiModulesPerDependencies } = (() => {
33
- const uiModulesPerDependencies: Record<string, string> = {};
32
+ const { extensionModulesPerDependencies } = (() => {
33
+ const extensionModulesPerDependencies: Record<string, string> = {};
34
34
 
35
- for (const { peerDependencies } of uiModuleMetas) {
35
+ for (const { peerDependencies } of extensionModuleMetas) {
36
36
  for (const [peerDependencyName, versionRange_candidate] of Object.entries(
37
37
  peerDependencies
38
38
  )) {
39
39
  const versionRange = (() => {
40
40
  const versionRange_current =
41
- uiModulesPerDependencies[peerDependencyName];
41
+ extensionModulesPerDependencies[peerDependencyName];
42
42
 
43
43
  if (versionRange_current === undefined) {
44
44
  return versionRange_candidate;
@@ -76,11 +76,11 @@ export async function installUiModulesPeerDependencies(params: {
76
76
  return versionRange;
77
77
  })();
78
78
 
79
- uiModulesPerDependencies[peerDependencyName] = versionRange;
79
+ extensionModulesPerDependencies[peerDependencyName] = versionRange;
80
80
  }
81
81
  }
82
82
 
83
- return { uiModulesPerDependencies };
83
+ return { extensionModulesPerDependencies };
84
84
  })();
85
85
 
86
86
  const parsedPackageJson = await (async () => {
@@ -117,7 +117,9 @@ export async function installUiModulesPeerDependencies(params: {
117
117
 
118
118
  const parsedPackageJson_before = JSON.parse(JSON.stringify(parsedPackageJson));
119
119
 
120
- for (const [moduleName, versionRange] of Object.entries(uiModulesPerDependencies)) {
120
+ for (const [moduleName, versionRange] of Object.entries(
121
+ extensionModulesPerDependencies
122
+ )) {
121
123
  if (moduleName.startsWith("@types/")) {
122
124
  (parsedPackageJson.devDependencies ??= {})[moduleName] = versionRange;
123
125
  continue;
@@ -149,7 +151,7 @@ export async function installUiModulesPeerDependencies(params: {
149
151
 
150
152
  await fsPr.writeFile(buildContext.packageJsonFilePath, packageJsonContentStr);
151
153
 
152
- npmInstall({
154
+ await npmInstall({
153
155
  packageJsonDirPath: pathDirname(buildContext.packageJsonFilePath)
154
156
  });
155
157
 
@@ -7,7 +7,7 @@ import {
7
7
  } from "path";
8
8
  import { assert } from "tsafe/assert";
9
9
  import type { BuildContext } from "../shared/buildContext";
10
- import type { UiModuleMeta } from "./uiModuleMeta";
10
+ import type { ExtensionModuleMeta } from "./extensionModuleMeta";
11
11
  import { existsAsync } from "../tools/fs.existsAsync";
12
12
  import { getAbsoluteAndInOsFormatPath } from "../tools/getAbsoluteAndInOsFormatPath";
13
13
 
@@ -17,17 +17,17 @@ export type BuildContextLike = {
17
17
 
18
18
  assert<BuildContext extends BuildContextLike ? true : false>();
19
19
 
20
- const DELIMITER_START = `# === Ejected files start ===`;
21
- const DELIMITER_END = `# === Ejected files end =====`;
20
+ const DELIMITER_START = `# === Owned files start ===`;
21
+ const DELIMITER_END = `# === Owned files end =====`;
22
22
 
23
23
  export async function writeManagedGitignoreFile(params: {
24
24
  buildContext: BuildContextLike;
25
- uiModuleMetas: UiModuleMeta[];
26
- ejectedFilesRelativePaths: string[];
25
+ extensionModuleMetas: ExtensionModuleMeta[];
26
+ ownedFilesRelativePaths: string[];
27
27
  }): Promise<void> {
28
- const { buildContext, uiModuleMetas, ejectedFilesRelativePaths } = params;
28
+ const { buildContext, extensionModuleMetas, ownedFilesRelativePaths } = params;
29
29
 
30
- if (uiModuleMetas.length === 0) {
30
+ if (extensionModuleMetas.length === 0) {
31
31
  return;
32
32
  }
33
33
 
@@ -38,19 +38,19 @@ export async function writeManagedGitignoreFile(params: {
38
38
  `# This file is managed by Keycloakify, do not edit it manually.`,
39
39
  ``,
40
40
  DELIMITER_START,
41
- ...ejectedFilesRelativePaths
41
+ ...ownedFilesRelativePaths
42
42
  .map(fileRelativePath => fileRelativePath.split(pathSep).join("/"))
43
43
  .map(line => `# ${line}`),
44
44
  DELIMITER_END,
45
45
  ``,
46
- ...uiModuleMetas
47
- .map(uiModuleMeta => [
48
- `# === ${uiModuleMeta.moduleName} v${uiModuleMeta.version} ===`,
49
- ...uiModuleMeta.files
46
+ ...extensionModuleMetas
47
+ .map(extensionModuleMeta => [
48
+ `# === ${extensionModuleMeta.moduleName} v${extensionModuleMeta.version} ===`,
49
+ ...extensionModuleMeta.files
50
50
  .map(({ fileRelativePath }) => fileRelativePath)
51
51
  .filter(
52
52
  fileRelativePath =>
53
- !ejectedFilesRelativePaths.includes(fileRelativePath)
53
+ !ownedFilesRelativePaths.includes(fileRelativePath)
54
54
  )
55
55
  .map(
56
56
  fileRelativePath =>
@@ -92,14 +92,14 @@ export async function writeManagedGitignoreFile(params: {
92
92
  export async function readManagedGitignoreFile(params: {
93
93
  buildContext: BuildContextLike;
94
94
  }): Promise<{
95
- ejectedFilesRelativePaths: string[];
95
+ ownedFilesRelativePaths: string[];
96
96
  }> {
97
97
  const { buildContext } = params;
98
98
 
99
99
  const filePath = pathJoin(buildContext.themeSrcDirPath, ".gitignore");
100
100
 
101
101
  if (!(await existsAsync(filePath))) {
102
- return { ejectedFilesRelativePaths: [] };
102
+ return { ownedFilesRelativePaths: [] };
103
103
  }
104
104
 
105
105
  const contentStr = (await fsPr.readFile(filePath)).toString("utf8");
@@ -116,10 +116,10 @@ export async function readManagedGitignoreFile(params: {
116
116
  })();
117
117
 
118
118
  if (payload === undefined) {
119
- return { ejectedFilesRelativePaths: [] };
119
+ return { ownedFilesRelativePaths: [] };
120
120
  }
121
121
 
122
- const ejectedFilesRelativePaths = payload
122
+ const ownedFilesRelativePaths = payload
123
123
  .split("\n")
124
124
  .map(line => line.trim())
125
125
  .map(line => line.replace(/^# /, ""))
@@ -132,5 +132,5 @@ export async function readManagedGitignoreFile(params: {
132
132
  )
133
133
  .map(filePath => pathRelative(buildContext.themeSrcDirPath, filePath));
134
134
 
135
- return { ejectedFilesRelativePaths };
135
+ return { ownedFilesRelativePaths };
136
136
  }
@@ -1,6 +1,6 @@
1
1
  import type { BuildContext } from "../shared/buildContext";
2
- import { getUiModuleMetas, computeHash } from "./uiModuleMeta";
3
- import { installUiModulesPeerDependencies } from "./installUiModulesPeerDependencies";
2
+ import { getExtensionModuleMetas, computeHash } from "./extensionModuleMeta";
3
+ import { installExtensionModulesPeerDependencies } from "./installExtensionModulesPeerDependencies";
4
4
  import {
5
5
  readManagedGitignoreFile,
6
6
  writeManagedGitignoreFile
@@ -9,36 +9,36 @@ import { dirname as pathDirname } from "path";
9
9
  import { join as pathJoin } from "path";
10
10
  import { existsAsync } from "../tools/fs.existsAsync";
11
11
  import * as fsPr from "fs/promises";
12
- import { getIsTrackedByGit } from "../tools/isTrackedByGit";
12
+ import { getIsKnownByGit } from "../tools/isKnownByGit";
13
13
  import { untrackFromGit } from "../tools/untrackFromGit";
14
14
 
15
15
  export async function command(params: { buildContext: BuildContext }) {
16
16
  const { buildContext } = params;
17
17
 
18
- const uiModuleMetas = await getUiModuleMetas({ buildContext });
18
+ const extensionModuleMetas = await getExtensionModuleMetas({ buildContext });
19
19
 
20
- await installUiModulesPeerDependencies({
20
+ await installExtensionModulesPeerDependencies({
21
21
  buildContext,
22
- uiModuleMetas
22
+ extensionModuleMetas
23
23
  });
24
24
 
25
- const { ejectedFilesRelativePaths } = await readManagedGitignoreFile({
25
+ const { ownedFilesRelativePaths } = await readManagedGitignoreFile({
26
26
  buildContext
27
27
  });
28
28
 
29
29
  await writeManagedGitignoreFile({
30
30
  buildContext,
31
- ejectedFilesRelativePaths,
32
- uiModuleMetas
31
+ ownedFilesRelativePaths,
32
+ extensionModuleMetas
33
33
  });
34
34
 
35
35
  await Promise.all(
36
- uiModuleMetas
37
- .map(uiModuleMeta =>
36
+ extensionModuleMetas
37
+ .map(extensionModuleMeta =>
38
38
  Promise.all(
39
- uiModuleMeta.files.map(
39
+ extensionModuleMeta.files.map(
40
40
  async ({ fileRelativePath, copyableFilePath, hash }) => {
41
- if (ejectedFilesRelativePaths.includes(fileRelativePath)) {
41
+ if (ownedFilesRelativePaths.includes(fileRelativePath)) {
42
42
  return;
43
43
  }
44
44
 
@@ -65,19 +65,7 @@ export async function command(params: { buildContext: BuildContext }) {
65
65
  return;
66
66
  }
67
67
 
68
- git_untrack: {
69
- if (!doesFileExist) {
70
- break git_untrack;
71
- }
72
-
73
- const isTracked = await getIsTrackedByGit({
74
- filePath: destFilePath
75
- });
76
-
77
- if (!isTracked) {
78
- break git_untrack;
79
- }
80
-
68
+ if (await getIsKnownByGit({ filePath: destFilePath })) {
81
69
  await untrackFromGit({
82
70
  filePath: destFilePath
83
71
  });
@@ -0,0 +1,45 @@
1
+ import * as child_process from "child_process";
2
+ import {
3
+ dirname as pathDirname,
4
+ basename as pathBasename,
5
+ join as pathJoin,
6
+ sep as pathSep
7
+ } from "path";
8
+ import { Deferred } from "evt/tools/Deferred";
9
+ import * as fs from "fs";
10
+
11
+ export function getIsKnownByGit(params: { filePath: string }): Promise<boolean> {
12
+ const { filePath } = params;
13
+
14
+ const dIsKnownByGit = new Deferred<boolean>();
15
+
16
+ let relativePath = pathBasename(filePath);
17
+
18
+ let dirPath = pathDirname(filePath);
19
+
20
+ while (!fs.existsSync(dirPath)) {
21
+ relativePath = pathJoin(pathBasename(dirPath), relativePath);
22
+
23
+ dirPath = pathDirname(dirPath);
24
+ }
25
+
26
+ child_process.exec(
27
+ `git ls-files --error-unmatch '${relativePath.split(pathSep).join("/")}'`,
28
+ { cwd: dirPath },
29
+ error => {
30
+ if (error === null) {
31
+ dIsKnownByGit.resolve(true);
32
+ return;
33
+ }
34
+
35
+ if (error.code === 1) {
36
+ dIsKnownByGit.resolve(false);
37
+ return;
38
+ }
39
+
40
+ dIsKnownByGit.reject(error);
41
+ }
42
+ );
43
+
44
+ return dIsKnownByGit.pr;
45
+ }
@@ -24,7 +24,7 @@ export async function listInstalledModules(params: {
24
24
  packageJsonFilePath
25
25
  });
26
26
 
27
- const uiModuleNames = (
27
+ const extensionModuleNames = (
28
28
  [parsedPackageJson.dependencies, parsedPackageJson.devDependencies] as const
29
29
  )
30
30
  .filter(exclude(undefined))
@@ -33,7 +33,7 @@ export async function listInstalledModules(params: {
33
33
  .filter(moduleName => filter({ moduleName }));
34
34
 
35
35
  const result = await Promise.all(
36
- uiModuleNames.map(async moduleName => {
36
+ extensionModuleNames.map(async moduleName => {
37
37
  const dirPath = await getInstalledModuleDirPath({
38
38
  moduleName,
39
39
  packageJsonDirPath: pathDirname(packageJsonFilePath),