@stonecrop/rockfoil 0.7.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.
@@ -0,0 +1 @@
1
+ {"version":"5.9.3"}
@@ -0,0 +1,3 @@
1
+ export * from './middleware/postgraphile';
2
+ export * from './types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAA;AACzC,cAAc,SAAS,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './middleware/postgraphile';
2
+ export * from './types';
@@ -0,0 +1,7 @@
1
+ import type { HookConfig } from '../types';
2
+ /**
3
+ * Creates a PostGraphile plugin that wraps GraphQL query and mutation plans with before/after hooks
4
+ * @public
5
+ */
6
+ export declare const createPglRockfoilPlugin: (hookMap: HookConfig) => GraphileConfig.Plugin;
7
+ //# sourceMappingURL=postgraphile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgraphile.d.ts","sourceRoot":"","sources":["../../../src/middleware/postgraphile.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,UAAU,CAAA;AAEpD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAAI,SAAS,UAAU,0BAoD1D,CAAA"}
@@ -0,0 +1,49 @@
1
+ import { wrapPlans } from 'postgraphile/utils';
2
+ /**
3
+ * Creates a PostGraphile plugin that wraps GraphQL query and mutation plans with before/after hooks
4
+ * @public
5
+ */
6
+ export const createPglRockfoilPlugin = (hookMap) => {
7
+ const queryPlans = {};
8
+ const mutationPlans = {};
9
+ for (const [fieldname, plans] of Object.entries(hookMap)) {
10
+ if (plans.beforeQuery || plans.afterQuery) {
11
+ queryPlans[fieldname] = {
12
+ plan: (plan, $source, fieldArgs, info) => {
13
+ // Process before query hooks
14
+ if (plans.beforeQuery) {
15
+ plans.beforeQuery(plan, $source, fieldArgs, info);
16
+ }
17
+ // Execute the query plan
18
+ let $result = plan();
19
+ // Process after query hooks
20
+ if (plans.afterQuery) {
21
+ $result = plans.afterQuery($result, plan, $source, fieldArgs, info);
22
+ }
23
+ return $result;
24
+ },
25
+ };
26
+ }
27
+ if (plans.beforeMutation || plans.afterMutation) {
28
+ mutationPlans[fieldname] = {
29
+ plan: (plan, $source, fieldArgs, info) => {
30
+ // Process before mutation hooks
31
+ if (plans.beforeMutation) {
32
+ plans.beforeMutation(plan, $source, fieldArgs, info);
33
+ }
34
+ // Execute the mutation plan
35
+ let $result = plan();
36
+ // Process after mutation hooks
37
+ if (plans.afterMutation) {
38
+ $result = plans.afterMutation($result, plan, $source, fieldArgs, info);
39
+ }
40
+ return $result;
41
+ },
42
+ };
43
+ }
44
+ }
45
+ return wrapPlans({
46
+ Query: queryPlans,
47
+ Mutation: mutationPlans,
48
+ });
49
+ };
@@ -0,0 +1,32 @@
1
+ import type { ExecutableStep, FieldArgs, FieldInfo } from 'postgraphile/grafast';
2
+ import type { PlanWrapperFn, PlanWrapperRule } from 'postgraphile/utils';
3
+ /**
4
+ * Configuration object mapping field names to their before/after hooks for queries and mutations
5
+ * @public
6
+ */
7
+ export interface HookConfig {
8
+ /**
9
+ * Hook configuration for a specific field
10
+ */
11
+ [fieldName: string]: {
12
+ /** Function to execute before a query operation */
13
+ beforeQuery?: PlanWrapperFn;
14
+ /** Function to execute after a query operation */
15
+ afterQuery?: (result: any, plan: any, $source: ExecutableStep, fieldArgs: FieldArgs, info: FieldInfo) => any;
16
+ /** Function to execute before a mutation operation */
17
+ beforeMutation?: PlanWrapperFn;
18
+ /** Function to execute after a mutation operation */
19
+ afterMutation?: (result: any, plan: any, $source: ExecutableStep, fieldArgs: FieldArgs, info: FieldInfo) => any;
20
+ };
21
+ }
22
+ /**
23
+ * Internal mapping of field names to their plan wrapper rules
24
+ * @public
25
+ */
26
+ export interface HookPlan {
27
+ /**
28
+ * Plan wrapper rule for a specific field
29
+ */
30
+ [fieldName: string]: PlanWrapperRule;
31
+ }
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAExE;;;GAGG;AACH,MAAM,WAAW,UAAU;IAC1B;;OAEG;IACH,CAAC,SAAS,EAAE,MAAM,GAAG;QACpB,mDAAmD;QACnD,WAAW,CAAC,EAAE,aAAa,CAAA;QAC3B,kDAAkD;QAClD,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,KAAK,GAAG,CAAA;QAC5G,sDAAsD;QACtD,cAAc,CAAC,EAAE,aAAa,CAAA;QAC9B,qDAAqD;QACrD,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,KAAK,GAAG,CAAA;KAC/G,CAAA;CACD;AAED;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACxB;;OAEG;IACH,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,CAAA;CACpC"}
File without changes
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=postgraphile.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgraphile.test.d.ts","sourceRoot":"","sources":["../../tests/postgraphile.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,58 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ // Mock postgraphile/utils with a simple implementation
3
+ vi.mock('postgraphile/utils', () => ({
4
+ wrapPlans: (config) => ({
5
+ name: 'TestPlugin',
6
+ version: '1.0.0',
7
+ _config: config, // Store config for testing
8
+ }),
9
+ }));
10
+ import { createPglRockfoilPlugin } from '../src/middleware/postgraphile';
11
+ describe('Rockfoil PostGraphile Plugin', () => {
12
+ describe('createPglRockfoilPlugin', () => {
13
+ it('should create a valid plugin with empty hook map', () => {
14
+ const plugin = createPglRockfoilPlugin({});
15
+ expect(plugin).toBeDefined();
16
+ expect(plugin.name).toBe('TestPlugin');
17
+ expect(plugin.version).toBe('1.0.0');
18
+ });
19
+ it('should create a plugin with query hooks', () => {
20
+ const hookMap = {
21
+ testField: {
22
+ beforeQuery: vi.fn(),
23
+ afterQuery: vi.fn(),
24
+ },
25
+ };
26
+ const plugin = createPglRockfoilPlugin(hookMap);
27
+ expect(plugin).toBeDefined();
28
+ expect(plugin.name).toBe('TestPlugin');
29
+ });
30
+ it('should create a plugin with mutation hooks', () => {
31
+ const hookMap = {
32
+ createTest: {
33
+ beforeMutation: vi.fn(),
34
+ afterMutation: vi.fn(),
35
+ },
36
+ };
37
+ const plugin = createPglRockfoilPlugin(hookMap);
38
+ expect(plugin).toBeDefined();
39
+ expect(plugin.name).toBe('TestPlugin');
40
+ });
41
+ it('should handle complex hook map', () => {
42
+ const hookMap = {
43
+ field1: {
44
+ beforeQuery: vi.fn(),
45
+ },
46
+ field2: {
47
+ afterQuery: vi.fn(),
48
+ },
49
+ field3: {
50
+ beforeMutation: vi.fn(),
51
+ afterMutation: vi.fn(),
52
+ },
53
+ };
54
+ const plugin = createPglRockfoilPlugin(hookMap);
55
+ expect(plugin).toBeDefined();
56
+ });
57
+ });
58
+ });
@@ -0,0 +1,11 @@
1
+ // This file is read by tools that parse documentation comments conforming to the TSDoc standard.
2
+ // It should be published with your NPM package. It should not be tracked by Git.
3
+ {
4
+ "tsdocVersion": "0.12",
5
+ "toolPackages": [
6
+ {
7
+ "packageName": "@microsoft/api-extractor",
8
+ "packageVersion": "7.55.2"
9
+ }
10
+ ]
11
+ }
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@stonecrop/rockfoil",
3
+ "version": "0.7.0",
4
+ "license": "MIT",
5
+ "type": "module",
6
+ "author": {
7
+ "name": "Tyler Matteson",
8
+ "email": "tyler@agritheory.com"
9
+ },
10
+ "homepage": "https://github.com/agritheory/rockfoil#readme",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/agritheory/stonecrop",
14
+ "directory": "rockfoil"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/agritheory/stonecrop/issues"
18
+ },
19
+ "exports": {
20
+ ".": {
21
+ "import": {
22
+ "types": "./dist/src/index.d.ts",
23
+ "default": "./dist/rockfoil.js"
24
+ },
25
+ "require": "./dist/rockfoil.umd.cjs"
26
+ },
27
+ "./types": {
28
+ "import": "./dist/src/types/index.d.ts",
29
+ "require": "./dist/src/types/index.d.ts"
30
+ },
31
+ "./styles": "./dist/assets/index.css"
32
+ },
33
+ "typings": "./dist/index.d.ts",
34
+ "files": [
35
+ "dist/*",
36
+ "src/*"
37
+ ],
38
+ "dependencies": {
39
+ "graphql": "^16.12.0",
40
+ "postgraphile": "^5.0.0-rc.3"
41
+ },
42
+ "devDependencies": {
43
+ "@rushstack/heft": "^1.1.7",
44
+ "@types/node": "^22.19.5",
45
+ "@vitest/coverage-istanbul": "^4.0.17",
46
+ "@vitest/ui": "^4.0.17",
47
+ "graphile-build": "^5.0.0-rc.2",
48
+ "jsdom": "^27.4.0",
49
+ "madr": "^4.0.0",
50
+ "typescript": "^5.9.3",
51
+ "vite": "^7.3.1",
52
+ "vitest": "^4.0.17",
53
+ "stonecrop-rig": "0.2.22"
54
+ },
55
+ "engines": {
56
+ "node": ">=22.5.0"
57
+ },
58
+ "scripts": {
59
+ "_phase:build": "heft build && vite build && rushx docs",
60
+ "prepublish": "heft build && vite build && rushx docs",
61
+ "build": "heft build && vite build && rushx docs",
62
+ "dev": "vite",
63
+ "docs": "bash ../common/scripts/run-docs.sh rockfoil",
64
+ "lint": "eslint .",
65
+ "preview": "vite preview",
66
+ "test": "vitest run --coverage.enabled false",
67
+ "test:watch": "vitest watch",
68
+ "test:coverage": "vitest run --coverage",
69
+ "test:ui": "vitest --ui"
70
+ }
71
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './middleware/postgraphile'
2
+ export * from './types'
@@ -0,0 +1,61 @@
1
+ import { wrapPlans } from 'postgraphile/utils'
2
+
3
+ import type { HookConfig, HookPlan } from '../types'
4
+
5
+ /**
6
+ * Creates a PostGraphile plugin that wraps GraphQL query and mutation plans with before/after hooks
7
+ * @public
8
+ */
9
+ export const createPglRockfoilPlugin = (hookMap: HookConfig) => {
10
+ const queryPlans: HookPlan = {}
11
+ const mutationPlans: HookPlan = {}
12
+
13
+ for (const [fieldname, plans] of Object.entries(hookMap)) {
14
+ if (plans.beforeQuery || plans.afterQuery) {
15
+ queryPlans[fieldname] = {
16
+ plan: (plan, $source, fieldArgs, info) => {
17
+ // Process before query hooks
18
+ if (plans.beforeQuery) {
19
+ plans.beforeQuery(plan, $source, fieldArgs, info)
20
+ }
21
+
22
+ // Execute the query plan
23
+ let $result = plan()
24
+
25
+ // Process after query hooks
26
+ if (plans.afterQuery) {
27
+ $result = plans.afterQuery($result, plan, $source, fieldArgs, info)
28
+ }
29
+
30
+ return $result
31
+ },
32
+ }
33
+ }
34
+
35
+ if (plans.beforeMutation || plans.afterMutation) {
36
+ mutationPlans[fieldname] = {
37
+ plan: (plan, $source, fieldArgs, info) => {
38
+ // Process before mutation hooks
39
+ if (plans.beforeMutation) {
40
+ plans.beforeMutation(plan, $source, fieldArgs, info)
41
+ }
42
+
43
+ // Execute the mutation plan
44
+ let $result = plan()
45
+
46
+ // Process after mutation hooks
47
+ if (plans.afterMutation) {
48
+ $result = plans.afterMutation($result, plan, $source, fieldArgs, info)
49
+ }
50
+
51
+ return $result
52
+ },
53
+ }
54
+ }
55
+ }
56
+
57
+ return wrapPlans({
58
+ Query: queryPlans,
59
+ Mutation: mutationPlans,
60
+ })
61
+ }
@@ -0,0 +1,33 @@
1
+ import type { ExecutableStep, FieldArgs, FieldInfo } from 'postgraphile/grafast'
2
+ import type { PlanWrapperFn, PlanWrapperRule } from 'postgraphile/utils'
3
+
4
+ /**
5
+ * Configuration object mapping field names to their before/after hooks for queries and mutations
6
+ * @public
7
+ */
8
+ export interface HookConfig {
9
+ /**
10
+ * Hook configuration for a specific field
11
+ */
12
+ [fieldName: string]: {
13
+ /** Function to execute before a query operation */
14
+ beforeQuery?: PlanWrapperFn
15
+ /** Function to execute after a query operation */
16
+ afterQuery?: (result: any, plan: any, $source: ExecutableStep, fieldArgs: FieldArgs, info: FieldInfo) => any
17
+ /** Function to execute before a mutation operation */
18
+ beforeMutation?: PlanWrapperFn
19
+ /** Function to execute after a mutation operation */
20
+ afterMutation?: (result: any, plan: any, $source: ExecutableStep, fieldArgs: FieldArgs, info: FieldInfo) => any
21
+ }
22
+ }
23
+
24
+ /**
25
+ * Internal mapping of field names to their plan wrapper rules
26
+ * @public
27
+ */
28
+ export interface HookPlan {
29
+ /**
30
+ * Plan wrapper rule for a specific field
31
+ */
32
+ [fieldName: string]: PlanWrapperRule
33
+ }