keycloakify 11.5.3 → 11.6.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/{682.index.js → 153.index.js} +300 -52
- package/bin/356.index.js +48 -25
- package/bin/{573.index.js → 880.index.js} +155 -9
- package/bin/main.js +6 -5
- package/bin/start-keycloak/realmConfig/{ParsedRealmJson.d.ts → ParsedRealmJson/ParsedRealmJson.d.ts} +2 -3
- package/bin/start-keycloak/realmConfig/ParsedRealmJson/index.d.ts +3 -0
- package/bin/start-keycloak/realmConfig/ParsedRealmJson/readRealmJsonFile.d.ts +4 -0
- package/bin/start-keycloak/realmConfig/ParsedRealmJson/writeRealmJsonFile.d.ts +6 -0
- package/bin/start-keycloak/realmConfig/defaultConfig/defaultConfig.d.ts +1 -4
- package/bin/tools/Stringifyable.d.ts +13 -0
- package/bin/tools/canonicalStringify.d.ts +5 -0
- package/bin/tools/createObjectThatThrowsIfAccessed.d.ts +21 -0
- package/package.json +18 -5
- package/src/bin/keycloakify/generateResources/generateResources.ts +162 -6
- package/src/bin/main.ts +4 -3
- package/src/bin/postinstall/getUiModuleFileSourceCodeReadyToBeCopied.ts +63 -24
- package/src/bin/start-keycloak/realmConfig/{ParsedRealmJson.ts → ParsedRealmJson/ParsedRealmJson.ts} +1 -19
- package/src/bin/start-keycloak/realmConfig/ParsedRealmJson/index.ts +3 -0
- package/src/bin/start-keycloak/realmConfig/ParsedRealmJson/readRealmJsonFile.ts +20 -0
- package/src/bin/start-keycloak/realmConfig/ParsedRealmJson/writeRealmJsonFile.ts +29 -0
- package/src/bin/start-keycloak/realmConfig/defaultConfig/defaultConfig.ts +3 -4
- package/src/bin/start-keycloak/realmConfig/defaultConfig/realm-kc-18.json +51 -33
- package/src/bin/start-keycloak/realmConfig/defaultConfig/realm-kc-19.json +48 -30
- package/src/bin/start-keycloak/realmConfig/defaultConfig/realm-kc-20.json +50 -32
- package/src/bin/start-keycloak/realmConfig/defaultConfig/realm-kc-21.json +29 -11
- package/src/bin/start-keycloak/realmConfig/defaultConfig/realm-kc-22.json +2201 -0
- package/src/bin/start-keycloak/realmConfig/defaultConfig/realm-kc-23.json +25 -7
- package/src/bin/start-keycloak/realmConfig/defaultConfig/realm-kc-24.json +26 -8
- package/src/bin/start-keycloak/realmConfig/defaultConfig/realm-kc-25.json +26 -8
- package/src/bin/start-keycloak/realmConfig/defaultConfig/realm-kc-26.json +11 -11
- package/src/bin/start-keycloak/realmConfig/prepareRealmConfig.ts +1 -1
- package/src/bin/start-keycloak/realmConfig/realmConfig.ts +15 -19
- package/src/bin/start-keycloak/start-keycloak.ts +131 -36
- package/src/bin/tools/Stringifyable.ts +99 -0
- package/src/bin/tools/canonicalStringify.ts +164 -0
- package/src/bin/tools/createObjectThatThrowsIfAccessed.ts +90 -0
@@ -0,0 +1,164 @@
|
|
1
|
+
import { getIsAtomic, getValueAtPath, type Stringifyable } from "./Stringifyable";
|
2
|
+
|
3
|
+
export function canonicalStringify(params: {
|
4
|
+
data: Record<string, Stringifyable> | Stringifyable[];
|
5
|
+
referenceData: Record<string, Stringifyable> | Stringifyable[];
|
6
|
+
}): string {
|
7
|
+
const { data, referenceData } = params;
|
8
|
+
|
9
|
+
return JSON.stringify(
|
10
|
+
makeDeterministicCopy({
|
11
|
+
path: [],
|
12
|
+
data,
|
13
|
+
getCanonicalKeys: path => {
|
14
|
+
const referenceValue = (() => {
|
15
|
+
const path_patched: (string | number)[] = [];
|
16
|
+
|
17
|
+
for (let i = 0; i < path.length; i++) {
|
18
|
+
let value_i = getValueAtPath(referenceData, [
|
19
|
+
...path_patched,
|
20
|
+
path[i]
|
21
|
+
]);
|
22
|
+
|
23
|
+
if (value_i !== undefined) {
|
24
|
+
path_patched.push(path[i]);
|
25
|
+
continue;
|
26
|
+
}
|
27
|
+
|
28
|
+
if (typeof path[i] !== "number") {
|
29
|
+
return undefined;
|
30
|
+
}
|
31
|
+
|
32
|
+
value_i = getValueAtPath(referenceData, [...path_patched, 0]);
|
33
|
+
|
34
|
+
if (value_i !== undefined) {
|
35
|
+
path_patched.push(0);
|
36
|
+
continue;
|
37
|
+
}
|
38
|
+
|
39
|
+
return undefined;
|
40
|
+
}
|
41
|
+
|
42
|
+
return getValueAtPath(referenceData, path_patched);
|
43
|
+
})();
|
44
|
+
|
45
|
+
if (referenceValue === undefined) {
|
46
|
+
return undefined;
|
47
|
+
}
|
48
|
+
|
49
|
+
if (getIsAtomic(referenceValue)) {
|
50
|
+
return undefined;
|
51
|
+
}
|
52
|
+
|
53
|
+
if (referenceValue instanceof Array) {
|
54
|
+
return undefined;
|
55
|
+
}
|
56
|
+
|
57
|
+
return Object.keys(referenceValue);
|
58
|
+
}
|
59
|
+
}),
|
60
|
+
null,
|
61
|
+
2
|
62
|
+
);
|
63
|
+
}
|
64
|
+
|
65
|
+
function makeDeterministicCopy(params: {
|
66
|
+
path: (string | number)[];
|
67
|
+
data: Stringifyable;
|
68
|
+
getCanonicalKeys: (path: (string | number)[]) => string[] | undefined;
|
69
|
+
}): Stringifyable {
|
70
|
+
const { path, data, getCanonicalKeys } = params;
|
71
|
+
|
72
|
+
if (getIsAtomic(data)) {
|
73
|
+
return data;
|
74
|
+
}
|
75
|
+
|
76
|
+
if (data instanceof Array) {
|
77
|
+
return makeDeterministicCopy_array({
|
78
|
+
path,
|
79
|
+
data,
|
80
|
+
getCanonicalKeys
|
81
|
+
});
|
82
|
+
}
|
83
|
+
|
84
|
+
return makeDeterministicCopy_record({
|
85
|
+
path,
|
86
|
+
data,
|
87
|
+
getCanonicalKeys
|
88
|
+
});
|
89
|
+
}
|
90
|
+
|
91
|
+
function makeDeterministicCopy_record(params: {
|
92
|
+
path: (string | number)[];
|
93
|
+
data: Record<string, Stringifyable>;
|
94
|
+
getCanonicalKeys: (path: (string | number)[]) => string[] | undefined;
|
95
|
+
}): Record<string, Stringifyable> {
|
96
|
+
const { path, data, getCanonicalKeys } = params;
|
97
|
+
|
98
|
+
const keysOfAtomicValues: string[] = [];
|
99
|
+
const keysOfNonAtomicValues: string[] = [];
|
100
|
+
|
101
|
+
for (const [key, value] of Object.entries(data)) {
|
102
|
+
if (getIsAtomic(value)) {
|
103
|
+
keysOfAtomicValues.push(key);
|
104
|
+
} else {
|
105
|
+
keysOfNonAtomicValues.push(key);
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
keysOfAtomicValues.sort();
|
110
|
+
keysOfNonAtomicValues.sort();
|
111
|
+
|
112
|
+
const keys = [...keysOfAtomicValues, ...keysOfNonAtomicValues];
|
113
|
+
|
114
|
+
reorder_according_to_canonical: {
|
115
|
+
const canonicalKeys = getCanonicalKeys(path);
|
116
|
+
|
117
|
+
if (canonicalKeys === undefined) {
|
118
|
+
break reorder_according_to_canonical;
|
119
|
+
}
|
120
|
+
|
121
|
+
const keys_toPrepend: string[] = [];
|
122
|
+
|
123
|
+
for (const key of canonicalKeys) {
|
124
|
+
const indexOfKey = keys.indexOf(key);
|
125
|
+
|
126
|
+
if (indexOfKey === -1) {
|
127
|
+
continue;
|
128
|
+
}
|
129
|
+
|
130
|
+
keys.splice(indexOfKey, 1);
|
131
|
+
keys_toPrepend.push(key);
|
132
|
+
}
|
133
|
+
|
134
|
+
keys.unshift(...keys_toPrepend);
|
135
|
+
}
|
136
|
+
|
137
|
+
const result: Record<string, Stringifyable> = {};
|
138
|
+
|
139
|
+
for (const key of keys) {
|
140
|
+
result[key] = makeDeterministicCopy({
|
141
|
+
path: [...path, key],
|
142
|
+
data: data[key],
|
143
|
+
getCanonicalKeys
|
144
|
+
});
|
145
|
+
}
|
146
|
+
|
147
|
+
return result;
|
148
|
+
}
|
149
|
+
|
150
|
+
function makeDeterministicCopy_array(params: {
|
151
|
+
path: (string | number)[];
|
152
|
+
data: Stringifyable[];
|
153
|
+
getCanonicalKeys: (path: (string | number)[]) => string[] | undefined;
|
154
|
+
}): Stringifyable[] {
|
155
|
+
const { path, data, getCanonicalKeys } = params;
|
156
|
+
|
157
|
+
return [...data].map((entry, i) =>
|
158
|
+
makeDeterministicCopy({
|
159
|
+
path: [...path, i],
|
160
|
+
data: entry,
|
161
|
+
getCanonicalKeys
|
162
|
+
})
|
163
|
+
);
|
164
|
+
}
|
@@ -0,0 +1,90 @@
|
|
1
|
+
const keyIsTrapped = "isTrapped_zSskDe9d";
|
2
|
+
|
3
|
+
export class AccessError extends Error {
|
4
|
+
constructor(message: string) {
|
5
|
+
super(message);
|
6
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
export function createObjectThatThrowsIfAccessed<T extends object>(params?: {
|
11
|
+
debugMessage?: string;
|
12
|
+
isPropertyWhitelisted?: (prop: string | number | symbol) => boolean;
|
13
|
+
}): T {
|
14
|
+
const { debugMessage = "", isPropertyWhitelisted = () => false } = params ?? {};
|
15
|
+
|
16
|
+
const get: NonNullable<ProxyHandler<T>["get"]> = (...args) => {
|
17
|
+
const [, prop] = args;
|
18
|
+
|
19
|
+
if (isPropertyWhitelisted(prop)) {
|
20
|
+
return Reflect.get(...args);
|
21
|
+
}
|
22
|
+
|
23
|
+
if (prop === keyIsTrapped) {
|
24
|
+
return true;
|
25
|
+
}
|
26
|
+
|
27
|
+
throw new AccessError(`Cannot access ${String(prop)} yet ${debugMessage}`);
|
28
|
+
};
|
29
|
+
|
30
|
+
const trappedObject = new Proxy<T>({} as any, {
|
31
|
+
get,
|
32
|
+
set: get
|
33
|
+
});
|
34
|
+
|
35
|
+
return trappedObject;
|
36
|
+
}
|
37
|
+
|
38
|
+
export function createObjectThatThrowsIfAccessedFactory(params: {
|
39
|
+
isPropertyWhitelisted?: (prop: string | number | symbol) => boolean;
|
40
|
+
}) {
|
41
|
+
const { isPropertyWhitelisted } = params;
|
42
|
+
|
43
|
+
return {
|
44
|
+
createObjectThatThrowsIfAccessed: <T extends object>(params?: {
|
45
|
+
debugMessage?: string;
|
46
|
+
}) => {
|
47
|
+
const { debugMessage } = params ?? {};
|
48
|
+
|
49
|
+
return createObjectThatThrowsIfAccessed<T>({
|
50
|
+
debugMessage,
|
51
|
+
isPropertyWhitelisted
|
52
|
+
});
|
53
|
+
}
|
54
|
+
};
|
55
|
+
}
|
56
|
+
|
57
|
+
export function isObjectThatThrowIfAccessed(obj: object) {
|
58
|
+
return (obj as any)[keyIsTrapped] === true;
|
59
|
+
}
|
60
|
+
|
61
|
+
export const THROW_IF_ACCESSED = {
|
62
|
+
__brand: "THROW_IF_ACCESSED"
|
63
|
+
};
|
64
|
+
|
65
|
+
export function createObjectWithSomePropertiesThatThrowIfAccessed<
|
66
|
+
T extends Record<string, unknown>
|
67
|
+
>(obj: { [K in keyof T]: T[K] | typeof THROW_IF_ACCESSED }, debugMessage?: string): T {
|
68
|
+
return Object.defineProperties(
|
69
|
+
obj,
|
70
|
+
Object.fromEntries(
|
71
|
+
Object.entries(obj)
|
72
|
+
.filter(([, value]) => value === THROW_IF_ACCESSED)
|
73
|
+
.map(([key]) => {
|
74
|
+
const getAndSet = () => {
|
75
|
+
throw new AccessError(
|
76
|
+
`Cannot access ${key} yet ${debugMessage ?? ""}`
|
77
|
+
);
|
78
|
+
};
|
79
|
+
|
80
|
+
const pd = {
|
81
|
+
get: getAndSet,
|
82
|
+
set: getAndSet,
|
83
|
+
enumerable: true
|
84
|
+
};
|
85
|
+
|
86
|
+
return [key, pd];
|
87
|
+
})
|
88
|
+
)
|
89
|
+
) as any;
|
90
|
+
}
|