@loomweaver/devkit 0.7.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/README.md +127 -0
- package/generators.json +41 -0
- package/package.json +38 -0
- package/src/generators/auth-source/generator.d.ts +4 -0
- package/src/generators/auth-source/generator.js +17 -0
- package/src/generators/auth-source/generator.js.map +1 -0
- package/src/generators/auth-source/schema.json +18 -0
- package/src/generators/distribution/generator.d.ts +4 -0
- package/src/generators/distribution/generator.js +61 -0
- package/src/generators/distribution/generator.js.map +1 -0
- package/src/generators/distribution/nx-files.d.ts +22 -0
- package/src/generators/distribution/nx-files.js +133 -0
- package/src/generators/distribution/nx-files.js.map +1 -0
- package/src/generators/distribution/schema.json +48 -0
- package/src/generators/frame-plugin/generator.d.ts +4 -0
- package/src/generators/frame-plugin/generator.js +20 -0
- package/src/generators/frame-plugin/generator.js.map +1 -0
- package/src/generators/frame-plugin/schema.json +22 -0
- package/src/generators/layout/generator.d.ts +4 -0
- package/src/generators/layout/generator.js +17 -0
- package/src/generators/layout/generator.js.map +1 -0
- package/src/generators/layout/schema.json +17 -0
- package/src/generators/nx-scaffold-shared.d.ts +32 -0
- package/src/generators/nx-scaffold-shared.js +87 -0
- package/src/generators/nx-scaffold-shared.js.map +1 -0
- package/src/generators/settings-store/generator.d.ts +4 -0
- package/src/generators/settings-store/generator.js +17 -0
- package/src/generators/settings-store/generator.js.map +1 -0
- package/src/generators/settings-store/schema.json +18 -0
- package/src/generators/shared.d.ts +47 -0
- package/src/generators/shared.js +152 -0
- package/src/generators/shared.js.map +1 -0
- package/src/generators/theme/generator.d.ts +4 -0
- package/src/generators/theme/generator.js +17 -0
- package/src/generators/theme/generator.js.map +1 -0
- package/src/generators/theme/schema.json +24 -0
- package/src/generators/weaver/generator.d.ts +4 -0
- package/src/generators/weaver/generator.js +75 -0
- package/src/generators/weaver/generator.js.map +1 -0
- package/src/generators/weaver/nx-files.d.ts +26 -0
- package/src/generators/weaver/nx-files.js +73 -0
- package/src/generators/weaver/nx-files.js.map +1 -0
- package/src/generators/weaver/schema.json +97 -0
- package/src/index.d.ts +15 -0
- package/src/index.js +47 -0
- package/src/index.js.map +1 -0
- package/src/lib/generate/casing.d.ts +4 -0
- package/src/lib/generate/casing.js +27 -0
- package/src/lib/generate/casing.js.map +1 -0
- package/src/lib/generate/generate.d.ts +2 -0
- package/src/lib/generate/generate.js +18 -0
- package/src/lib/generate/generate.js.map +1 -0
- package/src/lib/generate/types.d.ts +5 -0
- package/src/lib/generate/types.js +3 -0
- package/src/lib/generate/types.js.map +1 -0
- package/src/lib/scaffolds/scaffolds.d.ts +37 -0
- package/src/lib/scaffolds/scaffolds.js +357 -0
- package/src/lib/scaffolds/scaffolds.js.map +1 -0
- package/src/lib/validate/catalog.d.ts +15 -0
- package/src/lib/validate/catalog.js +247 -0
- package/src/lib/validate/catalog.js.map +1 -0
- package/src/lib/validate/i18n.d.ts +3 -0
- package/src/lib/validate/i18n.js +41 -0
- package/src/lib/validate/i18n.js.map +1 -0
- package/src/lib/validate/manifest.d.ts +8 -0
- package/src/lib/validate/manifest.js +74 -0
- package/src/lib/validate/manifest.js.map +1 -0
- package/src/lib/validate/types.d.ts +7 -0
- package/src/lib/validate/types.js +3 -0
- package/src/lib/validate/types.js.map +1 -0
- package/src/recipes/angular-distribution/logo.d.ts +1 -0
- package/src/recipes/angular-distribution/logo.js +9 -0
- package/src/recipes/angular-distribution/logo.js.map +1 -0
- package/src/recipes/angular-distribution/recipe.d.ts +25 -0
- package/src/recipes/angular-distribution/recipe.js +407 -0
- package/src/recipes/angular-distribution/recipe.js.map +1 -0
- package/src/recipes/angular-weaver/recipe.d.ts +48 -0
- package/src/recipes/angular-weaver/recipe.js +568 -0
- package/src/recipes/angular-weaver/recipe.js.map +1 -0
- package/src/recipes/angular-weaver/weaver-i18n.d.ts +3 -0
- package/src/recipes/angular-weaver/weaver-i18n.js +24 -0
- package/src/recipes/angular-weaver/weaver-i18n.js.map +1 -0
- package/src/recipes/auth-source/recipe.d.ts +11 -0
- package/src/recipes/auth-source/recipe.js +61 -0
- package/src/recipes/auth-source/recipe.js.map +1 -0
- package/src/recipes/frame-plugin/recipe.d.ts +11 -0
- package/src/recipes/frame-plugin/recipe.js +143 -0
- package/src/recipes/frame-plugin/recipe.js.map +1 -0
- package/src/recipes/layout/recipe.d.ts +10 -0
- package/src/recipes/layout/recipe.js +35 -0
- package/src/recipes/layout/recipe.js.map +1 -0
- package/src/recipes/settings-store/recipe.d.ts +10 -0
- package/src/recipes/settings-store/recipe.js +51 -0
- package/src/recipes/settings-store/recipe.js.map +1 -0
- package/src/recipes/shell-regions.d.ts +9 -0
- package/src/recipes/shell-regions.js +23 -0
- package/src/recipes/shell-regions.js.map +1 -0
- package/src/recipes/theme/recipe.d.ts +13 -0
- package/src/recipes/theme/recipe.js +142 -0
- package/src/recipes/theme/recipe.js.map +1 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"$id": "LoomWeaverWeaver",
|
|
4
|
+
"title": "Scaffold an Angular in-process plugin: manifest, surface, rail item, i18n, test",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"id": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "Plugin id in kebab-case, e.g. 'notes'.",
|
|
10
|
+
"pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$"
|
|
11
|
+
},
|
|
12
|
+
"name": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "Human-readable name. Defaults to a title-cased id."
|
|
15
|
+
},
|
|
16
|
+
"command": {
|
|
17
|
+
"type": "boolean",
|
|
18
|
+
"description": "Also scaffold a registered command the weaver can trigger.",
|
|
19
|
+
"default": false
|
|
20
|
+
},
|
|
21
|
+
"shortcut": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "Keyboard chord for the command, e.g. 'mod+shift+k'. Implies --command."
|
|
24
|
+
},
|
|
25
|
+
"menu": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "Hook a menu item into a slot, e.g. 'content/tab/context'. Implies --command."
|
|
28
|
+
},
|
|
29
|
+
"barItem": {
|
|
30
|
+
"type": "boolean",
|
|
31
|
+
"description": "Also add a status-bar button that triggers the command. Implies --command.",
|
|
32
|
+
"default": false
|
|
33
|
+
},
|
|
34
|
+
"settings": {
|
|
35
|
+
"type": "boolean",
|
|
36
|
+
"description": "Also scaffold a settings section with signal-backed value owners.",
|
|
37
|
+
"default": false
|
|
38
|
+
},
|
|
39
|
+
"about": {
|
|
40
|
+
"type": "boolean",
|
|
41
|
+
"description": "Also scaffold an About dialog that reads ctx.host, plus a bottom rail item.",
|
|
42
|
+
"default": false
|
|
43
|
+
},
|
|
44
|
+
"instanceable": {
|
|
45
|
+
"type": "boolean",
|
|
46
|
+
"description": "Dock the surface and give it named saved instances, each with its own view state. Not combinable with --container: named instances exist only for a docked, non-routable surface.",
|
|
47
|
+
"default": false
|
|
48
|
+
},
|
|
49
|
+
"container": {
|
|
50
|
+
"type": "boolean",
|
|
51
|
+
"description": "Make the surface a container: a routable tab at '<id>/:id' holding a nested pane tree of child surfaces, which the host draws. Not combinable with --instanceable.",
|
|
52
|
+
"default": false
|
|
53
|
+
},
|
|
54
|
+
"access": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"description": "Auth-gate the surface and rail item: 'authenticated', 'anonymous' or 'role:<name>'."
|
|
57
|
+
},
|
|
58
|
+
"spec": {
|
|
59
|
+
"type": "boolean",
|
|
60
|
+
"description": "Generate a starter unit test. Use --no-spec to skip it.",
|
|
61
|
+
"default": true
|
|
62
|
+
},
|
|
63
|
+
"projectName": {
|
|
64
|
+
"type": "string",
|
|
65
|
+
"description": "Nx project name. Defaults to '<id>-weaver'."
|
|
66
|
+
},
|
|
67
|
+
"importPath": {
|
|
68
|
+
"type": "string",
|
|
69
|
+
"description": "Import path for the workspace alias. Defaults to the workspace scope plus the project name."
|
|
70
|
+
},
|
|
71
|
+
"app": {
|
|
72
|
+
"type": "string",
|
|
73
|
+
"description": "Application to drop into. Inferred when the workspace has exactly one."
|
|
74
|
+
},
|
|
75
|
+
"directory": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"description": "Project root, relative to the workspace root."
|
|
78
|
+
},
|
|
79
|
+
"tags": {
|
|
80
|
+
"type": "string",
|
|
81
|
+
"description": "Comma-separated Nx tags for the project."
|
|
82
|
+
},
|
|
83
|
+
"prefix": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"description": "Selector prefix for generated components and directives.",
|
|
86
|
+
"default": "lw",
|
|
87
|
+
"pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$"
|
|
88
|
+
},
|
|
89
|
+
"unitTestRunner": {
|
|
90
|
+
"type": "string",
|
|
91
|
+
"description": "Test wiring to emit. 'vitest' uses @nx/angular:unit-test; 'none' emits no test target.",
|
|
92
|
+
"enum": ["vitest", "none"],
|
|
93
|
+
"default": "vitest"
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"required": ["id"]
|
|
97
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type { FileMap, Recipe } from './lib/generate/types';
|
|
2
|
+
export { generate } from './lib/generate/generate';
|
|
3
|
+
export { isKebabId, toCamelCase, toPascalCase, toTitleCase } from './lib/generate/casing';
|
|
4
|
+
export { angularWeaver, resolveWeaverInput, type WeaverInput, type ResolvedWeaver, } from './recipes/angular-weaver/recipe';
|
|
5
|
+
export { framePlugin, resolveFramePluginInput, type FramePluginInput, type ResolvedFramePlugin, } from './recipes/frame-plugin/recipe';
|
|
6
|
+
export { angularDistribution, resolveDistributionInput, type DistributionInput, type ResolvedDistribution, } from './recipes/angular-distribution/recipe';
|
|
7
|
+
export { authSource, resolveAuthSourceInput, type AuthSourceInput, type ResolvedAuthSource, } from './recipes/auth-source/recipe';
|
|
8
|
+
export { settingsStore, resolveSettingsStoreInput, type SettingsStoreInput, type ResolvedSettingsStore, } from './recipes/settings-store/recipe';
|
|
9
|
+
export { theme, resolveThemeInput, type ThemeInput, type ResolvedTheme } from './recipes/theme/recipe';
|
|
10
|
+
export { layout, resolveLayoutInput, type LayoutInput, type ResolvedLayout, } from './recipes/layout/recipe';
|
|
11
|
+
export { SCAFFOLDS, findScaffold, kebabCase, nxSchemaFor, portableOptions, usageFor, type ScaffoldDescriptor, type ScaffoldOption, type ScaffoldValues, } from './lib/scaffolds/scaffolds';
|
|
12
|
+
export type { Finding, FindingLevel } from './lib/validate/types';
|
|
13
|
+
export { validateManifest, KNOWN_CAPABILITIES, type ManifestLike } from './lib/validate/manifest';
|
|
14
|
+
export { validateI18nParity, type I18nBundle } from './lib/validate/i18n';
|
|
15
|
+
export { validateCatalog, CATALOG_ENTRY_KEYS } from './lib/validate/catalog';
|
package/src/index.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CATALOG_ENTRY_KEYS = exports.validateCatalog = exports.validateI18nParity = exports.KNOWN_CAPABILITIES = exports.validateManifest = exports.usageFor = exports.portableOptions = exports.nxSchemaFor = exports.kebabCase = exports.findScaffold = exports.SCAFFOLDS = exports.resolveLayoutInput = exports.layout = exports.resolveThemeInput = exports.theme = exports.resolveSettingsStoreInput = exports.settingsStore = exports.resolveAuthSourceInput = exports.authSource = exports.resolveDistributionInput = exports.angularDistribution = exports.resolveFramePluginInput = exports.framePlugin = exports.resolveWeaverInput = exports.angularWeaver = exports.toTitleCase = exports.toPascalCase = exports.toCamelCase = exports.isKebabId = exports.generate = void 0;
|
|
4
|
+
var generate_1 = require("./lib/generate/generate");
|
|
5
|
+
Object.defineProperty(exports, "generate", { enumerable: true, get: function () { return generate_1.generate; } });
|
|
6
|
+
var casing_1 = require("./lib/generate/casing");
|
|
7
|
+
Object.defineProperty(exports, "isKebabId", { enumerable: true, get: function () { return casing_1.isKebabId; } });
|
|
8
|
+
Object.defineProperty(exports, "toCamelCase", { enumerable: true, get: function () { return casing_1.toCamelCase; } });
|
|
9
|
+
Object.defineProperty(exports, "toPascalCase", { enumerable: true, get: function () { return casing_1.toPascalCase; } });
|
|
10
|
+
Object.defineProperty(exports, "toTitleCase", { enumerable: true, get: function () { return casing_1.toTitleCase; } });
|
|
11
|
+
var recipe_1 = require("./recipes/angular-weaver/recipe");
|
|
12
|
+
Object.defineProperty(exports, "angularWeaver", { enumerable: true, get: function () { return recipe_1.angularWeaver; } });
|
|
13
|
+
Object.defineProperty(exports, "resolveWeaverInput", { enumerable: true, get: function () { return recipe_1.resolveWeaverInput; } });
|
|
14
|
+
var recipe_2 = require("./recipes/frame-plugin/recipe");
|
|
15
|
+
Object.defineProperty(exports, "framePlugin", { enumerable: true, get: function () { return recipe_2.framePlugin; } });
|
|
16
|
+
Object.defineProperty(exports, "resolveFramePluginInput", { enumerable: true, get: function () { return recipe_2.resolveFramePluginInput; } });
|
|
17
|
+
var recipe_3 = require("./recipes/angular-distribution/recipe");
|
|
18
|
+
Object.defineProperty(exports, "angularDistribution", { enumerable: true, get: function () { return recipe_3.angularDistribution; } });
|
|
19
|
+
Object.defineProperty(exports, "resolveDistributionInput", { enumerable: true, get: function () { return recipe_3.resolveDistributionInput; } });
|
|
20
|
+
var recipe_4 = require("./recipes/auth-source/recipe");
|
|
21
|
+
Object.defineProperty(exports, "authSource", { enumerable: true, get: function () { return recipe_4.authSource; } });
|
|
22
|
+
Object.defineProperty(exports, "resolveAuthSourceInput", { enumerable: true, get: function () { return recipe_4.resolveAuthSourceInput; } });
|
|
23
|
+
var recipe_5 = require("./recipes/settings-store/recipe");
|
|
24
|
+
Object.defineProperty(exports, "settingsStore", { enumerable: true, get: function () { return recipe_5.settingsStore; } });
|
|
25
|
+
Object.defineProperty(exports, "resolveSettingsStoreInput", { enumerable: true, get: function () { return recipe_5.resolveSettingsStoreInput; } });
|
|
26
|
+
var recipe_6 = require("./recipes/theme/recipe");
|
|
27
|
+
Object.defineProperty(exports, "theme", { enumerable: true, get: function () { return recipe_6.theme; } });
|
|
28
|
+
Object.defineProperty(exports, "resolveThemeInput", { enumerable: true, get: function () { return recipe_6.resolveThemeInput; } });
|
|
29
|
+
var recipe_7 = require("./recipes/layout/recipe");
|
|
30
|
+
Object.defineProperty(exports, "layout", { enumerable: true, get: function () { return recipe_7.layout; } });
|
|
31
|
+
Object.defineProperty(exports, "resolveLayoutInput", { enumerable: true, get: function () { return recipe_7.resolveLayoutInput; } });
|
|
32
|
+
var scaffolds_1 = require("./lib/scaffolds/scaffolds");
|
|
33
|
+
Object.defineProperty(exports, "SCAFFOLDS", { enumerable: true, get: function () { return scaffolds_1.SCAFFOLDS; } });
|
|
34
|
+
Object.defineProperty(exports, "findScaffold", { enumerable: true, get: function () { return scaffolds_1.findScaffold; } });
|
|
35
|
+
Object.defineProperty(exports, "kebabCase", { enumerable: true, get: function () { return scaffolds_1.kebabCase; } });
|
|
36
|
+
Object.defineProperty(exports, "nxSchemaFor", { enumerable: true, get: function () { return scaffolds_1.nxSchemaFor; } });
|
|
37
|
+
Object.defineProperty(exports, "portableOptions", { enumerable: true, get: function () { return scaffolds_1.portableOptions; } });
|
|
38
|
+
Object.defineProperty(exports, "usageFor", { enumerable: true, get: function () { return scaffolds_1.usageFor; } });
|
|
39
|
+
var manifest_1 = require("./lib/validate/manifest");
|
|
40
|
+
Object.defineProperty(exports, "validateManifest", { enumerable: true, get: function () { return manifest_1.validateManifest; } });
|
|
41
|
+
Object.defineProperty(exports, "KNOWN_CAPABILITIES", { enumerable: true, get: function () { return manifest_1.KNOWN_CAPABILITIES; } });
|
|
42
|
+
var i18n_1 = require("./lib/validate/i18n");
|
|
43
|
+
Object.defineProperty(exports, "validateI18nParity", { enumerable: true, get: function () { return i18n_1.validateI18nParity; } });
|
|
44
|
+
var catalog_1 = require("./lib/validate/catalog");
|
|
45
|
+
Object.defineProperty(exports, "validateCatalog", { enumerable: true, get: function () { return catalog_1.validateCatalog; } });
|
|
46
|
+
Object.defineProperty(exports, "CATALOG_ENTRY_KEYS", { enumerable: true, get: function () { return catalog_1.CATALOG_ENTRY_KEYS; } });
|
|
47
|
+
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/tooling/devkit/src/index.ts"],"names":[],"mappings":";;;AACA,oDAAmD;AAA1C,oGAAA,QAAQ,OAAA;AACjB,gDAA0F;AAAjF,mGAAA,SAAS,OAAA;AAAE,qGAAA,WAAW,OAAA;AAAE,sGAAA,YAAY,OAAA;AAAE,qGAAA,WAAW,OAAA;AAC1D,0DAKyC;AAJvC,uGAAA,aAAa,OAAA;AACb,4GAAA,kBAAkB,OAAA;AAIpB,wDAKuC;AAJrC,qGAAA,WAAW,OAAA;AACX,iHAAA,uBAAuB,OAAA;AAIzB,gEAK+C;AAJ7C,6GAAA,mBAAmB,OAAA;AACnB,kHAAA,wBAAwB,OAAA;AAI1B,uDAKsC;AAJpC,oGAAA,UAAU,OAAA;AACV,gHAAA,sBAAsB,OAAA;AAIxB,0DAKyC;AAJvC,uGAAA,aAAa,OAAA;AACb,mHAAA,yBAAyB,OAAA;AAI3B,iDAAuG;AAA9F,+FAAA,KAAK,OAAA;AAAE,2GAAA,iBAAiB,OAAA;AACjC,kDAKiC;AAJ/B,gGAAA,MAAM,OAAA;AACN,4GAAA,kBAAkB,OAAA;AAIpB,uDAUmC;AATjC,sGAAA,SAAS,OAAA;AACT,yGAAA,YAAY,OAAA;AACZ,sGAAA,SAAS,OAAA;AACT,wGAAA,WAAW,OAAA;AACX,4GAAA,eAAe,OAAA;AACf,qGAAA,QAAQ,OAAA;AAMV,oDAAkG;AAAzF,4GAAA,gBAAgB,OAAA;AAAE,8GAAA,kBAAkB,OAAA;AAC7C,4CAA0E;AAAjE,0GAAA,kBAAkB,OAAA;AAC3B,kDAA6E;AAApE,0GAAA,eAAe,OAAA;AAAE,6GAAA,kBAAkB,OAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isKebabId = isKebabId;
|
|
4
|
+
exports.toPascalCase = toPascalCase;
|
|
5
|
+
exports.toCamelCase = toCamelCase;
|
|
6
|
+
exports.toTitleCase = toTitleCase;
|
|
7
|
+
function isKebabId(value) {
|
|
8
|
+
return /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(value);
|
|
9
|
+
}
|
|
10
|
+
function words(value) {
|
|
11
|
+
return value.split(/[-_\s]+/).filter(Boolean);
|
|
12
|
+
}
|
|
13
|
+
function toPascalCase(value) {
|
|
14
|
+
return words(value)
|
|
15
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
16
|
+
.join('');
|
|
17
|
+
}
|
|
18
|
+
function toCamelCase(value) {
|
|
19
|
+
const pascal = toPascalCase(value);
|
|
20
|
+
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
21
|
+
}
|
|
22
|
+
function toTitleCase(value) {
|
|
23
|
+
return words(value)
|
|
24
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
25
|
+
.join(' ');
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=casing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"casing.js","sourceRoot":"","sources":["../../../../../../../libs/tooling/devkit/src/lib/generate/casing.ts"],"names":[],"mappings":";;AAAA,8BAEC;AAMD,oCAIC;AAED,kCAGC;AAED,kCAIC;AAvBD,SAAgB,SAAS,CAAC,KAAa;IACrC,OAAO,+BAA+B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,KAAK,CAAC,KAAa;IAC1B,OAAO,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAChD,CAAC;AAED,SAAgB,YAAY,CAAC,KAAa;IACxC,OAAO,KAAK,CAAC,KAAK,CAAC;SAChB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC3D,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,SAAgB,WAAW,CAAC,KAAa;IACvC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,SAAgB,WAAW,CAAC,KAAa;IACvC,OAAO,KAAK,CAAC,KAAK,CAAC;SAChB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC3D,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generate = generate;
|
|
4
|
+
function isUnsafePath(path) {
|
|
5
|
+
return (path.length === 0 ||
|
|
6
|
+
path.startsWith('/') ||
|
|
7
|
+
path.includes('\\') ||
|
|
8
|
+
path.split('/').includes('..'));
|
|
9
|
+
}
|
|
10
|
+
function generate(recipe, input) {
|
|
11
|
+
const files = recipe.build(input);
|
|
12
|
+
const unsafe = Object.keys(files).find(isUnsafePath);
|
|
13
|
+
if (unsafe !== undefined) {
|
|
14
|
+
throw new Error(`Recipe "${recipe.id}" produced an unsafe path: "${unsafe}".`);
|
|
15
|
+
}
|
|
16
|
+
return files;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../../../../../libs/tooling/devkit/src/lib/generate/generate.ts"],"names":[],"mappings":";;AAWA,4BAOC;AAhBD,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,CACL,IAAI,CAAC,MAAM,KAAK,CAAC;QACjB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QACpB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QACnB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAC/B,CAAC;AACJ,CAAC;AAED,SAAgB,QAAQ,CAAQ,MAAqB,EAAE,KAAY;IACjE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACrD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,CAAC,EAAE,+BAA+B,MAAM,IAAI,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../../libs/tooling/devkit/src/lib/generate/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { FileMap } from '../generate/types';
|
|
2
|
+
export type ScaffoldValues = Readonly<Record<string, string | boolean | undefined>>;
|
|
3
|
+
export interface ScaffoldOption {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly type: 'string' | 'boolean';
|
|
6
|
+
readonly description: string;
|
|
7
|
+
readonly required?: boolean;
|
|
8
|
+
readonly default?: string | boolean;
|
|
9
|
+
readonly choices?: readonly string[];
|
|
10
|
+
readonly pattern?: string;
|
|
11
|
+
/**
|
|
12
|
+
* True for options that describe a place in an Nx workspace. An adapter that only returns or
|
|
13
|
+
* writes a file map has nowhere to put them, so it leaves them out of its surface.
|
|
14
|
+
*/
|
|
15
|
+
readonly workspaceOnly?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface ScaffoldDescriptor {
|
|
18
|
+
readonly name: string;
|
|
19
|
+
readonly summary: string;
|
|
20
|
+
readonly options: readonly ScaffoldOption[];
|
|
21
|
+
build(values: ScaffoldValues): FileMap;
|
|
22
|
+
}
|
|
23
|
+
export declare function str(values: ScaffoldValues, name: string): string | undefined;
|
|
24
|
+
export declare function bool(values: ScaffoldValues, name: string): boolean | undefined;
|
|
25
|
+
/** The kebab-case spelling of a camelCase option, for command lines that prefer it. */
|
|
26
|
+
export declare function kebabCase(name: string): string;
|
|
27
|
+
export declare const SCAFFOLDS: readonly ScaffoldDescriptor[];
|
|
28
|
+
export declare function findScaffold(name: string): ScaffoldDescriptor | undefined;
|
|
29
|
+
/** The option surface an adapter that only produces files can offer. */
|
|
30
|
+
export declare function portableOptions(scaffold: ScaffoldDescriptor): readonly ScaffoldOption[];
|
|
31
|
+
/**
|
|
32
|
+
* The JSON Schema an Nx generator loads. Nx reads it from disk before any of our code runs, so the
|
|
33
|
+
* file cannot be computed at call time — instead it is checked against this shape by a test, which
|
|
34
|
+
* fails the moment the two drift apart.
|
|
35
|
+
*/
|
|
36
|
+
export declare function nxSchemaFor(scaffold: ScaffoldDescriptor): Record<string, unknown>;
|
|
37
|
+
export declare function usageFor(scaffold: ScaffoldDescriptor): string;
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SCAFFOLDS = void 0;
|
|
4
|
+
exports.str = str;
|
|
5
|
+
exports.bool = bool;
|
|
6
|
+
exports.kebabCase = kebabCase;
|
|
7
|
+
exports.findScaffold = findScaffold;
|
|
8
|
+
exports.portableOptions = portableOptions;
|
|
9
|
+
exports.nxSchemaFor = nxSchemaFor;
|
|
10
|
+
exports.usageFor = usageFor;
|
|
11
|
+
const recipe_1 = require("../../recipes/angular-distribution/recipe");
|
|
12
|
+
const recipe_2 = require("../../recipes/angular-weaver/recipe");
|
|
13
|
+
const recipe_3 = require("../../recipes/auth-source/recipe");
|
|
14
|
+
const recipe_4 = require("../../recipes/layout/recipe");
|
|
15
|
+
const recipe_5 = require("../../recipes/frame-plugin/recipe");
|
|
16
|
+
const recipe_6 = require("../../recipes/settings-store/recipe");
|
|
17
|
+
const recipe_7 = require("../../recipes/theme/recipe");
|
|
18
|
+
const generate_1 = require("../generate/generate");
|
|
19
|
+
function str(values, name) {
|
|
20
|
+
const value = values[name];
|
|
21
|
+
return typeof value === 'string' ? value : undefined;
|
|
22
|
+
}
|
|
23
|
+
function bool(values, name) {
|
|
24
|
+
const value = values[name];
|
|
25
|
+
return typeof value === 'boolean' ? value : undefined;
|
|
26
|
+
}
|
|
27
|
+
/** The kebab-case spelling of a camelCase option, for command lines that prefer it. */
|
|
28
|
+
function kebabCase(name) {
|
|
29
|
+
return name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
|
|
30
|
+
}
|
|
31
|
+
const ID_PATTERN = '^[a-z][a-z0-9]*(-[a-z0-9]+)*$';
|
|
32
|
+
const PLACEMENT_OPTIONS = [
|
|
33
|
+
{
|
|
34
|
+
name: 'directory',
|
|
35
|
+
type: 'string',
|
|
36
|
+
description: 'Project root, relative to the workspace root.',
|
|
37
|
+
workspaceOnly: true,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'tags',
|
|
41
|
+
type: 'string',
|
|
42
|
+
description: 'Comma-separated Nx tags for the project.',
|
|
43
|
+
workspaceOnly: true,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'prefix',
|
|
47
|
+
type: 'string',
|
|
48
|
+
description: 'Selector prefix for generated components and directives.',
|
|
49
|
+
default: 'lw',
|
|
50
|
+
pattern: ID_PATTERN,
|
|
51
|
+
workspaceOnly: true,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'unitTestRunner',
|
|
55
|
+
type: 'string',
|
|
56
|
+
description: "Test wiring to emit. 'vitest' uses @nx/angular:unit-test; 'none' emits no test target.",
|
|
57
|
+
choices: ['vitest', 'none'],
|
|
58
|
+
default: 'vitest',
|
|
59
|
+
workspaceOnly: true,
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
const APP_OPTION = {
|
|
63
|
+
name: 'app',
|
|
64
|
+
type: 'string',
|
|
65
|
+
description: 'Application to drop into. Inferred when the workspace has exactly one.',
|
|
66
|
+
workspaceOnly: true,
|
|
67
|
+
};
|
|
68
|
+
exports.SCAFFOLDS = [
|
|
69
|
+
{
|
|
70
|
+
name: 'weaver',
|
|
71
|
+
summary: 'an Angular in-process plugin: manifest, surface, rail item, i18n, test',
|
|
72
|
+
options: [
|
|
73
|
+
{
|
|
74
|
+
name: 'id',
|
|
75
|
+
type: 'string',
|
|
76
|
+
description: "Plugin id in kebab-case, e.g. 'notes'.",
|
|
77
|
+
required: true,
|
|
78
|
+
pattern: ID_PATTERN,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'name',
|
|
82
|
+
type: 'string',
|
|
83
|
+
description: 'Human-readable name. Defaults to a title-cased id.',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: 'command',
|
|
87
|
+
type: 'boolean',
|
|
88
|
+
description: 'Also scaffold a registered command the weaver can trigger.',
|
|
89
|
+
default: false,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: 'shortcut',
|
|
93
|
+
type: 'string',
|
|
94
|
+
description: "Keyboard chord for the command, e.g. 'mod+shift+k'. Implies --command.",
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: 'menu',
|
|
98
|
+
type: 'string',
|
|
99
|
+
description: "Hook a menu item into a slot, e.g. 'content/tab/context'. Implies --command.",
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'barItem',
|
|
103
|
+
type: 'boolean',
|
|
104
|
+
description: 'Also add a status-bar button that triggers the command. Implies --command.',
|
|
105
|
+
default: false,
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'settings',
|
|
109
|
+
type: 'boolean',
|
|
110
|
+
description: 'Also scaffold a settings section with signal-backed value owners.',
|
|
111
|
+
default: false,
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: 'about',
|
|
115
|
+
type: 'boolean',
|
|
116
|
+
description: 'Also scaffold an About dialog that reads ctx.host, plus a bottom rail item.',
|
|
117
|
+
default: false,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: 'instanceable',
|
|
121
|
+
type: 'boolean',
|
|
122
|
+
description: 'Dock the surface and give it named saved instances, each with its own view state. Not combinable with --container: named instances exist only for a docked, non-routable surface.',
|
|
123
|
+
default: false,
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: 'container',
|
|
127
|
+
type: 'boolean',
|
|
128
|
+
description: "Make the surface a container: a routable tab at '<id>/:id' holding a nested pane tree of child surfaces, which the host draws. Not combinable with --instanceable.",
|
|
129
|
+
default: false,
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: 'access',
|
|
133
|
+
type: 'string',
|
|
134
|
+
description: "Auth-gate the surface and rail item: 'authenticated', 'anonymous' or 'role:<name>'.",
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: 'spec',
|
|
138
|
+
type: 'boolean',
|
|
139
|
+
description: 'Generate a starter unit test. Use --no-spec to skip it.',
|
|
140
|
+
default: true,
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
name: 'projectName',
|
|
144
|
+
type: 'string',
|
|
145
|
+
description: "Nx project name. Defaults to '<id>-weaver'.",
|
|
146
|
+
workspaceOnly: true,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: 'importPath',
|
|
150
|
+
type: 'string',
|
|
151
|
+
description: 'Import path for the workspace alias. Defaults to the workspace scope plus the project name.',
|
|
152
|
+
workspaceOnly: true,
|
|
153
|
+
},
|
|
154
|
+
APP_OPTION,
|
|
155
|
+
...PLACEMENT_OPTIONS,
|
|
156
|
+
],
|
|
157
|
+
build: (values) => {
|
|
158
|
+
var _a;
|
|
159
|
+
return (0, generate_1.generate)(recipe_2.angularWeaver, {
|
|
160
|
+
id: (_a = str(values, 'id')) !== null && _a !== void 0 ? _a : '',
|
|
161
|
+
name: str(values, 'name'),
|
|
162
|
+
prefix: str(values, 'prefix'),
|
|
163
|
+
importPath: str(values, 'importPath'),
|
|
164
|
+
features: {
|
|
165
|
+
command: bool(values, 'command'),
|
|
166
|
+
shortcut: str(values, 'shortcut'),
|
|
167
|
+
menu: str(values, 'menu'),
|
|
168
|
+
barItem: bool(values, 'barItem'),
|
|
169
|
+
settings: bool(values, 'settings'),
|
|
170
|
+
about: bool(values, 'about'),
|
|
171
|
+
instanceable: bool(values, 'instanceable'),
|
|
172
|
+
container: bool(values, 'container'),
|
|
173
|
+
access: str(values, 'access'),
|
|
174
|
+
spec: bool(values, 'spec'),
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: 'frame-plugin',
|
|
181
|
+
summary: 'a framework-agnostic iframe plugin (Penpal + the frame UI kit)',
|
|
182
|
+
options: [
|
|
183
|
+
{
|
|
184
|
+
name: 'id',
|
|
185
|
+
type: 'string',
|
|
186
|
+
description: "Plugin id in kebab-case, e.g. 'notes'.",
|
|
187
|
+
required: true,
|
|
188
|
+
pattern: ID_PATTERN,
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: 'name',
|
|
192
|
+
type: 'string',
|
|
193
|
+
description: 'Human-readable name. Defaults to a title-cased id.',
|
|
194
|
+
},
|
|
195
|
+
APP_OPTION,
|
|
196
|
+
],
|
|
197
|
+
build: (values) => {
|
|
198
|
+
var _a;
|
|
199
|
+
return (0, generate_1.generate)(recipe_5.framePlugin, {
|
|
200
|
+
id: (_a = str(values, 'id')) !== null && _a !== void 0 ? _a : '',
|
|
201
|
+
name: str(values, 'name'),
|
|
202
|
+
});
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: 'distribution',
|
|
207
|
+
summary: 'a runnable composition root that boots the shell',
|
|
208
|
+
options: [
|
|
209
|
+
{
|
|
210
|
+
name: 'name',
|
|
211
|
+
type: 'string',
|
|
212
|
+
description: "Distribution name in kebab-case, e.g. 'acme-studio'.",
|
|
213
|
+
required: true,
|
|
214
|
+
pattern: ID_PATTERN,
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: 'title',
|
|
218
|
+
type: 'string',
|
|
219
|
+
description: 'Product display title. Defaults to a title-cased name.',
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
name: 'styles',
|
|
223
|
+
type: 'string',
|
|
224
|
+
description: "Which stylesheet to emit. 'tailwind' compiles the shell's source theme and lets you write Tailwind utilities of your own; 'precompiled' imports the stylesheet we compiled, so the application needs no Tailwind and can be themed with Bootstrap or anything else.",
|
|
225
|
+
choices: ['tailwind', 'precompiled'],
|
|
226
|
+
default: 'tailwind',
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
name: 'force',
|
|
230
|
+
type: 'boolean',
|
|
231
|
+
description: 'Compose into the application already at that path, replacing the bootstrap files this scaffold owns and merging its build targets. Without it an existing project is an error.',
|
|
232
|
+
workspaceOnly: true,
|
|
233
|
+
},
|
|
234
|
+
...PLACEMENT_OPTIONS,
|
|
235
|
+
],
|
|
236
|
+
build: (values) => {
|
|
237
|
+
var _a, _b;
|
|
238
|
+
return (0, generate_1.generate)(recipe_1.angularDistribution, {
|
|
239
|
+
name: (_a = str(values, 'name')) !== null && _a !== void 0 ? _a : '',
|
|
240
|
+
title: str(values, 'title'),
|
|
241
|
+
directory: str(values, 'directory'),
|
|
242
|
+
styles: (_b = str(values, 'styles')) !== null && _b !== void 0 ? _b : 'tailwind',
|
|
243
|
+
});
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
name: 'auth-source',
|
|
248
|
+
summary: 'a provider-neutral AuthSource that feeds the session',
|
|
249
|
+
options: [
|
|
250
|
+
{
|
|
251
|
+
name: 'name',
|
|
252
|
+
type: 'string',
|
|
253
|
+
description: "Source name in kebab-case, e.g. 'dev'.",
|
|
254
|
+
required: true,
|
|
255
|
+
pattern: ID_PATTERN,
|
|
256
|
+
},
|
|
257
|
+
APP_OPTION,
|
|
258
|
+
],
|
|
259
|
+
build: (values) => { var _a; return (0, generate_1.generate)(recipe_3.authSource, { name: (_a = str(values, 'name')) !== null && _a !== void 0 ? _a : '' }); },
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: 'settings-store',
|
|
263
|
+
summary: 'a settings-store implementation backed by your API',
|
|
264
|
+
options: [
|
|
265
|
+
{
|
|
266
|
+
name: 'name',
|
|
267
|
+
type: 'string',
|
|
268
|
+
description: "Store name in kebab-case, e.g. 'backend'.",
|
|
269
|
+
required: true,
|
|
270
|
+
pattern: ID_PATTERN,
|
|
271
|
+
},
|
|
272
|
+
APP_OPTION,
|
|
273
|
+
],
|
|
274
|
+
build: (values) => { var _a; return (0, generate_1.generate)(recipe_6.settingsStore, { name: (_a = str(values, 'name')) !== null && _a !== void 0 ? _a : '' }); },
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
name: 'theme',
|
|
278
|
+
summary: 'a token-override stylesheet in @layer lw-tenant-theme',
|
|
279
|
+
options: [
|
|
280
|
+
{
|
|
281
|
+
name: 'name',
|
|
282
|
+
type: 'string',
|
|
283
|
+
description: "Theme name in kebab-case, e.g. 'midnight'.",
|
|
284
|
+
required: true,
|
|
285
|
+
pattern: ID_PATTERN,
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
name: 'preset',
|
|
289
|
+
type: 'string',
|
|
290
|
+
description: "Where the token values come from. 'literal' writes editable colours; 'bootstrap' maps them onto Bootstrap 5.3's --bs-* variables, which makes the shell follow your Bootstrap theme live.",
|
|
291
|
+
choices: ['literal', 'bootstrap'],
|
|
292
|
+
default: 'literal',
|
|
293
|
+
},
|
|
294
|
+
APP_OPTION,
|
|
295
|
+
],
|
|
296
|
+
build: (values) => {
|
|
297
|
+
var _a, _b;
|
|
298
|
+
return (0, generate_1.generate)(recipe_7.theme, {
|
|
299
|
+
name: (_a = str(values, 'name')) !== null && _a !== void 0 ? _a : '',
|
|
300
|
+
preset: (_b = str(values, 'preset')) !== null && _b !== void 0 ? _b : 'literal',
|
|
301
|
+
});
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
name: 'layout',
|
|
306
|
+
summary: 'a ShellLayout with the regions a weaver expects',
|
|
307
|
+
options: [
|
|
308
|
+
{
|
|
309
|
+
name: 'name',
|
|
310
|
+
type: 'string',
|
|
311
|
+
description: 'Layout name. Defaults to a base layout.',
|
|
312
|
+
},
|
|
313
|
+
APP_OPTION,
|
|
314
|
+
],
|
|
315
|
+
build: (values) => (0, generate_1.generate)(recipe_4.layout, { name: str(values, 'name') }),
|
|
316
|
+
},
|
|
317
|
+
];
|
|
318
|
+
function findScaffold(name) {
|
|
319
|
+
return exports.SCAFFOLDS.find((scaffold) => scaffold.name === name);
|
|
320
|
+
}
|
|
321
|
+
/** The option surface an adapter that only produces files can offer. */
|
|
322
|
+
function portableOptions(scaffold) {
|
|
323
|
+
return scaffold.options.filter((option) => !option.workspaceOnly);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* The JSON Schema an Nx generator loads. Nx reads it from disk before any of our code runs, so the
|
|
327
|
+
* file cannot be computed at call time — instead it is checked against this shape by a test, which
|
|
328
|
+
* fails the moment the two drift apart.
|
|
329
|
+
*/
|
|
330
|
+
function nxSchemaFor(scaffold) {
|
|
331
|
+
const properties = {};
|
|
332
|
+
for (const option of scaffold.options) {
|
|
333
|
+
properties[option.name] = Object.assign(Object.assign(Object.assign({ type: option.type, description: option.description }, (option.pattern ? { pattern: option.pattern } : {})), (option.choices ? { enum: option.choices } : {})), (option.default === undefined ? {} : { default: option.default }));
|
|
334
|
+
}
|
|
335
|
+
return {
|
|
336
|
+
$schema: 'https://json-schema.org/schema',
|
|
337
|
+
$id: `LoomWeaver${scaffold.name
|
|
338
|
+
.split('-')
|
|
339
|
+
.map((part) => part[0].toUpperCase() + part.slice(1))
|
|
340
|
+
.join('')}`,
|
|
341
|
+
title: `Scaffold ${scaffold.summary}`,
|
|
342
|
+
type: 'object',
|
|
343
|
+
properties,
|
|
344
|
+
required: scaffold.options
|
|
345
|
+
.filter((option) => option.required)
|
|
346
|
+
.map((option) => option.name),
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
function usageFor(scaffold) {
|
|
350
|
+
const parts = portableOptions(scaffold).map((option) => {
|
|
351
|
+
const flag = `--${kebabCase(option.name)}`;
|
|
352
|
+
const body = option.type === 'boolean' ? flag : `${flag} <${option.name}>`;
|
|
353
|
+
return option.required ? body : `[${body}]`;
|
|
354
|
+
});
|
|
355
|
+
return [scaffold.name, ...parts].join(' ');
|
|
356
|
+
}
|
|
357
|
+
//# sourceMappingURL=scaffolds.js.map
|