mad-data-parser 0.0.1 → 0.0.2-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/mad-data-parser-0.0.2-beta.2.tgz +0 -0
  2. package/package.json +5 -33
  3. package/version.txt +1 -0
  4. package/.env.example +0 -0
  5. package/.swcrc +0 -27
  6. package/example/data/__tests__/output.ts +0 -57
  7. package/example/data/data.ts +0 -226
  8. package/example/data/output.ts +0 -74
  9. package/example/data/types.ts +0 -92
  10. package/example/example.ts +0 -26
  11. package/example/jsonPaths.data.ts +0 -13
  12. package/example/loadSchema.ts +0 -32
  13. package/jest.config.d.ts +0 -6
  14. package/jest.config.ts +0 -241
  15. package/nodemon.json +0 -27
  16. package/register.setup.jest.d.ts +0 -2
  17. package/register.setup.jest.ts +0 -19
  18. package/src/index.ts +0 -2
  19. package/src/parser/parseJsonPaths.ts +0 -136
  20. package/src/utils/graphql/index.ts +0 -51
  21. package/src/utils/jsonPath/guards.ts +0 -37
  22. package/src/utils/jsonPath/index.ts +0 -3
  23. package/src/utils/jsonPath/types.ts +0 -56
  24. package/src/utils/jsonPath/visitor.ts +0 -108
  25. package/src/utils/ts/helpers.ts +0 -13
  26. package/tsconfig.build.json +0 -19
  27. package/tsconfig.jest.json +0 -18
  28. package/tsconfig.json +0 -36
  29. /package/{dist/index.d.ts → index.d.ts} +0 -0
  30. /package/{dist/index.d.ts.map → index.d.ts.map} +0 -0
  31. /package/{dist/index.js → index.js} +0 -0
  32. /package/{dist/index.js.map → index.js.map} +0 -0
  33. /package/{dist/parser → parser}/parseJsonPaths.d.ts +0 -0
  34. /package/{dist/parser → parser}/parseJsonPaths.d.ts.map +0 -0
  35. /package/{dist/parser → parser}/parseJsonPaths.js +0 -0
  36. /package/{dist/parser → parser}/parseJsonPaths.js.map +0 -0
  37. /package/{dist/utils → utils}/graphql/index.d.ts +0 -0
  38. /package/{dist/utils → utils}/graphql/index.d.ts.map +0 -0
  39. /package/{dist/utils → utils}/graphql/index.js +0 -0
  40. /package/{dist/utils → utils}/graphql/index.js.map +0 -0
  41. /package/{dist/utils → utils}/jsonPath/guards.d.ts +0 -0
  42. /package/{dist/utils → utils}/jsonPath/guards.d.ts.map +0 -0
  43. /package/{dist/utils → utils}/jsonPath/guards.js +0 -0
  44. /package/{dist/utils → utils}/jsonPath/guards.js.map +0 -0
  45. /package/{dist/utils → utils}/jsonPath/index.d.ts +0 -0
  46. /package/{dist/utils → utils}/jsonPath/index.d.ts.map +0 -0
  47. /package/{dist/utils → utils}/jsonPath/index.js +0 -0
  48. /package/{dist/utils → utils}/jsonPath/index.js.map +0 -0
  49. /package/{dist/utils → utils}/jsonPath/types.d.ts +0 -0
  50. /package/{dist/utils → utils}/jsonPath/types.d.ts.map +0 -0
  51. /package/{dist/utils → utils}/jsonPath/types.js +0 -0
  52. /package/{dist/utils → utils}/jsonPath/types.js.map +0 -0
  53. /package/{dist/utils → utils}/jsonPath/visitor.d.ts +0 -0
  54. /package/{dist/utils → utils}/jsonPath/visitor.d.ts.map +0 -0
  55. /package/{dist/utils → utils}/jsonPath/visitor.js +0 -0
  56. /package/{dist/utils → utils}/jsonPath/visitor.js.map +0 -0
  57. /package/{dist/utils → utils}/ts/helpers.d.ts +0 -0
  58. /package/{dist/utils → utils}/ts/helpers.d.ts.map +0 -0
  59. /package/{dist/utils → utils}/ts/helpers.js +0 -0
  60. /package/{dist/utils → utils}/ts/helpers.js.map +0 -0
