@keycloakify/angular 0.0.11 → 0.1.0
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/bin/108.index.js +242 -0
- package/bin/338.index.js +104 -54
- package/bin/402.index.js +1250 -0
- package/bin/758.index.js +777 -53
- package/bin/{925.index.js → 84.index.js} +124 -624
- package/bin/main.js +59 -4
- package/package.json +1 -1
- package/src/bin/add-story.ts +126 -0
- package/src/bin/eject-page.ts +49 -11
- package/src/bin/main.ts +2 -4
- package/src/bin/tools/nodeModulesBinDirPath.ts +38 -0
- package/src/bin/tools/runPrettier.ts +89 -0
- package/src/bin/tools/transformCodebase_async.ts +89 -0
- package/src/bin/update-kc-gen.ts +20 -15
- package/stories/account/pages/account.stories.ts +133 -0
- package/stories/account/pages/applications.stories.ts +196 -0
- package/stories/account/pages/federated-identity.stories.ts +78 -0
- package/stories/account/pages/log.stories.ts +147 -0
- package/stories/account/pages/password.stories.ts +104 -0
- package/stories/account/pages/sessions.stories.ts +143 -0
- package/stories/account/pages/totp.stories.ts +100 -0
- package/stories/login/pages/code.stories.ts +51 -0
- package/stories/login/pages/delete-account-confirm.stories.ts +43 -0
- package/stories/login/pages/delete-credential.stories.ts +56 -0
- package/stories/login/pages/error.stories.ts +56 -0
- package/stories/login/pages/frontchannel-logout.stories.ts +26 -0
- package/stories/login/pages/idp-review-user-profile.stories.ts +60 -0
- package/stories/login/pages/info.stories.ts +94 -0
- package/stories/login/pages/login-config-totp.stories.ts +57 -0
- package/stories/login/pages/login-device-verify-user-code.stories.ts +14 -0
- package/stories/login/pages/login-idp-link-confirm-override.stories.ts +17 -0
- package/stories/login/pages/login-idp-link-confirm.stories.ts +103 -0
- package/stories/login/pages/login-idp-link-email.stories.ts +102 -0
- package/stories/login/pages/login-oauth-grant.stories.ts +68 -0
- package/stories/login/pages/login-oauth2-device-verify-user-code.stories.ts +15 -0
- package/stories/login/pages/login-otp.stories.ts +94 -0
- package/stories/login/pages/login-page-expired.stories.ts +31 -0
- package/stories/login/pages/login-passkeys-conditional-authenticate.stories.ts +16 -0
- package/stories/login/pages/login-password.stories.ts +52 -0
- package/stories/login/pages/login-recovery-authn-code-config.stories.ts +31 -0
- package/stories/login/pages/login-recovery-authn-code-input.stories.ts +16 -0
- package/stories/login/pages/login-reset-otp.stories.ts +71 -0
- package/stories/login/pages/login-reset-password.stories.ts +50 -0
- package/stories/login/pages/login-update-password.stories.ts +46 -0
- package/stories/login/pages/login-update-profile.stories.ts +31 -0
- package/stories/login/pages/login-username.stories.ts +28 -0
- package/stories/login/pages/login-verify-email.stories.ts +98 -0
- package/stories/login/pages/login-x509-info.stories.ts +40 -0
- package/stories/login/pages/login.stories.ts +260 -0
- package/stories/login/pages/logout-confirm.stories.ts +44 -0
- package/stories/login/pages/register.stories.ts +230 -0
- package/stories/login/pages/saml-post-form.stories.ts +17 -0
- package/stories/login/pages/select-authenticator.stories.ts +95 -0
- package/stories/login/pages/terms.stories.ts +79 -0
- package/stories/login/pages/update-email.stories.ts +31 -0
- package/stories/login/pages/webauthn-authenticate.stories.ts +126 -0
- package/stories/login/pages/webauthn-error.stories.ts +62 -0
- package/stories/login/pages/webauthn-register.stories.ts +46 -0
- package/src/bin/tools/runFormat.ts +0 -71
- package/src/stories/login/pages/login/login.stories.ts +0 -146
package/bin/main.js
CHANGED
|
@@ -102,6 +102,13 @@ module.exports = require("fs");
|
|
|
102
102
|
|
|
103
103
|
/***/ }),
|
|
104
104
|
|
|
105
|
+
/***/ 943:
|
|
106
|
+
/***/ ((module) => {
|
|
107
|
+
|
|
108
|
+
module.exports = require("fs/promises");
|
|
109
|
+
|
|
110
|
+
/***/ }),
|
|
111
|
+
|
|
105
112
|
/***/ 161:
|
|
106
113
|
/***/ ((module) => {
|
|
107
114
|
|
|
@@ -130,6 +137,13 @@ module.exports = require("path");
|
|
|
130
137
|
|
|
131
138
|
/***/ }),
|
|
132
139
|
|
|
140
|
+
/***/ 824:
|
|
141
|
+
/***/ ((module) => {
|
|
142
|
+
|
|
143
|
+
module.exports = require("prettier");
|
|
144
|
+
|
|
145
|
+
/***/ }),
|
|
146
|
+
|
|
133
147
|
/***/ 785:
|
|
134
148
|
/***/ ((module) => {
|
|
135
149
|
|
|
@@ -319,6 +333,36 @@ const assertIsRefWrapper = {
|
|
|
319
333
|
/******/ };
|
|
320
334
|
/******/ })();
|
|
321
335
|
/******/
|
|
336
|
+
/******/ /* webpack/runtime/create fake namespace object */
|
|
337
|
+
/******/ (() => {
|
|
338
|
+
/******/ var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__);
|
|
339
|
+
/******/ var leafPrototypes;
|
|
340
|
+
/******/ // create a fake namespace object
|
|
341
|
+
/******/ // mode & 1: value is a module id, require it
|
|
342
|
+
/******/ // mode & 2: merge all properties of value into the ns
|
|
343
|
+
/******/ // mode & 4: return value when already ns object
|
|
344
|
+
/******/ // mode & 16: return value when it's Promise-like
|
|
345
|
+
/******/ // mode & 8|1: behave like require
|
|
346
|
+
/******/ __nccwpck_require__.t = function(value, mode) {
|
|
347
|
+
/******/ if(mode & 1) value = this(value);
|
|
348
|
+
/******/ if(mode & 8) return value;
|
|
349
|
+
/******/ if(typeof value === 'object' && value) {
|
|
350
|
+
/******/ if((mode & 4) && value.__esModule) return value;
|
|
351
|
+
/******/ if((mode & 16) && typeof value.then === 'function') return value;
|
|
352
|
+
/******/ }
|
|
353
|
+
/******/ var ns = Object.create(null);
|
|
354
|
+
/******/ __nccwpck_require__.r(ns);
|
|
355
|
+
/******/ var def = {};
|
|
356
|
+
/******/ leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];
|
|
357
|
+
/******/ for(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) {
|
|
358
|
+
/******/ Object.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key])));
|
|
359
|
+
/******/ }
|
|
360
|
+
/******/ def['default'] = () => (value);
|
|
361
|
+
/******/ __nccwpck_require__.d(ns, def);
|
|
362
|
+
/******/ return ns;
|
|
363
|
+
/******/ };
|
|
364
|
+
/******/ })();
|
|
365
|
+
/******/
|
|
322
366
|
/******/ /* webpack/runtime/define property getters */
|
|
323
367
|
/******/ (() => {
|
|
324
368
|
/******/ // define getter functions for harmony exports
|
|
@@ -358,6 +402,17 @@ const assertIsRefWrapper = {
|
|
|
358
402
|
/******/ __nccwpck_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
359
403
|
/******/ })();
|
|
360
404
|
/******/
|
|
405
|
+
/******/ /* webpack/runtime/make namespace object */
|
|
406
|
+
/******/ (() => {
|
|
407
|
+
/******/ // define __esModule on exports
|
|
408
|
+
/******/ __nccwpck_require__.r = (exports) => {
|
|
409
|
+
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
|
410
|
+
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
411
|
+
/******/ }
|
|
412
|
+
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
413
|
+
/******/ };
|
|
414
|
+
/******/ })();
|
|
415
|
+
/******/
|
|
361
416
|
/******/ /* webpack/runtime/compat */
|
|
362
417
|
/******/
|
|
363
418
|
/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/";
|
|
@@ -439,19 +494,19 @@ const { buildContext, commandName } = readParams({ apiVersion: 'v1' });
|
|
|
439
494
|
switch (commandName) {
|
|
440
495
|
case 'add-story':
|
|
441
496
|
{
|
|
442
|
-
|
|
443
|
-
|
|
497
|
+
const { command } = await Promise.all(/* import() */[__nccwpck_require__.e(402), __nccwpck_require__.e(108)]).then(__nccwpck_require__.bind(__nccwpck_require__, 108));
|
|
498
|
+
command({ buildContext });
|
|
444
499
|
}
|
|
445
500
|
return;
|
|
446
501
|
case 'eject-page':
|
|
447
502
|
{
|
|
448
|
-
const { command } = await Promise.all(/* import() */[__nccwpck_require__.e(
|
|
503
|
+
const { command } = await Promise.all(/* import() */[__nccwpck_require__.e(402), __nccwpck_require__.e(84)]).then(__nccwpck_require__.bind(__nccwpck_require__, 84));
|
|
449
504
|
command({ buildContext });
|
|
450
505
|
}
|
|
451
506
|
return;
|
|
452
507
|
case 'update-kc-gen':
|
|
453
508
|
{
|
|
454
|
-
const { command } = await
|
|
509
|
+
const { command } = await __nccwpck_require__.e(/* import() */ 758).then(__nccwpck_require__.bind(__nccwpck_require__, 758));
|
|
455
510
|
command({ buildContext });
|
|
456
511
|
}
|
|
457
512
|
return;
|
package/package.json
CHANGED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { getThisCodebaseRootDirPath } from './tools/getThisCodebaseRootDirPath';
|
|
2
|
+
import cliSelect from 'cli-select';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import { join as pathJoin, relative as pathRelative, dirname as pathDirname } from 'path';
|
|
5
|
+
import { assert, Equals } from 'tsafe/assert';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import { runPrettier, getIsPrettierAvailable } from './tools/runPrettier';
|
|
8
|
+
import {
|
|
9
|
+
type BuildContext,
|
|
10
|
+
LOGIN_THEME_PAGE_IDS,
|
|
11
|
+
ACCOUNT_THEME_PAGE_IDS,
|
|
12
|
+
type LoginThemePageId,
|
|
13
|
+
type AccountThemePageId,
|
|
14
|
+
THEME_TYPES
|
|
15
|
+
} from './core';
|
|
16
|
+
|
|
17
|
+
export async function command(params: { buildContext: BuildContext }) {
|
|
18
|
+
const { buildContext } = params;
|
|
19
|
+
|
|
20
|
+
console.log(chalk.cyan('Theme type:'));
|
|
21
|
+
|
|
22
|
+
const themeType = await (async () => {
|
|
23
|
+
const values = THEME_TYPES.filter(themeType => {
|
|
24
|
+
switch (themeType) {
|
|
25
|
+
case 'account':
|
|
26
|
+
return buildContext.implementedThemeTypes.account.isImplemented;
|
|
27
|
+
case 'login':
|
|
28
|
+
return buildContext.implementedThemeTypes.login.isImplemented;
|
|
29
|
+
}
|
|
30
|
+
assert<Equals<typeof themeType, never>>(false);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
assert(values.length > 0, 'No theme is implemented in this project');
|
|
34
|
+
|
|
35
|
+
if (values.length === 1) {
|
|
36
|
+
return values[0];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const { value } = await cliSelect({
|
|
40
|
+
values
|
|
41
|
+
}).catch(() => {
|
|
42
|
+
process.exit(-1);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return value;
|
|
46
|
+
})();
|
|
47
|
+
|
|
48
|
+
console.log(`→ ${themeType}`);
|
|
49
|
+
|
|
50
|
+
console.log(chalk.cyan('Select the page you want to create a Storybook for:'));
|
|
51
|
+
|
|
52
|
+
const { value: pageId } = await cliSelect<LoginThemePageId | AccountThemePageId>({
|
|
53
|
+
values: (() => {
|
|
54
|
+
switch (themeType) {
|
|
55
|
+
case 'login':
|
|
56
|
+
return [...LOGIN_THEME_PAGE_IDS];
|
|
57
|
+
case 'account':
|
|
58
|
+
return [...ACCOUNT_THEME_PAGE_IDS];
|
|
59
|
+
}
|
|
60
|
+
assert<Equals<typeof themeType, never>>(false);
|
|
61
|
+
})()
|
|
62
|
+
}).catch(() => {
|
|
63
|
+
process.exit(-1);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
console.log(`→ ${pageId}`);
|
|
67
|
+
|
|
68
|
+
const componentBasename = pageId.replace(/ftl$/, 'stories.ts');
|
|
69
|
+
|
|
70
|
+
const targetFilePath = pathJoin(
|
|
71
|
+
buildContext.themeSrcDirPath,
|
|
72
|
+
themeType,
|
|
73
|
+
'pages',
|
|
74
|
+
pageId.replace(/\.ftl$/, ''),
|
|
75
|
+
componentBasename
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
if (fs.existsSync(targetFilePath)) {
|
|
79
|
+
console.log(`${pathRelative(process.cwd(), targetFilePath)} already exists`);
|
|
80
|
+
|
|
81
|
+
process.exit(-1);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let sourceCode = fs
|
|
85
|
+
.readFileSync(
|
|
86
|
+
pathJoin(
|
|
87
|
+
getThisCodebaseRootDirPath(),
|
|
88
|
+
'stories',
|
|
89
|
+
themeType,
|
|
90
|
+
'pages',
|
|
91
|
+
componentBasename
|
|
92
|
+
)
|
|
93
|
+
)
|
|
94
|
+
.toString('utf8')
|
|
95
|
+
.replace(/["']\.\.\/KcPageStory["']/, "'../../KcPageStory'");
|
|
96
|
+
|
|
97
|
+
run_prettier: {
|
|
98
|
+
if (!(await getIsPrettierAvailable())) {
|
|
99
|
+
break run_prettier;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
sourceCode = await runPrettier({
|
|
103
|
+
filePath: targetFilePath,
|
|
104
|
+
sourceCode: sourceCode
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
{
|
|
109
|
+
const targetDirPath = pathDirname(targetFilePath);
|
|
110
|
+
|
|
111
|
+
if (!fs.existsSync(targetDirPath)) {
|
|
112
|
+
fs.mkdirSync(targetDirPath, { recursive: true });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
fs.writeFileSync(targetFilePath, Buffer.from(sourceCode, 'utf8'));
|
|
117
|
+
|
|
118
|
+
console.log(
|
|
119
|
+
[
|
|
120
|
+
`${chalk.green('✓')} ${chalk.bold(
|
|
121
|
+
pathJoin('.', pathRelative(process.cwd(), targetFilePath))
|
|
122
|
+
)} copy pasted from the Keycloakify source code into your project`,
|
|
123
|
+
`You can start storybook with ${chalk.bold('npm run storybook')}`
|
|
124
|
+
].join('\n')
|
|
125
|
+
);
|
|
126
|
+
}
|
package/src/bin/eject-page.ts
CHANGED
|
@@ -21,11 +21,11 @@ import {
|
|
|
21
21
|
} from 'path';
|
|
22
22
|
import { assert, Equals } from 'tsafe/assert';
|
|
23
23
|
import chalk from 'chalk';
|
|
24
|
-
import { transformCodebase } from './tools/
|
|
24
|
+
import { transformCodebase } from './tools/transformCodebase_async';
|
|
25
25
|
import { kebabCaseToCamelCase } from './tools/kebabCaseToSnakeCase';
|
|
26
26
|
import { replaceAll } from './tools/String.prototype.replaceAll';
|
|
27
27
|
import { capitalize } from 'tsafe/capitalize';
|
|
28
|
-
import {
|
|
28
|
+
import { getIsPrettierAvailable, runPrettier } from './tools/runPrettier';
|
|
29
29
|
|
|
30
30
|
export async function command(params: { buildContext: BuildContext }) {
|
|
31
31
|
const { buildContext } = params;
|
|
@@ -149,15 +149,33 @@ export async function command(params: { buildContext: BuildContext }) {
|
|
|
149
149
|
themeType
|
|
150
150
|
);
|
|
151
151
|
|
|
152
|
-
transformCodebase({
|
|
152
|
+
await transformCodebase({
|
|
153
153
|
srcDirPath: pathJoin(
|
|
154
154
|
localThemeTypeDirPath,
|
|
155
155
|
componentDirRelativeToThemeTypePath_i
|
|
156
156
|
),
|
|
157
157
|
destDirPath,
|
|
158
|
-
transformSourceCode: ({ filePath, sourceCode }) => {
|
|
158
|
+
transformSourceCode: async ({ filePath, sourceCode }) => {
|
|
159
159
|
if (!filePath.endsWith('.ts')) {
|
|
160
|
-
|
|
160
|
+
let modifiedSourceCode_str = sourceCode.toString('utf8');
|
|
161
|
+
|
|
162
|
+
run_prettier: {
|
|
163
|
+
if (!(await getIsPrettierAvailable())) {
|
|
164
|
+
break run_prettier;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
modifiedSourceCode_str = await runPrettier({
|
|
168
|
+
filePath,
|
|
169
|
+
sourceCode: modifiedSourceCode_str
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
modifiedSourceCode: Buffer.from(
|
|
175
|
+
modifiedSourceCode_str,
|
|
176
|
+
'utf8'
|
|
177
|
+
)
|
|
178
|
+
};
|
|
161
179
|
}
|
|
162
180
|
|
|
163
181
|
if (filePath.endsWith('index.ts')) {
|
|
@@ -229,6 +247,17 @@ export async function command(params: { buildContext: BuildContext }) {
|
|
|
229
247
|
}
|
|
230
248
|
);
|
|
231
249
|
|
|
250
|
+
run_prettier: {
|
|
251
|
+
if (!(await getIsPrettierAvailable())) {
|
|
252
|
+
break run_prettier;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
modifiedSourceCode_str = await runPrettier({
|
|
256
|
+
filePath,
|
|
257
|
+
sourceCode: modifiedSourceCode_str
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
232
261
|
return {
|
|
233
262
|
modifiedSourceCode: Buffer.from(modifiedSourceCode_str, 'utf8')
|
|
234
263
|
};
|
|
@@ -243,10 +272,6 @@ export async function command(params: { buildContext: BuildContext }) {
|
|
|
243
272
|
}
|
|
244
273
|
}
|
|
245
274
|
|
|
246
|
-
runFormat({
|
|
247
|
-
packageJsonFilePath: buildContext.packageJsonFilePath
|
|
248
|
-
});
|
|
249
|
-
|
|
250
275
|
edit_KcPage: {
|
|
251
276
|
if (
|
|
252
277
|
pageIdOrComponent !== templateValue &&
|
|
@@ -263,17 +288,30 @@ export async function command(params: { buildContext: BuildContext }) {
|
|
|
263
288
|
|
|
264
289
|
const kcAppTsCode = fs.readFileSync(kcAppTsFilePath).toString('utf8');
|
|
265
290
|
|
|
266
|
-
const modifiedKcAppTsCode = (() => {
|
|
291
|
+
const modifiedKcAppTsCode = await (async () => {
|
|
267
292
|
const componentRelativeDirPath_posix = componentDirRelativeToThemeTypePath
|
|
268
293
|
.split(pathSep)
|
|
269
294
|
.join('/');
|
|
270
295
|
|
|
271
|
-
|
|
296
|
+
let sourceCode = kcAppTsCode.replace(
|
|
272
297
|
`@keycloakify/angular/${themeType}/${componentRelativeDirPath_posix}`,
|
|
273
298
|
componentRelativeDirPath_posix_to_componentRelativeFilePath_posix({
|
|
274
299
|
componentRelativeDirPath_posix: `./${componentRelativeDirPath_posix}`
|
|
275
300
|
})
|
|
276
301
|
);
|
|
302
|
+
|
|
303
|
+
run_prettier: {
|
|
304
|
+
if (!(await getIsPrettierAvailable())) {
|
|
305
|
+
break run_prettier;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
sourceCode = await runPrettier({
|
|
309
|
+
filePath: kcAppTsFilePath,
|
|
310
|
+
sourceCode
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return sourceCode;
|
|
277
315
|
})();
|
|
278
316
|
|
|
279
317
|
if (modifiedKcAppTsCode === kcAppTsCode) {
|
package/src/bin/main.ts
CHANGED
|
@@ -8,10 +8,8 @@ const { buildContext, commandName } = readParams({ apiVersion: 'v1' });
|
|
|
8
8
|
switch (commandName) {
|
|
9
9
|
case 'add-story':
|
|
10
10
|
{
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
);
|
|
14
|
-
process.exit(-1);
|
|
11
|
+
const { command } = await import('./add-story');
|
|
12
|
+
command({ buildContext });
|
|
15
13
|
}
|
|
16
14
|
return;
|
|
17
15
|
case 'eject-page':
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { sep as pathSep } from 'path';
|
|
2
|
+
|
|
3
|
+
let cache: string | undefined = undefined;
|
|
4
|
+
|
|
5
|
+
export function getNodeModulesBinDirPath() {
|
|
6
|
+
if (cache !== undefined) {
|
|
7
|
+
return cache;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const binPath = process.argv[1];
|
|
11
|
+
|
|
12
|
+
const segments: string[] = ['.bin'];
|
|
13
|
+
|
|
14
|
+
let foundNodeModules = false;
|
|
15
|
+
|
|
16
|
+
for (const segment of binPath.split(pathSep).reverse()) {
|
|
17
|
+
skip_segment: {
|
|
18
|
+
if (foundNodeModules) {
|
|
19
|
+
break skip_segment;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (segment === 'node_modules') {
|
|
23
|
+
foundNodeModules = true;
|
|
24
|
+
break skip_segment;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
segments.unshift(segment);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const nodeModulesBinDirPath = segments.join(pathSep);
|
|
34
|
+
|
|
35
|
+
cache = nodeModulesBinDirPath;
|
|
36
|
+
|
|
37
|
+
return nodeModulesBinDirPath;
|
|
38
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { getNodeModulesBinDirPath } from './nodeModulesBinDirPath';
|
|
2
|
+
import { join as pathJoin } from 'path';
|
|
3
|
+
import * as fsPr from 'fs/promises';
|
|
4
|
+
import { id } from 'tsafe/id';
|
|
5
|
+
import { assert } from 'tsafe/assert';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
|
|
8
|
+
getIsPrettierAvailable.cache = id<boolean | undefined>(undefined);
|
|
9
|
+
|
|
10
|
+
export async function getIsPrettierAvailable(): Promise<boolean> {
|
|
11
|
+
if (getIsPrettierAvailable.cache !== undefined) {
|
|
12
|
+
return getIsPrettierAvailable.cache;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const nodeModulesBinDirPath = getNodeModulesBinDirPath();
|
|
16
|
+
|
|
17
|
+
const prettierBinPath = pathJoin(nodeModulesBinDirPath, 'prettier');
|
|
18
|
+
|
|
19
|
+
const stats = await fsPr.stat(prettierBinPath).catch(() => undefined);
|
|
20
|
+
|
|
21
|
+
const isPrettierAvailable = stats?.isFile() ?? false;
|
|
22
|
+
|
|
23
|
+
getIsPrettierAvailable.cache = isPrettierAvailable;
|
|
24
|
+
|
|
25
|
+
return isPrettierAvailable;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type PrettierAndConfig = {
|
|
29
|
+
prettier: typeof import('prettier');
|
|
30
|
+
config: import('prettier').Options | null;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
getPrettierAndConfig.cache = id<PrettierAndConfig | undefined>(undefined);
|
|
34
|
+
|
|
35
|
+
export async function getPrettierAndConfig(): Promise<PrettierAndConfig> {
|
|
36
|
+
assert(getIsPrettierAvailable());
|
|
37
|
+
|
|
38
|
+
if (getPrettierAndConfig.cache !== undefined) {
|
|
39
|
+
return getPrettierAndConfig.cache;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const prettier = await import('prettier');
|
|
43
|
+
|
|
44
|
+
const prettierAndConfig: PrettierAndConfig = {
|
|
45
|
+
prettier,
|
|
46
|
+
config: await prettier.resolveConfig(pathJoin(getNodeModulesBinDirPath(), '..'))
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
getPrettierAndConfig.cache = prettierAndConfig;
|
|
50
|
+
|
|
51
|
+
return prettierAndConfig;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export async function runPrettier(params: {
|
|
55
|
+
sourceCode: string;
|
|
56
|
+
filePath: string;
|
|
57
|
+
}): Promise<string> {
|
|
58
|
+
const { sourceCode, filePath } = params;
|
|
59
|
+
|
|
60
|
+
let formattedSourceCode: string;
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const { prettier, config } = await getPrettierAndConfig();
|
|
64
|
+
|
|
65
|
+
const { ignored, inferredParser } = await prettier.getFileInfo(filePath, {
|
|
66
|
+
resolveConfig: true
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
if (ignored) {
|
|
70
|
+
return sourceCode;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
formattedSourceCode = await prettier.format(sourceCode, {
|
|
74
|
+
...config,
|
|
75
|
+
filePath,
|
|
76
|
+
parser: inferredParser ?? undefined
|
|
77
|
+
});
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.log(
|
|
80
|
+
chalk.red(
|
|
81
|
+
`You probably need to upgrade the version of prettier in your project`
|
|
82
|
+
)
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return formattedSourceCode;
|
|
89
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { crawl } from './crawl';
|
|
4
|
+
import { rmSync } from '../tools/fs.rmSync';
|
|
5
|
+
|
|
6
|
+
type TransformSourceCode = (params: {
|
|
7
|
+
sourceCode: Buffer;
|
|
8
|
+
filePath: string;
|
|
9
|
+
fileRelativePath: string;
|
|
10
|
+
}) => Promise<
|
|
11
|
+
| {
|
|
12
|
+
modifiedSourceCode: Buffer;
|
|
13
|
+
newFileName?: string;
|
|
14
|
+
}
|
|
15
|
+
| undefined
|
|
16
|
+
>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Apply a transformation function to every file of directory
|
|
20
|
+
* If source and destination are the same this function can be used to apply the transformation in place
|
|
21
|
+
* like filtering out some files or modifying them.
|
|
22
|
+
* */
|
|
23
|
+
export async function transformCodebase(params: {
|
|
24
|
+
srcDirPath: string;
|
|
25
|
+
destDirPath: string;
|
|
26
|
+
transformSourceCode?: TransformSourceCode;
|
|
27
|
+
}) {
|
|
28
|
+
const { srcDirPath, transformSourceCode } = params;
|
|
29
|
+
|
|
30
|
+
const isTargetSameAsSource = path.relative(srcDirPath, params.destDirPath) === '';
|
|
31
|
+
|
|
32
|
+
const destDirPath = isTargetSameAsSource
|
|
33
|
+
? path.join(srcDirPath, '..', 'tmp_xOsPdkPsTdzPs34sOkHs')
|
|
34
|
+
: params.destDirPath;
|
|
35
|
+
|
|
36
|
+
fs.mkdirSync(destDirPath, {
|
|
37
|
+
recursive: true
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
for (const fileRelativePath of crawl({
|
|
41
|
+
dirPath: srcDirPath,
|
|
42
|
+
returnedPathsType: 'relative to dirPath'
|
|
43
|
+
})) {
|
|
44
|
+
const filePath = path.join(srcDirPath, fileRelativePath);
|
|
45
|
+
const destFilePath = path.join(destDirPath, fileRelativePath);
|
|
46
|
+
|
|
47
|
+
// NOTE: Optimization, if we don't need to transform the file, just copy
|
|
48
|
+
// it using the lower level implementation.
|
|
49
|
+
if (transformSourceCode === undefined) {
|
|
50
|
+
fs.mkdirSync(path.dirname(destFilePath), {
|
|
51
|
+
recursive: true
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
fs.copyFileSync(filePath, destFilePath);
|
|
55
|
+
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const transformSourceCodeResult = await transformSourceCode({
|
|
60
|
+
sourceCode: fs.readFileSync(filePath),
|
|
61
|
+
filePath,
|
|
62
|
+
fileRelativePath
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (transformSourceCodeResult === undefined) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
fs.mkdirSync(path.dirname(destFilePath), {
|
|
70
|
+
recursive: true
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const { newFileName, modifiedSourceCode } = transformSourceCodeResult;
|
|
74
|
+
|
|
75
|
+
fs.writeFileSync(
|
|
76
|
+
path.join(
|
|
77
|
+
path.dirname(destFilePath),
|
|
78
|
+
newFileName ?? path.basename(destFilePath)
|
|
79
|
+
),
|
|
80
|
+
modifiedSourceCode
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (isTargetSameAsSource) {
|
|
85
|
+
rmSync(srcDirPath, { recursive: true });
|
|
86
|
+
|
|
87
|
+
fs.renameSync(destDirPath, srcDirPath);
|
|
88
|
+
}
|
|
89
|
+
}
|
package/src/bin/update-kc-gen.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { BuildContext } from './core';
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import { join as pathJoin } from 'path';
|
|
4
|
-
import {
|
|
4
|
+
import { getIsPrettierAvailable, runPrettier } from './tools/runPrettier';
|
|
5
5
|
import * as crypto from 'crypto';
|
|
6
6
|
|
|
7
|
-
export function command(params: { buildContext: BuildContext }) {
|
|
7
|
+
export async function command(params: { buildContext: BuildContext }) {
|
|
8
8
|
const { buildContext } = params;
|
|
9
9
|
|
|
10
10
|
const filePath = pathJoin(buildContext.themeSrcDirPath, 'kc.gen.ts');
|
|
@@ -149,18 +149,23 @@ export function command(params: { buildContext: BuildContext }) {
|
|
|
149
149
|
return;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
152
|
+
let sourceCode = [
|
|
153
|
+
`// This file is auto-generated by keycloakify. Do not edit it manually.`,
|
|
154
|
+
`// Hash: ${hash}`,
|
|
155
|
+
``,
|
|
156
|
+
newContent
|
|
157
|
+
].join('\n');
|
|
158
|
+
|
|
159
|
+
run_prettier: {
|
|
160
|
+
if (!(await getIsPrettierAvailable())) {
|
|
161
|
+
break run_prettier;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
sourceCode = await runPrettier({
|
|
165
|
+
filePath,
|
|
166
|
+
sourceCode
|
|
167
|
+
});
|
|
168
|
+
}
|
|
164
169
|
|
|
165
|
-
|
|
170
|
+
fs.writeFileSync(filePath, Buffer.from(sourceCode, 'utf8'));
|
|
166
171
|
}
|