diff --git a/README.md b/README.md index 9388a90..6bc65e8 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ For most other editors, you can use the schemas by adding the `$schema` property } ``` -You can also use these schemas programatially. For example, Salesforce CLI uses these schema to do certain validation. +You can also use these schemas programatically. For example, Salesforce CLI uses these schema to do certain validation. ```javascript const schemas = require('@salesforce/schemas'); @@ -33,6 +33,14 @@ const projectJsonSchema = require('@salesforce/schema/sfdx-project-schema.json'] Run the `features-update` and `settings-update` scripts on every major release and open a PR with the new changes against the `main` branch to keep the schema files up to date +## Generating Schema from TS files + +the /src folder contains the TS type used to generate the [`replacements`](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_string_replace.htm?q=replacements) project property. + +You can define (or import and re-export) TS types and then use [this extension](https://marketplace.visualstudio.com/items?itemName=marcoq.vscode-typescript-to-json-schema). It adds a "Generate JSON Schema from type" action to your palette. + +The results go into `/compiled`, which can be used to copy-paste into the project. + ## Bugs and Feedback To report issues or feedback with the schemas, open a bug on [GitHub](https://github.com/forcedotcom/schemas/issues). diff --git a/compiled/replacements.json b/compiled/replacements.json new file mode 100644 index 0000000..c90f04f --- /dev/null +++ b/compiled/replacements.json @@ -0,0 +1,266 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/Replacements", + "definitions": { + "Replacements": { + "anyOf": [ + { + "type": "object", + "additionalProperties": false, + "properties": { + "replaceWithFile": { + "type": "string" + }, + "stringToReplace": { + "type": "string" + }, + "filename": { + "type": "string" + }, + "replaceWhenEnv": { + "type": "array", + "items": { + "type": "object", + "properties": { + "env": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": ["env", "value"], + "additionalProperties": false + } + } + }, + "required": ["filename", "replaceWithFile", "stringToReplace"] + }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "replaceWithEnv": { + "type": "string" + }, + "stringToReplace": { + "type": "string" + }, + "filename": { + "type": "string" + }, + "replaceWhenEnv": { + "type": "array", + "items": { + "type": "object", + "properties": { + "env": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": ["env", "value"], + "additionalProperties": false + } + } + }, + "required": ["filename", "replaceWithEnv", "stringToReplace"] + }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "replaceWithFile": { + "type": "string" + }, + "regexToReplace": { + "type": "string" + }, + "filename": { + "type": "string" + }, + "replaceWhenEnv": { + "type": "array", + "items": { + "type": "object", + "properties": { + "env": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": ["env", "value"], + "additionalProperties": false + } + } + }, + "required": ["filename", "regexToReplace", "replaceWithFile"] + }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "replaceWithEnv": { + "type": "string" + }, + "regexToReplace": { + "type": "string" + }, + "filename": { + "type": "string" + }, + "replaceWhenEnv": { + "type": "array", + "items": { + "type": "object", + "properties": { + "env": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": ["env", "value"], + "additionalProperties": false + } + } + }, + "required": ["filename", "regexToReplace", "replaceWithEnv"] + }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "replaceWithFile": { + "type": "string" + }, + "stringToReplace": { + "type": "string" + }, + "glob": { + "type": "string" + }, + "replaceWhenEnv": { + "type": "array", + "items": { + "type": "object", + "properties": { + "env": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": ["env", "value"], + "additionalProperties": false + } + } + }, + "required": ["glob", "replaceWithFile", "stringToReplace"] + }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "replaceWithEnv": { + "type": "string" + }, + "stringToReplace": { + "type": "string" + }, + "glob": { + "type": "string" + }, + "replaceWhenEnv": { + "type": "array", + "items": { + "type": "object", + "properties": { + "env": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": ["env", "value"], + "additionalProperties": false + } + } + }, + "required": ["glob", "replaceWithEnv", "stringToReplace"] + }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "replaceWithFile": { + "type": "string" + }, + "regexToReplace": { + "type": "string" + }, + "glob": { + "type": "string" + }, + "replaceWhenEnv": { + "type": "array", + "items": { + "type": "object", + "properties": { + "env": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": ["env", "value"], + "additionalProperties": false + } + } + }, + "required": ["glob", "regexToReplace", "replaceWithFile"] + }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "replaceWithEnv": { + "type": "string" + }, + "regexToReplace": { + "type": "string" + }, + "glob": { + "type": "string" + }, + "replaceWhenEnv": { + "type": "array", + "items": { + "type": "object", + "properties": { + "env": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": ["env", "value"], + "additionalProperties": false + } + } + }, + "required": ["glob", "regexToReplace", "replaceWithEnv"] + } + ] + } + } +} diff --git a/examples/sfdx-project/replacements.json b/examples/sfdx-project/replacements.json index 99a45d2..cb49f67 100644 --- a/examples/sfdx-project/replacements.json +++ b/examples/sfdx-project/replacements.json @@ -12,6 +12,11 @@ "stringToReplace": "replaceMe", "replaceWithEnv": "THE_REPLACEMENT" }, + { + "filename": "force-app/main/default/classes/myClass.cls", + "stringToReplace": "replaceMe", + "replaceWithFile": "~/substitutions.txt" + }, { "glob": "**/*.cls", "regexToReplace": "\\d", @@ -29,4 +34,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/package.json b/package.json index cb6777f..4806d4a 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,10 @@ "devDependencies": { "@commitlint/cli": "^7", "@commitlint/config-conventional": "^7", + "@salesforce/dev-config": "^3.1.0", + "ajv": "^8.11.0", "commitizen": "^3.0.5", "cz-conventional-changelog": "^2.1.0", - "ajv": "^8.11.0", "husky": "^3.0.2", "jest": "^24.8.0", "prettier": "^1.18.2", @@ -52,4 +53,4 @@ "path": "./node_modules/cz-conventional-changelog" } } -} \ No newline at end of file +} diff --git a/sfdx-project.schema.json b/sfdx-project.schema.json index dcd45a4..562a7cb 100644 --- a/sfdx-project.schema.json +++ b/sfdx-project.schema.json @@ -206,6 +206,15 @@ "type": "object", "additionalProperties": false, "properties": { + "replaceWithFile": { + "type": "string" + }, + "stringToReplace": { + "type": "string" + }, + "filename": { + "type": "string" + }, "replaceWhenEnv": { "type": "array", "items": { @@ -215,30 +224,36 @@ "type": "string" }, "value": { - "type": ["string", "number", "boolean"] + "type": "string" } }, - "required": ["env", "value"], + "required": [ + "env", + "value" + ], "additionalProperties": false - }, - "maxItems": 1 - }, - "stringToReplace": { - "$ref": "#/definitions/replacements.stringToReplace" - }, - "replaceWithEnv": { - "$ref": "#/definitions/replacements.replaceWithEnv" - }, - "filename": { - "$ref": "#/definitions/replacements.filename" + } } }, - "required": ["filename", "replaceWithEnv", "stringToReplace"] + "required": [ + "filename", + "replaceWithFile", + "stringToReplace" + ] }, { "type": "object", "additionalProperties": false, "properties": { + "replaceWithEnv": { + "type": "string" + }, + "stringToReplace": { + "type": "string" + }, + "filename": { + "type": "string" + }, "replaceWhenEnv": { "type": "array", "items": { @@ -248,30 +263,36 @@ "type": "string" }, "value": { - "type": ["string", "number", "boolean"] + "type": "string" } }, - "required": ["env", "value"], + "required": [ + "env", + "value" + ], "additionalProperties": false - }, - "maxItems": 1 - }, - "regexToReplace": { - "$ref": "#/definitions/replacements.regexToReplace" - }, - "replaceWithEnv": { - "$ref": "#/definitions/replacements.replaceWithEnv" - }, - "filename": { - "$ref": "#/definitions/replacements.filename" + } } }, - "required": ["filename", "regexToReplace", "replaceWithEnv"] + "required": [ + "filename", + "replaceWithEnv", + "stringToReplace" + ] }, { "type": "object", "additionalProperties": false, "properties": { + "replaceWithFile": { + "type": "string" + }, + "regexToReplace": { + "type": "string" + }, + "filename": { + "type": "string" + }, "replaceWhenEnv": { "type": "array", "items": { @@ -281,29 +302,36 @@ "type": "string" }, "value": { - "type": ["string", "number", "boolean"] + "type": "string" } }, - "required": ["env", "value"], + "required": [ + "env", + "value" + ], "additionalProperties": false } - }, - "stringToReplace": { - "$ref": "#/definitions/replacements.stringToReplace" - }, - "replaceWithEnv": { - "$ref": "#/definitions/replacements.replaceWithEnv" - }, - "filename": { - "$ref": "#/definitions/replacements.filename" } }, - "required": ["filename", "replaceWithFile", "stringToReplace"] + "required": [ + "filename", + "regexToReplace", + "replaceWithFile" + ] }, { "type": "object", "additionalProperties": false, "properties": { + "replaceWithEnv": { + "type": "string" + }, + "regexToReplace": { + "type": "string" + }, + "filename": { + "type": "string" + }, "replaceWhenEnv": { "type": "array", "items": { @@ -313,30 +341,36 @@ "type": "string" }, "value": { - "type": ["string", "number", "boolean"] + "type": "string" } }, - "required": ["env", "value"], + "required": [ + "env", + "value" + ], "additionalProperties": false - }, - "maxItems": 1 - }, - "regexToReplace": { - "$ref": "#/definitions/replacements.regexToReplace" - }, - "replaceWithFile": { - "$ref": "#/definitions/replacements.replaceWithFile" - }, - "filename": { - "$ref": "#/definitions/replacements.filename" + } } }, - "required": ["filename", "regexToReplace", "replaceWithFile"] + "required": [ + "filename", + "regexToReplace", + "replaceWithEnv" + ] }, { "type": "object", "additionalProperties": false, "properties": { + "replaceWithFile": { + "type": "string" + }, + "stringToReplace": { + "type": "string" + }, + "glob": { + "type": "string" + }, "replaceWhenEnv": { "type": "array", "items": { @@ -346,30 +380,36 @@ "type": "string" }, "value": { - "type": ["string", "number", "boolean"] + "type": "string" } }, - "required": ["env", "value"], + "required": [ + "env", + "value" + ], "additionalProperties": false - }, - "maxItems": 1 - }, - "stringToReplace": { - "$ref": "#/definitions/replacements.stringToReplace" - }, - "replaceWithEnv": { - "$ref": "#/definitions/replacements.replaceWithEnv" - }, - "glob": { - "$ref": "#/definitions/replacements.glob" + } } }, - "required": ["glob", "replaceWithEnv", "stringToReplace"] + "required": [ + "glob", + "replaceWithFile", + "stringToReplace" + ] }, { "type": "object", "additionalProperties": false, "properties": { + "replaceWithEnv": { + "type": "string" + }, + "stringToReplace": { + "type": "string" + }, + "glob": { + "type": "string" + }, "replaceWhenEnv": { "type": "array", "items": { @@ -379,30 +419,36 @@ "type": "string" }, "value": { - "type": ["string", "number", "boolean"] + "type": "string" } }, - "required": ["env", "value"], + "required": [ + "env", + "value" + ], "additionalProperties": false - }, - "maxItems": 1 - }, - "regexToReplace": { - "$ref": "#/definitions/replacements.regexToReplace" - }, - "replaceWithEnv": { - "$ref": "#/definitions/replacements.replaceWithEnv" - }, - "glob": { - "$ref": "#/definitions/replacements.glob" + } } }, - "required": ["glob", "regexToReplace", "replaceWithEnv"] + "required": [ + "glob", + "replaceWithEnv", + "stringToReplace" + ] }, { "type": "object", "additionalProperties": false, "properties": { + "replaceWithFile": { + "type": "string" + }, + "regexToReplace": { + "type": "string" + }, + "glob": { + "type": "string" + }, "replaceWhenEnv": { "type": "array", "items": { @@ -412,30 +458,36 @@ "type": "string" }, "value": { - "type": ["string", "number", "boolean"] + "type": "string" } }, - "required": ["env", "value"], + "required": [ + "env", + "value" + ], "additionalProperties": false - }, - "maxItems": 1 - }, - "stringToReplace": { - "$ref": "#/definitions/replacements.stringToReplace" - }, - "replaceWithEnv": { - "$ref": "#/definitions/replacements.replaceWithEnv" - }, - "glob": { - "$ref": "#/definitions/replacements.glob" + } } }, - "required": ["glob", "replaceWithFile", "stringToReplace"] + "required": [ + "glob", + "regexToReplace", + "replaceWithFile" + ] }, { "type": "object", "additionalProperties": false, "properties": { + "replaceWithEnv": { + "type": "string" + }, + "regexToReplace": { + "type": "string" + }, + "glob": { + "type": "string" + }, "replaceWhenEnv": { "type": "array", "items": { @@ -445,25 +497,22 @@ "type": "string" }, "value": { - "type": ["string", "number", "boolean"] + "type": "string" } }, - "required": ["env", "value"], + "required": [ + "env", + "value" + ], "additionalProperties": false - }, - "maxItems": 1 - }, - "regexToReplace": { - "$ref": "#/definitions/replacements.regexToReplace" - }, - "replaceWithFile": { - "$ref": "#/definitions/replacements.replaceWithFile" - }, - "glob": { - "$ref": "#/definitions/replacements.glob" + } } }, - "required": ["glob", "regexToReplace", "replaceWithFile"] + "required": [ + "glob", + "regexToReplace", + "replaceWithEnv" + ] } ] } @@ -679,4 +728,4 @@ "description": "Use the contents of this file to replace the target" } } -} +} \ No newline at end of file diff --git a/src/replacements.ts b/src/replacements.ts new file mode 100644 index 0000000..eff67ea --- /dev/null +++ b/src/replacements.ts @@ -0,0 +1,28 @@ +export type Replacements = { + replaceWhenEnv?: Array; +} & WhereToReplace & + WhatToReplace & + ReplaceWith; + +type WhereToReplace = + | { filename: string; glob?: never } + | { glob: string; filename?: never }; + +type WhatToReplace = + | { + stringToReplace: string; + regexToReplace?: never; + } + | { regexToReplace: string; stringToReplace?: never }; + +type ReplaceWith = + | { + replaceWithFile: string; + replaceWithEnv?: never; + } + | { replaceWithEnv: string; replaceWithFile?: never }; + +type EnvConditional = { + env: string; + value: string; +}; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..dcfebe2 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "./node_modules/@salesforce/dev-config/tsconfig-strict", + "compilerOptions": { + "outDir": "./lib", + "skipLibCheck": true, + "strictNullChecks": true + }, + "include": ["src/**/*.ts"] +} diff --git a/yarn.lock b/yarn.lock index 238808c..2a596d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -501,6 +501,11 @@ mkdirp "^0.5.1" rimraf "^2.5.2" +"@salesforce/dev-config@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@salesforce/dev-config/-/dev-config-3.1.0.tgz#8eb5b35860ff60d1c1dc3fd9329b01a28475d5b9" + integrity sha512-cPph7ibj3DeSzWDFLcLtxOh5fmUlDUY2Ezq43n0V6auVP+l8orxRHjCExHS86SB3QKVgXkC8yYhryXiS8KF7Zw== + "@types/babel__core@^7.1.0": version "7.1.6" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.6.tgz#16ff42a5ae203c9af1c6e190ed1f30f83207b610"