package/jest.config.ts DELETED
@@ -1,241 +0,0 @@
1
- /**
2
- * For a detailed explanation regarding each configuration property, visit:
3
- * https://jestjs.io/docs/configuration
4
- */
5
-
6
- const fs = require('node:fs')
7
- const { pathsToModuleNameMapper } = require('ts-jest')
8
- const JSON5 = require('json5')
9
-
10
-
11
- const jsonData = fs.readFileSync('./tsconfig.jest.json')
12
- const jscConfig = JSON5.parse(fs.readFileSync('./.swcrc').toString('utf-8'))
13
- const { compilerOptions } = JSON5.parse(jsonData.toString('utf-8'))
14
-
15
- const config = {
16
- // All imported modules in your tests should be mocked automatically
17
- // automock: false,
18
-
19
- // Stop running tests after `n` failures
20
- // bail: 0,
21
-
22
- // The directory where Jest should store its cached dependency information
23
- // cacheDirectory: "/tmp/jest_rs",
24
-
25
- // Automatically clear mock calls, instances, contexts and results before every test
26
- clearMocks: true,
27
-
28
- // Indicates whether the coverage information should be collected while executing the test
29
- collectCoverage: true,
30
-
31
- // An array of glob patterns indicating a set of files for which coverage information should be collected
32
- // collectCoverageFrom: undefined,
33
-
34
- // The directory where Jest should output its coverage files
35
- coverageDirectory: 'coverage',
36
-
37
- // An array of regexp pattern strings used to skip coverage collection
38
- coveragePathIgnorePatterns: [
39
- "/node_modules/",
40
-
41
- ],
42
-
43
- // Indicates which provider should be used to instrument code for coverage
44
- coverageProvider: 'v8',
45
-
46
- // A list of reporter names that Jest uses when writing coverage reports
47
- // coverageReporters: [
48
- // "json",
49
- // "text",
50
- // "lcov",
51
- // "clover"
52
- // ],
53
-
54
- // An object that configures minimum threshold enforcement for coverage results
55
- // coverageThreshold: undefined,
56
-
57
- // A path to a custom dependency extractor
58
- // dependencyExtractor: undefined,
59
-
60
- // Make calling deprecated APIs throw helpful error messages
61
- // errorOnDeprecated: false,
62
-
63
- // The default configuration for fake timers
64
- // fakeTimers: {
65
- // "enableGlobally": false
66
- // },
67
-
68
- // Force coverage collection from ignored files using an array of glob patterns
69
- // forceCoverageMatch: [],
70
-
71
- // A path to a module which exports an async function that is triggered once before all test suites
72
- // globalSetup: undefined,
73
-
74
- // A path to a module which exports an async function that is triggered once after all test suites
75
- // globalTeardown: undefined,
76
-
77
- // A set of global variables that need to be available in all test environments
78
- globals: {
79
-
80
- },
81
- transform: {
82
- // '^.+\\.tsx?$': ['ts-jest', {
83
- // // babel: true,
84
- // tsconfig: 'tsconfig.jest.json',
85
- // }],
86
- '^.+\\.(t|j)sx?$': ['@swc/jest',
87
- jscConfig
88
- ]
89
-
90
- },
91
-
92
- testEnvironment: 'node',
93
-
94
- // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
95
- // maxWorkers: "50%",
96
-
97
- // An array of directory names to be searched recursively up from the requiring module's location
98
- // moduleDirectories: [
99
- // "node_modules"
100
- // ],
101
-
102
- // An array of file extensions your modules use
103
- // moduleFileExtensions: [
104
- // "js",
105
- // "mjs",
106
- // "cjs",
107
- // "jsx",
108
- // "ts",
109
- // "tsx",
110
- // "json",
111
- // "node"
112
- // ],
113
-
114
- // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
115
- moduleNameMapper: {
116
- ...pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>/' }),
117
- '^~/(.*)$': '<rootDir>/src/$1',
118
- },
119
-
120
- // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
121
- // modulePathIgnorePatterns: [],
122
-
123
- // Activates notifications for test results
124
- notify: true,
125
-
126
- // An enum that specifies notification mode. Requires { notify: true }
127
- notifyMode: 'failure',
128
-
129
- // A preset that is used as a base for Jest's configuration
130
- preset: 'ts-jest',
131
-
132
- // Run tests from one or more projects
133
- // projects: undefined,
134
-
135
- // Use this configuration option to add custom reporters to Jest
136
- // reporters: undefined,
137
- reporters: [
138
- 'default',
139
- [
140
- '@jest-performance-reporter/core',
141
- {
142
- errorAfterMs: 1000,
143
- warnAfterMs: 50,
144
- logLevel: 'warn',
145
- maxItems: 1,
146
- // "jsonReportPath": "performance-report.json",
147
- // "csvReportPath": "performance-report.csv"
148
- },
149
- ],
150
- ],
151
-
152
- // Automatically reset mock state before every test
153
- // resetMocks: false,
154
-
155
- // Reset the module registry before running each individual test
156
- // resetModules: false,
157
-
158
- // A path to a custom resolver
159
- // resolver: undefined,
160
-
161
- // Automatically restore mock state and implementation before every test
162
- // restoreMocks: false,
163
-
164
- // The root directory that Jest should scan for tests and modules within
165
- rootDir: './',
166
-
167
- // A list of paths to directories that Jest should use to search for files in
168
- // roots: [
169
- // "<rootDir>"
170
- // ],
171
-
172
- // Allows you to use a custom runner instead of Jest's default test runner
173
- // runner: "jest-runner",
174
-
175
- // The paths to modules that run some code to configure or set up the testing environment before each test
176
- setupFiles: [
177
- "./register.setup.jest.ts"
178
- ],
179
-
180
- // A list of paths to modules that run some code to configure or set up the testing framework before each test
181
- // setupFilesAfterEnv: [],
182
-
183
- // The number of seconds after which a test is considered as slow and reported as such in the results.
184
- // slowTestThreshold: 5,
185
-
186
- // A list of paths to snapshot serializer modules Jest should use for snapshot testing
187
- // snapshotSerializers: [],
188
-
189
- // The test environment that will be used for testing
190
- // testEnvironment: "jest-environment-node",
191
-
192
- // Options that will be passed to the testEnvironment
193
- // testEnvironmentOptions: {},
194
-
195
- // Adds a location field to test results
196
- // testLocationInResults: false,
197
-
198
- // The glob patterns Jest uses to detect test files
199
- testMatch: [
200
- "**/src/**/__tests__/**/*.[jt]s?(x)",
201
- "**/src/**/?(*.)+(spec|test).[tj]s?(x)"
202
- ],
203
-
204
- // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
205
- testPathIgnorePatterns: [
206
- '/node_modules/',
207
- '/dist/',
208
- ],
209
-
210
- // The regexp pattern or array of patterns that Jest uses to detect test files
211
- // testRegex: [],
212
-
213
- // This option allows the use of a custom results processor
214
- // testResultsProcessor: undefined,
215
-
216
- // This option allows use of a custom test runner
217
- // testRunner: "jest-circus/runner",
218
-
219
- // A map from regular expressions to paths to transformers
220
- // transform: undefined,
221
-
222
- // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
223
- transformIgnorePatterns: [
224
- '/node_modules/',
225
- '\\.pnp\\.[^\\/]+$',
226
- ],
227
-
228
- // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
229
- // unmockedModulePathPatterns: undefined,
230
-
231
- // Indicates whether each individual test should be reported during the run
232
- // verbose: undefined,
233
-
234
- // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
235
- // watchPathIgnorePatterns: [],
236
-
237
- // Whether to use watchman for file crawling
238
- // watchman: true,
239
- }
240
-
241
- module.exports = config
package/nodemon.json DELETED
@@ -1,27 +0,0 @@
1
- {
2
- "verbose": false,
3
- "ignore": [
4
- ".git",
5
- "node_modules",
6
- "./.*",
7
- "./var/**/*",
8
- "./docker-compose/**"
9
- ],
10
- "watch": [
11
- "**/*"
12
- ],
13
- "ext": "js ts gql",
14
- "signal": "SIGQUIT",
15
- "execMap": {
16
- "ts": "NODE_ENV=${NODE_ENV:-development} NODE_OPTIONS='--max-http-header-size=65535' UWS_HTTP_MAX_HEADERS_SIZE=65535 tsx --trace-warnings --trace-uncaught"
17
-
18
- },
19
- "spawn": false,
20
- "delay": "200",
21
- "legacyWatch": false,
22
-
23
- "events": {
24
-
25
- }
26
-
27
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=register.setup.jest.d.ts.map
@@ -1,19 +0,0 @@
1
-
2
- // import {jest} from '@jest/globals'
3
-
4
- import path from 'path'
5
-
6
-
7
-
8
-
9
- import glob from 'fast-glob'
10
- // jest.mock('~/config/AWS')
11
-
12
-
13
-
14
-
15
-
16
- glob.sync('src/**/__mock__/**/*.ts', {cwd: process.cwd()}).forEach(file => {
17
- require(path.join(process.cwd(), file))
18
- })
19
-
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from '~/parser/parseJsonPaths'
2
-
@@ -1,136 +0,0 @@
1
- import { getNamedType, GraphQLSchema, isObjectType, isUnionType } from "graphql"
2
- import type { DocumentNode, GraphQLObjectType, GraphQLOutputType, SelectionSetNode, FragmentDefinitionNode, FieldNode, InlineFragmentNode } from "graphql"
3
-
4
- import { createFieldNode, createInlineFragment, findFieldNode, isPrimitiveType } from "~/utils/graphql"
5
- import { Kind } from "graphql"
6
- import * as JSONPath from '~/utils/jsonPath'
7
-
8
-
9
- type StackItem = {type: GraphQLOutputType, selectionSet: SelectionSetNode, parent: StackItem|null}
10
- const typeNameFieldNode = createFieldNode('__typename')
11
-
12
- export function parseJsonPaths(jsonPaths:Array<JSONPath.ASTNode[]>, rootType: GraphQLObjectType, fragmentName?: string): DocumentNode {
13
- fragmentName = fragmentName ?? `autoGen${rootType.name}`
14
-
15
- const rootFragment:FragmentDefinitionNode = {
16
- kind: Kind.FRAGMENT_DEFINITION,
17
- typeCondition: { kind: Kind.NAMED_TYPE, name: { kind: Kind.NAME, value: rootType.name } },
18
- name: { kind: Kind.NAME, value: fragmentName },
19
- selectionSet: {
20
- kind: Kind.SELECTION_SET,
21
- selections: [typeNameFieldNode],
22
- } satisfies SelectionSetNode,
23
- }
24
-
25
- const doc: DocumentNode = {
26
- kind: Kind.DOCUMENT,
27
- definitions: [rootFragment],
28
- }
29
- const stack: Array<StackItem[]> = []
30
- const visitor: JSONPath.NodeVisitor = {
31
- Root() {
32
- stack.push([{type: rootType, selectionSet: rootFragment.selectionSet!, parent: null}])
33
- return
34
- },
35
- Identifier(node) {
36
- const stackItems = stack[stack.length - 1]!
37
- const passStackItems = processStackItems(stackItems, {fieldName: node.expression.value!, value: undefined, condition: undefined})
38
- stack.push(passStackItems)
39
- return
40
- },
41
- FilterExpression(node) {
42
- const stackItems = stack[stack.length - 1]!
43
- const regex = /\?\(@\.(?<field>\w+)(\s*(?<condition>(?:==|!=)=?)\s*(?<quote>'|")(?<value>.*?)(\4))?/
44
- const matches = node.expression.value!.match(regex)
45
- const fieldName = matches?.groups?.field ?? '__typename'
46
- const condition = matches?.groups?.condition
47
- const value = matches?.groups?.value
48
- const passStackItems = processStackItems(stackItems, {fieldName, value, condition})
49
- stack.push(passStackItems)
50
- return
51
- },
52
- leave(node, parent, path, ancestors) {
53
- if(needProcess(node)) {
54
- stack.pop()
55
- }
56
- }
57
- }
58
- JSONPath.visit(jsonPaths, visitor)
59
- return doc
60
- }
61
-
62
- function needProcess(node:JSONPath.ASTNode):boolean {
63
- return JSONPath.isRootNode(node) || JSONPath.isIdentifierNode(node) || JSONPath.isFilterExpressionNode(node)
64
- }
65
-
66
-
67
-
68
-
69
- function processStackItems(stackItems: StackItem[], {fieldName, value, condition}: {fieldName: string, value?: string, condition?: string}) {
70
- const passStackItems: StackItem[] = []
71
- stackItems.forEach(stackItem => {
72
- const parentType = stackItem.type
73
- if(isPrimitiveType(parentType)) {
74
- return
75
- }
76
- const selSet = stackItem.selectionSet
77
- if (isUnionType(parentType)) {
78
- const filterField = (type: GraphQLObjectType) => fieldName === '__typename'? type.name === value : Boolean(type.getFields()[fieldName!])
79
- const filter = condition && !condition.includes('!')
80
- ? (type: GraphQLObjectType) => filterField(type)
81
- : (type: GraphQLObjectType) => !filterField(type)
82
- const possibleTypes = parentType.getTypes().filter(filter)
83
- possibleTypes.forEach(type => {
84
- let inlineFragment:InlineFragmentNode|undefined = selSet.selections.find(
85
- selection => selection.kind === Kind.INLINE_FRAGMENT
86
- && (selection.typeCondition?.name.value === type.name)
87
- ) as InlineFragmentNode|undefined
88
-
89
- if (!inlineFragment) {
90
- inlineFragment = createInlineFragment(type, '__typename')
91
- ;(selSet.selections as any[]).push(inlineFragment)
92
- }
93
- const fragmentStackItem = {type: type, selectionSet: inlineFragment.selectionSet!, parent: stackItem}
94
- const appendFieldType = type.getFields()[fieldName!]?.type
95
- if(!appendFieldType) {
96
- if (fieldName === '__typename') {
97
- passStackItems.push(fragmentStackItem)
98
- }
99
- return
100
- }
101
- const newStackItem = processGraphqlObjectType(fragmentStackItem, appendFieldType, fieldName!)
102
- passStackItems.push(newStackItem)
103
- })
104
- return;
105
- }
106
- const parentObjectType = isObjectType(parentType) ? parentType : stackItem.parent?.type as GraphQLObjectType|undefined
107
- if (!parentObjectType) return;
108
- const field = parentObjectType.getFields()[fieldName!]
109
- if(!field) {
110
- return
111
- }
112
- const newStackItem = processGraphqlObjectType(stackItem, field.type, fieldName!)
113
- passStackItems.push(newStackItem)
114
-
115
- })
116
- return passStackItems
117
- }
118
-
119
-
120
-
121
- function processGraphqlObjectType(stackItem: StackItem, fieldType: GraphQLOutputType, fieldName: string): StackItem {
122
- const selSet = stackItem.selectionSet
123
- if(!selSet){
124
- throw new Error('Selection set not found')
125
- }
126
- const realFieldType = getNamedType(fieldType)
127
- const subFieldsSelections = [isPrimitiveType(realFieldType) ? undefined : typeNameFieldNode].filter(Boolean) as FieldNode[]
128
- let fieldNode = findFieldNode(selSet, fieldName)
129
- if(!fieldNode) {
130
- fieldNode = createFieldNode(fieldName, subFieldsSelections.map(selection => selection.name.value!))
131
- ;(selSet.selections as any[]).push(fieldNode)
132
- }
133
- return {type: realFieldType, selectionSet: fieldNode.selectionSet!, parent: stackItem}
134
- }
135
-
136
-
@@ -1,51 +0,0 @@
1
- import { getNamedType, isScalarType, isEnumType, Kind } from "graphql"
2
- import type { GraphQLOutputType, SelectionSetNode, FieldNode, InlineFragmentNode, GraphQLNamedOutputType, SelectionNode } from "graphql"
3
-
4
-
5
- export function isPrimitiveType(type: GraphQLOutputType): boolean {
6
- const namedType = getNamedType(type)
7
- return isScalarType(namedType) || isEnumType(namedType)
8
- }
9
-
10
- export function findFieldNode(selectionSet: SelectionSetNode, fieldName: string):FieldNode|undefined {
11
- return selectionSet?.selections.find(selection => selection.kind === Kind.FIELD && selection.name.value === fieldName) as FieldNode|undefined
12
- }
13
-
14
-
15
- export function createFieldNode(fieldName: string, children?: string[]):FieldNode {
16
- let selectionSet: SelectionSetNode|undefined = undefined
17
- if(children?.length) {
18
- selectionSet = {
19
- kind: Kind.SELECTION_SET,
20
- selections: children.map(child => createFieldNode(child)),
21
- } satisfies SelectionSetNode
22
- }
23
- return {
24
- kind: Kind.FIELD,
25
- name: { kind: Kind.NAME, value: fieldName },
26
- selectionSet
27
- }
28
- }
29
-
30
-
31
-
32
- export function createFieldSelectionSet(outputType: GraphQLNamedOutputType, fieldName?: string):SelectionSetNode {
33
- const ret = {
34
- kind: Kind.SELECTION_SET,
35
- selections: [fieldName ? createFieldNode(fieldName): undefined].filter(Boolean) as SelectionNode[],
36
- } satisfies SelectionSetNode
37
-
38
- if (!isPrimitiveType(outputType) && !ret.selections.find(selection => selection.kind === Kind.FIELD && selection.name.value === '__typename')) {
39
- ret.selections.unshift(createFieldNode('__typename'))
40
- }
41
- return ret
42
- }
43
-
44
-
45
- export function createInlineFragment(outputType: GraphQLNamedOutputType, fieldName: string):InlineFragmentNode {
46
- return {
47
- kind: Kind.INLINE_FRAGMENT,
48
- typeCondition: { kind: Kind.NAMED_TYPE, name: { kind: Kind.NAME, value: outputType.name } },
49
- selectionSet: createFieldSelectionSet(outputType, fieldName),
50
- } satisfies InlineFragmentNode
51
- }
@@ -1,37 +0,0 @@
1
-
2
- import type { BaseNode, IdentifierNode, ASTNode, NumericLiteralNode, FilterExpressionNode, ScriptExpressionNode, StringLiteralNode, WildcardNode, SliceNode, RootNode } from "./types"
3
-
4
- export function isAstNode(node: unknown): node is ASTNode {
5
- return typeof node === 'object' && node !== null && 'expression' in node && typeof node.expression === 'object' && node.expression !== null && 'type' in node.expression && typeof node.expression.type === 'string'
6
- }
7
- export function isBaseNode(node: ASTNode): node is BaseNode {
8
- return isAstNode(node) && 'operation' in node && typeof node.operation === 'string' && 'scope' in node && typeof node.scope === 'string'
9
- }
10
- export function isIdentifierNode(node: ASTNode): node is IdentifierNode {
11
- return isBaseNode(node) && node.operation === 'member' && node.expression.type === 'identifier'
12
- }
13
- export function isNumericLiteralNode(node: ASTNode): node is NumericLiteralNode {
14
- return isBaseNode(node) && node.operation === 'subscript' && node.expression.type === 'numeric_literal'
15
- }
16
- export function isFilterExpressionNode(node: ASTNode): node is FilterExpressionNode {
17
- return isBaseNode(node) && node.operation === 'subscript' && node.expression.type === 'filter_expression'
18
- }
19
- export function isScriptExpressionNode(node: ASTNode): node is ScriptExpressionNode {
20
- return isBaseNode(node) && node.operation === 'subscript' && node.expression.type === 'script_expression'
21
- }
22
- export function isStringLiteralNode(node: ASTNode): node is StringLiteralNode {
23
- return isBaseNode(node) && node.operation === 'subscript' && node.expression.type === 'string_literal'
24
- }
25
- export function isWildcardNode(node: ASTNode): node is WildcardNode {
26
- return isBaseNode(node) && node.operation === 'subscript' && node.expression.type === 'wildcard'
27
- }
28
- export function isSliceNode(node: ASTNode): node is SliceNode {
29
- return isBaseNode(node) && node.operation === 'subscript' && node.expression.type === 'slice'
30
- }
31
- export function isRootNode(node: ASTNode): node is RootNode {
32
- return isAstNode(node) && node.expression.type === 'root' && node.expression.value === '$'
33
- }
34
-
35
- export function isJSONPath(nodes: unknown): nodes is ASTNode[] {
36
- return Array.isArray(nodes) && nodes.every(node => isAstNode(node))
37
- }
@@ -1,3 +0,0 @@
1
- export * from './types'
2
- export * from './guards'
3
- export * from './visitor'
@@ -1,56 +0,0 @@
1
- export interface ASTNode {
2
- expression: Expression
3
- }
4
-
5
- export type ExpressionType = 'root' | 'identifier' | 'numeric_literal' | 'filter_expression' | 'script_expression' | 'string_literal' | 'wildcard' | 'slice'
6
- export type ExpressionValue = string | number | undefined
7
-
8
- interface BuildExpression<T extends ExpressionType = ExpressionType, V extends ExpressionValue = ExpressionValue> {
9
- type: T
10
- value: V
11
- }
12
- /** expression types */
13
- export type Expression = BuildExpression<ExpressionType, ExpressionValue>
14
- export type RootExpression = BuildExpression<'root', '$'>
15
- export type IdentifierExpression = BuildExpression<'identifier', string>
16
- export type NumericLiteralExpression = BuildExpression<'numeric_literal', number>
17
- export type FilterExpressionExpression = BuildExpression<'filter_expression', `?(${string})`>
18
- export type ScriptExpressionExpression = BuildExpression<'script_expression', string>
19
- export type StringLiteralExpression = BuildExpression<'string_literal', string>
20
- export type WildcardExpression = BuildExpression<'wildcard', '*'>
21
- export type SliceExpression = BuildExpression<'slice', `${number|''}:${number|''}`>
22
-
23
- /** node types */
24
- export interface RootNode extends ASTNode {
25
- expression: RootExpression
26
- }
27
- export interface BaseNode<T extends 'member' | 'subscript' = 'member'|'subscript'> extends ASTNode {
28
- operation: T
29
- scope: 'child' | 'descendant' | 'parent'
30
- }
31
- export interface IdentifierNode extends BaseNode<'member'> {
32
- expression: IdentifierExpression
33
- }
34
- export interface NumericLiteralNode extends BaseNode<'subscript'> {
35
- expression: NumericLiteralExpression
36
- }
37
- export interface FilterExpressionNode extends BaseNode<'subscript'> {
38
- expression: FilterExpressionExpression
39
- }
40
- export interface ScriptExpressionNode extends BaseNode<'subscript'> {
41
- expression: ScriptExpressionExpression
42
- }
43
- export interface StringLiteralNode extends BaseNode<'subscript'> {
44
- expression: StringLiteralExpression
45
- }
46
- export interface WildcardNode extends BaseNode<'subscript'> {
47
- expression: WildcardExpression
48
- }
49
- export interface SliceNode extends BaseNode<'subscript'> {
50
- expression: SliceExpression
51
- }
52
-
53
-
54
-
55
-
56
-