@c6fc/spellcraft 0.0.7 → 0.0.9
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 +171 -8
- package/bin/spellcraft.js +1 -1
- package/package.json +1 -1
- package/src/index.js +1 -2
package/README.md
CHANGED
@@ -1,17 +1,180 @@
|
|
1
|
-
# SpellCraft
|
1
|
+
# ✨ SpellCraft ✨
|
2
2
|
|
3
|
-
|
3
|
+
**The Sorcerer's Toolkit for Unified Configuration Management.**
|
4
4
|
|
5
|
-
|
5
|
+
SpellCraft is a powerful framework for generating and managing configurations across a diverse toolchain. It was born from the challenge of orchestrating tools like Terraform, Packer, Kubernetes, and Ansible, each with its own fragmented and isolated configuration format (YAML, JSON, HCL, etc.).
|
6
6
|
|
7
|
-
|
7
|
+
SpellCraft provides a single, unified source of truth, allowing you to generate tightly-integrated, context-aware configurations for any tool, all from one place.
|
8
|
+
|
9
|
+
[](https://www.npmjs.com/package/@c6fc/spellcraft)
|
10
|
+
[](https://github.com/your-repo/spellcraft/blob/main/LICENSE)
|
11
|
+
|
12
|
+
---
|
13
|
+
|
14
|
+
## The SpellCraft Philosophy
|
15
|
+
|
16
|
+
SpellCraft is built on three core principles to provide a superior Infrastructure-as-Code experience:
|
17
|
+
|
18
|
+
1. **Declarative Power (Jsonnet):** Configurations are written in [Jsonnet](https://jsonnet.org/), a superset of JSON. This gives you the power of variables, functions, conditionals, loops, and inheritance, eliminating the endless copy-pasting and structural limitations of plain YAML or JSON. Define a component once, and reuse it everywhere.
|
19
|
+
|
20
|
+
2. **Seamless Extensibility (Node.js):** Sometimes, declarative logic isn't enough. SpellCraft allows you to "escape" the confines of Jsonnet by writing custom logic in Node.js. Need to fetch a secret from a vault, call a third-party API, or perform complex data manipulation? Simply write a JavaScript function and expose it directly to your Jsonnet code as a `std.native()` function.
|
21
|
+
|
22
|
+
3. **Robust Modularity (NPM):** SpellCraft's module system is built on the battle-tested foundation of NPM. This means you can version, share, and manage your infrastructure modules just like any other software dependency. Leverage public or private NPM registries to build a reusable, maintainable, and collaborative infrastructure codebase.
|
23
|
+
|
24
|
+
## Quick Start
|
25
|
+
|
26
|
+
Get up and running with SpellCraft in minutes.
|
27
|
+
|
28
|
+
### 1. Installation
|
29
|
+
|
30
|
+
Install the SpellCraft CLI and core library into your project.
|
31
|
+
|
32
|
+
```sh
|
33
|
+
npm install --save @c6fc/spellcraft
|
34
|
+
```
|
35
|
+
|
36
|
+
### 2. Import a Module
|
37
|
+
|
38
|
+
Modules are the building blocks of SpellCraft. Let's import a module for interacting with AWS. The `importModule` command will install the package from NPM and link it into your project.
|
8
39
|
|
9
40
|
```sh
|
10
|
-
|
11
|
-
|
41
|
+
npx spellcraft importModule @c6fc/spellcraft-aws-auth
|
42
|
+
|
43
|
+
# Expected Output:
|
44
|
+
# [*] Attempting to install @c6fc/spellcraft-aws-auth...
|
45
|
+
# [+] Successfully installed @c6fc/spellcraft-aws-auth.
|
46
|
+
# [+] Linked @c6fc/spellcraft-aws-auth as SpellCraft module 'awsauth'
|
47
|
+
```
|
48
|
+
This makes the `@c6fc/spellcraft-aws-auth` package available in your Jsonnet files under the name `awsauth`.
|
49
|
+
|
50
|
+
### 3. Create Your First Spell
|
51
|
+
|
52
|
+
A "Spell" is a `.jsonnet` file that defines the files you want to create. The top-level keys of the output object become filenames.
|
53
|
+
|
54
|
+
Create a file named `manifest.jsonnet`:
|
55
|
+
```jsonnet
|
56
|
+
// manifest.jsonnet
|
57
|
+
local modules = import 'modules';
|
58
|
+
|
59
|
+
{
|
60
|
+
// The 'awsauth' module provides a native function `getCallerIdentity()`.
|
61
|
+
// We call it here and direct its output to a file named 'aws-identity.json'.
|
62
|
+
'aws-identity.json': modules.awsauth.getCallerIdentity(),
|
63
|
+
|
64
|
+
// We can also create YAML files. SpellCraft has built-in handlers for common types.
|
65
|
+
'config.yaml': {
|
66
|
+
apiVersion: 'v1',
|
67
|
+
kind: 'ConfigMap',
|
68
|
+
metadata: {
|
69
|
+
name: 'my-app-config',
|
70
|
+
},
|
71
|
+
data: {
|
72
|
+
region: std.native('envvar')('AWS_REGION') || 'us-east-1',
|
73
|
+
// The result of the native function is just data. We can reuse it!
|
74
|
+
callerArn: modules.awsauth.getCallerIdentity().Arn,
|
75
|
+
},
|
76
|
+
},
|
77
|
+
}
|
12
78
|
```
|
13
79
|
|
14
|
-
|
80
|
+
### 4. Generate the Artifacts
|
81
|
+
|
82
|
+
Use the `generate` command to render your `.jsonnet` file into the `render/` directory.
|
83
|
+
|
84
|
+
```sh
|
85
|
+
npx spellcraft generate manifest.jsonnet
|
86
|
+
|
87
|
+
# Expected Output:
|
88
|
+
# [+] Linked @c6fc/spellcraft-aws-auth as awsauth.libsonnet
|
89
|
+
# ...
|
90
|
+
# [+] Registered native functions [getCallerIdentity, ...] to modules.awsauth
|
91
|
+
# [+] Evaluating Jsonnet file manifest.jsonnet
|
92
|
+
# [+] Writing files to: render
|
93
|
+
# -> aws-identity.json
|
94
|
+
# -> config.yaml
|
95
|
+
# [+] Generation complete.
|
96
|
+
```
|
97
|
+
|
98
|
+
Check your `render/` directory. You will find two files created from your single source of truth!
|
99
|
+
|
100
|
+
```
|
101
|
+
.
|
102
|
+
├── manifest.jsonnet
|
103
|
+
├── node_modules/
|
104
|
+
├── package.json
|
105
|
+
└── render/
|
106
|
+
├── aws-identity.json
|
107
|
+
└── config.yaml
|
108
|
+
```
|
109
|
+
|
110
|
+
## The SpellCraft CLI
|
111
|
+
|
112
|
+
The `spellcraft` CLI is your primary interface for managing modules and generating files.
|
113
|
+
|
114
|
+
### Core Commands
|
115
|
+
|
116
|
+
- `generate <filename>`: Renders a `.jsonnet` file and writes the output to the `render/` directory.
|
117
|
+
- `importModule <npmPackage> [name]`: Installs an NPM package and links it as a SpellCraft module. If `[name]` is omitted, it uses the default name defined by the module.
|
118
|
+
|
119
|
+
### Extensible CLI
|
120
|
+
|
121
|
+
Modules can extend the SpellCraft CLI with their own custom commands. For example, after importing `@c6fc/spellcraft-aws-auth`, you gain new AWS-related commands.
|
122
|
+
|
123
|
+
Run `npx spellcraft --help` to see all available commands, including those added by modules.
|
124
|
+
|
125
|
+
```sh
|
126
|
+
$ npx spellcraft --help
|
127
|
+
|
128
|
+
# ... output showing core commands and module-added commands ...
|
129
|
+
Commands:
|
130
|
+
spellcraft generate <filename> Generates files from a configuration
|
131
|
+
spellcraft importModule <npmPackage> [name] Configures the current project to use a SpellCraft module
|
132
|
+
spellcraft aws-identity Display the AWS IAM identity of the SpellCraft context # Added by a module
|
133
|
+
spellcraft aws-exportcredentials Export the current credentials as environment variables # Added by a module
|
134
|
+
```
|
135
|
+
|
136
|
+
## Programmatic Usage (API)
|
137
|
+
|
138
|
+
For more advanced workflows, such as integration into larger automation scripts, you can use the `SpellFrame` class directly in your Node.js code.
|
139
|
+
|
140
|
+
The typical flow is:
|
141
|
+
1. Instantiate `SpellFrame`.
|
142
|
+
2. Run module initializers with `init()`.
|
143
|
+
3. Render the Jsonnet file with `render()`.
|
144
|
+
4. Write the resulting object to disk with `write()`.
|
145
|
+
|
146
|
+
```javascript
|
147
|
+
// my-automation-script.js
|
148
|
+
const { SpellFrame } = require('@c6fc/spellcraft');
|
149
|
+
const path = require('path');
|
150
|
+
|
151
|
+
// 1. Instantiate the SpellFrame
|
152
|
+
// Options allow you to customize output paths, cleaning behavior, etc.
|
153
|
+
const frame = new SpellFrame({
|
154
|
+
renderPath: "dist", // Output to 'dist/' instead of 'render/'
|
155
|
+
cleanBeforeRender: true,
|
156
|
+
});
|
157
|
+
|
158
|
+
(async () => {
|
159
|
+
|
160
|
+
// 2. Initialize modules before rendering.
|
161
|
+
await frame.init();
|
162
|
+
|
163
|
+
// 3. Render the master Jsonnet file
|
164
|
+
const manifest = await frame.render(path.resolve('./manifest.jsonnet'));
|
165
|
+
|
166
|
+
// The result is available in memory
|
167
|
+
console.log('Rendered Manifest:', JSON.stringify(manifest, null, 2));
|
168
|
+
|
169
|
+
// 4. Write the manifest object to the filesystem. Defaults to the contents of
|
170
|
+
// the most recent 'render'.
|
171
|
+
frame.write();
|
172
|
+
|
173
|
+
console.log('Successfully wrote files to the dist/ directory!');
|
174
|
+
|
175
|
+
})();
|
176
|
+
```
|
15
177
|
|
178
|
+
## Creating Your Own Spells (Modules)
|
16
179
|
|
17
|
-
|
180
|
+
When you're ready to start writing your own modules and unleashing the true power of SpellCraft, check out **[create-spellcraft-module](https://www.npmjs.com/package/@c6fc/spellcraft)**
|
package/bin/spellcraft.js
CHANGED
@@ -115,7 +115,7 @@ const spellframe = new SpellFrame();
|
|
115
115
|
},
|
116
116
|
async (argv) => {
|
117
117
|
await sfInstance.importSpellCraftModuleFromNpm(argv.npmPackage, argv.name);
|
118
|
-
console.log(`[+] Module '${argv.npmPackage.green}' ${argv.name ? `(aliased as ${argv.name.green})` : ''}
|
118
|
+
console.log(`[+] Module '${argv.npmPackage.green}' ${argv.name ? `(aliased as ${argv.name.green}) ` : ''}linked successfully.`);
|
119
119
|
});
|
120
120
|
|
121
121
|
// No JSDoc for CLI extensions loop if considered internal detail
|
package/package.json
CHANGED
package/src/index.js
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
// ./src/index.js
|
2
1
|
'use strict';
|
3
2
|
|
4
3
|
const fs = require("fs");
|
@@ -129,7 +128,7 @@ exports.SpellFrame = class SpellFrame {
|
|
129
128
|
}
|
130
129
|
|
131
130
|
addJpath(jpath) {
|
132
|
-
console.log(`[*] Adding Jpath ${jpath}`);
|
131
|
+
// console.log(`[*] Adding Jpath ${jpath}`);
|
133
132
|
this.jsonnet.addJpath(jpath);
|
134
133
|
return this;
|
135
134
|
}
|