kadence-lang 0.2.0 → 0.2.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 +23 -13
- package/bin/kadence.js +244 -26
- package/icon.svg +76 -0
- package/package.json +11 -11
- package/stdlib/REVIEW_NEW_LIBS.md +92 -0
- package/stdlib/array.js +165 -0
- package/stdlib/array.kade +137 -0
- package/stdlib/async-helpers.js +115 -0
- package/stdlib/async.js +78 -0
- package/stdlib/async.kade +43 -0
- package/stdlib/check.js +8 -1
- package/stdlib/check.kade +7 -0
- package/stdlib/file.js +4 -4
- package/stdlib/file.kade +4 -2
- package/stdlib/format-helpers.js +51 -0
- package/stdlib/format.js +150 -0
- package/stdlib/format.kade +123 -0
- package/stdlib/list-helpers.js +21 -0
- package/stdlib/list-test.js +109 -0
- package/stdlib/list.js +9 -0
- package/stdlib/list.kade +10 -0
- package/stdlib/map.js +103 -0
- package/stdlib/map.kade +68 -0
- package/stdlib/network.js +8 -5
- package/stdlib/network.kade +10 -7
- package/stdlib/object-helpers.js +50 -1
- package/stdlib/random.js +1 -1
- package/stdlib/random.kade +1 -1
- package/stdlib/set.js +137 -0
- package/stdlib/set.kade +110 -0
- package/stdlib/test-reverse.kade +12 -0
- package/stdlib/test.js +28 -1
- package/stdlib/test.kade +27 -0
- package/stdlib/uuid.js +10 -10
- package/stdlib/uuid.kade +10 -10
- package/stdlib/validation-helpers.js +75 -0
- package/stdlib/validation.js +113 -0
- package/stdlib/validation.kade +78 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/kadence-lang)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
[](https://github.com/
|
|
5
|
+
[](https://github.com/Down2EarthGG/Kadence-lang)
|
|
6
6
|
|
|
7
7
|
**A human-readable programming language that feels like poetry.**
|
|
8
8
|
|
|
@@ -135,22 +135,32 @@ Kadence ships with a comprehensive set of modules for common tasks.
|
|
|
135
135
|
|
|
136
136
|
| Module | Core Functionality |
|
|
137
137
|
| :--- | :--- |
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
138
|
+
| `array` | `flatten`, `zip`, `chunk`, `partition`, `take`, `drop`, `reverse`, `findIndex` |
|
|
139
|
+
| `async` | `delay`, `timeout`, `retry`, `debounce`, `throttle`, `parallel`, `sequential`, `waterfall` |
|
|
140
|
+
| `list` | `first`, `lastOf`, `shuffle`, `makeRange`, `unique`, `sort`, `sortBy` |
|
|
141
|
+
| `string` | `trimmed`, `repeated`, `toCamelCase`, `padStart`, `words`, `lines`, `capitalized` |
|
|
142
|
+
| `map` | `keys`, `values`, `entries`, `merge`, `pick`, `omit`, `mapValues`, `deepClone`, `fromPairs` |
|
|
143
|
+
| `set` | `union`, `intersection`, `difference`, `isSubset`, `isSuperset`, `cartesianProduct` |
|
|
144
|
+
| `format` | `currency`, `fileSize`, `ordinal`, `plural`, `titleCase`, `snakeCase`, `kebabCase` |
|
|
145
|
+
| `validation` | `isEmail`, `isUrl`, `isNumeric`, `isAlpha`, `isInRange`, `isHexColor`, `isCreditCard` |
|
|
146
|
+
| `math` | `clamp`, `randomFloat`, `hypotenuse`, `areaOfCircle`, `isEven`, `toRadians` |
|
|
147
|
+
| `datetime` | `currentTime`, `today`, `year`, `month`, `day`, `toIso`, `addDays` |
|
|
148
|
+
| `file` | `readFile`, `writeFile`, `copyDir`, `removeDir`, `stat`, `listDir`, `exists` |
|
|
143
149
|
| `path` | `joinPaths`, `resolve`, `basename`, `dirname`, `extension` |
|
|
144
|
-
| `env` | `getEnv`, `hasEnv`
|
|
150
|
+
| `env` | `getEnv`, `hasEnv` |
|
|
145
151
|
| `process` | `args`, `exit`, `cwd` |
|
|
146
|
-
| `system` | `platform`, `arch`, `totalMemory`, `freeMemory` |
|
|
147
|
-
| `network` | `serve`, `fetchJson`
|
|
152
|
+
| `system` | `platform`, `arch`, `totalMemory`, `freeMemory`, `cpus`, `homedir` |
|
|
153
|
+
| `network` | `serve`, `fetchJson` |
|
|
148
154
|
| `json` | `readJson`, `writeJson`, `format`, `parseSafe` |
|
|
149
|
-
| `check` | `isNumber`, `isString`, `isEmail`, `between` |
|
|
155
|
+
| `check` | `isNumber`, `isString`, `isEmail`, `between`, `coalesce` |
|
|
150
156
|
| `test` | `suite`, `assertEquals`, `assertTrue`, `assertThrows` |
|
|
151
|
-
| `color` | `
|
|
152
|
-
| `html` | `div`, `span`, `p`, `img`, `link`
|
|
153
|
-
| `crypto` | `hash`, `randomBytes
|
|
157
|
+
| `color` | `rgb`, `rgba`, `hex`, `randomHex` |
|
|
158
|
+
| `html` | `tag`, `div`, `span`, `p`, `img`, `link`, `h1` |
|
|
159
|
+
| `crypto` | `hash`, `randomBytes` |
|
|
160
|
+
| `uuid` | `v4`, `validate` |
|
|
161
|
+
| `random` | `float`, `integer`, `choice`, `shuffle` |
|
|
162
|
+
| `stream` | `createReader`, `readAll`, `pipe` |
|
|
163
|
+
| `url` | `parseUrl`, `buildUrl`, `getSearchParam` |
|
|
154
164
|
|
|
155
165
|
*Usage Example:*
|
|
156
166
|
```kadence
|
package/bin/kadence.js
CHANGED
|
@@ -5,7 +5,7 @@ const readline = require("readline");
|
|
|
5
5
|
const { execSync } = require("child_process");
|
|
6
6
|
const { compile } = require("../src/compiler");
|
|
7
7
|
|
|
8
|
-
const VERSION = "0.2.
|
|
8
|
+
const VERSION = "0.2.2";
|
|
9
9
|
|
|
10
10
|
const colors = {
|
|
11
11
|
reset: "\x1b[0m",
|
|
@@ -34,26 +34,32 @@ function getPkgName(pkg) {
|
|
|
34
34
|
|
|
35
35
|
function printHelp() {
|
|
36
36
|
log(`Kadence CLI v${VERSION}`, colors.bright + colors.cyan);
|
|
37
|
+
log("A human-readable programming language that feels like poetry", colors.dim);
|
|
37
38
|
console.log(`
|
|
38
39
|
Usage:
|
|
40
|
+
npx kadence-lang [command] [options]
|
|
41
|
+
|
|
42
|
+
Core Commands:
|
|
39
43
|
kadence Start interactive REPL
|
|
40
44
|
kadence <file> Compile and run a .kade file
|
|
41
45
|
kadence -c <file> Compile to JavaScript only
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
kadence create <name> [--web]
|
|
45
|
-
kadence init [--web]
|
|
46
|
-
kadence
|
|
47
|
-
kadence
|
|
48
|
-
kadence
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
kadence
|
|
52
|
-
kadence
|
|
53
|
-
kadence
|
|
54
|
-
kadence
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
|
|
47
|
+
Project Commands:
|
|
48
|
+
kadence create <name> [--web] Create a new project from a template
|
|
49
|
+
kadence init [--web] Initialize Kadence in existing folder
|
|
50
|
+
kadence dev Start Vite development server (Web only)
|
|
51
|
+
kadence build Compile all .kade files in project
|
|
52
|
+
kadence test Run all .test.kade files
|
|
53
|
+
|
|
54
|
+
Package Management:
|
|
55
|
+
kadence install <pkg> Install a package (kadence or npm)
|
|
56
|
+
kadence uninstall <pkg> Remove a package
|
|
57
|
+
kadence update Update all dependencies
|
|
58
|
+
kadence list List installed packages
|
|
59
|
+
|
|
60
|
+
Other Options:
|
|
61
|
+
kadence -v Show version
|
|
62
|
+
kadence help Show this help
|
|
57
63
|
`);
|
|
58
64
|
}
|
|
59
65
|
|
|
@@ -138,7 +144,7 @@ function writeScaffold(targetDir, opts) {
|
|
|
138
144
|
const config = {
|
|
139
145
|
name: projectName,
|
|
140
146
|
version: version || "1.0.0",
|
|
141
|
-
description: description || "",
|
|
147
|
+
description: description || "A beautiful Kadence project",
|
|
142
148
|
author: author || "",
|
|
143
149
|
scripts: isWeb
|
|
144
150
|
? { dev: "kadence dev", build: "kadence build --web", preview: "vite preview" }
|
|
@@ -148,19 +154,97 @@ function writeScaffold(targetDir, opts) {
|
|
|
148
154
|
|
|
149
155
|
const mainKade = path.join(targetDir, "src", "main.kade");
|
|
150
156
|
if (!fs.existsSync(mainKade)) {
|
|
151
|
-
|
|
157
|
+
if (isWeb) {
|
|
158
|
+
fs.writeFileSync(
|
|
159
|
+
mainKade,
|
|
160
|
+
`// Welcome to your new Kadence Web App!
|
|
161
|
+
say "Kadence is running!"
|
|
162
|
+
|
|
163
|
+
// Simple reactive counter example
|
|
164
|
+
let count = 0
|
|
165
|
+
|
|
166
|
+
function increment() {
|
|
167
|
+
count = count + 1
|
|
168
|
+
updateUI()
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function updateUI() {
|
|
172
|
+
const el = document.getElementById("counter")
|
|
173
|
+
if el {
|
|
174
|
+
el.innerText = "Count: " + count
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Initialize
|
|
179
|
+
updateUI()
|
|
180
|
+
|
|
181
|
+
// Expose increment to window for button clicks
|
|
182
|
+
window.increment = increment
|
|
183
|
+
`,
|
|
184
|
+
"utf8"
|
|
185
|
+
);
|
|
186
|
+
} else {
|
|
187
|
+
fs.writeFileSync(
|
|
188
|
+
mainKade,
|
|
189
|
+
`// Welcome to your new Kadence Tool!
|
|
190
|
+
import math
|
|
191
|
+
|
|
192
|
+
say "Hello from Kadence!"
|
|
193
|
+
say "The square root of 144 is " + math.sqrt(144)
|
|
194
|
+
|
|
195
|
+
// Try running with: kadence src/main.kade
|
|
196
|
+
`,
|
|
197
|
+
"utf8"
|
|
198
|
+
);
|
|
199
|
+
}
|
|
152
200
|
}
|
|
153
201
|
|
|
154
202
|
const gitignore = path.join(targetDir, ".gitignore");
|
|
155
203
|
if (!fs.existsSync(gitignore)) {
|
|
156
|
-
fs.writeFileSync(gitignore, "node_modules/\ndist/\n*.js\n*.js.map\n", "utf8");
|
|
204
|
+
fs.writeFileSync(gitignore, "node_modules/\ndist/\n*.js\n*.js.map\n.DS_Store\n", "utf8");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const readme = path.join(targetDir, "README.md");
|
|
208
|
+
if (!fs.existsSync(readme)) {
|
|
209
|
+
fs.writeFileSync(
|
|
210
|
+
readme,
|
|
211
|
+
`# ${projectName}
|
|
212
|
+
|
|
213
|
+
${description || "A new Kadence project."}
|
|
214
|
+
|
|
215
|
+
## Getting Started
|
|
216
|
+
|
|
217
|
+
1. Install dependencies:
|
|
218
|
+
\`\`\`bash
|
|
219
|
+
npm install
|
|
220
|
+
\`\`\`
|
|
221
|
+
|
|
222
|
+
2. Start the project:
|
|
223
|
+
\`\`\`bash
|
|
224
|
+
${isWeb ? "npm run dev" : "npm run start"}
|
|
225
|
+
\`\`\`
|
|
226
|
+
|
|
227
|
+
## Project Structure
|
|
228
|
+
|
|
229
|
+
- \`src/\`: Source files (.kade)
|
|
230
|
+
- \`dist/\`: Compiled JavaScript
|
|
231
|
+
- \`kadence.json\`: Kadence project configuration
|
|
232
|
+
`,
|
|
233
|
+
"utf8"
|
|
234
|
+
);
|
|
157
235
|
}
|
|
158
236
|
|
|
159
237
|
const kadenceConfig = path.join(targetDir, "kadence.config.js");
|
|
160
238
|
if (!fs.existsSync(kadenceConfig)) {
|
|
161
239
|
fs.writeFileSync(
|
|
162
240
|
kadenceConfig,
|
|
163
|
-
|
|
241
|
+
`/** @type {import('kadence-lang').Config} */
|
|
242
|
+
module.exports = {
|
|
243
|
+
outDir: 'dist',
|
|
244
|
+
srcDir: 'src',
|
|
245
|
+
target: '${isWeb ? "browser" : "node"}'
|
|
246
|
+
};
|
|
247
|
+
`,
|
|
164
248
|
"utf8"
|
|
165
249
|
);
|
|
166
250
|
}
|
|
@@ -172,11 +256,13 @@ function writeScaffold(targetDir, opts) {
|
|
|
172
256
|
const pkg = {
|
|
173
257
|
name: projectName,
|
|
174
258
|
version: version || "1.0.0",
|
|
259
|
+
description: description || "",
|
|
175
260
|
type: "commonjs",
|
|
176
|
-
|
|
261
|
+
scripts: config.scripts,
|
|
262
|
+
dependencies: { "kadence-lang": "^0.2.1" },
|
|
177
263
|
};
|
|
178
264
|
if (isWeb) {
|
|
179
|
-
pkg.devDependencies = { vite: "latest", "vite-plugin-kadence": "
|
|
265
|
+
pkg.devDependencies = { vite: "latest", "vite-plugin-kadence": "^0.2.1" };
|
|
180
266
|
}
|
|
181
267
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
182
268
|
}
|
|
@@ -187,18 +273,146 @@ function writeScaffold(targetDir, opts) {
|
|
|
187
273
|
fs.writeFileSync(
|
|
188
274
|
indexHtml,
|
|
189
275
|
`<!DOCTYPE html>
|
|
190
|
-
<html>
|
|
276
|
+
<html lang="en">
|
|
191
277
|
<head>
|
|
192
|
-
<
|
|
278
|
+
<meta charset="UTF-8">
|
|
279
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
280
|
+
<title>${projectName} | Kadence</title>
|
|
281
|
+
<link rel="stylesheet" href="/src/style.css">
|
|
282
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
283
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
284
|
+
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600&display=swap" rel="stylesheet">
|
|
193
285
|
</head>
|
|
194
286
|
<body>
|
|
195
|
-
<div
|
|
287
|
+
<div class="container">
|
|
288
|
+
<header>
|
|
289
|
+
<div class="logo">♪</div>
|
|
290
|
+
<h1>${projectName}</h1>
|
|
291
|
+
<p class="subtitle">Built with Kadence</p>
|
|
292
|
+
</header>
|
|
293
|
+
|
|
294
|
+
<main>
|
|
295
|
+
<div class="card">
|
|
296
|
+
<h2 id="counter">Count: 0</h2>
|
|
297
|
+
<button onclick="increment()">Increment</button>
|
|
298
|
+
</div>
|
|
299
|
+
|
|
300
|
+
<div class="info">
|
|
301
|
+
<p>Edit <code>src/main.kade</code> to get started.</p>
|
|
302
|
+
</div>
|
|
303
|
+
</main>
|
|
304
|
+
</div>
|
|
196
305
|
<script type="module" src="/src/main.kade"></script>
|
|
197
306
|
</body>
|
|
198
307
|
</html>`,
|
|
199
308
|
"utf8"
|
|
200
309
|
);
|
|
201
310
|
}
|
|
311
|
+
|
|
312
|
+
const styleCss = path.join(targetDir, "src", "style.css");
|
|
313
|
+
if (!fs.existsSync(styleCss)) {
|
|
314
|
+
fs.writeFileSync(
|
|
315
|
+
styleCss,
|
|
316
|
+
`body {
|
|
317
|
+
margin: 0;
|
|
318
|
+
padding: 0;
|
|
319
|
+
font-family: 'Outfit', sans-serif;
|
|
320
|
+
background: radial-gradient(circle at top right, #1a1a2e, #0f0f1b);
|
|
321
|
+
color: white;
|
|
322
|
+
min-height: 100vh;
|
|
323
|
+
display: flex;
|
|
324
|
+
justify-content: center;
|
|
325
|
+
align-items: center;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.container {
|
|
329
|
+
text-align: center;
|
|
330
|
+
max-width: 600px;
|
|
331
|
+
padding: 2rem;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
header {
|
|
335
|
+
margin-bottom: 3rem;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.logo {
|
|
339
|
+
font-size: 4rem;
|
|
340
|
+
margin-bottom: 1rem;
|
|
341
|
+
background: linear-gradient(135deg, #00f2fe 0%, #4facfe 100%);
|
|
342
|
+
-webkit-background-clip: text;
|
|
343
|
+
-webkit-text-fill-color: transparent;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
h1 {
|
|
347
|
+
font-weight: 600;
|
|
348
|
+
font-size: 2.5rem;
|
|
349
|
+
margin: 0;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.subtitle {
|
|
353
|
+
color: #94a3b8;
|
|
354
|
+
font-size: 1.1rem;
|
|
355
|
+
margin-top: 0.5rem;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.card {
|
|
359
|
+
background: rgba(255, 255, 255, 0.05);
|
|
360
|
+
backdrop-filter: blur(10px);
|
|
361
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
362
|
+
padding: 2.5rem;
|
|
363
|
+
border-radius: 24px;
|
|
364
|
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
|
|
365
|
+
margin-bottom: 2rem;
|
|
366
|
+
transition: transform 0.3s ease;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
.card:hover {
|
|
370
|
+
transform: translateY(-5px);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
h2 {
|
|
374
|
+
font-size: 2rem;
|
|
375
|
+
margin-bottom: 1.5rem;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
button {
|
|
379
|
+
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
|
380
|
+
border: none;
|
|
381
|
+
color: white;
|
|
382
|
+
padding: 0.75rem 2rem;
|
|
383
|
+
font-size: 1.1rem;
|
|
384
|
+
font-weight: 600;
|
|
385
|
+
border-radius: 12px;
|
|
386
|
+
cursor: pointer;
|
|
387
|
+
transition: all 0.2s ease;
|
|
388
|
+
box-shadow: 0 10px 15px -3px rgba(79, 172, 254, 0.3);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
button:hover {
|
|
392
|
+
transform: scale(1.05);
|
|
393
|
+
box-shadow: 0 20px 25px -5px rgba(79, 172, 254, 0.4);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
button:active {
|
|
397
|
+
transform: scale(0.98);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
.info {
|
|
401
|
+
color: #64748b;
|
|
402
|
+
font-size: 0.9rem;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
code {
|
|
406
|
+
background: rgba(255, 255, 255, 0.1);
|
|
407
|
+
padding: 0.2rem 0.4rem;
|
|
408
|
+
border-radius: 4px;
|
|
409
|
+
color: #e2e8f0;
|
|
410
|
+
}
|
|
411
|
+
`,
|
|
412
|
+
"utf8"
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
|
|
202
416
|
const viteConfig = path.join(targetDir, "vite.config.js");
|
|
203
417
|
if (!fs.existsSync(viteConfig)) {
|
|
204
418
|
fs.writeFileSync(
|
|
@@ -207,7 +421,11 @@ function writeScaffold(targetDir, opts) {
|
|
|
207
421
|
import { kadencePlugin } from './vite-plugin-kadence';
|
|
208
422
|
|
|
209
423
|
export default defineConfig({
|
|
210
|
-
plugins: [kadencePlugin()]
|
|
424
|
+
plugins: [kadencePlugin()],
|
|
425
|
+
server: {
|
|
426
|
+
port: 3000,
|
|
427
|
+
open: true
|
|
428
|
+
}
|
|
211
429
|
});`,
|
|
212
430
|
"utf8"
|
|
213
431
|
);
|
package/icon.svg
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<svg width="512" height="512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<defs>
|
|
4
|
+
<!-- Premium Dark Gradient Background -->
|
|
5
|
+
<linearGradient id="bgGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
6
|
+
<stop offset="0%" style="stop-color:#1a1a2e;stop-opacity:1" />
|
|
7
|
+
<stop offset="100%" style="stop-color:#16213e;stop-opacity:1" />
|
|
8
|
+
</linearGradient>
|
|
9
|
+
|
|
10
|
+
<!-- Vibrant Accent Gradient (vertical) -->
|
|
11
|
+
<linearGradient id="accentGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
|
12
|
+
<stop offset="0%" style="stop-color:#06d6a0;stop-opacity:1" />
|
|
13
|
+
<stop offset="50%" style="stop-color:#118ab2;stop-opacity:1" />
|
|
14
|
+
<stop offset="100%" style="stop-color:#7b2cbf;stop-opacity:1" />
|
|
15
|
+
</linearGradient>
|
|
16
|
+
|
|
17
|
+
<!-- Outer Glow Effect -->
|
|
18
|
+
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
|
|
19
|
+
<feGaussianBlur stdDeviation="6" result="coloredBlur"/>
|
|
20
|
+
<feMerge>
|
|
21
|
+
<feMergeNode in="coloredBlur"/>
|
|
22
|
+
<feMergeNode in="SourceGraphic"/>
|
|
23
|
+
</feMerge>
|
|
24
|
+
</filter>
|
|
25
|
+
|
|
26
|
+
<!-- Subtle Drop Shadow -->
|
|
27
|
+
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
28
|
+
<feDropShadow dx="0" dy="4" stdDeviation="10" flood-color="#000000" flood-opacity="0.3"/>
|
|
29
|
+
</filter>
|
|
30
|
+
</defs>
|
|
31
|
+
|
|
32
|
+
<!-- Background Container with Rounded Corners -->
|
|
33
|
+
<rect x="24" y="24" width="464" height="464" rx="96" fill="url(#bgGradient)" filter="url(#shadow)"/>
|
|
34
|
+
|
|
35
|
+
<!-- Subtle Border Ring -->
|
|
36
|
+
<rect x="24" y="24" width="464" height="464" rx="96" fill="none" stroke="url(#accentGradient)" stroke-width="3" opacity="0.4"/>
|
|
37
|
+
|
|
38
|
+
<!-- Rebuilt, unified Kadence "K" -->
|
|
39
|
+
<g filter="url(#glow)">
|
|
40
|
+
<!-- Single sculpted K shape using negative space logic -->
|
|
41
|
+
<path
|
|
42
|
+
d="
|
|
43
|
+
M 120 116
|
|
44
|
+
L 160 116
|
|
45
|
+
L 160 220
|
|
46
|
+
L 230 160
|
|
47
|
+
Q 244 148 262 148
|
|
48
|
+
L 292 148
|
|
49
|
+
L 292 188
|
|
50
|
+
Q 276 188 266 196
|
|
51
|
+
L 200 252
|
|
52
|
+
L 270 320
|
|
53
|
+
Q 284 334 304 334
|
|
54
|
+
L 332 334
|
|
55
|
+
L 332 374
|
|
56
|
+
L 296 374
|
|
57
|
+
Q 270 374 252 356
|
|
58
|
+
L 180 286
|
|
59
|
+
L 160 304
|
|
60
|
+
L 160 396
|
|
61
|
+
L 120 396
|
|
62
|
+
Z
|
|
63
|
+
"
|
|
64
|
+
fill="url(#accentGradient)"
|
|
65
|
+
/>
|
|
66
|
+
|
|
67
|
+
<!-- Accent rhythm bars to the right -->
|
|
68
|
+
<rect x="320" y="196" width="24" height="120" rx="12" fill="#06d6a0" opacity="0.9"/>
|
|
69
|
+
<rect x="360" y="161" width="24" height="190" rx="12" fill="#118ab2" opacity="0.85"/>
|
|
70
|
+
<rect x="400" y="216" width="24" height="80" rx="12" fill="#7b2cbf" opacity="0.8"/>
|
|
71
|
+
</g>
|
|
72
|
+
|
|
73
|
+
<!-- Small accent dots for visual interest -->
|
|
74
|
+
<circle cx="420" cy="100" r="8" fill="#06d6a0" opacity="0.6"/>
|
|
75
|
+
<circle cx="100" cy="420" r="6" fill="#7b2cbf" opacity="0.5"/>
|
|
76
|
+
</svg>
|
package/package.json
CHANGED
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kadence-lang",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "A human-readable programming language that feels like poetry",
|
|
5
|
+
"icon": "icon.svg",
|
|
5
6
|
"main": "src/compiler.js",
|
|
6
7
|
"bin": {
|
|
7
|
-
"kadence": "./bin/kadence.js"
|
|
8
|
+
"kadence": "./bin/kadence.js",
|
|
9
|
+
"kadence-lang": "./bin/kadence.js"
|
|
8
10
|
},
|
|
9
11
|
"repository": {
|
|
10
12
|
"type": "git",
|
|
11
|
-
"url": "git+https://github.com/
|
|
13
|
+
"url": "git+https://github.com/Down2EarthGG/Kadence-lang.git"
|
|
12
14
|
},
|
|
13
15
|
"bugs": {
|
|
14
|
-
"url": "https://github.com/
|
|
16
|
+
"url": "https://github.com/Down2EarthGG/Kadence-lang/issues"
|
|
15
17
|
},
|
|
16
|
-
"homepage": "https://github.com/
|
|
18
|
+
"homepage": "https://github.com/Down2EarthGG/Kadence-lang#readme",
|
|
17
19
|
"files": [
|
|
18
20
|
"src/",
|
|
19
21
|
"bin/",
|
|
20
22
|
"stdlib/",
|
|
21
23
|
"README.md",
|
|
22
|
-
"LICENSE"
|
|
24
|
+
"LICENSE",
|
|
25
|
+
"icon.svg"
|
|
23
26
|
],
|
|
24
27
|
"engines": {
|
|
25
28
|
"node": ">=14.0.0"
|
|
@@ -28,9 +31,9 @@
|
|
|
28
31
|
"dev": "npm run serve:demo",
|
|
29
32
|
"demo": "npm run serve:demo",
|
|
30
33
|
"build:demo": "node scripts/build-demo.js",
|
|
31
|
-
"serve:demo": "npm run build:demo && serve
|
|
34
|
+
"serve:demo": "npm run build:demo && serve apps/website -p 3000",
|
|
32
35
|
"build:apps": "node scripts/build-apps.js",
|
|
33
|
-
"serve:apps": "npm run build:apps && serve
|
|
36
|
+
"serve:apps": "npm run build:apps && serve apps/website -p 3000",
|
|
34
37
|
"test": "vitest run",
|
|
35
38
|
"lint": "eslint .",
|
|
36
39
|
"lint:fix": "eslint . --fix",
|
|
@@ -48,10 +51,7 @@
|
|
|
48
51
|
"author": "The Kadence Team",
|
|
49
52
|
"license": "MIT",
|
|
50
53
|
"dependencies": {
|
|
51
|
-
"lodash": "^4.17.23",
|
|
52
54
|
"ohm-js": "^17.3.0",
|
|
53
|
-
"readline-sync": "^1.4.10",
|
|
54
|
-
"safe-eval": "^0.4.1",
|
|
55
55
|
"source-map": "^0.7.4"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Review: New stdlib Libraries
|
|
2
|
+
|
|
3
|
+
Summary of the new/untracked stdlib modules and fixes applied.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. **array.kade** ✓
|
|
8
|
+
|
|
9
|
+
Pure Kadence array utilities: `flatten`, `zip`, `chunk`, `partition`, `take`, `drop`, `reverse`, `findIndex`.
|
|
10
|
+
|
|
11
|
+
- **Style**: Uses `list`, `add … to result`, `size of`, `increment`/`decrement` consistently.
|
|
12
|
+
- **Note**: `flatten` treats any `elem` with `typeof "object"` and `elem.length` as nested array; that matches array-like values. Consider documenting that only one level of “array-like” is assumed if you want to avoid surprises with non-Array objects.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 2. **async.kade** + **async-helpers.js** ✓
|
|
17
|
+
|
|
18
|
+
Kadence wrapper over JS helpers: `delay`, `timeout`, `retry`, `debounce`, `throttle`, `parallel`, `race`, `sequential`, `waterfall`, `batch`.
|
|
19
|
+
|
|
20
|
+
- **Pattern**: Same as other `.kade` + `-helpers.js` pairs: Kadence exports call `run require "./async-helpers.js"` and `run mod.<name> …`.
|
|
21
|
+
- **async-helpers.js**: Clear, no extra dependencies; `batch` expects `processFn(batchItems)` to return an array of results.
|
|
22
|
+
- **async.js**: Generated output; contains leftover `__kadence_*` and `fs` at the top. Prefer regenerating from `async.kade` or trimming the stub so only the actual exports remain.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 3. **format.kade** + **format-helpers.js** ✓ (ordinal fixed)
|
|
27
|
+
|
|
28
|
+
Formatting: `currency`, `formatNumber`, `percentage`, `fileSize`, `ordinal`, `plural`, `truncate`, `ellipsis`, `padNumber`, `phoneNumber`, `titleCase`, `snakeCase`, `kebabCase`.
|
|
29
|
+
|
|
30
|
+
- **ordinal**: Logic was wrong for both remainder and 11/12/13. Updated to use `floor` for integer-like behavior and to treat 11–13 correctly (e.g. 11th, 12th, 13th, 21st, 22nd).
|
|
31
|
+
- **format-helpers.js**: Only `currency` and `phoneNumber`; used via `require`. Fine as-is.
|
|
32
|
+
- **titleCase**: Uses `split`/`join`/`uppercase`/`lowercase`; consistent with language reference.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 4. **map.kade** + **map.js** + **object-helpers.js** ✓
|
|
37
|
+
|
|
38
|
+
Map/object utilities: `keys`, `values`, `entries`, `hasKey`, `merge`, `pick`, `omit`, `mapValues`, `mapKeys`, `invert`, `isEmpty`, `fromPairs`.
|
|
39
|
+
|
|
40
|
+
- **map.kade**: Delegates to `object-helpers.js` for everything except `isEmpty` (uses `Object.keys`) and `fromPairs` (inline loop). Good split.
|
|
41
|
+
- **object-helpers.js**: Provides `pick`, `omit`, `deepClone`, `get`, `defaults`, plus key/values/entries/hasKey/merge/mapValues/mapKeys/invert. `map.kade` does not yet expose `deepClone`, `get`, or `defaults`; add wrappers in `map.kade` if you want them in the public API.
|
|
42
|
+
- **fromPairs**: Uses `let result = {}` and `result[pair[0]] = pair[1]`. For consistency with LANGUAGE_REFERENCE (“Object: object { key: val }”), you could use `object {}` and `set … of result to …` if the compiler supports empty `object {}` and property set.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 5. **set.kade** ✓
|
|
47
|
+
|
|
48
|
+
Set operations on lists (no native Set): `union`, `intersection`, `difference`, `symmetricDifference`, `isSubset`, `isSuperset`, `areDisjoint`, `cartesianProduct`.
|
|
49
|
+
|
|
50
|
+
- **Style**: Pure Kadence, no JS helpers; uses nested `for each` and equality. Readable.
|
|
51
|
+
- **Cost**: O(n²) in many places (e.g. membership via linear search). Acceptable for small sets; for large sets consider a JS helper backed by `Set` and call it from a thin `.kade` wrapper (like async/format).
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 6. **validation.kade** ✓ (comparisons fixed)
|
|
56
|
+
|
|
57
|
+
Validators: `isEmail`, `isUrl`, `isNumeric`, `isAlpha`, `isAlphanumeric`, `isInteger`, `isPositive`, `isNegative`, `isInRange`, `isLength`, `isEmpty`/`isNotEmpty`, `isHexColor`, `isIpAddress`, `isPhoneNumber`, `isCreditCard` (Luhn), `isStrongPassword`.
|
|
58
|
+
|
|
59
|
+
- **Comparisons**: The compiler only supports `at least` / `at most` for ≥/≤ (see `CompareOp` in grammar). Replaced “more than or equals” / “less than or equals” with “at least” / “at most” in `isInRange`, `isLength`, `isPhoneNumber`, and the Luhn loop.
|
|
60
|
+
- **Name clash**: Resolved by renaming string “blank” check from `isEmpty` to `isBlank`; `isNotEmpty` now calls `isBlank`.
|
|
61
|
+
- **Luhn**: Logic for `isCreditCard` is correct; `(sum / 10) * 10 equals sum` is a valid way to express “sum divisible by 10” without a mod operator.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 7. **object-helpers.js** (modified)
|
|
66
|
+
|
|
67
|
+
Shared implementation for object/map operations. Used by **map.kade**; no issues found. Exports are consistent with what **map.kade** calls.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 8. **.object.kade.js**
|
|
72
|
+
|
|
73
|
+
Appears to be compiled output (e.g. from a file like `object.kade`). Typically such files are generated; consider adding them to `.gitignore` or generating them in a build step so they aren’t committed as source.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Summary of changes made
|
|
78
|
+
|
|
79
|
+
| File | Change |
|
|
80
|
+
|------------------|------------------------------------------------------------------------|
|
|
81
|
+
| **validation.kade** | Replaced “more than or equals” / “less than or equals” with “at least” / “at most” in four places so the code parses and runs. |
|
|
82
|
+
| **format.kade** | Reworked `ordinal` to use `floor` for tens/remainder and to handle 11–13 correctly (e.g. 11th, 21st). |
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Recommendations (implemented)
|
|
87
|
+
|
|
88
|
+
1. **Consistency**: Use “at least” / “at most” everywhere; **validation.kade** and **test-reverse.kade** were updated.
|
|
89
|
+
2. **validation.kade** `isEmpty`: Renamed to `isBlank`; `isNotEmpty` now calls `isBlank`.
|
|
90
|
+
3. **map.kade**: Exposes `deepClone`, `get`, and `defaults` from **object-helpers.js**; **map.js** updated to match.
|
|
91
|
+
4. **async.js / map.js**: Removed `__kadence_*` and `fs` stubs so the emitted JS is minimal.
|
|
92
|
+
5. **.object.kade.js**: Added `stdlib/.object.kade.js` to **.gitignore** so generated output is not committed.
|