@deessejs/functions 0.0.2 → 0.0.4
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/dist/api/index.d.ts +3 -5
- package/dist/api/index.js +23 -8
- package/dist/context/generated.d.ts +2 -0
- package/dist/context/generated.js +40 -0
- package/dist/context/generator.d.ts +9 -0
- package/dist/context/generator.js +116 -0
- package/dist/context/index.d.ts +4 -0
- package/dist/context/index.js +17 -1
- package/dist/context/typing.d.ts +10 -0
- package/dist/context/typing.js +62 -0
- package/dist/functions/group.d.ts +7 -0
- package/dist/functions/group.js +31 -0
- package/dist/functions/mutation.d.ts +9 -0
- package/dist/functions/mutation.js +31 -0
- package/dist/functions/query.d.ts +12 -3
- package/dist/functions/query.js +13 -4
- package/dist/functions/types.d.ts +15 -8
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/package.json +1 -1
package/dist/api/index.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { API, APIConfig } from "./types";
|
|
2
|
-
export declare const createAPI: <TContext extends Record<string, unknown>>(config: APIConfig<TContext
|
|
3
|
-
declare const
|
|
4
|
-
|
|
5
|
-
}>;
|
|
6
|
-
export default api;
|
|
2
|
+
export declare const createAPI: <TContext extends Record<string, unknown>>(config: APIConfig<TContext>, contextName?: string) => API<TContext>;
|
|
3
|
+
export declare const clearGeneratedContextCache: () => void;
|
|
4
|
+
export declare const getGeneratedContexts: () => string[];
|
package/dist/api/index.js
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createAPI = void 0;
|
|
4
|
-
const
|
|
3
|
+
exports.getGeneratedContexts = exports.clearGeneratedContextCache = exports.createAPI = void 0;
|
|
4
|
+
const generator_1 = require("../context/generator");
|
|
5
|
+
// Cache pour éviter de générer plusieurs fois le même contexte
|
|
6
|
+
const generatedContexts = new Set();
|
|
7
|
+
const createAPI = (config, contextName = 'App') => {
|
|
8
|
+
// Générer les types de contexte si ce n'est pas déjà fait
|
|
9
|
+
if (!generatedContexts.has(contextName)) {
|
|
10
|
+
(0, generator_1.generateContextDeclarationFile)(contextName, config.context)
|
|
11
|
+
.then(() => {
|
|
12
|
+
generatedContexts.add(contextName);
|
|
13
|
+
})
|
|
14
|
+
.catch((error) => {
|
|
15
|
+
console.error(`Failed to generate context types for ${contextName}:`, error);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
5
18
|
let context = { ...config.context };
|
|
6
19
|
const addContext = (key, value) => {
|
|
7
20
|
context = { ...context, [key]: value };
|
|
@@ -16,9 +29,11 @@ const createAPI = (config) => {
|
|
|
16
29
|
return api;
|
|
17
30
|
};
|
|
18
31
|
exports.createAPI = createAPI;
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
const clearGeneratedContextCache = () => {
|
|
33
|
+
generatedContexts.clear();
|
|
34
|
+
};
|
|
35
|
+
exports.clearGeneratedContextCache = clearGeneratedContextCache;
|
|
36
|
+
const getGeneratedContexts = () => {
|
|
37
|
+
return Array.from(generatedContexts);
|
|
38
|
+
};
|
|
39
|
+
exports.getGeneratedContexts = getGeneratedContexts;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// This file is automatically generated by the context type generator.
|
|
3
|
+
// Do not modify this file directly. It will be overwritten when new context types are generated.
|
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
+
if (k2 === undefined) k2 = k;
|
|
6
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
+
}
|
|
10
|
+
Object.defineProperty(o, k2, desc);
|
|
11
|
+
}) : (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
o[k2] = m[k];
|
|
14
|
+
}));
|
|
15
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
16
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
// Import utilities for context access
|
|
20
|
+
__exportStar(require("./index"), exports);
|
|
21
|
+
// Generated context types will be added here by the generator
|
|
22
|
+
// Example:
|
|
23
|
+
// declare module "./generated" {
|
|
24
|
+
// export interface AppContext {
|
|
25
|
+
// user: null;
|
|
26
|
+
// permissions: string[];
|
|
27
|
+
// settings: {
|
|
28
|
+
// theme: string;
|
|
29
|
+
// language: string;
|
|
30
|
+
// };
|
|
31
|
+
// database: {
|
|
32
|
+
// host: string;
|
|
33
|
+
// port: number;
|
|
34
|
+
// };
|
|
35
|
+
// }
|
|
36
|
+
//
|
|
37
|
+
// export type AppAPI<T extends AppContext = AppContext> = T & {
|
|
38
|
+
// __contextName: "App";
|
|
39
|
+
// };
|
|
40
|
+
// }
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface GeneratorOptions {
|
|
2
|
+
outputPath: string;
|
|
3
|
+
moduleName: string;
|
|
4
|
+
contextName: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const generateContextDeclaration: (contextName: string, context: Record<string, unknown>) => string;
|
|
7
|
+
export declare const generateContextDeclarationFile: (contextName: string, context: Record<string, unknown>) => Promise<void>;
|
|
8
|
+
export declare const clearGeneratedCache: () => void;
|
|
9
|
+
export declare const getGeneratedContextNames: () => string[];
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getGeneratedContextNames = exports.clearGeneratedCache = exports.generateContextDeclarationFile = exports.generateContextDeclaration = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const process_1 = __importDefault(require("process"));
|
|
10
|
+
// Cache pour éviter de générer plusieurs fois le même contexte
|
|
11
|
+
const generatedContexts = new Set();
|
|
12
|
+
const generateContextDeclaration = (contextName, context) => {
|
|
13
|
+
const properties = Object.entries(context)
|
|
14
|
+
.map(([key, value]) => {
|
|
15
|
+
const type = inferTypeFromValue(value);
|
|
16
|
+
return ` ${key}: ${type};`;
|
|
17
|
+
})
|
|
18
|
+
.join('\n');
|
|
19
|
+
return `
|
|
20
|
+
declare module "${process_1.default.cwd()}/packages/functions/src/context/generated" {
|
|
21
|
+
export interface ${contextName}Context {
|
|
22
|
+
${properties}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type ${contextName}API<T extends ${contextName}Context = ${contextName}Context> = T & {
|
|
26
|
+
__contextName: "${contextName}";
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
`;
|
|
30
|
+
};
|
|
31
|
+
exports.generateContextDeclaration = generateContextDeclaration;
|
|
32
|
+
const generateContextDeclarationFile = async (contextName, context) => {
|
|
33
|
+
// Vérifier si le contexte a déjà été généré
|
|
34
|
+
if (generatedContexts.has(contextName)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const declaration = (0, exports.generateContextDeclaration)(contextName, context);
|
|
38
|
+
const outputPath = path_1.default.join(process_1.default.cwd(), 'packages', 'functions', 'src', 'context', 'generated.ts');
|
|
39
|
+
try {
|
|
40
|
+
// S'assurer que le répertoire existe
|
|
41
|
+
const dir = path_1.default.dirname(outputPath);
|
|
42
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
43
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
44
|
+
}
|
|
45
|
+
// Lire le contenu existant s'il existe
|
|
46
|
+
let existingContent = '';
|
|
47
|
+
if (fs_1.default.existsSync(outputPath)) {
|
|
48
|
+
existingContent = fs_1.default.readFileSync(outputPath, 'utf8');
|
|
49
|
+
}
|
|
50
|
+
// Vérifier si le fichier contient déjà notre déclaration
|
|
51
|
+
if (existingContent.includes(`__contextName: "${contextName}"`)) {
|
|
52
|
+
generatedContexts.add(contextName);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Écrire ou ajouter au fichier généré
|
|
56
|
+
const finalContent = existingContent ?
|
|
57
|
+
`${existingContent}\n\n${declaration}` :
|
|
58
|
+
declaration;
|
|
59
|
+
fs_1.default.writeFileSync(outputPath, finalContent, 'utf8');
|
|
60
|
+
generatedContexts.add(contextName);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error(`Failed to generate context types for ${contextName}:`, error);
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
exports.generateContextDeclarationFile = generateContextDeclarationFile;
|
|
68
|
+
const clearGeneratedCache = () => {
|
|
69
|
+
generatedContexts.clear();
|
|
70
|
+
};
|
|
71
|
+
exports.clearGeneratedCache = clearGeneratedCache;
|
|
72
|
+
const getGeneratedContextNames = () => {
|
|
73
|
+
return Array.from(generatedContexts);
|
|
74
|
+
};
|
|
75
|
+
exports.getGeneratedContextNames = getGeneratedContextNames;
|
|
76
|
+
const inferTypeFromValue = (value) => {
|
|
77
|
+
if (value === null) {
|
|
78
|
+
return 'null';
|
|
79
|
+
}
|
|
80
|
+
if (Array.isArray(value)) {
|
|
81
|
+
if (value.length > 0) {
|
|
82
|
+
const elementType = inferTypeFromValue(value[0]);
|
|
83
|
+
return `${elementType}[]`;
|
|
84
|
+
}
|
|
85
|
+
return 'unknown[]';
|
|
86
|
+
}
|
|
87
|
+
switch (typeof value) {
|
|
88
|
+
case 'string':
|
|
89
|
+
return 'string';
|
|
90
|
+
case 'number':
|
|
91
|
+
return 'number';
|
|
92
|
+
case 'boolean':
|
|
93
|
+
return 'boolean';
|
|
94
|
+
case 'object': {
|
|
95
|
+
if (value !== null && !Array.isArray(value)) {
|
|
96
|
+
const obj = value;
|
|
97
|
+
const properties = Object.entries(obj)
|
|
98
|
+
.map(([key, val]) => {
|
|
99
|
+
const type = inferTypeFromValue(val);
|
|
100
|
+
return ` ${key}: ${type};`;
|
|
101
|
+
})
|
|
102
|
+
.join('\n');
|
|
103
|
+
return `{\n${properties}\n }`;
|
|
104
|
+
}
|
|
105
|
+
return 'Record<string, unknown>';
|
|
106
|
+
}
|
|
107
|
+
case 'bigint':
|
|
108
|
+
return 'bigint';
|
|
109
|
+
case 'symbol':
|
|
110
|
+
return 'symbol';
|
|
111
|
+
case 'undefined':
|
|
112
|
+
return 'undefined';
|
|
113
|
+
default:
|
|
114
|
+
return 'unknown';
|
|
115
|
+
}
|
|
116
|
+
};
|
package/dist/context/index.d.ts
CHANGED
|
@@ -2,3 +2,7 @@ import { Context } from "./types";
|
|
|
2
2
|
export declare const createContext: (ctx: Context) => void;
|
|
3
3
|
export declare const addContext: <K extends string, V>(key: K, value: V) => void;
|
|
4
4
|
export declare const getContext: () => Context;
|
|
5
|
+
export declare const getCurrentContext: () => Context;
|
|
6
|
+
export declare const clearContext: () => void;
|
|
7
|
+
export declare const setContextProperty: <K extends string, V>(key: K, value: V) => void;
|
|
8
|
+
export declare const getContextProperty: <K extends string>(key: K) => unknown;
|
package/dist/context/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getContext = exports.addContext = exports.createContext = void 0;
|
|
3
|
+
exports.getContextProperty = exports.setContextProperty = exports.clearContext = exports.getCurrentContext = exports.getContext = exports.addContext = exports.createContext = void 0;
|
|
4
4
|
let currentContext = {};
|
|
5
5
|
const createContext = (ctx) => {
|
|
6
6
|
currentContext = { ...ctx };
|
|
@@ -12,3 +12,19 @@ const addContext = (key, value) => {
|
|
|
12
12
|
exports.addContext = addContext;
|
|
13
13
|
const getContext = () => currentContext;
|
|
14
14
|
exports.getContext = getContext;
|
|
15
|
+
const getCurrentContext = () => {
|
|
16
|
+
return { ...currentContext };
|
|
17
|
+
};
|
|
18
|
+
exports.getCurrentContext = getCurrentContext;
|
|
19
|
+
const clearContext = () => {
|
|
20
|
+
currentContext = {};
|
|
21
|
+
};
|
|
22
|
+
exports.clearContext = clearContext;
|
|
23
|
+
const setContextProperty = (key, value) => {
|
|
24
|
+
currentContext = { ...currentContext, [key]: value };
|
|
25
|
+
};
|
|
26
|
+
exports.setContextProperty = setContextProperty;
|
|
27
|
+
const getContextProperty = (key) => {
|
|
28
|
+
return currentContext[key];
|
|
29
|
+
};
|
|
30
|
+
exports.getContextProperty = getContextProperty;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type AppContext = Record<string, unknown>;
|
|
2
|
+
export declare const getTypedContext: <TContext = AppContext>() => TContext;
|
|
3
|
+
export declare const getSafeTypedContext: <TContext = AppContext>() => TContext | null;
|
|
4
|
+
export declare const assertContextProperty: <K extends string>(key: K) => asserts key is Extract<keyof AppContext, K>;
|
|
5
|
+
export declare const getContextPropertyTyped: <K extends string, T>(key: K) => T | undefined;
|
|
6
|
+
export declare const setContextPropertyTyped: <K extends string, T>(key: K, value: T) => void;
|
|
7
|
+
export type ContextValidator<TContext> = (context: unknown) => context is TContext;
|
|
8
|
+
export declare const createContextValidator: <TContext>(validator: ContextValidator<TContext>) => ContextValidator<TContext>;
|
|
9
|
+
export declare const getValidatedContext: <TContext>(validator: ContextValidator<TContext>) => TContext;
|
|
10
|
+
export declare const assertContextProperties: <TContext extends Record<string, unknown>, TKeys extends readonly (keyof TContext)[]>(keys: TKeys) => asserts keys is TKeys;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assertContextProperties = exports.getValidatedContext = exports.createContextValidator = exports.setContextPropertyTyped = exports.getContextPropertyTyped = exports.assertContextProperty = exports.getSafeTypedContext = exports.getTypedContext = void 0;
|
|
4
|
+
const index_1 = require("./index");
|
|
5
|
+
// Type utilities for context access
|
|
6
|
+
const getTypedContext = () => {
|
|
7
|
+
return (0, index_1.getContext)();
|
|
8
|
+
};
|
|
9
|
+
exports.getTypedContext = getTypedContext;
|
|
10
|
+
const getSafeTypedContext = () => {
|
|
11
|
+
try {
|
|
12
|
+
const context = (0, index_1.getContext)();
|
|
13
|
+
return context;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
exports.getSafeTypedContext = getSafeTypedContext;
|
|
20
|
+
const assertContextProperty = (key) => {
|
|
21
|
+
const context = (0, index_1.getContext)();
|
|
22
|
+
if (!(key in context)) {
|
|
23
|
+
throw new Error(`Context property '${key}' does not exist`);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
exports.assertContextProperty = assertContextProperty;
|
|
27
|
+
const getContextPropertyTyped = (key) => {
|
|
28
|
+
const context = (0, index_1.getContext)();
|
|
29
|
+
return context[key];
|
|
30
|
+
};
|
|
31
|
+
exports.getContextPropertyTyped = getContextPropertyTyped;
|
|
32
|
+
const setContextPropertyTyped = (key, value) => {
|
|
33
|
+
const context = (0, index_1.getContext)();
|
|
34
|
+
const updatedContext = { ...context, [key]: value };
|
|
35
|
+
// Note: This would require updating the global context
|
|
36
|
+
// For now, this is a utility that shows how it could work
|
|
37
|
+
// In a real implementation, you might want to pass the context explicitly
|
|
38
|
+
};
|
|
39
|
+
exports.setContextPropertyTyped = setContextPropertyTyped;
|
|
40
|
+
const createContextValidator = (validator) => {
|
|
41
|
+
return validator;
|
|
42
|
+
};
|
|
43
|
+
exports.createContextValidator = createContextValidator;
|
|
44
|
+
// Generic context access with validation
|
|
45
|
+
const getValidatedContext = (validator) => {
|
|
46
|
+
const context = (0, index_1.getContext)();
|
|
47
|
+
if (validator(context)) {
|
|
48
|
+
return context;
|
|
49
|
+
}
|
|
50
|
+
throw new Error('Context validation failed');
|
|
51
|
+
};
|
|
52
|
+
exports.getValidatedContext = getValidatedContext;
|
|
53
|
+
// Utility for partial context validation
|
|
54
|
+
const assertContextProperties = (keys) => {
|
|
55
|
+
const context = (0, index_1.getContext)();
|
|
56
|
+
for (const key of keys) {
|
|
57
|
+
if (!(key in context)) {
|
|
58
|
+
throw new Error(`Required context property '${String(key)}' is missing`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
exports.assertContextProperties = assertContextProperties;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Command, CommandGroupConfig, GroupFromConfig } from "./types";
|
|
2
|
+
export declare const group: <TName extends string, TChildren extends readonly (Command | CommandGroupConfig)[]>(config: {
|
|
3
|
+
name: TName;
|
|
4
|
+
children: TChildren;
|
|
5
|
+
}) => {
|
|
6
|
+
name: TName;
|
|
7
|
+
} & { [K in Extract<TChildren[number], CommandGroupConfig> as K["name"]]: GroupFromConfig<K>; };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.group = void 0;
|
|
4
|
+
function isGroup(x) {
|
|
5
|
+
return (typeof x?.name === "string" && Array.isArray(x.children));
|
|
6
|
+
}
|
|
7
|
+
const groupFromConfig = (cfg) => {
|
|
8
|
+
const mapped = {};
|
|
9
|
+
for (const child of cfg.children) {
|
|
10
|
+
if (isGroup(child)) {
|
|
11
|
+
mapped[child.name] = groupFromConfig(child);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
name: cfg.name,
|
|
16
|
+
...mapped,
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
const group = (config) => {
|
|
20
|
+
const mapped = {};
|
|
21
|
+
for (const child of config.children) {
|
|
22
|
+
if (isGroup(child)) {
|
|
23
|
+
mapped[child.name] = groupFromConfig(child);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
name: config.name,
|
|
28
|
+
...mapped,
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
exports.group = group;
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { z, ZodType } from "zod";
|
|
2
2
|
import { Exception } from "../errors/types";
|
|
3
3
|
import { AsyncResult } from "../types";
|
|
4
|
+
import type { AppContext } from "../context/typing";
|
|
4
5
|
export declare function mutation<TArgs extends ZodType<any, any, any>, TOutput, TError extends Exception = Exception>(options: {
|
|
5
6
|
args: TArgs;
|
|
6
7
|
handler: (args: z.infer<TArgs>) => AsyncResult<TOutput, TError>;
|
|
7
8
|
}): (input: z.core.output<TArgs>) => AsyncResult<TOutput, TError>;
|
|
9
|
+
export declare const createMutation: <TContext extends AppContext = AppContext>() => <TArgs extends ZodType<any, any, any>, TOutput, TError extends Exception = Exception>(options: {
|
|
10
|
+
args: TArgs;
|
|
11
|
+
handler: (args: z.infer<TArgs>) => AsyncResult<TOutput, TError>;
|
|
12
|
+
}) => (input: z.core.output<TArgs>) => AsyncResult<TOutput, TError>;
|
|
13
|
+
export declare function mutationWithContext<TArgs extends ZodType<any, any, any>, TOutput, TError extends Exception = Exception, TContext extends AppContext = AppContext>(options: {
|
|
14
|
+
args: TArgs;
|
|
15
|
+
handler: (args: z.infer<TArgs>, ctx: TContext) => AsyncResult<TOutput, TError>;
|
|
16
|
+
}): (input: z.core.output<TArgs>, context?: TContext) => AsyncResult<TOutput, TError>;
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMutation = void 0;
|
|
3
4
|
exports.mutation = mutation;
|
|
5
|
+
exports.mutationWithContext = mutationWithContext;
|
|
4
6
|
const errors_1 = require("../errors");
|
|
5
7
|
const types_1 = require("../types");
|
|
6
8
|
const parse_1 = require("./parse");
|
|
9
|
+
// Mutation functions do not accept context to avoid side effects
|
|
10
|
+
// They remain pure and focused on state modification
|
|
7
11
|
function mutation(options) {
|
|
8
12
|
return (input) => {
|
|
9
13
|
const parsed = (0, parse_1.parseArgs)(options.args, input);
|
|
@@ -19,3 +23,30 @@ function mutation(options) {
|
|
|
19
23
|
});
|
|
20
24
|
};
|
|
21
25
|
}
|
|
26
|
+
// Mutation builder for consistency with query builder
|
|
27
|
+
const createMutation = () => {
|
|
28
|
+
return (options) => {
|
|
29
|
+
return mutation(options);
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
exports.createMutation = createMutation;
|
|
33
|
+
// Optional: Mutation that can access context but should not modify it
|
|
34
|
+
function mutationWithContext(options) {
|
|
35
|
+
return (input, context) => {
|
|
36
|
+
const parsed = (0, parse_1.parseArgs)(options.args, input);
|
|
37
|
+
return parsed.match({
|
|
38
|
+
onSuccess: (data) => {
|
|
39
|
+
// Use provided context or get from global context
|
|
40
|
+
const ctx = context ?? globalThis.__context;
|
|
41
|
+
return options.handler(data, ctx);
|
|
42
|
+
},
|
|
43
|
+
onFailure: (error) => {
|
|
44
|
+
const ValidationError = (0, errors_1.exception)({
|
|
45
|
+
name: "ValidationError",
|
|
46
|
+
message: error.message,
|
|
47
|
+
});
|
|
48
|
+
return Promise.resolve((0, types_1.failure)(ValidationError));
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import { z, ZodType } from "zod";
|
|
2
2
|
import { Exception } from "../errors/types";
|
|
3
3
|
import { AsyncResult } from "../types";
|
|
4
|
-
import {
|
|
4
|
+
import type { AppContext } from "../context/typing";
|
|
5
|
+
export declare function query<TArgs extends ZodType<any, any, any>, TOutput, TError extends Exception = Exception, TContext extends AppContext = AppContext>(options: {
|
|
6
|
+
args: TArgs;
|
|
7
|
+
handler: (args: z.infer<TArgs>, ctx: TContext) => AsyncResult<TOutput, TError>;
|
|
8
|
+
contextName?: string;
|
|
9
|
+
}): (input: z.infer<TArgs>, context?: TContext) => AsyncResult<TOutput, TError>;
|
|
5
10
|
export declare function query<TArgs extends ZodType<any, any, any>, TOutput, TError extends Exception = Exception>(options: {
|
|
6
11
|
args: TArgs;
|
|
7
|
-
handler: (args: z.infer<TArgs
|
|
8
|
-
}): (input: z.
|
|
12
|
+
handler: (args: z.infer<TArgs>) => AsyncResult<TOutput, TError>;
|
|
13
|
+
}): (input: z.infer<TArgs>) => AsyncResult<TOutput, TError>;
|
|
14
|
+
export declare const createQuery: <TContext extends AppContext = AppContext>() => <TArgs extends ZodType<any, any, any>, TOutput, TError extends Exception = Exception>(options: {
|
|
15
|
+
args: TArgs;
|
|
16
|
+
handler: (args: z.infer<TArgs>, ctx: TContext) => AsyncResult<TOutput, TError>;
|
|
17
|
+
}) => (input: z.core.output<TArgs>, context?: TContext | undefined) => AsyncResult<TOutput, TError>;
|
package/dist/functions/query.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createQuery = void 0;
|
|
3
4
|
exports.query = query;
|
|
4
5
|
const errors_1 = require("../errors");
|
|
5
6
|
const types_1 = require("../types");
|
|
6
7
|
const parse_1 = require("./parse");
|
|
7
|
-
const
|
|
8
|
-
//
|
|
8
|
+
const typing_1 = require("../context/typing");
|
|
9
|
+
// Implementation
|
|
9
10
|
function query(options) {
|
|
10
|
-
return (input) => {
|
|
11
|
+
return (input, context) => {
|
|
11
12
|
const parsed = (0, parse_1.parseArgs)(options.args, input);
|
|
12
13
|
return parsed.match({
|
|
13
14
|
onSuccess: (data) => {
|
|
14
|
-
|
|
15
|
+
// If context is provided, use it; otherwise get from global context
|
|
16
|
+
const ctx = context ?? (0, typing_1.getTypedContext)();
|
|
15
17
|
return options.handler(data, ctx);
|
|
16
18
|
},
|
|
17
19
|
onFailure: (error) => {
|
|
@@ -24,3 +26,10 @@ function query(options) {
|
|
|
24
26
|
});
|
|
25
27
|
};
|
|
26
28
|
}
|
|
29
|
+
// Query builder with strong typing
|
|
30
|
+
const createQuery = () => {
|
|
31
|
+
return (options) => {
|
|
32
|
+
return query(options);
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
exports.createQuery = createQuery;
|
|
@@ -2,18 +2,25 @@ import { z, ZodType } from "zod";
|
|
|
2
2
|
import { Exception } from "../errors/types";
|
|
3
3
|
import { AsyncResult, Unit } from "../types";
|
|
4
4
|
export type Command = {
|
|
5
|
-
beforeInvoke: () => Promise<
|
|
6
|
-
afterInvoke: () => Promise<
|
|
7
|
-
onSuccess: () => Promise<
|
|
5
|
+
beforeInvoke: () => Promise<void>;
|
|
6
|
+
afterInvoke: () => Promise<void>;
|
|
7
|
+
onSuccess: () => Promise<void>;
|
|
8
8
|
onError: (config: {
|
|
9
9
|
exception: Exception;
|
|
10
|
-
}) => Promise<
|
|
10
|
+
}) => Promise<void>;
|
|
11
11
|
};
|
|
12
|
-
export type
|
|
12
|
+
export type CommandGroupConfig = {
|
|
13
13
|
name: string;
|
|
14
|
-
children: (Command |
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
children: readonly (Command | CommandGroupConfig)[];
|
|
15
|
+
};
|
|
16
|
+
export type IsGroup<T> = T extends {
|
|
17
|
+
name: string;
|
|
18
|
+
children: readonly (Command | CommandGroupConfig)[];
|
|
19
|
+
} ? T : never;
|
|
20
|
+
export type GroupFromConfig<C extends CommandGroupConfig> = {
|
|
21
|
+
name: C["name"];
|
|
22
|
+
} & {
|
|
23
|
+
[K in Extract<C["children"][number], CommandGroupConfig> as K["name"]]: GroupFromConfig<K>;
|
|
17
24
|
};
|
|
18
25
|
export type Query<TArgs extends ZodType = ZodType, TError extends Exception = Exception, TOutput = Unit, TContext = {}> = (options: {
|
|
19
26
|
args: TArgs;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -18,3 +18,7 @@ __exportStar(require("./api"), exports);
|
|
|
18
18
|
__exportStar(require("./api/types"), exports);
|
|
19
19
|
__exportStar(require("./functions"), exports);
|
|
20
20
|
__exportStar(require("./types"), exports);
|
|
21
|
+
// Context and typing exports
|
|
22
|
+
__exportStar(require("./context"), exports);
|
|
23
|
+
__exportStar(require("./context/typing"), exports);
|
|
24
|
+
__exportStar(require("./context/generator"), exports);
|
package/package.json
CHANGED