@chrismo/superkit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +29 -0
- package/README.md +26 -0
- package/dist/cli/pager.d.ts +6 -0
- package/dist/cli/pager.d.ts.map +1 -0
- package/dist/cli/pager.js +21 -0
- package/dist/cli/pager.js.map +1 -0
- package/dist/cli/skdoc.d.ts +3 -0
- package/dist/cli/skdoc.d.ts.map +1 -0
- package/dist/cli/skdoc.js +42 -0
- package/dist/cli/skdoc.js.map +1 -0
- package/dist/cli/skgrok.d.ts +3 -0
- package/dist/cli/skgrok.d.ts.map +1 -0
- package/dist/cli/skgrok.js +21 -0
- package/dist/cli/skgrok.js.map +1 -0
- package/dist/cli/skops.d.ts +3 -0
- package/dist/cli/skops.d.ts.map +1 -0
- package/dist/cli/skops.js +32 -0
- package/dist/cli/skops.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/docs.d.ts +11 -0
- package/dist/lib/docs.d.ts.map +1 -0
- package/dist/lib/docs.js +29 -0
- package/dist/lib/docs.js.map +1 -0
- package/dist/lib/expert-sections.d.ts +32 -0
- package/dist/lib/expert-sections.d.ts.map +1 -0
- package/dist/lib/expert-sections.js +130 -0
- package/dist/lib/expert-sections.js.map +1 -0
- package/dist/lib/grok.d.ts +15 -0
- package/dist/lib/grok.d.ts.map +1 -0
- package/dist/lib/grok.js +57 -0
- package/dist/lib/grok.js.map +1 -0
- package/dist/lib/help.d.ts +20 -0
- package/dist/lib/help.d.ts.map +1 -0
- package/dist/lib/help.js +163 -0
- package/dist/lib/help.js.map +1 -0
- package/dist/lib/recipes.d.ts +29 -0
- package/dist/lib/recipes.d.ts.map +1 -0
- package/dist/lib/recipes.js +133 -0
- package/dist/lib/recipes.js.map +1 -0
- package/dist/superkit.tar.gz +0 -0
- package/docs/grok-patterns.sup +89 -0
- package/docs/recipes/array.md +66 -0
- package/docs/recipes/array.spq +31 -0
- package/docs/recipes/character.md +110 -0
- package/docs/recipes/character.spq +57 -0
- package/docs/recipes/escape.md +159 -0
- package/docs/recipes/escape.spq +102 -0
- package/docs/recipes/format.md +51 -0
- package/docs/recipes/format.spq +24 -0
- package/docs/recipes/index.md +23 -0
- package/docs/recipes/integer.md +101 -0
- package/docs/recipes/integer.spq +53 -0
- package/docs/recipes/records.md +84 -0
- package/docs/recipes/records.spq +61 -0
- package/docs/recipes/string.md +177 -0
- package/docs/recipes/string.spq +105 -0
- package/docs/superdb-expert.md +929 -0
- package/docs/tutorials/bash_to_sup.md +123 -0
- package/docs/tutorials/chess-tiebreaks.md +233 -0
- package/docs/tutorials/debug.md +439 -0
- package/docs/tutorials/fork_for_window.md +296 -0
- package/docs/tutorials/grok.md +166 -0
- package/docs/tutorials/index.md +10 -0
- package/docs/tutorials/joins.md +79 -0
- package/docs/tutorials/moar_subqueries.md +35 -0
- package/docs/tutorials/subqueries.md +236 -0
- package/docs/tutorials/sup_to_bash.md +164 -0
- package/docs/tutorials/super_db_update.md +34 -0
- package/docs/tutorials/unnest.md +113 -0
- package/docs/zq-to-super-upgrades.md +549 -0
- package/package.json +46 -0
package/dist/lib/help.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { readFileSync, readdirSync } from 'fs';
|
|
2
|
+
import { join, basename } from 'path';
|
|
3
|
+
import { getDocsDir } from './docs.js';
|
|
4
|
+
import { getExpertDoc, buildOverview } from './expert-sections.js';
|
|
5
|
+
/**
|
|
6
|
+
* List available tutorial names from docs/tutorials/
|
|
7
|
+
*/
|
|
8
|
+
function listTutorials() {
|
|
9
|
+
const tutorialsDir = join(getDocsDir(), 'tutorials');
|
|
10
|
+
try {
|
|
11
|
+
return readdirSync(tutorialsDir)
|
|
12
|
+
.filter(f => f.endsWith('.md') && f !== 'index.md')
|
|
13
|
+
.map(f => basename(f, '.md'))
|
|
14
|
+
.sort();
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const SITE_BASE = 'https://chrismo.github.io/superkit/docs';
|
|
21
|
+
const webUrls = {
|
|
22
|
+
'expert': `${SITE_BASE}/superdb-expert`,
|
|
23
|
+
'upgrade': `${SITE_BASE}/zq-to-super-upgrades`,
|
|
24
|
+
'upgrade-guide': `${SITE_BASE}/zq-to-super-upgrades`,
|
|
25
|
+
'migration': `${SITE_BASE}/zq-to-super-upgrades`,
|
|
26
|
+
'tutorials': `${SITE_BASE}/tutorials`,
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Get help documentation by topic.
|
|
30
|
+
*
|
|
31
|
+
* Topics: expert, expert:all, expert:<slug>, upgrade, upgrade-guide, migration,
|
|
32
|
+
* tutorials, tutorial:<name>
|
|
33
|
+
*/
|
|
34
|
+
export function superHelp(topic) {
|
|
35
|
+
const docsDir = getDocsDir();
|
|
36
|
+
const topics = {
|
|
37
|
+
'upgrade': 'zq-to-super-upgrades.md',
|
|
38
|
+
'upgrade-guide': 'zq-to-super-upgrades.md',
|
|
39
|
+
'migration': 'zq-to-super-upgrades.md',
|
|
40
|
+
};
|
|
41
|
+
const normalized = topic.toLowerCase();
|
|
42
|
+
// Handle expert doc topics: expert, expert:all, expert:<slug>
|
|
43
|
+
if (normalized === 'expert' || normalized.startsWith('expert:')) {
|
|
44
|
+
try {
|
|
45
|
+
const doc = getExpertDoc();
|
|
46
|
+
const webUrl = webUrls['expert'];
|
|
47
|
+
const suffix = normalized === 'expert' ? null : normalized.slice('expert:'.length);
|
|
48
|
+
if (suffix === 'all') {
|
|
49
|
+
const filepath = join(docsDir, 'superdb-expert.md');
|
|
50
|
+
const content = readFileSync(filepath, 'utf-8');
|
|
51
|
+
return { success: true, topic, content, web_url: webUrl, error: null };
|
|
52
|
+
}
|
|
53
|
+
if (suffix) {
|
|
54
|
+
const section = doc.sections.find(s => s.slug === suffix);
|
|
55
|
+
if (!section) {
|
|
56
|
+
const available = doc.sections.map(s => `expert:${s.slug}`).join(', ');
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
topic,
|
|
60
|
+
content: '',
|
|
61
|
+
error: `Unknown expert section: ${suffix}. Available sections: ${available}`,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return { success: true, topic, content: section.content, web_url: webUrl, error: null };
|
|
65
|
+
}
|
|
66
|
+
const content = buildOverview(doc);
|
|
67
|
+
const sections = doc.sections.map(s => ({ slug: s.slug, title: s.title, lines: s.lines }));
|
|
68
|
+
return { success: true, topic, content, sections, web_url: webUrl, error: null };
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
return {
|
|
72
|
+
success: false,
|
|
73
|
+
topic,
|
|
74
|
+
content: '',
|
|
75
|
+
error: `Failed to read expert documentation: ${e instanceof Error ? e.message : String(e)}`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Handle "tutorials" topic — list available tutorials
|
|
80
|
+
if (normalized === 'tutorials') {
|
|
81
|
+
const tutorials = listTutorials();
|
|
82
|
+
const listing = tutorials.length > 0
|
|
83
|
+
? tutorials.map(t => `- tutorial:${t}`).join('\n')
|
|
84
|
+
: 'No tutorials found.';
|
|
85
|
+
return {
|
|
86
|
+
success: true,
|
|
87
|
+
topic,
|
|
88
|
+
content: `# Available Tutorials\n\nUse \`super_help\` with topic \`"tutorial:<name>"\` to read a specific tutorial.\n\n${listing}`,
|
|
89
|
+
web_url: webUrls['tutorials'],
|
|
90
|
+
error: null,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
// Handle "tutorial:<name>" topics
|
|
94
|
+
if (normalized.startsWith('tutorial:')) {
|
|
95
|
+
const tutorialName = normalized.slice('tutorial:'.length);
|
|
96
|
+
const tutorialsDir = join(docsDir, 'tutorials');
|
|
97
|
+
const candidates = [
|
|
98
|
+
`${tutorialName}.md`,
|
|
99
|
+
`${tutorialName.replace(/-/g, '_')}.md`,
|
|
100
|
+
`${tutorialName.replace(/_/g, '-')}.md`,
|
|
101
|
+
];
|
|
102
|
+
for (const candidate of candidates) {
|
|
103
|
+
try {
|
|
104
|
+
const filepath = join(tutorialsDir, candidate);
|
|
105
|
+
const content = readFileSync(filepath, 'utf-8');
|
|
106
|
+
const resolvedName = basename(candidate, '.md');
|
|
107
|
+
return {
|
|
108
|
+
success: true,
|
|
109
|
+
topic,
|
|
110
|
+
content,
|
|
111
|
+
web_url: `${SITE_BASE}/tutorials/${resolvedName}`,
|
|
112
|
+
error: null,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// Try next candidate
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const tutorials = listTutorials();
|
|
120
|
+
return {
|
|
121
|
+
success: false,
|
|
122
|
+
topic,
|
|
123
|
+
content: '',
|
|
124
|
+
error: `Unknown tutorial: ${tutorialName}. Available tutorials: ${tutorials.join(', ')}`,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const filename = topics[normalized];
|
|
128
|
+
if (!filename) {
|
|
129
|
+
const tutorials = listTutorials();
|
|
130
|
+
const allTopics = [
|
|
131
|
+
'expert',
|
|
132
|
+
...Object.keys(topics),
|
|
133
|
+
'tutorials',
|
|
134
|
+
...tutorials.map(t => `tutorial:${t}`),
|
|
135
|
+
];
|
|
136
|
+
return {
|
|
137
|
+
success: false,
|
|
138
|
+
topic,
|
|
139
|
+
content: '',
|
|
140
|
+
error: `Unknown topic: ${topic}. Available topics: ${allTopics.join(', ')}`,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
try {
|
|
144
|
+
const filepath = join(docsDir, filename);
|
|
145
|
+
const content = readFileSync(filepath, 'utf-8');
|
|
146
|
+
return {
|
|
147
|
+
success: true,
|
|
148
|
+
topic,
|
|
149
|
+
content,
|
|
150
|
+
...(webUrls[normalized] && { web_url: webUrls[normalized] }),
|
|
151
|
+
error: null,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
catch (e) {
|
|
155
|
+
return {
|
|
156
|
+
success: false,
|
|
157
|
+
topic,
|
|
158
|
+
content: '',
|
|
159
|
+
error: `Failed to read documentation: ${e instanceof Error ? e.message : String(e)}`,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=help.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/lib/help.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface RecipeArg {
|
|
2
|
+
name: string;
|
|
3
|
+
desc?: string;
|
|
4
|
+
value?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface RecipeExample {
|
|
7
|
+
i: string;
|
|
8
|
+
o: string;
|
|
9
|
+
}
|
|
10
|
+
export interface RecipeFunction {
|
|
11
|
+
name: string;
|
|
12
|
+
type: string;
|
|
13
|
+
description: string;
|
|
14
|
+
args: RecipeArg[];
|
|
15
|
+
examples: RecipeExample[];
|
|
16
|
+
snippet?: string;
|
|
17
|
+
source_file: string;
|
|
18
|
+
}
|
|
19
|
+
export interface RecipesResult {
|
|
20
|
+
success: boolean;
|
|
21
|
+
recipes: RecipeFunction[];
|
|
22
|
+
count: number;
|
|
23
|
+
error: string | null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Search/list available recipe functions.
|
|
27
|
+
*/
|
|
28
|
+
export declare function superRecipes(query?: string): RecipesResult;
|
|
29
|
+
//# sourceMappingURL=recipes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipes.d.ts","sourceRoot":"","sources":["../../src/lib/recipes.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AA2GD;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,CAmC1D"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { readFileSync, readdirSync } from 'fs';
|
|
2
|
+
import { join, basename } from 'path';
|
|
3
|
+
import { getDocsDir } from './docs.js';
|
|
4
|
+
/**
|
|
5
|
+
* Parse skdoc metadata from a .spq file.
|
|
6
|
+
*/
|
|
7
|
+
function parseSkdocFromFile(filepath) {
|
|
8
|
+
const content = readFileSync(filepath, 'utf-8');
|
|
9
|
+
const sourceFile = basename(filepath, '.spq');
|
|
10
|
+
const recipes = [];
|
|
11
|
+
const skdocPattern = /fn\s+skdoc_\w+\(\):\s*\(\s*cast\(\s*(\{[\s\S]*?\}),\s*<skdoc>\)/g;
|
|
12
|
+
const skdocOpPattern = /op\s+skdoc_\w+:\s*\(\s*cast\(\s*(\{[\s\S]*?\}),\s*<skdoc>\)/g;
|
|
13
|
+
for (const pattern of [skdocPattern, skdocOpPattern]) {
|
|
14
|
+
let match;
|
|
15
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
16
|
+
try {
|
|
17
|
+
const raw = match[1];
|
|
18
|
+
const recipe = parseSkdocObject(raw, sourceFile);
|
|
19
|
+
if (recipe) {
|
|
20
|
+
recipes.push(recipe);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// Skip malformed skdoc entries
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return recipes;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Parse a SUP-format skdoc object into a RecipeFunction.
|
|
32
|
+
*/
|
|
33
|
+
function parseSkdocObject(raw, sourceFile) {
|
|
34
|
+
const nameMatch = raw.match(/name:"([^"]+)"/);
|
|
35
|
+
const typeMatch = raw.match(/type:"([^"]+)"/);
|
|
36
|
+
const descMatch = raw.match(/desc:"([^"]+)"/);
|
|
37
|
+
if (!nameMatch || !typeMatch || !descMatch) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const args = [];
|
|
41
|
+
const argsMatch = raw.match(/args:\[([\s\S]*?)\]/);
|
|
42
|
+
if (argsMatch) {
|
|
43
|
+
const argsContent = argsMatch[1];
|
|
44
|
+
const argPattern = /\{([^}]+)\}/g;
|
|
45
|
+
let argMatch;
|
|
46
|
+
while ((argMatch = argPattern.exec(argsContent)) !== null) {
|
|
47
|
+
const argObj = argMatch[1];
|
|
48
|
+
const argName = argObj.match(/name:"([^"]+)"/);
|
|
49
|
+
const argDesc = argObj.match(/desc:"([^"]+)"/);
|
|
50
|
+
const argValue = argObj.match(/value:"([^"]+)"/);
|
|
51
|
+
if (argName) {
|
|
52
|
+
args.push({
|
|
53
|
+
name: argName[1],
|
|
54
|
+
...(argDesc && { desc: argDesc[1] }),
|
|
55
|
+
...(argValue && { value: argValue[1] }),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const examples = [];
|
|
61
|
+
const examplesMatch = raw.match(/examples:\[([\s\S]*?)\]/);
|
|
62
|
+
if (examplesMatch) {
|
|
63
|
+
const exContent = examplesMatch[1];
|
|
64
|
+
const exPattern = /\{([^}]+)\}/g;
|
|
65
|
+
let exMatch;
|
|
66
|
+
while ((exMatch = exPattern.exec(exContent)) !== null) {
|
|
67
|
+
const exObj = exMatch[1];
|
|
68
|
+
const iMatch = exObj.match(/i:"([^"]+)"/);
|
|
69
|
+
const oMatch = exObj.match(/o:"([^"]+)"/);
|
|
70
|
+
if (iMatch && oMatch) {
|
|
71
|
+
examples.push({ i: iMatch[1], o: oMatch[1] });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const snippetMatch = raw.match(/snippet:'([^']+)'/);
|
|
76
|
+
return {
|
|
77
|
+
name: nameMatch[1],
|
|
78
|
+
type: typeMatch[1],
|
|
79
|
+
description: descMatch[1],
|
|
80
|
+
args,
|
|
81
|
+
examples,
|
|
82
|
+
...(snippetMatch && { snippet: snippetMatch[1] }),
|
|
83
|
+
source_file: sourceFile,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Load all recipes from the docs/recipes directory.
|
|
88
|
+
*/
|
|
89
|
+
function loadAllRecipes() {
|
|
90
|
+
const recipesDir = join(getDocsDir(), 'recipes');
|
|
91
|
+
const files = readdirSync(recipesDir).filter(f => f.endsWith('.spq')).sort();
|
|
92
|
+
const all = [];
|
|
93
|
+
for (const file of files) {
|
|
94
|
+
const filepath = join(recipesDir, file);
|
|
95
|
+
all.push(...parseSkdocFromFile(filepath));
|
|
96
|
+
}
|
|
97
|
+
return all;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Search/list available recipe functions.
|
|
101
|
+
*/
|
|
102
|
+
export function superRecipes(query) {
|
|
103
|
+
try {
|
|
104
|
+
const allRecipes = loadAllRecipes();
|
|
105
|
+
if (!query) {
|
|
106
|
+
return {
|
|
107
|
+
success: true,
|
|
108
|
+
recipes: allRecipes,
|
|
109
|
+
count: allRecipes.length,
|
|
110
|
+
error: null,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
const q = query.toLowerCase();
|
|
114
|
+
const filtered = allRecipes.filter(r => r.name.toLowerCase().includes(q) ||
|
|
115
|
+
r.description.toLowerCase().includes(q) ||
|
|
116
|
+
r.source_file.toLowerCase().includes(q));
|
|
117
|
+
return {
|
|
118
|
+
success: true,
|
|
119
|
+
recipes: filtered,
|
|
120
|
+
count: filtered.length,
|
|
121
|
+
error: null,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
return {
|
|
126
|
+
success: false,
|
|
127
|
+
recipes: [],
|
|
128
|
+
count: 0,
|
|
129
|
+
error: e instanceof Error ? e.message : String(e),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=recipes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipes.js","sourceRoot":"","sources":["../../src/lib/recipes.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{pattern_name:"USERNAME",regex:"[a-zA-Z0-9._-]+"}
|
|
2
|
+
{pattern_name:"USER",regex:"%{USERNAME}"}
|
|
3
|
+
{pattern_name:"EMAILLOCALPART",regex:"[a-zA-Z][a-zA-Z0-9_.+-=:]+"}
|
|
4
|
+
{pattern_name:"HOSTNAME",regex:"\\b[0-9A-Za-z][0-9A-Za-z-]{0,62}(?:\\.[0-9A-Za-z][0-9A-Za-z-]{0,62})*(\\.?|\\b)"}
|
|
5
|
+
{pattern_name:"EMAILADDRESS",regex:"%{EMAILLOCALPART}@%{HOSTNAME}"}
|
|
6
|
+
{pattern_name:"HTTPDUSER",regex:"%{EMAILADDRESS}|%{USER}"}
|
|
7
|
+
{pattern_name:"INT",regex:"[+-]?(?:[0-9]+)"}
|
|
8
|
+
{pattern_name:"BASE10NUM",regex:"[+-]?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))"}
|
|
9
|
+
{pattern_name:"NUMBER",regex:"%{BASE10NUM}"}
|
|
10
|
+
{pattern_name:"BASE16NUM",regex:"[+-]?(?:0x)?(?:[0-9A-Fa-f]+)"}
|
|
11
|
+
{pattern_name:"BASE16FLOAT",regex:"\\b[+-]?(?:0x)?(?:(?:[0-9A-Fa-f]+(?:\\.[0-9A-Fa-f]*)?)|(?:\\.[0-9A-Fa-f]+))\\b"}
|
|
12
|
+
{pattern_name:"POSINT",regex:"\\b[1-9][0-9]*\\b"}
|
|
13
|
+
{pattern_name:"NONNEGINT",regex:"\\b[0-9]+\\b"}
|
|
14
|
+
{pattern_name:"WORD",regex:"\\b\\w+\\b"}
|
|
15
|
+
{pattern_name:"NOTSPACE",regex:"\\S+"}
|
|
16
|
+
{pattern_name:"SPACE",regex:"\\s*"}
|
|
17
|
+
{pattern_name:"DATA",regex:".*?"}
|
|
18
|
+
{pattern_name:"GREEDYDATA",regex:".*"}
|
|
19
|
+
{pattern_name:"QUOTEDSTRING",regex:"(\"(\\\\.|[^\\\\\"]+)+\")\"\"|('(\\\\.|[^\\\\'+)+')+'|''|"}
|
|
20
|
+
{pattern_name:"UUID",regex:"[A-Fa-f0-9]{8}-(?:[A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}"}
|
|
21
|
+
{pattern_name:"CISCOMAC",regex:"(?:[A-Fa-f0-9]{4}\\.){2}[A-Fa-f0-9]{4}"}
|
|
22
|
+
{pattern_name:"WINDOWSMAC",regex:"(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2}"}
|
|
23
|
+
{pattern_name:"COMMONMAC",regex:"(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}"}
|
|
24
|
+
{pattern_name:"MAC",regex:"%{CISCOMAC}|%{WINDOWSMAC}|%{COMMONMAC}"}
|
|
25
|
+
{pattern_name:"IPV6",regex:"((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?"}
|
|
26
|
+
{pattern_name:"IPV4",regex:"(?:(?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]))"}
|
|
27
|
+
{pattern_name:"IP",regex:"%{IPV6}|%{IPV4}"}
|
|
28
|
+
{pattern_name:"IPORHOST",regex:"%{IP}|%{HOSTNAME}"}
|
|
29
|
+
{pattern_name:"HOSTPORT",regex:"%{IPORHOST}:%{POSINT}"}
|
|
30
|
+
{pattern_name:"UNIXPATH",regex:"(/([\\w_%!$@:.,~-]+|\\\\.)*)+"}
|
|
31
|
+
{pattern_name:"TTY",regex:"/dev/(pts|tty([pq])?)( \\w+)?/?(?:[0-9]+)"}
|
|
32
|
+
{pattern_name:"WINPATH",regex:"(?:[A-Za-z]+:|\\\\)(?:\\\\[^\\\\?*]*)+"}
|
|
33
|
+
{pattern_name:"PATH",regex:"%{UNIXPATH}|%{WINPATH}"}
|
|
34
|
+
{pattern_name:"URIPROTO",regex:"[A-Za-z]+(\\+[A-Za-z+]+)?"}
|
|
35
|
+
{pattern_name:"URIHOST",regex:"%{IPORHOST}(?::%{POSINT:port})?"}
|
|
36
|
+
{pattern_name:"URIPATH",regex:"(?:/[A-Za-z0-9$.+!'(){},~:;=@#%_\\-]*)+"}
|
|
37
|
+
{pattern_name:"URIPARAM",regex:"\\?[A-Za-z0-9$.+!'|(){},~@#%&/=:;_?\\-\\[\\]<>]*"}
|
|
38
|
+
{pattern_name:"URIPATHPARAM",regex:"%{URIPATH}(?:%{URIPARAM})?"}
|
|
39
|
+
{pattern_name:"URI",regex:"%{URIPROTO}://(?:%{USER}(?::[^@]*)?@)?(?:%{URIHOST})?(?:%{URIPATHPARAM})?"}
|
|
40
|
+
{pattern_name:"MONTH",regex:"\\bJan(?:uary|uar)?|Feb(?:ruary|ruar)?|M(?:a|ä)?r(?:ch|z)?|Apr(?:il)?|Ma(?:y|i)?|Jun(?:e|i)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|O(?:c|k)?t(?:ober)?|Nov(?:ember)?|De(?:c|z)(?:ember)?\\b"}
|
|
41
|
+
{pattern_name:"MONTHNUM",regex:"0?[1-9]|1[0-2]"}
|
|
42
|
+
{pattern_name:"MONTHNUM2",regex:"0[1-9]|1[0-2]"}
|
|
43
|
+
{pattern_name:"MONTHDAY",regex:"(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9]"}
|
|
44
|
+
{pattern_name:"DAY",regex:"Mon(?:day)?|Tue(?:sday)?|Wed(?:nesday)?|Thu(?:rsday)?|Fri(?:day)?|Sat(?:urday)?|Sun(?:day)?"}
|
|
45
|
+
{pattern_name:"YEAR",regex:"(?:\\d\\d){1,2}"}
|
|
46
|
+
{pattern_name:"HOUR",regex:"2[0123]|[01]?[0-9]"}
|
|
47
|
+
{pattern_name:"MINUTE",regex:"[0-5][0-9]"}
|
|
48
|
+
{pattern_name:"SECOND",regex:"(?:[0-5]?[0-9]|60)(?:[:.,][0-9]+)?"}
|
|
49
|
+
{pattern_name:"TIME",regex:"%{HOUR}:%{MINUTE}:%{SECOND}"}
|
|
50
|
+
{pattern_name:"DATE_US",regex:"%{MONTHNUM}[/-]%{MONTHDAY}[/-]%{YEAR}"}
|
|
51
|
+
{pattern_name:"DATE_EU",regex:"%{MONTHDAY}[./-]%{MONTHNUM}[./-]%{YEAR}"}
|
|
52
|
+
{pattern_name:"DATE_X",regex:"%{YEAR}/%{MONTHNUM2}/%{MONTHDAY}"}
|
|
53
|
+
{pattern_name:"ISO8601_TIMEZONE",regex:"Z|[+-]%{HOUR}(?::?%{MINUTE})"}
|
|
54
|
+
{pattern_name:"ISO8601_SECOND",regex:"%{SECOND}|60"}
|
|
55
|
+
{pattern_name:"DATESTAMP_ISO8601",regex:"%{YEAR}-%{MONTHNUM}-%{MONTHDAY}"}
|
|
56
|
+
{pattern_name:"TIMESTAMP_ISO8601",regex:"%{DATESTAMP_ISO8601}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}?"}
|
|
57
|
+
{pattern_name:"DATE",regex:"%{DATE_US}|%{DATE_EU}|%{DATE_X}"}
|
|
58
|
+
{pattern_name:"DATESTAMP",regex:"%{DATE}[- ]%{TIME}"}
|
|
59
|
+
{pattern_name:"TZ",regex:"[A-Z]{3}"}
|
|
60
|
+
{pattern_name:"NUMTZ",regex:"[+-]\\d{4}"}
|
|
61
|
+
{pattern_name:"DATESTAMP_RFC822",regex:"%{DAY} %{MONTH} %{MONTHDAY} %{YEAR} %{TIME} %{TZ}"}
|
|
62
|
+
{pattern_name:"DATESTAMP_RFC2822",regex:"%{DAY}, %{MONTHDAY} %{MONTH} %{YEAR} %{TIME} %{ISO8601_TIMEZONE}"}
|
|
63
|
+
{pattern_name:"DATESTAMP_OTHER",regex:"%{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{TZ} %{YEAR}"}
|
|
64
|
+
{pattern_name:"DATESTAMP_EVENTLOG",regex:"%{YEAR}%{MONTHNUM2}%{MONTHDAY}%{HOUR}%{MINUTE}%{SECOND}"}
|
|
65
|
+
{pattern_name:"HTTPDERROR_DATE",regex:"%{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{YEAR}"}
|
|
66
|
+
{pattern_name:"ANSIC",regex:"%{DAY} %{MONTH} [_123]\\d %{TIME} %{YEAR}\""}
|
|
67
|
+
{pattern_name:"UNIXDATE",regex:"%{DAY} %{MONTH} [_123]\\d %{TIME} %{TZ} %{YEAR}"}
|
|
68
|
+
{pattern_name:"RUBYDATE",regex:"%{DAY} %{MONTH} [0-3]\\d %{TIME} %{NUMTZ} %{YEAR}"}
|
|
69
|
+
{pattern_name:"RFC822Z",regex:"[0-3]\\d %{MONTH} %{YEAR} %{TIME} %{NUMTZ}"}
|
|
70
|
+
{pattern_name:"RFC850",regex:"%{DAY}, [0-3]\\d-%{MONTH}-%{YEAR} %{TIME} %{TZ}"}
|
|
71
|
+
{pattern_name:"RFC1123",regex:"%{DAY}, [0-3]\\d %{MONTH} %{YEAR} %{TIME} %{TZ}"}
|
|
72
|
+
{pattern_name:"RFC1123Z",regex:"%{DAY}, [0-3]\\d %{MONTH} %{YEAR} %{TIME} %{NUMTZ}"}
|
|
73
|
+
{pattern_name:"RFC3339",regex:"%{YEAR}-[01]\\d-[0-3]\\dT%{TIME}%{ISO8601_TIMEZONE}"}
|
|
74
|
+
{pattern_name:"RFC3339NANO",regex:"%{YEAR}-[01]\\d-[0-3]\\dT%{TIME}\\.\\d{9}%{ISO8601_TIMEZONE}"}
|
|
75
|
+
{pattern_name:"KITCHEN",regex:"\\d{1,2}:\\d{2}(AM|PM|am|pm)"}
|
|
76
|
+
{pattern_name:"SYSLOGTIMESTAMP",regex:"%{MONTH} +%{MONTHDAY} %{TIME}"}
|
|
77
|
+
{pattern_name:"PROG",regex:"[\\x21-\\x5a\\x5c\\x5e-\\x7e]+"}
|
|
78
|
+
{pattern_name:"SYSLOGPROG",regex:"%{PROG:program}(?:\\[%{POSINT:pid}\\])?"}
|
|
79
|
+
{pattern_name:"SYSLOGHOST",regex:"%{IPORHOST}"}
|
|
80
|
+
{pattern_name:"SYSLOGFACILITY",regex:"<%{NONNEGINT:facility}.%{NONNEGINT:priority}>"}
|
|
81
|
+
{pattern_name:"HTTPDATE",regex:"%{MONTHDAY}/%{MONTH}/%{YEAR}:%{TIME} %{INT}"}
|
|
82
|
+
{pattern_name:"QS",regex:"%{QUOTEDSTRING}"}
|
|
83
|
+
{pattern_name:"LOGLEVEL",regex:"[Aa]lert|ALERT|[Tt]race|TRACE|[Dd]ebug|DEBUG|[Nn]otice|NOTICE|[Ii]nfo|INFO|[Ww]arn?(?:ing)?|WARN?(?:ING)?|[Ee]rr?(?:or)?|ERR?(?:OR)?|[Cc]rit?(?:ical)?|CRIT?(?:ICAL)?|[Ff]atal|FATAL|[Ss]evere|SEVERE|EMERG(?:ENCY)?|[Ee]merg(?:ency)?"}
|
|
84
|
+
{pattern_name:"SYSLOGBASE",regex:"%{SYSLOGTIMESTAMP:timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:logsource} %{SYSLOGPROG}:"}
|
|
85
|
+
{pattern_name:"COMMONAPACHELOG",regex:"%{IPORHOST:clientip} %{HTTPDUSER:ident} %{USER:auth} \\[%{HTTPDATE:timestamp}\\] \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})\" %{NUMBER:response} (?:%{NUMBER:bytes}|-)"}
|
|
86
|
+
{pattern_name:"COMBINEDAPACHELOG",regex:"%{COMMONAPACHELOG} %{QS:referrer} %{QS:agent}"}
|
|
87
|
+
{pattern_name:"HTTPD20_ERRORLOG",regex:"\\[%{HTTPDERROR_DATE:timestamp}\\] \\[%{LOGLEVEL:loglevel}\\] (?:\\[client %{IPORHOST:clientip}\\] ){0,1}%{GREEDYDATA:errormsg}"}
|
|
88
|
+
{pattern_name:"HTTPD24_ERRORLOG",regex:"\\[%{HTTPDERROR_DATE:timestamp}\\] \\[%{WORD:module}:%{LOGLEVEL:loglevel}\\] \\[pid %{POSINT:pid}:tid %{NUMBER:tid}\\]( \\(%{POSINT:proxy_errorcode}\\)%{DATA:proxy_errormessage}:)?( \\[client %{IPORHOST:client}:%{POSINT:clientport}\\])? %{DATA:errorcode}: %{GREEDYDATA:message}"}
|
|
89
|
+
{pattern_name:"HTTPD_ERRORLOG",regex:"%{HTTPD20_ERRORLOG}|%{HTTPD24_ERRORLOG}"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Array
|
|
3
|
+
layout: default
|
|
4
|
+
nav_order: 2
|
|
5
|
+
parent: Recipes
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Array Recipes
|
|
9
|
+
|
|
10
|
+
Source: `array.spq`
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## sk_in_array
|
|
15
|
+
|
|
16
|
+
Puts value in an array if value isn't an array itself.
|
|
17
|
+
|
|
18
|
+
**Type:** function
|
|
19
|
+
|
|
20
|
+
| Argument | Description |
|
|
21
|
+
|----------|-------------|
|
|
22
|
+
| `value` | any |
|
|
23
|
+
|
|
24
|
+
```supersql
|
|
25
|
+
sk_in_array(1)
|
|
26
|
+
-- => [1]
|
|
27
|
+
|
|
28
|
+
sk_in_array([1])
|
|
29
|
+
-- => [1]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Implementation:**
|
|
33
|
+
|
|
34
|
+
```supersql
|
|
35
|
+
fn sk_in_array(value): (
|
|
36
|
+
kind(value) == "array" ? value : [value]
|
|
37
|
+
)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## sk_array_flatten
|
|
43
|
+
|
|
44
|
+
Flattens an array of arrays into a single array.
|
|
45
|
+
|
|
46
|
+
**Type:** operator
|
|
47
|
+
|
|
48
|
+
```supersql
|
|
49
|
+
[1,2,[3,4],5] | sk_array_flatten
|
|
50
|
+
-- => [1,2,3,4,5]
|
|
51
|
+
|
|
52
|
+
[[1,2],[3,4]] | sk_array_flatten
|
|
53
|
+
-- => [1,2,3,4]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Implementation:**
|
|
57
|
+
|
|
58
|
+
```supersql
|
|
59
|
+
op sk_array_flatten: (
|
|
60
|
+
this::string
|
|
61
|
+
| this[1:-1]
|
|
62
|
+
| replace(this,'[','')
|
|
63
|
+
| replace(this, ']','')
|
|
64
|
+
| parse_sup(f'[{this}]')
|
|
65
|
+
)
|
|
66
|
+
```
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
fn skdoc_in_array(): (
|
|
2
|
+
cast(
|
|
3
|
+
{name:"sk_in_array",
|
|
4
|
+
type:"func",
|
|
5
|
+
desc:"Puts value in an array if value isn't an array itself.",
|
|
6
|
+
args:[{name:"value",value:"any"}],
|
|
7
|
+
examples:[{i:"sk_in_array(1)",o:"[1]"}
|
|
8
|
+
{i:"sk_in_array([1])",o:"[1]"}]}, <skdoc>)
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
fn sk_in_array(value): (
|
|
12
|
+
kind(value) == "array" ? value : [value]
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
fn skdoc_array_flatten(): (
|
|
16
|
+
cast(
|
|
17
|
+
{name:"sk_array_flatten",
|
|
18
|
+
type:"op",
|
|
19
|
+
desc:"Flattens an array of arrays into a single array.",
|
|
20
|
+
args:[],
|
|
21
|
+
examples:[{i:"[1,2,[3,4],5] | sk_array_flatten",o:"[1,2,3,4,5]"}
|
|
22
|
+
{i:"[[1,2],[3,4]] | sk_array_flatten",o:"[1,2,3,4]"}]}, <skdoc>)
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
op sk_array_flatten: (
|
|
26
|
+
this::string
|
|
27
|
+
| this[1:-1]
|
|
28
|
+
| replace(this,'[','')
|
|
29
|
+
| replace(this, ']','')
|
|
30
|
+
| parse_sup(f'[{this}]')
|
|
31
|
+
)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Character
|
|
3
|
+
layout: default
|
|
4
|
+
nav_order: 4
|
|
5
|
+
parent: Recipes
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Character Recipes
|
|
9
|
+
|
|
10
|
+
Source: `character.spq` (includes `string.spq`)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## sk_seq
|
|
15
|
+
|
|
16
|
+
Generates a sequence 0..n-1 (like generate_series).
|
|
17
|
+
|
|
18
|
+
**Type:** operator
|
|
19
|
+
|
|
20
|
+
| Argument | Description |
|
|
21
|
+
|----------|-------------|
|
|
22
|
+
| `n` | Number of elements to generate |
|
|
23
|
+
|
|
24
|
+
```supersql
|
|
25
|
+
sk_seq(3)
|
|
26
|
+
-- => 0, 1, 2
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Implementation:**
|
|
30
|
+
|
|
31
|
+
```supersql
|
|
32
|
+
op sk_seq(n): (
|
|
33
|
+
split(sk_pad_left('', '0', n), '')
|
|
34
|
+
| unnest this
|
|
35
|
+
| count
|
|
36
|
+
| values count - 1
|
|
37
|
+
)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## sk_hex_digits
|
|
43
|
+
|
|
44
|
+
Returns the 16 hex digit characters as an array.
|
|
45
|
+
|
|
46
|
+
**Type:** function
|
|
47
|
+
|
|
48
|
+
```supersql
|
|
49
|
+
sk_hex_digits()
|
|
50
|
+
-- => ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Implementation:**
|
|
54
|
+
|
|
55
|
+
```supersql
|
|
56
|
+
fn sk_hex_digits(): (
|
|
57
|
+
split("0123456789abcdef", "")
|
|
58
|
+
)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## sk_chr
|
|
64
|
+
|
|
65
|
+
Converts an integer (0-127) to its ASCII character.
|
|
66
|
+
|
|
67
|
+
**Type:** function
|
|
68
|
+
|
|
69
|
+
| Argument | Description |
|
|
70
|
+
|----------|-------------|
|
|
71
|
+
| `code` | ASCII code (0-127) |
|
|
72
|
+
|
|
73
|
+
```supersql
|
|
74
|
+
sk_chr(65)
|
|
75
|
+
-- => 'A'
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Implementation:**
|
|
79
|
+
|
|
80
|
+
```supersql
|
|
81
|
+
fn sk_chr(code): (
|
|
82
|
+
let d = sk_hex_digits() |
|
|
83
|
+
hex(f'{d[code/16]}{d[code%16]}')::string
|
|
84
|
+
)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## sk_alpha
|
|
90
|
+
|
|
91
|
+
Converts 1-26 to A-Z.
|
|
92
|
+
|
|
93
|
+
**Type:** function
|
|
94
|
+
|
|
95
|
+
| Argument | Description |
|
|
96
|
+
|----------|-------------|
|
|
97
|
+
| `n` | Number 1-26 |
|
|
98
|
+
|
|
99
|
+
```supersql
|
|
100
|
+
sk_alpha(3)
|
|
101
|
+
-- => 'C'
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Implementation:**
|
|
105
|
+
|
|
106
|
+
```supersql
|
|
107
|
+
fn sk_alpha(n): (
|
|
108
|
+
sk_chr(64 + n)
|
|
109
|
+
)
|
|
110
|
+
```
|