diff --git a/package-lock.json b/package-lock.json index 4f9e64c..39d7f73 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@apexlang/core", - "version": "0.0.16", + "version": "0.0.20", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@apexlang/core", - "version": "0.0.16", + "version": "0.0.20", "license": "Apache-2.0", "devDependencies": { "@typescript-eslint/eslint-plugin": "^4.22.0", diff --git a/package.json b/package.json index c00778d..873f76f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apexlang/core", - "version": "0.0.20", + "version": "0.0.21", "description": "Apex language JavaScript support", "keywords": [ "apex", diff --git a/src/model/visitor.ts b/src/model/visitor.ts index 4564636..634b808 100644 --- a/src/model/visitor.ts +++ b/src/model/visitor.ts @@ -109,6 +109,20 @@ class ErrorHolder { } } +function dummyValue(fieldName: string): T { + return new Proxy( + {}, + { + get: function (target, name, receiver) { + throw new Error(`${fieldName} is not available in this scope`); + }, + set: function (target, name, value, receiver) { + throw new Error(`${fieldName} is not available in this scope`); + }, + } + ) as T; +} + export class Context { config: ObjectMap; document?: Document; @@ -119,26 +133,26 @@ export class Context { // Drill-down definitions namespace: Namespace; namespacePos: number = 9999; - directive?: Directive; - alias?: Alias; - interface?: Interface; - role?: Role; - type?: MObject; - operations?: Operation[]; - operation?: Operation; - parameters?: Parameter[]; - parameter?: Parameter; - parameterIndex?: number; - fields?: Field[]; - field?: Field; - fieldIndex?: number; - enum?: Enum; - enumValues?: EnumValue[]; - enumValue?: EnumValue; - union?: Union; - - annotations?: Annotation[]; - annotation?: Annotation; + directive: Directive = dummyValue("directive"); + alias: Alias = dummyValue("alias"); + interface: Interface = dummyValue("interface"); + role: Role = dummyValue("role"); + type: MObject = dummyValue("type"); + operations: Operation[] = dummyValue("operations"); + operation: Operation = dummyValue("operation"); + parameters: Parameter[] = dummyValue("parameters"); + parameter: Parameter = dummyValue("parameter"); + parameterIndex: number = 9999; + fields: Field[] = dummyValue("fields"); + field: Field = dummyValue("fields"); + fieldIndex: number = 9999; + enum: Enum = dummyValue("enum"); + enumValues: EnumValue[] = dummyValue("enumValues"); + enumValue: EnumValue = dummyValue("enumValue"); + union: Union = dummyValue("union"); + + annotations: Annotation[] = dummyValue("annotations"); + annotation: Annotation = dummyValue("annotation"); private errors: ErrorHolder; private typeMap: { @@ -270,7 +284,7 @@ export class Context { throw new Error("namespace not found"); } - this.document!.definitions.forEach((value, index) => { + this.document!.definitions.forEach((value) => { switch (value.getKind()) { case Kind.DirectiveDefinition: const directiveDef = value as DirectiveDefinition; @@ -328,6 +342,44 @@ export class Context { break; } }); + + // Reorder all types per the contents of the spec document. + this.document!.definitions.forEach((value) => { + switch (value.getKind()) { + case Kind.AliasDefinition: + const aliasDef = value as AliasDefinition; + const a = this.namespace.aliases[aliasDef.name.value]; + delete this.namespace.aliases[a.name]; + delete this.namespace.allTypes[a.name]; + this.namespace.aliases[a.name] = a; + this.namespace.allTypes[a.name] = a; + break; + case Kind.TypeDefinition: + const typeDef = value as TypeDefinition; + const t = this.namespace.types[typeDef.name.value]; + delete this.namespace.types[t.name]; + delete this.namespace.allTypes[t.name]; + this.namespace.types[t.name] = t; + this.namespace.allTypes[t.name] = t; + break; + case Kind.EnumDefinition: + const enumDef = value as EnumDefinition; + const e = this.namespace.enums[enumDef.name.value]; + delete this.namespace.enums[e.name]; + delete this.namespace.allTypes[e.name]; + this.namespace.enums[e.name] = e; + this.namespace.allTypes[e.name] = e; + break; + case Kind.UnionDefinition: + const unionDef = value as UnionDefinition; + const u = this.namespace.unions[unionDef.name.value]; + delete this.namespace.unions[u.name]; + delete this.namespace.allTypes[u.name]; + this.namespace.unions[u.name] = u; + this.namespace.allTypes[u.name] = u; + break; + } + }); } reportError(error: ApexError): void { @@ -363,37 +415,37 @@ export class Context { this.getType.bind(this), anyTypeDef as AliasDefinition ); - this.namespace!.aliases[name] = alias; - this.namespace!.allTypes[name] = alias; + this.namespace.aliases[name] = alias; + this.namespace.allTypes[name] = alias; return alias; case ASTKind.TypeDefinition: const type = new MObject( this.getType.bind(this), anyTypeDef as TypeDefinition ); - this.namespace!.types[name] = type; - this.namespace!.allTypes[name] = type; + this.namespace.types[name] = type; + this.namespace.allTypes[name] = type; return type; case ASTKind.UnionDefinition: const union = new Union( this.getType.bind(this), anyTypeDef as UnionDefinition ); - this.namespace!.unions[name] = union; - this.namespace!.allTypes[name] = union; + this.namespace.unions[name] = union; + this.namespace.allTypes[name] = union; return union; case ASTKind.EnumDefinition: const enumDef = (namedType = new Enum( this.getType.bind(this), anyTypeDef as EnumDefinition )); - this.namespace!.enums[name] = enumDef; - this.namespace!.allTypes[name] = enumDef; + this.namespace.enums[name] = enumDef; + this.namespace.allTypes[name] = enumDef; return enumDef; } if (namedType != undefined) { - this.namespace!.allTypes[name] = namedType; + this.namespace.allTypes[name] = namedType; return namedType; } diff --git a/templates/local/.template b/templates/local/.template new file mode 100644 index 0000000..28bf503 --- /dev/null +++ b/templates/local/.template @@ -0,0 +1,2 @@ +name: local +description: Add custom generators to a project by running `apex init local` \ No newline at end of file diff --git a/templates/local/.vscode/extensions.json b/templates/local/.vscode/extensions.json new file mode 100644 index 0000000..bb39c68 --- /dev/null +++ b/templates/local/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["apexlang.apexlang"] +} \ No newline at end of file diff --git a/templates/local/codegen/package.json b/templates/local/codegen/package.json new file mode 100644 index 0000000..364f575 --- /dev/null +++ b/templates/local/codegen/package.json @@ -0,0 +1,32 @@ +{ + "name": "codegen", + "type": "module", + "engines": { + "node": ">=14.0" + }, + "sideEffects": false, + "scripts": { + "prebuild": "npm run clean", + "build": "tsc", + "watch": "tsc -w", + "clean": "shx rm -rf dist", + "test": "echo todo", + "style": "npm run format -- --list-different && npm run lint", + "style:fix": "npm run format:fix && npm run lint:fix", + "format": "prettier \"src/**/*.{ts,tsx,js,jsx,css,scss,sass,less,md}\"", + "format:fix": "npm run format -- --write", + "lint": "eslint -c ./config/.eslintrc.json src --ext .ts", + "lint:fix": "npm run lint -- --fix" + }, + "dependencies": { + "@apexlang/core": "^0.0.20" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^4.22.0", + "@typescript-eslint/parser": "^4.22.0", + "eslint": "^7.22.0", + "prettier": "^2.2.1", + "shx": "0.3.3", + "typescript": "^4.5.5" + } +} diff --git a/templates/local/codegen/src/index.ts b/templates/local/codegen/src/index.ts new file mode 100644 index 0000000..4216c62 --- /dev/null +++ b/templates/local/codegen/src/index.ts @@ -0,0 +1 @@ +// Module code here \ No newline at end of file diff --git a/templates/local/codegen/tsconfig.json b/templates/local/codegen/tsconfig.json new file mode 100644 index 0000000..0b6ab45 --- /dev/null +++ b/templates/local/codegen/tsconfig.json @@ -0,0 +1,31 @@ +{ + "include": ["src/**/*"], + "exclude": ["dist"], + "compilerOptions": { + "target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, + "module": "ES2020" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, + "lib": [ + "es2020", + "dom" + ] /* Specify library files to be included in the compilation. */, + "declaration": true /* Generates corresponding '.d.ts' file. */, + "declarationMap": true /* Generates a sourcemap for each corresponding '.d.ts' file. */, + "sourceMap": true /* Generates corresponding '.map' file. */, + "outDir": "./dist" /* Redirect output structure to the directory. */, + "rootDir": "." /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, + "strict": true /* Enable all strict type-checking options. */, + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + "typeRoots": ["./types", "./node_modules/@types"], + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, + "stripInternal": true, + "importHelpers": true, + "plugins": [ + { + "name": "typescript-tslint-plugin", + "alwaysShowRuleFailuresAsWarnings": false + } + ] + }, + "compileOnSave": false +} diff --git a/templates/module/.gitignore b/templates/module/.gitignore index 52a3a6f..e2c654e 100644 --- a/templates/module/.gitignore +++ b/templates/module/.gitignore @@ -1,4 +1,4 @@ -node_modules +./node_modules dist docs coverage diff --git a/templates/module/.template b/templates/module/.template index 519a8e4..de3c348 100644 --- a/templates/module/.template +++ b/templates/module/.template @@ -1,5 +1,5 @@ name: module -description: A Apex codegen project +description: An Apex codegen project variables: - name: module diff --git a/templates/module/.vscode/extensions.json b/templates/module/.vscode/extensions.json new file mode 100644 index 0000000..bb39c68 --- /dev/null +++ b/templates/module/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["apexlang.apexlang"] +} \ No newline at end of file diff --git a/templates/module/config/jest.config.js b/templates/module/config/jest.config.js deleted file mode 100644 index dad6f73..0000000 --- a/templates/module/config/jest.config.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @type {Partial} - */ -const config = { - preset: "ts-jest", - rootDir: "..", - testMatch: [ - "/src/**/__tests__/**/*.ts?(x)", - "/src/**/?(*.)+(spec|test).ts?(x)", - ], - testPathIgnorePatterns: ["dist"], - coverageThreshold: { - global: { - branches: 80, - functions: 80, - lines: 80, - statements: 80, - }, - }, - setupFiles: ["/config/setup-tests.js"], - watchPlugins: [ - "jest-watch-typeahead/filename", - "jest-watch-typeahead/testname", - ], -}; - -module.exports = config; diff --git a/templates/module/config/rollup.config.js b/templates/module/config/rollup.config.js deleted file mode 100644 index 8b8e446..0000000 --- a/templates/module/config/rollup.config.js +++ /dev/null @@ -1,25 +0,0 @@ -import commonjs from "@rollup/plugin-commonjs"; -import resolve from "@rollup/plugin-node-resolve"; -import pkg from "../package.json"; - -export default [ - // browser-friendly UMD build - { - input: "dist/cjs/index.js", - external: [ - "@apexlang/core", - "@apexlang/core/ast" - ], - output: { - name: "apex.codegen", - file: pkg.browser, - format: "umd", - sourcemap: true, - globals: { - '@apexlang/core': 'apex', - '@apexlang/core/ast': 'apex.ast' - } - }, - plugins: [commonjs(), resolve()], - }, -]; diff --git a/templates/module/config/setup-tests.js b/templates/module/config/setup-tests.js deleted file mode 100644 index c0c91c6..0000000 --- a/templates/module/config/setup-tests.js +++ /dev/null @@ -1,4 +0,0 @@ -// add here any code that you wanna execute before tests like -// - polyfills -// - some custom code -// for more docs check see https://jestjs.io/docs/en/configuration.html#setupfiles-array diff --git a/templates/module/config/tsconfig.json b/templates/module/config/tsconfig.json deleted file mode 100644 index 2596b2b..0000000 --- a/templates/module/config/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "target": "es2017", - "module": "commonjs", - "allowJs": true, - "checkJs": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "noEmit": true, - "importHelpers": false - }, - "include": [ - "." - ] -} diff --git a/templates/module/package.json.tmpl b/templates/module/package.json.tmpl index fe4c136..2397ed3 100644 --- a/templates/module/package.json.tmpl +++ b/templates/module/package.json.tmpl @@ -6,16 +6,11 @@ "apex", "codegen" ], - "engines": { - "node": ">=8.5" - }, - "main": "./dist/cjs/index.js", - "module": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "browser": "./dist/standalone.js", - "browser-min": "./dist/standalone.min.js", + "type": "module", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", "exports": { - ".": "./dist/cjs/index.js" + ".": "./dist/index.js" }, "files": [ "templates", @@ -24,56 +19,33 @@ "test", "src", "docs", + "definitions", "templates" ], "sideEffects": false, "scripts": { "prebuild": "npm run clean", - "build": "npm run build:esm && npm run build:cjs && npm run build:umd && npm run build:umd:min", - "build:esm": "tsc --module es2015 --outDir dist/esm", - "build:cjs": "tsc --declaration --declarationMap --declarationDir dist/types ", - "build:umd": "rollup --config config/rollup.config.js", - "build:umd:min": "cd dist && uglifyjs --compress --mangle --source-map --comments --output standalone.min.js -- standalone.js", + "build": "tsc", "watch": "tsc -w", "clean": "shx rm -rf dist", - "docs": "typedoc --theme minimal --exclude \"**/src/**/__tests__/*.*\" --out docs src/", - "test": "jest -c ./config/jest.config.js --passWithNoTests", - "test:watch": "npm t -- --watch", - "test:coverage": "npm t -- --coverage", - "test:ci": "npm t -- --ci", + "test": "echo todo", "style": "npm run format -- --list-different && npm run lint", "style:fix": "npm run format:fix && npm run lint:fix", "format": "prettier \"src/**/*.{ts,tsx,js,jsx,css,scss,sass,less,md}\"", "format:fix": "npm run format -- --write", "lint": "eslint -c ./config/.eslintrc.json src --ext .ts", "lint:fix": "npm run lint -- --fix", - "prerelease": "npm run build", - "release": "standard-version", - "release:github": "git push --no-verify --follow-tags origin master", - "release:npm": "npm publish --access public", - "release:preflight": "npm pack --dry-run" + "prerelease": "npm run build" }, "dependencies": { - "@apexlang/core": "^0.0.16" + "@apexlang/core": "^0.0.20" }, "devDependencies": { - "@rollup/plugin-commonjs": "^17.1.0", - "@rollup/plugin-node-resolve": "^11.2.0", - "@types/jest": "23.3.10", "@typescript-eslint/eslint-plugin": "^4.22.0", "@typescript-eslint/parser": "^4.22.0", "eslint": "^7.22.0", - "jest": "26.6.3", - "jest-watch-typeahead": "^0.6.1", "prettier": "^2.2.1", - "rollup": "2.41.3", "shx": "0.3.3", - "standard-version": "4.4.0", - "ts-jest": "26.5.3", - "tslib": "^2.1.0", - "typedoc": "0.20.32", - "typescript": "4.1.3", - "uglify-js": "^3.13.1", - "webpack-config-utils": "2.3.1" + "typescript": "^4.5.5" } } diff --git a/templates/module/tsconfig.json b/templates/module/tsconfig.json index f6bffb9..8185d41 100644 --- a/templates/module/tsconfig.json +++ b/templates/module/tsconfig.json @@ -1,19 +1,23 @@ { + "include": ["src/**/*"], + "exclude": ["dist", "node_modules"], "compilerOptions": { - "moduleResolution": "node", - "module": "CommonJS", - "target": "es2015", - "lib": ["es2015"], - "outDir": "dist/cjs", - "baseUrl": ".", - "paths": { - "@apexlang/core": ["node_modules/@apexlang/core/dist/types"], - "@apexlang/core/*": ["node_modules/@apexlang/core/dist/types/*"] - }, - "strict": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "sourceMap": true, + "target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, + "module": "ES2020" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, + "lib": [ + "es2020", + "dom" + ] /* Specify library files to be included in the compilation. */, + "declaration": true /* Generates corresponding '.d.ts' file. */, + "declarationMap": true /* Generates a sourcemap for each corresponding '.d.ts' file. */, + "sourceMap": true /* Generates corresponding '.map' file. */, + "outDir": "./dist" /* Redirect output structure to the directory. */, + "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, + "strict": true /* Enable all strict type-checking options. */, + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + "typeRoots": ["./types", "./node_modules/@types"], + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, "stripInternal": true, "importHelpers": true, "plugins": [ @@ -23,6 +27,5 @@ } ] }, - "include": ["./src"], "compileOnSave": false }