@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.
Files changed (74) hide show
  1. package/LICENSE.txt +29 -0
  2. package/README.md +26 -0
  3. package/dist/cli/pager.d.ts +6 -0
  4. package/dist/cli/pager.d.ts.map +1 -0
  5. package/dist/cli/pager.js +21 -0
  6. package/dist/cli/pager.js.map +1 -0
  7. package/dist/cli/skdoc.d.ts +3 -0
  8. package/dist/cli/skdoc.d.ts.map +1 -0
  9. package/dist/cli/skdoc.js +42 -0
  10. package/dist/cli/skdoc.js.map +1 -0
  11. package/dist/cli/skgrok.d.ts +3 -0
  12. package/dist/cli/skgrok.d.ts.map +1 -0
  13. package/dist/cli/skgrok.js +21 -0
  14. package/dist/cli/skgrok.js.map +1 -0
  15. package/dist/cli/skops.d.ts +3 -0
  16. package/dist/cli/skops.d.ts.map +1 -0
  17. package/dist/cli/skops.js +32 -0
  18. package/dist/cli/skops.js.map +1 -0
  19. package/dist/index.d.ts +10 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +11 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/lib/docs.d.ts +11 -0
  24. package/dist/lib/docs.d.ts.map +1 -0
  25. package/dist/lib/docs.js +29 -0
  26. package/dist/lib/docs.js.map +1 -0
  27. package/dist/lib/expert-sections.d.ts +32 -0
  28. package/dist/lib/expert-sections.d.ts.map +1 -0
  29. package/dist/lib/expert-sections.js +130 -0
  30. package/dist/lib/expert-sections.js.map +1 -0
  31. package/dist/lib/grok.d.ts +15 -0
  32. package/dist/lib/grok.d.ts.map +1 -0
  33. package/dist/lib/grok.js +57 -0
  34. package/dist/lib/grok.js.map +1 -0
  35. package/dist/lib/help.d.ts +20 -0
  36. package/dist/lib/help.d.ts.map +1 -0
  37. package/dist/lib/help.js +163 -0
  38. package/dist/lib/help.js.map +1 -0
  39. package/dist/lib/recipes.d.ts +29 -0
  40. package/dist/lib/recipes.d.ts.map +1 -0
  41. package/dist/lib/recipes.js +133 -0
  42. package/dist/lib/recipes.js.map +1 -0
  43. package/dist/superkit.tar.gz +0 -0
  44. package/docs/grok-patterns.sup +89 -0
  45. package/docs/recipes/array.md +66 -0
  46. package/docs/recipes/array.spq +31 -0
  47. package/docs/recipes/character.md +110 -0
  48. package/docs/recipes/character.spq +57 -0
  49. package/docs/recipes/escape.md +159 -0
  50. package/docs/recipes/escape.spq +102 -0
  51. package/docs/recipes/format.md +51 -0
  52. package/docs/recipes/format.spq +24 -0
  53. package/docs/recipes/index.md +23 -0
  54. package/docs/recipes/integer.md +101 -0
  55. package/docs/recipes/integer.spq +53 -0
  56. package/docs/recipes/records.md +84 -0
  57. package/docs/recipes/records.spq +61 -0
  58. package/docs/recipes/string.md +177 -0
  59. package/docs/recipes/string.spq +105 -0
  60. package/docs/superdb-expert.md +929 -0
  61. package/docs/tutorials/bash_to_sup.md +123 -0
  62. package/docs/tutorials/chess-tiebreaks.md +233 -0
  63. package/docs/tutorials/debug.md +439 -0
  64. package/docs/tutorials/fork_for_window.md +296 -0
  65. package/docs/tutorials/grok.md +166 -0
  66. package/docs/tutorials/index.md +10 -0
  67. package/docs/tutorials/joins.md +79 -0
  68. package/docs/tutorials/moar_subqueries.md +35 -0
  69. package/docs/tutorials/subqueries.md +236 -0
  70. package/docs/tutorials/sup_to_bash.md +164 -0
  71. package/docs/tutorials/super_db_update.md +34 -0
  72. package/docs/tutorials/unnest.md +113 -0
  73. package/docs/zq-to-super-upgrades.md +549 -0
  74. package/package.json +46 -0
@@ -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
+ ```