Compare commits

...

15 Commits

15 changed files with 114 additions and 59 deletions

View File

@ -1,6 +1,6 @@
{
"name": "keycloakify",
"version": "10.0.0-rc.126",
"version": "10.0.0-rc.132",
"description": "Create Keycloak themes using React",
"repository": {
"type": "git",

View File

@ -2,7 +2,10 @@ import { join as pathJoin, relative as pathRelative, dirname as pathDirname } fr
import type { BuildContext } from "../shared/buildContext";
import * as fs from "fs";
import chalk from "chalk";
import { getLatestsSemVersionedTag } from "../shared/getLatestsSemVersionedTag";
import {
getLatestsSemVersionedTag,
type BuildContextLike as BuildContextLike_getLatestsSemVersionedTag
} from "../shared/getLatestsSemVersionedTag";
import fetch from "make-fetch-happen";
import { z } from "zod";
import { assert, type Equals } from "tsafe/assert";
@ -12,8 +15,7 @@ import { npmInstall } from "../tools/npmInstall";
import { copyBoilerplate } from "./copyBoilerplate";
import { getThisCodebaseRootDirPath } from "../tools/getThisCodebaseRootDirPath";
type BuildContextLike = {
cacheDirPath: string;
type BuildContextLike = BuildContextLike_getLatestsSemVersionedTag & {
fetchOptions: BuildContext["fetchOptions"];
packageJsonFilePath: string;
};
@ -30,11 +32,11 @@ export async function initializeAccountTheme_singlePage(params: {
const REPO = "keycloak-account-ui";
const [semVersionedTag] = await getLatestsSemVersionedTag({
cacheDirPath: buildContext.cacheDirPath,
owner: OWNER,
repo: REPO,
count: 1,
doIgnoreReleaseCandidates: false
doIgnoreReleaseCandidates: false,
buildContext
});
const dependencies = await fetch(

View File

@ -30,7 +30,7 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
// NOTE: This is arbitrary
startingFromMajor: 17,
excludeMajorVersions: [],
cacheDirPath: buildContext.cacheDirPath
buildContext
});
const { defaultThemeDirPath } = await downloadKeycloakDefaultTheme({

View File

@ -9,6 +9,7 @@ import { assert, type Equals } from "tsafe/assert";
import { id } from "tsafe/id";
import type { SemVer } from "../tools/SemVer";
import { same } from "evt/tools/inDepth/same";
import type { BuildContext } from "./buildContext";
type GetLatestsSemVersionedTag = ReturnType<
typeof getLatestsSemVersionedTagFactory
@ -31,11 +32,23 @@ type Cache = {
}[];
};
export type BuildContextLike = {
cacheDirPath: string;
fetchOptions: BuildContext["fetchOptions"];
};
assert<BuildContext extends BuildContextLike ? true : false>();
export async function getLatestsSemVersionedTag({
cacheDirPath,
buildContext,
...params
}: Params & { cacheDirPath: string }): Promise<R> {
const cacheFilePath = pathJoin(cacheDirPath, "latest-sem-versioned-tags.json");
}: Params & {
buildContext: BuildContextLike;
}): Promise<R> {
const cacheFilePath = pathJoin(
buildContext.cacheDirPath,
"latest-sem-versioned-tags.json"
);
const cacheLookupResult = (() => {
const getResult_currentCache = (currentCacheEntries: Cache["entries"]) => ({
@ -144,9 +157,10 @@ export async function getLatestsSemVersionedTag({
const octokit = (() => {
const githubToken = process.env.GITHUB_TOKEN;
const octokit = new Octokit(
githubToken === undefined ? undefined : { auth: githubToken }
);
const octokit = new Octokit({
...(githubToken === undefined ? {} : { auth: githubToken }),
request: buildContext.fetchOptions
});
return octokit;
})();

View File

@ -1,22 +1,31 @@
import { getLatestsSemVersionedTag } from "./getLatestsSemVersionedTag";
import {
getLatestsSemVersionedTag,
type BuildContextLike as BuildContextLike_getLatestsSemVersionedTag
} from "./getLatestsSemVersionedTag";
import cliSelect from "cli-select";
import { assert } from "tsafe/assert";
import { SemVer } from "../tools/SemVer";
import type { BuildContext } from "./buildContext";
export type BuildContextLike = BuildContextLike_getLatestsSemVersionedTag & {};
assert<BuildContext extends BuildContextLike ? true : false>();
export async function promptKeycloakVersion(params: {
startingFromMajor: number | undefined;
excludeMajorVersions: number[];
cacheDirPath: string;
buildContext: BuildContextLike;
}) {
const { startingFromMajor, excludeMajorVersions, cacheDirPath } = params;
const { startingFromMajor, excludeMajorVersions, buildContext } = params;
const semVersionedTagByMajor = new Map<number, { tag: string; version: SemVer }>();
const semVersionedTags = await getLatestsSemVersionedTag({
cacheDirPath,
count: 50,
owner: "keycloak",
repo: "keycloak",
doIgnoreReleaseCandidates: true
doIgnoreReleaseCandidates: true,
buildContext
});
semVersionedTags.forEach(semVersionedTag => {

View File

@ -73,7 +73,7 @@
"composites": {
"realm": ["offline_access", "uma_authorization"],
"client": {
"account": ["view-profile", "manage-account"]
"account": ["delete-account", "view-profile", "manage-account"]
}
},
"clientRole": false,
@ -611,8 +611,8 @@
"name": "",
"description": "",
"rootUrl": "https://my-theme.keycloakify.dev",
"adminUrl": "",
"baseUrl": "",
"adminUrl": "https://my-theme.keycloakify.dev",
"baseUrl": "https://my-theme.keycloakify.dev",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
@ -2099,7 +2099,7 @@
"alias": "delete_account",
"name": "Delete Account",
"providerId": "delete_account",
"enabled": false,
"enabled": true,
"defaultAction": false,
"priority": 60,
"config": {}

View File

@ -73,7 +73,7 @@
"composites": {
"realm": ["offline_access", "uma_authorization"],
"client": {
"account": ["view-profile", "manage-account"]
"account": ["delete-account", "view-profile", "manage-account"]
}
},
"clientRole": false,
@ -618,8 +618,8 @@
"name": "",
"description": "",
"rootUrl": "https://my-theme.keycloakify.dev",
"adminUrl": "",
"baseUrl": "",
"adminUrl": "https://my-theme.keycloakify.dev",
"baseUrl": "https://my-theme.keycloakify.dev",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
@ -2130,7 +2130,7 @@
"alias": "delete_account",
"name": "Delete Account",
"providerId": "delete_account",
"enabled": false,
"enabled": true,
"defaultAction": false,
"priority": 60,
"config": {}

View File

@ -73,7 +73,7 @@
"composites": {
"realm": ["offline_access", "uma_authorization"],
"client": {
"account": ["view-profile", "manage-account"]
"account": ["delete-account", "view-profile", "manage-account"]
}
},
"clientRole": false,
@ -628,8 +628,8 @@
"name": "",
"description": "",
"rootUrl": "https://my-theme.keycloakify.dev",
"adminUrl": "",
"baseUrl": "",
"adminUrl": "https://my-theme.keycloakify.dev",
"baseUrl": "https://my-theme.keycloakify.dev",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
@ -2140,7 +2140,7 @@
"alias": "delete_account",
"name": "Delete Account",
"providerId": "delete_account",
"enabled": false,
"enabled": true,
"defaultAction": false,
"priority": 60,
"config": {}

View File

@ -73,7 +73,7 @@
"composites": {
"realm": ["offline_access", "uma_authorization"],
"client": {
"account": ["view-profile", "manage-account"]
"account": ["delete-account", "view-profile", "manage-account"]
}
},
"clientRole": false,
@ -632,8 +632,8 @@
"name": "",
"description": "",
"rootUrl": "https://my-theme.keycloakify.dev",
"adminUrl": "",
"baseUrl": "",
"adminUrl": "https://my-theme.keycloakify.dev",
"baseUrl": "https://my-theme.keycloakify.dev",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
@ -2144,7 +2144,7 @@
"alias": "delete_account",
"name": "Delete Account",
"providerId": "delete_account",
"enabled": false,
"enabled": true,
"defaultAction": false,
"priority": 60,
"config": {}

View File

@ -55,7 +55,7 @@
"composites": {
"realm": ["offline_access", "uma_authorization"],
"client": {
"account": ["view-profile", "manage-account"]
"account": ["delete-account", "view-profile", "manage-account"]
}
},
"clientRole": false,
@ -644,7 +644,7 @@
"description": "",
"rootUrl": "https://my-theme.keycloakify.dev",
"adminUrl": "https://my-theme.keycloakify.dev",
"baseUrl": "",
"baseUrl": "https://my-theme.keycloakify.dev",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
@ -2088,7 +2088,7 @@
"alias": "delete_account",
"name": "Delete Account",
"providerId": "delete_account",
"enabled": false,
"enabled": true,
"defaultAction": false,
"priority": 60,
"config": {}

View File

@ -63,7 +63,7 @@
"composites": {
"realm": ["offline_access", "uma_authorization"],
"client": {
"account": ["manage-account", "view-profile"]
"account": ["delete-account", "manage-account", "view-profile"]
}
},
"clientRole": false,
@ -653,7 +653,7 @@
"description": "",
"rootUrl": "https://my-theme.keycloakify.dev",
"adminUrl": "https://my-theme.keycloakify.dev",
"baseUrl": "",
"baseUrl": "https://my-theme.keycloakify.dev",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
@ -2235,7 +2235,7 @@
"alias": "delete_account",
"name": "Delete Account",
"providerId": "delete_account",
"enabled": false,
"enabled": true,
"defaultAction": false,
"priority": 60,
"config": {}

View File

@ -63,7 +63,7 @@
"composites": {
"realm": ["offline_access", "uma_authorization"],
"client": {
"account": ["manage-account", "view-profile"]
"account": ["delete-account", "manage-account", "view-profile"]
}
},
"clientRole": false,
@ -543,7 +543,7 @@
"favourite_pet": ["cat"],
"bio": ["Hello I'm Test User and I do not exist."],
"phone_number": ["1111111111"],
"locale": ["fr"],
"locale": ["en"],
"favorite_media": ["movies", "series"]
},
"createdTimestamp": 1716183898408,
@ -767,7 +767,7 @@
"description": "",
"rootUrl": "https://my-theme.keycloakify.dev",
"adminUrl": "https://my-theme.keycloakify.dev",
"baseUrl": "",
"baseUrl": "https://my-theme.keycloakify.dev",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
@ -2315,7 +2315,7 @@
"alias": "delete_account",
"name": "Delete Account",
"providerId": "delete_account",
"enabled": false,
"enabled": true,
"defaultAction": false,
"priority": 60,
"config": {}

View File

@ -97,13 +97,20 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
}
console.log(
chalk.cyan("On which version of Keycloak do you want to test your theme?")
[
chalk.cyan(
"On which version of Keycloak do you want to test your theme?"
),
chalk.gray(
"You can also explicitly provide the version with `npx keycloakify start-keycloak --keycloak-version 25.0.2` (or any other version)"
)
].join("\n")
);
const { keycloakVersion } = await promptKeycloakVersion({
startingFromMajor: 18,
excludeMajorVersions: [22],
cacheDirPath: buildContext.cacheDirPath
buildContext
});
console.log(`${keycloakVersion}`);

View File

@ -5,9 +5,11 @@ export function assertNoPnpmDlx() {
if (__dirname.includes(`${pathSep}pnpm${pathSep}dlx${pathSep}`)) {
console.log(
[
chalk.red("Please don't use `pnpm dlx keycloakify`"),
chalk.red(
"Please don't use `pnpm dlx keycloakify` (download and execute)"
),
"\nUse `npx keycloakify` or `pnpm exec keycloakify` instead since you want to use the keycloakify",
"version that is installed in your project and not the latest version on NPM."
"version that is installed in your project and not download and run the latest NPM version of keycloakify."
].join(" ")
);
process.exit(1);

View File

@ -1,6 +1,7 @@
import { type FetchOptions } from "make-fetch-happen";
import * as child_process from "child_process";
import * as fs from "fs";
import { exclude } from "tsafe/exclude";
export type ProxyFetchOptions = Pick<
FetchOptions,
@ -23,12 +24,32 @@ export function getProxyFetchOptions(params: {
.split("\n")
.filter(line => !line.startsWith(";"))
.map(line => line.trim())
.map(line => line.split("=", 2) as [string, string])
.map(line => {
const [key, value] = line.split("=");
if (key === undefined) {
return undefined;
}
if (value === undefined) {
return undefined;
}
return [key.trim(), value.trim()] as const;
})
.filter(exclude(undefined))
.filter(([key]) => key !== "")
.map(([key, value]) => {
if (value.startsWith('"') && value.endsWith('"')) {
return [key, value.slice(1, -1)] as const;
}
if (value === "true" || value === "false") {
return [key, value] as const;
}
return undefined;
})
.filter(exclude(undefined))
.reduce(
(
cfg: Record<string, string | string[]>,
[key, value]: [string, string]
) =>
(cfg: Record<string, string | string[]>, [key, value]) =>
key in cfg
? { ...cfg, [key]: [...ensureArray(cfg[key]), value] }
: { ...cfg, [key]: value },
@ -37,18 +58,18 @@ export function getProxyFetchOptions(params: {
})();
const proxy = ensureSingleOrNone(cfg["https-proxy"] ?? cfg["proxy"]);
const noProxy = cfg["noproxy"] ?? cfg["no-proxy"];
function maybeBoolean(arg0: string | undefined) {
return typeof arg0 === "undefined" ? undefined : Boolean(arg0);
}
const strictSSL = ensureSingleOrNone(cfg["strict-ssl"]) === "true";
const strictSSL = maybeBoolean(ensureSingleOrNone(cfg["strict-ssl"]));
const cert = cfg["cert"];
const ca = ensureArray(cfg["ca"] ?? cfg["ca[]"]);
const cafile = ensureSingleOrNone(cfg["cafile"]);
if (typeof cafile !== "undefined" && cafile !== "null") {
if (cafile !== undefined) {
ca.push(
...(() => {
const cafileContent = fs.readFileSync(cafile).toString("utf8");
@ -82,7 +103,7 @@ export function getProxyFetchOptions(params: {
}
function ensureArray<T>(arg0: T | T[]) {
return Array.isArray(arg0) ? arg0 : typeof arg0 === "undefined" ? [] : [arg0];
return Array.isArray(arg0) ? arg0 : arg0 === undefined ? [] : [arg0];
}
function ensureSingleOrNone<T>(arg0: T | T[]) {