@loomweaver/cli 0.9.0 → 0.9.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.
- package/dist/main.mjs +400 -29
- package/package.json +1 -1
package/dist/main.mjs
CHANGED
|
@@ -98,7 +98,7 @@ function ensureBuildTarget(target, amendment, projectRoot) {
|
|
|
98
98
|
added.push(...assets.added.map((entry) => `assets: ${entry}`));
|
|
99
99
|
}
|
|
100
100
|
next["options"] = options;
|
|
101
|
-
if (amendment.inlineCritical !== void 0 || amendment.serviceWorker) {
|
|
101
|
+
if (amendment.inlineCritical !== void 0 || amendment.serviceWorker || amendment.initialBudget) {
|
|
102
102
|
const configurations = { ...asObject(next["configurations"]) };
|
|
103
103
|
const production = { ...asObject(configurations["production"]) };
|
|
104
104
|
if (amendment.serviceWorker && production["serviceWorker"] === void 0) {
|
|
@@ -124,6 +124,18 @@ function ensureBuildTarget(target, amendment, projectRoot) {
|
|
|
124
124
|
);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
|
+
if (amendment.initialBudget) {
|
|
128
|
+
const budgets = ensureInitialBudget(
|
|
129
|
+
production["budgets"],
|
|
130
|
+
amendment.initialBudget
|
|
131
|
+
);
|
|
132
|
+
if (budgets.changed) {
|
|
133
|
+
production["budgets"] = budgets.value;
|
|
134
|
+
added.push(
|
|
135
|
+
`production budget initial: ${amendment.initialBudget.warning} warning, ${amendment.initialBudget.error} error`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
127
139
|
configurations["production"] = production;
|
|
128
140
|
next["configurations"] = configurations;
|
|
129
141
|
}
|
|
@@ -139,6 +151,56 @@ function ensureStylesheetSource(css, source) {
|
|
|
139
151
|
@source '${source}';
|
|
140
152
|
`;
|
|
141
153
|
}
|
|
154
|
+
function ensureInitialBudget(budgets, wanted) {
|
|
155
|
+
const entries = Array.isArray(budgets) ? [...budgets] : [];
|
|
156
|
+
const index = entries.findIndex(
|
|
157
|
+
(entry) => asObject(entry)?.["type"] === "initial"
|
|
158
|
+
);
|
|
159
|
+
if (index === -1) {
|
|
160
|
+
return {
|
|
161
|
+
value: [
|
|
162
|
+
...entries,
|
|
163
|
+
{
|
|
164
|
+
type: "initial",
|
|
165
|
+
maximumWarning: wanted.warning,
|
|
166
|
+
maximumError: wanted.error
|
|
167
|
+
}
|
|
168
|
+
],
|
|
169
|
+
changed: true
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const current = asObject(entries[index]) ?? {};
|
|
173
|
+
if (!isBelow(current["maximumError"], wanted.error)) {
|
|
174
|
+
return { value: entries, changed: false };
|
|
175
|
+
}
|
|
176
|
+
entries[index] = {
|
|
177
|
+
...current,
|
|
178
|
+
maximumWarning: wanted.warning,
|
|
179
|
+
maximumError: wanted.error
|
|
180
|
+
};
|
|
181
|
+
return { value: entries, changed: true };
|
|
182
|
+
}
|
|
183
|
+
function isBelow(recorded, wanted) {
|
|
184
|
+
const left = toBytes(recorded);
|
|
185
|
+
const right = toBytes(wanted);
|
|
186
|
+
return left !== void 0 && right !== void 0 && left < right;
|
|
187
|
+
}
|
|
188
|
+
function toBytes(size) {
|
|
189
|
+
if (typeof size !== "string") {
|
|
190
|
+
return void 0;
|
|
191
|
+
}
|
|
192
|
+
const match = /^([\d.]+)\s*(b|kb|mb|gb)?$/i.exec(size.trim());
|
|
193
|
+
if (!match) {
|
|
194
|
+
return void 0;
|
|
195
|
+
}
|
|
196
|
+
const units = {
|
|
197
|
+
b: 1,
|
|
198
|
+
kb: 1e3,
|
|
199
|
+
mb: 1e3 * 1e3,
|
|
200
|
+
gb: 1e3 * 1e3 * 1e3
|
|
201
|
+
};
|
|
202
|
+
return Number(match[1]) * units[(match[2] ?? "b").toLowerCase()];
|
|
203
|
+
}
|
|
142
204
|
function ensureInlineCritical(optimization, inlineCritical) {
|
|
143
205
|
if (typeof optimization === "boolean") {
|
|
144
206
|
return { value: optimization, changed: false, declined: true };
|
|
@@ -199,6 +261,7 @@ function asObject(value) {
|
|
|
199
261
|
|
|
200
262
|
// ../devkit/src/lib/amend/compose.ts
|
|
201
263
|
var APP_CONFIG = /export\s+const\s+appConfig\s*:[^=]*=\s*\{/;
|
|
264
|
+
var NAMESPACES = /provideTranslationNamespaces\(([^)]*)\)/;
|
|
202
265
|
var PROVIDERS_OPEN = /providers\s*:\s*\[/g;
|
|
203
266
|
var SHELL_IMPORT = /import\s*\{([^}]*)\}\s*from\s*'@loomweaver\/shell';/;
|
|
204
267
|
function closingLine(source, from) {
|
|
@@ -228,47 +291,96 @@ function providersBlock(source) {
|
|
|
228
291
|
}
|
|
229
292
|
function composePlugin(source, amendment, importPath) {
|
|
230
293
|
if (source.includes(amendment.symbol)) {
|
|
231
|
-
return { source, composed: true };
|
|
294
|
+
return { source, composed: true, kept: [] };
|
|
232
295
|
}
|
|
233
296
|
const shellImport = SHELL_IMPORT.exec(source);
|
|
234
297
|
if (!shellImport || !providersBlock(source)) {
|
|
235
|
-
return { source, composed: false };
|
|
298
|
+
return { source, composed: false, kept: [] };
|
|
236
299
|
}
|
|
300
|
+
const wanted = providersToAdd(source, amendment);
|
|
301
|
+
const ownSymbols = [amendment.symbol, ...wanted.flatMap((provider) => provider.own ?? [])];
|
|
302
|
+
const foreign = wanted.flatMap((provider) => provider.from ?? []);
|
|
237
303
|
const withImports = source.replace(
|
|
238
304
|
SHELL_IMPORT,
|
|
239
|
-
() =>
|
|
240
|
-
import {
|
|
305
|
+
() => [
|
|
306
|
+
`import {${withShellSymbols(shellImport[1], wanted)}} from '@loomweaver/shell';`,
|
|
307
|
+
...foreign.map(
|
|
308
|
+
(entry) => `import { ${[...entry.symbols].toSorted((a, b) => a.localeCompare(b)).join(", ")} } from '${entry.path}';`
|
|
309
|
+
),
|
|
310
|
+
`import { ${ownSymbols.toSorted((a, b) => a.localeCompare(b)).join(", ")} } from '${importPath}';`
|
|
311
|
+
].join("\n")
|
|
241
312
|
);
|
|
242
|
-
const
|
|
313
|
+
const joined = joinNamespaces(withImports, amendment.id);
|
|
314
|
+
const block = providersBlock(joined.source);
|
|
243
315
|
if (!block) {
|
|
244
|
-
return { source, composed: false };
|
|
316
|
+
return { source, composed: false, kept: [] };
|
|
245
317
|
}
|
|
246
318
|
const indent = `${block.indent} `;
|
|
247
319
|
const lines = [
|
|
248
|
-
`${indent}
|
|
320
|
+
...wanted.map((provider) => `${indent}${provider.line}`),
|
|
321
|
+
...joined.joined ? [] : [`${indent}provideTranslationNamespaces('${amendment.id}'),`],
|
|
249
322
|
`${indent}provideCapabilityGrants({ ${amendment.id}: [${amendment.capabilities.map((capability) => `'${capability}'`).join(", ")}] }),`,
|
|
250
323
|
`${indent}...providePlugins(${amendment.symbol}),`
|
|
251
324
|
].join("\n");
|
|
252
325
|
return {
|
|
253
|
-
source: `${
|
|
254
|
-
${lines}${
|
|
255
|
-
composed: true
|
|
326
|
+
source: `${joined.source.slice(0, block.insertAt)}
|
|
327
|
+
${lines}${joined.source.slice(block.insertAt)}`,
|
|
328
|
+
composed: true,
|
|
329
|
+
kept: keptProviders(source, amendment).map((provider) => provider.line)
|
|
256
330
|
};
|
|
257
331
|
}
|
|
332
|
+
function joinNamespaces(source, id) {
|
|
333
|
+
const existing = NAMESPACES.exec(source);
|
|
334
|
+
if (!existing) {
|
|
335
|
+
return { source, joined: false };
|
|
336
|
+
}
|
|
337
|
+
const names = existing[1].split(",").map((name) => name.trim()).filter(Boolean);
|
|
338
|
+
if (names.includes(`'${id}'`)) {
|
|
339
|
+
return { source, joined: true };
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
source: source.replace(
|
|
343
|
+
NAMESPACES,
|
|
344
|
+
() => `provideTranslationNamespaces(${[...names, `'${id}'`].join(", ")})`
|
|
345
|
+
),
|
|
346
|
+
joined: true
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
function providersToAdd(source, amendment) {
|
|
350
|
+
return (amendment.providers ?? []).filter(
|
|
351
|
+
(provider) => !(provider.unless && source.includes(provider.unless))
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
function keptProviders(source, amendment) {
|
|
355
|
+
return (amendment.providers ?? []).filter(
|
|
356
|
+
(provider) => provider.unless !== void 0 && source.includes(provider.unless)
|
|
357
|
+
);
|
|
358
|
+
}
|
|
258
359
|
function composeLines(amendment, importPath) {
|
|
360
|
+
const providers = amendment.providers ?? [];
|
|
361
|
+
const own = [amendment.symbol, ...providers.flatMap((provider) => provider.own ?? [])];
|
|
362
|
+
const shell = [
|
|
363
|
+
"providePlugins",
|
|
364
|
+
"provideCapabilityGrants",
|
|
365
|
+
"provideTranslationNamespaces",
|
|
366
|
+
...providers.flatMap((provider) => provider.shell ?? [])
|
|
367
|
+
];
|
|
259
368
|
return [
|
|
260
|
-
`import { ${
|
|
261
|
-
|
|
369
|
+
`import { ${own.join(", ")} } from '${importPath}';`,
|
|
370
|
+
`import { ${shell.join(", ")} } from '@loomweaver/shell';`,
|
|
371
|
+
...providers.flatMap((provider) => provider.from ?? []).map((entry) => `import { ${entry.symbols.join(", ")} } from '${entry.path}';`),
|
|
372
|
+
...providers.map((provider) => provider.line),
|
|
262
373
|
`provideTranslationNamespaces('${amendment.id}'),`,
|
|
263
374
|
`provideCapabilityGrants({ ${amendment.id}: [${amendment.capabilities.map((capability) => `'${capability}'`).join(", ")}] }),`,
|
|
264
375
|
`...providePlugins(${amendment.symbol}),`
|
|
265
376
|
];
|
|
266
377
|
}
|
|
267
|
-
function withShellSymbols(existing) {
|
|
378
|
+
function withShellSymbols(existing, providers) {
|
|
268
379
|
const wanted = [
|
|
269
380
|
"provideCapabilityGrants",
|
|
270
381
|
"providePlugins",
|
|
271
|
-
"provideTranslationNamespaces"
|
|
382
|
+
"provideTranslationNamespaces",
|
|
383
|
+
...providers.flatMap((provider) => provider.shell ?? [])
|
|
272
384
|
];
|
|
273
385
|
const present = existing.split(",").map((symbol) => symbol.trim()).filter(Boolean);
|
|
274
386
|
const missing = wanted.filter(
|
|
@@ -296,7 +408,8 @@ function describeAmendment(amendment) {
|
|
|
296
408
|
return `Add an @source entry for '${amendment.sourceRoot}' to the application's entry stylesheet, resolved from that stylesheet. Without it none of that code's utilities are emitted.`;
|
|
297
409
|
}
|
|
298
410
|
if (amendment.kind === "compose-plugin") {
|
|
299
|
-
|
|
411
|
+
const providers = (amendment.providers ?? []).map((provider) => provider.line.replace(/,$/, ""));
|
|
412
|
+
return `Register ${amendment.id} in the composition root: import { ${amendment.symbol} }, ${providers.map((line) => `${line}, `).join("")}provideTranslationNamespaces('${amendment.id}'), provideCapabilityGrants({ ${amendment.id}: [${amendment.capabilities.map((capability) => `'${capability}'`).join(
|
|
300
413
|
", "
|
|
301
414
|
)}] }) and ...providePlugins(${amendment.symbol}). Without it none of its contributions appear.`;
|
|
302
415
|
}
|
|
@@ -312,7 +425,10 @@ function describeAmendment(amendment) {
|
|
|
312
425
|
] : [],
|
|
313
426
|
...amendment.inlineCritical === void 0 ? [] : [
|
|
314
427
|
`set optimization.styles.inlineCritical to ${amendment.inlineCritical} in the production configuration (the generated content-security policy blocks the inline handler Angular's critical-CSS pass attaches, so a release build renders unstyled)`
|
|
315
|
-
]
|
|
428
|
+
],
|
|
429
|
+
...amendment.initialBudget ? [
|
|
430
|
+
`raise the initial bundle budget to ${amendment.initialBudget.warning} warning and ${amendment.initialBudget.error} error in the production configuration (a fresh workspace carries one sized for an empty application, and the workbench alone spends almost all of it, so a release build fails)`
|
|
431
|
+
] : []
|
|
316
432
|
].map((step, index) => `${index + 1}. ${step}`).join(" ");
|
|
317
433
|
}
|
|
318
434
|
|
|
@@ -704,7 +820,7 @@ function pause(): Promise<void> {
|
|
|
704
820
|
}
|
|
705
821
|
|
|
706
822
|
// ../devkit/src/recipes/angular-weaver/agent-files.ts
|
|
707
|
-
var AG_UI_ADAPTER_VERSION = "0.9.
|
|
823
|
+
var AG_UI_ADAPTER_VERSION = "0.9.2";
|
|
708
824
|
var AG_UI_PROTOCOL_VERSION = "0.0.x";
|
|
709
825
|
function connectionFile(w) {
|
|
710
826
|
return `import { signal } from '@angular/core';
|
|
@@ -1686,9 +1802,21 @@ var framePlugin = {
|
|
|
1686
1802
|
}
|
|
1687
1803
|
};
|
|
1688
1804
|
|
|
1805
|
+
// ../devkit/src/recipes/platform-version.ts
|
|
1806
|
+
var PLATFORM_VERSION = "0.9.2";
|
|
1807
|
+
|
|
1689
1808
|
// ../devkit/src/recipes/angular-distribution/amendments.ts
|
|
1809
|
+
var DISTRIBUTION_INITIAL_BUDGET = {
|
|
1810
|
+
warning: "1.5MB",
|
|
1811
|
+
error: "2MB"
|
|
1812
|
+
};
|
|
1690
1813
|
function distributionAmendments(d) {
|
|
1691
1814
|
return [
|
|
1815
|
+
{
|
|
1816
|
+
kind: "package",
|
|
1817
|
+
name: "@loomweaver/frame-kit",
|
|
1818
|
+
version: `^${PLATFORM_VERSION}`
|
|
1819
|
+
},
|
|
1692
1820
|
...d.styles === "tailwind" ? [
|
|
1693
1821
|
{
|
|
1694
1822
|
kind: "postcss",
|
|
@@ -1715,7 +1843,8 @@ function distributionAmendments(d) {
|
|
|
1715
1843
|
}
|
|
1716
1844
|
],
|
|
1717
1845
|
serviceWorker: "ngsw-config.json",
|
|
1718
|
-
inlineCritical: false
|
|
1846
|
+
inlineCritical: false,
|
|
1847
|
+
initialBudget: DISTRIBUTION_INITIAL_BUDGET
|
|
1719
1848
|
}
|
|
1720
1849
|
];
|
|
1721
1850
|
}
|
|
@@ -1910,9 +2039,10 @@ function readme2(d) {
|
|
|
1910
2039
|
"the stylesheet with an **inline** `onload` handler that the policy blocks \u2014 the app then renders",
|
|
1911
2040
|
"completely unstyled, and only in production builds.",
|
|
1912
2041
|
"",
|
|
1913
|
-
"
|
|
1914
|
-
"
|
|
1915
|
-
"
|
|
2042
|
+
"The initial-bundle budget in your build target was raised for the same reason: the shell is a",
|
|
2043
|
+
"whole application chrome and spends most of Angular's default before your own code arrives, so",
|
|
2044
|
+
"a production build would have failed on a number meant for an empty app. It is still a budget,",
|
|
2045
|
+
"and it is yours to move.",
|
|
1916
2046
|
"",
|
|
1917
2047
|
"## Ship less than the whole workbench",
|
|
1918
2048
|
"",
|
|
@@ -2226,6 +2356,7 @@ var angularDistribution = {
|
|
|
2226
2356
|
};
|
|
2227
2357
|
|
|
2228
2358
|
// ../devkit/src/recipes/auth-source/recipe.ts
|
|
2359
|
+
var SESSION_PLUGIN_ID = "session";
|
|
2229
2360
|
function resolveAuthSourceInput(input) {
|
|
2230
2361
|
if (!isKebabId(input.name)) {
|
|
2231
2362
|
throw new Error(`Auth source name must be kebab-case (e.g. "dev"); got "${input.name}".`);
|
|
@@ -2233,9 +2364,13 @@ function resolveAuthSourceInput(input) {
|
|
|
2233
2364
|
return {
|
|
2234
2365
|
name: input.name,
|
|
2235
2366
|
className: toPascalCase(input.name),
|
|
2236
|
-
propertyName: toCamelCase(input.name)
|
|
2367
|
+
propertyName: toCamelCase(input.name),
|
|
2368
|
+
bare: input.bare ?? false
|
|
2237
2369
|
};
|
|
2238
2370
|
}
|
|
2371
|
+
function sessionPluginSymbol(a) {
|
|
2372
|
+
return `${a.propertyName}SessionPlugin`;
|
|
2373
|
+
}
|
|
2239
2374
|
function moduleFile(a) {
|
|
2240
2375
|
return `// Provider-neutral AuthSource. LoomWeaver owns no authentication \u2014 it only reacts to
|
|
2241
2376
|
// a session snapshot. Wire it with: provideAuthSource(() => ${a.propertyName}AuthSource()).
|
|
@@ -2274,11 +2409,177 @@ export function cycle${a.className}User(): void {
|
|
|
2274
2409
|
}
|
|
2275
2410
|
`;
|
|
2276
2411
|
}
|
|
2412
|
+
function pluginFile2(a) {
|
|
2413
|
+
return `// The verbs a user needs to operate the stand-in session: sign in, switch the account, sign
|
|
2414
|
+
// out, from a rail item whose menu carries them. This is presentation for a product that has no
|
|
2415
|
+
// backend yet; nothing here protects anything. Delete it once your own session arrives.
|
|
2416
|
+
import type { Disposable, Plugin, PluginContext } from '@loomweaver/plugin-sdk';
|
|
2417
|
+
import { cycle${a.className}User, ${a.propertyName}AuthSource } from './${a.name}-auth-source';
|
|
2418
|
+
|
|
2419
|
+
const MENU = 'session.account/menu';
|
|
2420
|
+
const snapshot = ${a.propertyName}AuthSource();
|
|
2421
|
+
|
|
2422
|
+
let drawn: Disposable[] = [];
|
|
2423
|
+
|
|
2424
|
+
function signIn(): void {
|
|
2425
|
+
if (!snapshot().authenticated) {
|
|
2426
|
+
cycle${a.className}User();
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
|
|
2430
|
+
function switchAccount(): void {
|
|
2431
|
+
cycle${a.className}User();
|
|
2432
|
+
if (!snapshot().authenticated) {
|
|
2433
|
+
cycle${a.className}User();
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
|
|
2437
|
+
function signOut(): void {
|
|
2438
|
+
while (snapshot().authenticated) {
|
|
2439
|
+
cycle${a.className}User();
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
function initialsOf(name: string): string {
|
|
2444
|
+
return name
|
|
2445
|
+
.split(' ')
|
|
2446
|
+
.map((word) => word[0] ?? '')
|
|
2447
|
+
.join('')
|
|
2448
|
+
.slice(0, 2)
|
|
2449
|
+
.toUpperCase();
|
|
2450
|
+
}
|
|
2451
|
+
|
|
2452
|
+
function draw(ctx: PluginContext): void {
|
|
2453
|
+
for (const part of drawn) {
|
|
2454
|
+
part.dispose();
|
|
2455
|
+
}
|
|
2456
|
+
const current = snapshot();
|
|
2457
|
+
const name = current.displayName ?? '';
|
|
2458
|
+
drawn = [
|
|
2459
|
+
ctx.registerRailItem({
|
|
2460
|
+
id: 'session.account',
|
|
2461
|
+
rail: 'primary',
|
|
2462
|
+
icon: 'account',
|
|
2463
|
+
title: current.authenticated ? name : 'session.signIn',
|
|
2464
|
+
anchor: 'bottom',
|
|
2465
|
+
order: 20,
|
|
2466
|
+
menu: MENU,
|
|
2467
|
+
menuTrigger: 'primary',
|
|
2468
|
+
...(current.authenticated ? { initials: initialsOf(name) } : {}),
|
|
2469
|
+
menuHeader: current.authenticated
|
|
2470
|
+
? {
|
|
2471
|
+
title: name,
|
|
2472
|
+
detail: \`session.role.\${current.roles.includes('admin') ? 'admin' : 'user'}\`,
|
|
2473
|
+
initials: initialsOf(name),
|
|
2474
|
+
}
|
|
2475
|
+
: { title: 'session.signedOut', icon: 'account' },
|
|
2476
|
+
}),
|
|
2477
|
+
...(current.authenticated
|
|
2478
|
+
? [
|
|
2479
|
+
ctx.registerMenuItem({
|
|
2480
|
+
id: 'session.menu.switch',
|
|
2481
|
+
menu: MENU,
|
|
2482
|
+
command: 'session.switchAccount',
|
|
2483
|
+
group: 'account',
|
|
2484
|
+
order: 10,
|
|
2485
|
+
}),
|
|
2486
|
+
ctx.registerMenuItem({
|
|
2487
|
+
id: 'session.menu.signOut',
|
|
2488
|
+
menu: MENU,
|
|
2489
|
+
command: 'session.signOut',
|
|
2490
|
+
group: 'account',
|
|
2491
|
+
order: 20,
|
|
2492
|
+
}),
|
|
2493
|
+
]
|
|
2494
|
+
: [
|
|
2495
|
+
ctx.registerMenuItem({
|
|
2496
|
+
id: 'session.menu.signIn',
|
|
2497
|
+
menu: MENU,
|
|
2498
|
+
command: 'session.signIn',
|
|
2499
|
+
group: 'account',
|
|
2500
|
+
order: 10,
|
|
2501
|
+
}),
|
|
2502
|
+
]),
|
|
2503
|
+
];
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
export const ${sessionPluginSymbol(a)}: Plugin = {
|
|
2507
|
+
manifest: { id: 'session', name: 'Account', capabilities: ['contributions'] },
|
|
2508
|
+
activate(ctx) {
|
|
2509
|
+
const then = (step: () => void) => () => {
|
|
2510
|
+
step();
|
|
2511
|
+
draw(ctx);
|
|
2512
|
+
};
|
|
2513
|
+
ctx.registerCommand({
|
|
2514
|
+
id: 'session.signIn',
|
|
2515
|
+
title: 'session.signIn',
|
|
2516
|
+
icon: 'account',
|
|
2517
|
+
access: { authenticated: false },
|
|
2518
|
+
run: then(signIn),
|
|
2519
|
+
});
|
|
2520
|
+
ctx.registerCommand({
|
|
2521
|
+
id: 'session.switchAccount',
|
|
2522
|
+
title: 'session.switchAccount',
|
|
2523
|
+
icon: 'account',
|
|
2524
|
+
access: { authenticated: true },
|
|
2525
|
+
run: then(switchAccount),
|
|
2526
|
+
});
|
|
2527
|
+
ctx.registerCommand({
|
|
2528
|
+
id: 'session.signOut',
|
|
2529
|
+
title: 'session.signOut',
|
|
2530
|
+
icon: 'signOut',
|
|
2531
|
+
access: { authenticated: true },
|
|
2532
|
+
run: then(signOut),
|
|
2533
|
+
});
|
|
2534
|
+
draw(ctx);
|
|
2535
|
+
},
|
|
2536
|
+
deactivate() {
|
|
2537
|
+
for (const part of drawn) {
|
|
2538
|
+
part.dispose();
|
|
2539
|
+
}
|
|
2540
|
+
drawn = [];
|
|
2541
|
+
},
|
|
2542
|
+
};
|
|
2543
|
+
`;
|
|
2544
|
+
}
|
|
2545
|
+
function indexFile2(a) {
|
|
2546
|
+
return `export { cycle${a.className}User, ${a.propertyName}AuthSource } from './${a.name}-auth-source';
|
|
2547
|
+
export { ${sessionPluginSymbol(a)} } from './${a.name}-session.plugin';
|
|
2548
|
+
`;
|
|
2549
|
+
}
|
|
2550
|
+
var I18N = {
|
|
2551
|
+
en: {
|
|
2552
|
+
signIn: "Sign in",
|
|
2553
|
+
switchAccount: "Switch account",
|
|
2554
|
+
signOut: "Sign out",
|
|
2555
|
+
signedOut: "Not signed in",
|
|
2556
|
+
role: { user: "User", admin: "Administrator" }
|
|
2557
|
+
},
|
|
2558
|
+
de: {
|
|
2559
|
+
signIn: "Anmelden",
|
|
2560
|
+
switchAccount: "Konto wechseln",
|
|
2561
|
+
signOut: "Abmelden",
|
|
2562
|
+
signedOut: "Nicht angemeldet",
|
|
2563
|
+
role: { user: "Benutzer", admin: "Administrator" }
|
|
2564
|
+
}
|
|
2565
|
+
};
|
|
2277
2566
|
var authSource = {
|
|
2278
2567
|
id: "auth-source",
|
|
2279
2568
|
build(input) {
|
|
2280
2569
|
const a = resolveAuthSourceInput(input);
|
|
2281
|
-
|
|
2570
|
+
const source = { [`${a.name}-auth-source.ts`]: moduleFile(a) };
|
|
2571
|
+
if (a.bare) {
|
|
2572
|
+
return source;
|
|
2573
|
+
}
|
|
2574
|
+
return {
|
|
2575
|
+
...source,
|
|
2576
|
+
[`${a.name}-session.plugin.ts`]: pluginFile2(a),
|
|
2577
|
+
"index.ts": indexFile2(a),
|
|
2578
|
+
"i18n/en.json": `${JSON.stringify(I18N.en, null, 2)}
|
|
2579
|
+
`,
|
|
2580
|
+
"i18n/de.json": `${JSON.stringify(I18N.de, null, 2)}
|
|
2581
|
+
`
|
|
2582
|
+
};
|
|
2282
2583
|
}
|
|
2283
2584
|
};
|
|
2284
2585
|
|
|
@@ -2543,6 +2844,54 @@ function weaverAmendments(input, where) {
|
|
|
2543
2844
|
];
|
|
2544
2845
|
}
|
|
2545
2846
|
|
|
2847
|
+
// ../devkit/src/recipes/auth-source/recipe-amendments.ts
|
|
2848
|
+
function authSourceAmendments(input, where) {
|
|
2849
|
+
const a = resolveAuthSourceInput(input);
|
|
2850
|
+
const directory = normalizeProjectRoot(where ?? "");
|
|
2851
|
+
if (a.bare || !directory) {
|
|
2852
|
+
return [];
|
|
2853
|
+
}
|
|
2854
|
+
return [
|
|
2855
|
+
{
|
|
2856
|
+
kind: "build-target",
|
|
2857
|
+
styles: [],
|
|
2858
|
+
assets: [
|
|
2859
|
+
{
|
|
2860
|
+
glob: "**/*.json",
|
|
2861
|
+
input: `${directory}/i18n`,
|
|
2862
|
+
from: "workspace",
|
|
2863
|
+
output: `i18n/${SESSION_PLUGIN_ID}`
|
|
2864
|
+
}
|
|
2865
|
+
]
|
|
2866
|
+
},
|
|
2867
|
+
{
|
|
2868
|
+
kind: "compose-plugin",
|
|
2869
|
+
id: SESSION_PLUGIN_ID,
|
|
2870
|
+
symbol: sessionPluginSymbol(a),
|
|
2871
|
+
capabilities: ["contributions"],
|
|
2872
|
+
sourceRoot: directory,
|
|
2873
|
+
providers: [
|
|
2874
|
+
{
|
|
2875
|
+
line: `provideAuthSource(() => ${a.propertyName}AuthSource()),`,
|
|
2876
|
+
shell: ["provideAuthSource"],
|
|
2877
|
+
own: [`${a.propertyName}AuthSource`],
|
|
2878
|
+
unless: "provideAuthSource("
|
|
2879
|
+
},
|
|
2880
|
+
{
|
|
2881
|
+
line: "provideIcons({ account: heroUserCircle, signOut: heroArrowRightStartOnRectangle }),",
|
|
2882
|
+
shell: ["provideIcons"],
|
|
2883
|
+
from: [
|
|
2884
|
+
{
|
|
2885
|
+
path: "@ng-icons/heroicons/outline",
|
|
2886
|
+
symbols: ["heroArrowRightStartOnRectangle", "heroUserCircle"]
|
|
2887
|
+
}
|
|
2888
|
+
]
|
|
2889
|
+
}
|
|
2890
|
+
]
|
|
2891
|
+
}
|
|
2892
|
+
];
|
|
2893
|
+
}
|
|
2894
|
+
|
|
2546
2895
|
// ../devkit/src/lib/scaffolds/inputs.ts
|
|
2547
2896
|
function weaverInput(values) {
|
|
2548
2897
|
return {
|
|
@@ -2623,6 +2972,9 @@ var APP_OPTION = {
|
|
|
2623
2972
|
description: "Application to drop into. Inferred when the workspace has exactly one.",
|
|
2624
2973
|
workspaceOnly: true
|
|
2625
2974
|
};
|
|
2975
|
+
function authSourceInput(values) {
|
|
2976
|
+
return { name: str(values, "name") ?? "", bare: bool(values, "bare") };
|
|
2977
|
+
}
|
|
2626
2978
|
var SCAFFOLDS = [
|
|
2627
2979
|
{
|
|
2628
2980
|
name: "weaver",
|
|
@@ -2780,7 +3132,7 @@ var SCAFFOLDS = [
|
|
|
2780
3132
|
},
|
|
2781
3133
|
{
|
|
2782
3134
|
name: "auth-source",
|
|
2783
|
-
summary: "a
|
|
3135
|
+
summary: "a stand-in session a user can operate: the AuthSource, the sign-in, switch and sign-out verbs in the rail, composed in",
|
|
2784
3136
|
options: [
|
|
2785
3137
|
{
|
|
2786
3138
|
name: "name",
|
|
@@ -2789,9 +3141,22 @@ var SCAFFOLDS = [
|
|
|
2789
3141
|
required: true,
|
|
2790
3142
|
pattern: ID_PATTERN
|
|
2791
3143
|
},
|
|
2792
|
-
|
|
3144
|
+
{
|
|
3145
|
+
name: "bare",
|
|
3146
|
+
type: "boolean",
|
|
3147
|
+
description: "Write the AuthSource alone, without the verbs, for a product that maps a session of its own onto it.",
|
|
3148
|
+
default: false
|
|
3149
|
+
},
|
|
3150
|
+
APP_OPTION,
|
|
3151
|
+
{
|
|
3152
|
+
name: "directory",
|
|
3153
|
+
type: "string",
|
|
3154
|
+
description: "Where the files land, relative to the workspace root.",
|
|
3155
|
+
workspaceOnly: true
|
|
3156
|
+
}
|
|
2793
3157
|
],
|
|
2794
|
-
build: (values) => generate(authSource,
|
|
3158
|
+
build: (values) => generate(authSource, authSourceInput(values)),
|
|
3159
|
+
amend: (values) => authSourceAmendments(authSourceInput(values), str(values, "directory"))
|
|
2795
3160
|
},
|
|
2796
3161
|
{
|
|
2797
3162
|
name: "settings-store",
|
|
@@ -2850,6 +3215,8 @@ var SCAFFOLDS = [
|
|
|
2850
3215
|
function findScaffold(name) {
|
|
2851
3216
|
return SCAFFOLDS.find((scaffold2) => scaffold2.name === name);
|
|
2852
3217
|
}
|
|
3218
|
+
|
|
3219
|
+
// ../devkit/src/lib/scaffolds/surface.ts
|
|
2853
3220
|
function portableOptions(scaffold2) {
|
|
2854
3221
|
return scaffold2.options.filter((option) => !option.workspaceOnly);
|
|
2855
3222
|
}
|
|
@@ -3709,7 +4076,11 @@ var Amender = class {
|
|
|
3709
4076
|
file: root,
|
|
3710
4077
|
display: this.displayName(root),
|
|
3711
4078
|
added: [
|
|
3712
|
-
`${amendment.symbol}, its translations and its capability grants
|
|
4079
|
+
`${amendment.symbol}, its translations and its capability grants`,
|
|
4080
|
+
...(amendment.providers ?? []).filter((provider) => !result.kept.includes(provider.line)).map((provider) => provider.line.replace(/,$/, "")),
|
|
4081
|
+
...result.kept.map(
|
|
4082
|
+
(line) => `kept the ${line.split("(", 1)[0]} already there instead of ${line.replace(/,$/, "")}`
|
|
4083
|
+
)
|
|
3713
4084
|
],
|
|
3714
4085
|
content: result.source
|
|
3715
4086
|
});
|
|
@@ -3929,7 +4300,7 @@ function replaceSymlinkEntry(absolute) {
|
|
|
3929
4300
|
}
|
|
3930
4301
|
|
|
3931
4302
|
// src/lib/run.ts
|
|
3932
|
-
var VERSION = "0.9.
|
|
4303
|
+
var VERSION = "0.9.2";
|
|
3933
4304
|
function help() {
|
|
3934
4305
|
const commands = SCAFFOLDS.map((s) => ` ${s.name.padEnd(16)}${s.summary}`);
|
|
3935
4306
|
return [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loomweaver/cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "LoomWeaver: open-source plugin platform for Angular workbenches. The scaffolding CLI: generates weavers, distributions and integrations into any project, with no Nx workspace and no checkout required.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"loomweaver",
|