diff --git a/docs/docs/cmd/spo/field/field-get.mdx b/docs/docs/cmd/spo/field/field-get.mdx
index 130e7fc1206..fa77496a0a6 100644
--- a/docs/docs/cmd/spo/field/field-get.mdx
+++ b/docs/docs/cmd/spo/field/field-get.mdx
@@ -28,10 +28,14 @@ m365 spo field get [options]
: Server- or web-relative URL of the list where the field is located. Specify either `listTitle`, `listId` or `listUrl`.
`-i, --id [id]`
-: The ID of the field to retrieve. Specify `id` or `title` but not both.
+: The ID of the field to retrieve. Specify either `id`, `title` or `internalName`.
`-t, --title [title]`
-: The display name (case-sensitive) of the field to retrieve. Specify `id` or `title` but not both.
+: The display name (case-sensitive) of the field to retrieve. Specify either `id`, `title` or `internalName`.
+```
+
+`--internalName [internalName]`
+: The internal name (case-sensitive) of the field to retrieve. Specify either `id`, `title` or `internalName`.
```
@@ -56,6 +60,12 @@ Retrieves list column by display name located in the specified site. Retrieves t
m365 spo field get --webUrl https://contoso.sharepoint.com/sites/contoso-sales --listUrl "Lists/Events" --title "Title"
```
+Retrieves list column by internal name located in the specified site. Retrieves the list by its url.
+
+```sh
+m365 spo field get --webUrl https://contoso.sharepoint.com/sites/contoso-sales --listUrl "Lists/Events" --internalName "Title"
+```
+
## Response
diff --git a/docs/docs/cmd/spo/field/field-remove.mdx b/docs/docs/cmd/spo/field/field-remove.mdx
index f1e3b39fbd9..193c8ab6fa2 100644
--- a/docs/docs/cmd/spo/field/field-remove.mdx
+++ b/docs/docs/cmd/spo/field/field-remove.mdx
@@ -26,13 +26,16 @@ m365 spo field remove [options]
: Server- or web-relative URL of the list where the field is located. Specify either `listTitle`, `listId` or `listUrl`.
`-i, --id [id]`
-: The ID of the field to remove. Specify either `id`, `title`, or `group`.
+: The ID of the field to remove. Specify either `id`, `title`, `internalName`, or `group`.
`-t, --title [title]`
-: The display name (case-sensitive) of the field to remove. Specify either `id`, `title`, or `group`.
+: The display name (case-sensitive) of the field to remove. Specify either `id`, `title`, `internalName`, or `group`.
+
+`--internalName [internalName]`
+: The internal name (case-sensitive) of the field to remove. Specify either `id`, `title`, `internalName`, or `group`.
`-g, --group [group]`
-: Delete all fields from this group (case-sensitive). Specify either `id`, `title`, or `group`.
+: Delete all fields from this group (case-sensitive). Specify either `id`, `title`, `internalName`, or `group`.
`-f, --force`
: Don't prompt for confirming removing the field.
@@ -60,6 +63,12 @@ Remove the list column with the specified display name, located in the specified
m365 spo field remove --webUrl https://contoso.sharepoint.com/sites/contoso-sales --listUrl "Lists/Events" --title "Title"
```
+Remove the list column with the specified display name, located in the specified site. Retrieves the list by its url.
+
+```sh
+m365 spo field remove --webUrl https://contoso.sharepoint.com/sites/contoso-sales --listUrl "Lists/Events" --internalName "Title"
+```
+
Remove all site columns from the specified group.
```sh
diff --git a/docs/docs/cmd/spo/field/field-set.mdx b/docs/docs/cmd/spo/field/field-set.mdx
index 14d532bfb64..cb449bc81a0 100644
--- a/docs/docs/cmd/spo/field/field-set.mdx
+++ b/docs/docs/cmd/spo/field/field-set.mdx
@@ -26,10 +26,13 @@ m365 spo field set [options]
: Server- or site-relative URL of the list where the field is located (if list column). Specify either `listTitle`, `listId` or `listUrl`.
`-i, --id [id]`
-: ID of the field to update. Specify either `id` or `title` but not both.
+: ID of the field to update. Specify either `id`, `title`, or 'internalName' but not all.
`-t, --title [title]`
-: Title or internal name of the field to update. Specify either `id` or `title` but not both.
+: Title of the field to update. Specify either `id`, `title`, or 'internalName' but not all.
+
+`--internalName [internalName]`
+: Internal name of the field to update. Specify either `id`, `title`, or 'internalName' but not all.
`--updateExistingLists`
: Set, to push the update to existing lists. Otherwise, the changes will apply to new lists only.
@@ -51,6 +54,12 @@ When updating column formatting for a field with the `--CustomFormatter` option,
Update the title of the site column specified by its internal name and push changes to existing lists.
+```sh
+m365 spo field set --webUrl https://contoso.sharepoint.com/sites/project-x --internalName 'MyColumn' --updateExistingLists --Title 'My column'
+```
+
+Update the title of the site column specified by its title and push changes to existing lists.
+
```sh
m365 spo field set --webUrl https://contoso.sharepoint.com/sites/project-x --title 'MyColumn' --updateExistingLists --Title 'My column'
```
@@ -67,11 +76,16 @@ Update the description of a column specified by the ID on a list retrieved by th
m365 spo field set --webUrl https://contoso.sharepoint.com/sites/project-x --listUrl '/sites/project-x/Lists/My List' --id 330f29c5-5c4c-465f-9f4b-7903020ae1ce --Description 'My column Description'
```
-Update column formatting of the specified list column.
+Update column formatting of the specified list column based on title.
```sh
m365 spo field set --webUrl https://contoso.sharepoint.com/sites/project-x --listTitle 'My List' --title 'MyColumn' --CustomFormatter '{"schema":"https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json", "elmType": "div", "txtContent": "@currentField"}'
```
+Update column formatting of the specified list column based on internalName.
+
+```sh
+m365 spo field set --webUrl https://contoso.sharepoint.com/sites/project-x --listTitle 'My List' --internalName 'MyColumn' --CustomFormatter '{"schema":"https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json", "elmType": "div", "txtContent": "@currentField"}'
+```
## Response
diff --git a/src/m365/spo/commands/field/field-get.spec.ts b/src/m365/spo/commands/field/field-get.spec.ts
index 5f7fbc806d8..0521ff16064 100644
--- a/src/m365/spo/commands/field/field-get.spec.ts
+++ b/src/m365/spo/commands/field/field-get.spec.ts
@@ -86,7 +86,7 @@ describe(commands.FIELD_GET, () => {
it('gets information about a site column', async () => {
sinon.stub(request, 'get').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/fields/getbyid('5ee2dd25-d941-455a-9bdb-7f2c54aed11b')`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/fields/getbyid('5ee2dd25-d941-455a-9bdb-7f2c54aed11b')`) {
return {
"AutoIndexed": false,
"CanBeDeleted": true,
@@ -177,7 +177,7 @@ describe(commands.FIELD_GET, () => {
it('gets information about a list column', async () => {
sinon.stub(request, 'get').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/lists/getByTitle('Documents')/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle('Documents')/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) {
return {
"AutoIndexed": false,
"CanBeDeleted": false,
@@ -262,7 +262,7 @@ describe(commands.FIELD_GET, () => {
it('should call the correct GET url when id and list url specified', async () => {
const getStub = sinon.stub(request, 'get').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/lists`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/GetList('%2Fsites%2Fportal%2FLists%2FEvents')/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) {
return {
"Id": "03e45e84-1992-4d42-9116-26f756012634"
};
@@ -270,14 +270,13 @@ describe(commands.FIELD_GET, () => {
throw 'Invalid request';
});
-
- await assert.rejects(command.action(logger, { options: { verbose: true, webUrl: 'https://contoso.sharepoint.com/sites/portal', id: '03e45e84-1992-4d42-9116-26f756012634', listUrl: 'Lists/Events' } }));
+ await command.action(logger, { options: { debug: true, verbose: true, webUrl: 'https://contoso.sharepoint.com/sites/portal', id: '03e45e84-1992-4d42-9116-26f756012634', listUrl: 'Lists/Events' } });
assert.strictEqual(getStub.lastCall.args[0].url, 'https://contoso.sharepoint.com/sites/portal/_api/web/GetList(\'%2Fsites%2Fportal%2FLists%2FEvents\')/fields/getbyid(\'03e45e84-1992-4d42-9116-26f756012634\')');
});
it('should call the correct GET url when field title and list title specified (verbose)', async () => {
const getStub = sinon.stub(request, 'get').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/lists`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle('Documents')/fields/getbyinternalnameortitle('Title')`) {
return {
"Id": "03e45e84-1992-4d42-9116-26f756012634"
};
@@ -292,7 +291,7 @@ describe(commands.FIELD_GET, () => {
it('should call the correct GET url when field title and list title specified', async () => {
const getStub = sinon.stub(request, 'get').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/lists`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle('Documents')/fields/getbyinternalnameortitle('Title')`) {
return {
"Id": "03e45e84-1992-4d42-9116-26f756012634"
};
@@ -306,8 +305,9 @@ describe(commands.FIELD_GET, () => {
});
it('should call the correct GET url when field title and list url specified', async () => {
+ const webUrl = 'https://contoso.sharepoint.com/sites/portal';
const getStub = sinon.stub(request, 'get').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/lists`) > -1) {
+ if (opts.url === `${webUrl}/_api/web/lists(guid'03e45e84-1992-4d42-9116-26f756012634')/fields/getbyinternalnameortitle('Title')`) {
return {
"Id": "03e45e84-1992-4d42-9116-26f756012634"
};
@@ -320,16 +320,63 @@ describe(commands.FIELD_GET, () => {
assert.strictEqual(getStub.lastCall.args[0].url, 'https://contoso.sharepoint.com/sites/portal/_api/web/lists(guid\'03e45e84-1992-4d42-9116-26f756012634\')/fields/getbyinternalnameortitle(\'Title\')');
});
+ it('should call the correct GET url when field internalName and list title specified (verbose)', async () => {
+ const webUrl = 'https://contoso.sharepoint.com/sites/portal';
+ const getStub = sinon.stub(request, 'get').callsFake(async (opts) => {
+ if (opts.url === `${webUrl}/_api/web/lists/getByTitle('Documents')/fields/getbyinternalnameortitle('Title')`) {
+ return {
+ "Id": "03e45e84-1992-4d42-9116-26f756012634"
+ };
+ }
+
+ throw 'Invalid request';
+ });
+
+ await command.action(logger, { options: { debug: true, verbose: true, webUrl: 'https://contoso.sharepoint.com/sites/portal', internalName: 'Title', listTitle: 'Documents' } });
+ assert.strictEqual(getStub.lastCall.args[0].url, 'https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle(\'Documents\')/fields/getbyinternalnameortitle(\'Title\')');
+ });
+
+ it('should call the correct GET url when field internalName and list title specified', async () => {
+ const getStub = sinon.stub(request, 'get').callsFake(async (opts) => {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle('Documents')/fields/getbyinternalnameortitle('Title')`) {
+ return {
+ "Id": "03e45e84-1992-4d42-9116-26f756012634"
+ };
+ }
+
+ throw 'Invalid request';
+ });
+
+ await command.action(logger, { options: { webUrl: 'https://contoso.sharepoint.com/sites/portal', internalName: 'Title', listTitle: 'Documents' } });
+ assert.strictEqual(getStub.lastCall.args[0].url, 'https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle(\'Documents\')/fields/getbyinternalnameortitle(\'Title\')');
+ });
+
+ it('should call the correct GET url when field internalName and list url specified', async () => {
+ const webUrl = 'https://contoso.sharepoint.com/sites/portal';
+ const getStub = sinon.stub(request, 'get').callsFake(async (opts) => {
+ if (opts.url === `${webUrl}/_api/web/lists(guid'03e45e84-1992-4d42-9116-26f756012634')/fields/getbyinternalnameortitle('Title')`) {
+ return {
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634'
+ };
+ }
+
+ throw 'Invalid request';
+ });
+
+ await command.action(logger, { options: { debug: true, webUrl: 'https://contoso.sharepoint.com/sites/portal', internalName: 'Title', listId: '03e45e84-1992-4d42-9116-26f756012634' } });
+ assert.strictEqual(getStub.lastCall.args[0].url, 'https://contoso.sharepoint.com/sites/portal/_api/web/lists(guid\'03e45e84-1992-4d42-9116-26f756012634\')/fields/getbyinternalnameortitle(\'Title\')');
+ });
+
it('correctly handles site column not found', async () => {
sinon.stub(request, 'get').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) {
throw {
error: {
"odata.error": {
"code": "-2147024809, System.ArgumentException",
"message": {
"lang": "en-US",
- "value": "Invalid field name. {03e45e84-1992-4d42-9116-26f756012634} https://m365x526922.sharepoint.com/sites/portal "
+ "value": "Invalid field name. {03e45e84-1992-4d42-9116-26f756012634} https://contoso.sharepoint.com/sites/portal "
}
}
}
@@ -340,12 +387,12 @@ describe(commands.FIELD_GET, () => {
});
await assert.rejects(command.action(logger, { options: { debug: true, webUrl: 'https://contoso.sharepoint.com/sites/portal', id: '03e45e84-1992-4d42-9116-26f756012634' } } as any),
- new CommandError('Invalid field name. {03e45e84-1992-4d42-9116-26f756012634} https://m365x526922.sharepoint.com/sites/portal '));
+ new CommandError('Invalid field name. {03e45e84-1992-4d42-9116-26f756012634} https://contoso.sharepoint.com/sites/portal '));
});
it('correctly handles list column not found', async () => {
sinon.stub(request, 'get').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/lists/getByTitle('Documents')/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle('Documents')/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) {
throw {
error: {
"odata.error": {
@@ -368,7 +415,7 @@ describe(commands.FIELD_GET, () => {
it('correctly handles list not found', async () => {
sinon.stub(request, 'get').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/lists/getByTitle('Documents')/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle('Documents')/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) {
throw {
error: {
"odata.error": {
diff --git a/src/m365/spo/commands/field/field-get.ts b/src/m365/spo/commands/field/field-get.ts
index 9fd81b4458c..40e55719ea4 100644
--- a/src/m365/spo/commands/field/field-get.ts
+++ b/src/m365/spo/commands/field/field-get.ts
@@ -18,6 +18,7 @@ interface Options extends GlobalOptions {
listUrl?: string;
id?: string;
title?: string;
+ internalName?: string;
}
class SpoFieldGetCommand extends SpoCommand {
@@ -45,7 +46,8 @@ class SpoFieldGetCommand extends SpoCommand {
listTitle: typeof args.options.listTitle !== 'undefined',
listUrl: typeof args.options.listUrl !== 'undefined',
id: typeof args.options.id !== 'undefined',
- title: typeof args.options.title !== 'undefined'
+ title: typeof args.options.title !== 'undefined',
+ internalName: typeof args.options.internalName !== 'undefined'
});
});
}
@@ -69,6 +71,9 @@ class SpoFieldGetCommand extends SpoCommand {
},
{
option: '-t, --title [title]'
+ },
+ {
+ option: '--internalName [internalName]'
}
);
}
@@ -95,7 +100,7 @@ class SpoFieldGetCommand extends SpoCommand {
}
#initOptionSets(): void {
- this.optionSets.push({ options: ['id', 'title'] });
+ this.optionSets.push({ options: ['id', 'title', 'internalName'] });
}
public async commandAction(logger: Logger, args: CommandArgs): Promise {
@@ -118,7 +123,7 @@ class SpoFieldGetCommand extends SpoCommand {
fieldRestUrl = `/getbyid('${formatting.encodeQueryParameter(args.options.id)}')`;
}
else {
- fieldRestUrl = `/getbyinternalnameortitle('${formatting.encodeQueryParameter(args.options.title as string)}')`;
+ fieldRestUrl = `/getbyinternalnameortitle('${formatting.encodeQueryParameter((args.options.title || args.options.internalName) as string)}')`;
}
const requestOptions: CliRequestOptions = {
diff --git a/src/m365/spo/commands/field/field-remove.spec.ts b/src/m365/spo/commands/field/field-remove.spec.ts
index de7e5156484..a88bd3152c6 100644
--- a/src/m365/spo/commands/field/field-remove.spec.ts
+++ b/src/m365/spo/commands/field/field-remove.spec.ts
@@ -94,6 +94,18 @@ describe(commands.FIELD_REMOVE, () => {
assert(promptIssued);
});
+ it('prompts before removing field when confirmation argument not passed (internalName)', async () => {
+ await command.action(logger, { options: { internalName: 'myfield1', webUrl: 'https://contoso.sharepoint.com' } });
+
+ assert(promptIssued);
+ });
+
+ it('prompts before removing list column when confirmation argument not passed (internalName)', async () => {
+ await command.action(logger, { options: { internalName: 'myfield1', webUrl: 'https://contoso.sharepoint.com', listTitle: 'My List' } });
+
+ assert(promptIssued);
+ });
+
it('aborts removing field when prompt not confirmed', async () => {
sinonUtil.restore(cli.promptForConfirmation);
sinon.stub(cli, 'promptForConfirmation').resolves(false);
@@ -113,8 +125,7 @@ describe(commands.FIELD_REMOVE, () => {
it('removes the field when prompt confirmed', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
requests.push(opts);
-
- if ((opts.url as string).indexOf(`/_api/web/fields(guid'`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/fields(guid'b2307a39-e878-458b-bc90-03bc578531d6')`) {
if (opts.headers &&
opts.headers.accept &&
(opts.headers.accept as string).indexOf('application/json') === 0) {
@@ -142,7 +153,7 @@ describe(commands.FIELD_REMOVE, () => {
it('command correctly handles field get reject request', async () => {
const err = 'Invalid request';
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf('/_api/web/fields/getbyinternalnameortitle(') > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/fields/getbyinternalnameortitle('field1')`) {
throw err;
}
@@ -161,38 +172,18 @@ describe(commands.FIELD_REMOVE, () => {
}), new CommandError(err));
});
- it('uses correct API url when id option is passed', async () => {
- sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf('/_api/web/fields/getbyid(\'') > -1) {
- return 'Correct Url';
- }
-
- throw 'Invalid request';
- });
-
- const actionId: string = '0CD891EF-AFCE-4E55-B836-FCE03286CCCF';
-
- await command.action(logger, {
- options: {
- id: actionId,
- webUrl: 'https://contoso.sharepoint.com',
- force: true
- }
- });
- });
-
it('calls the correct remove url when id and list url specified', async () => {
const getStub = sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/lists`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/GetList('%2Fsites%2Fportal%2FLists%2FEvents')/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) {
return {
- "Id": "03e45e84-1992-4d42-9116-26f756012634"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634'
};
}
throw 'Invalid request';
});
- await assert.rejects(command.action(logger, { options: { verbose: true, webUrl: 'https://contoso.sharepoint.com/sites/portal', id: '03e45e84-1992-4d42-9116-26f756012634', listUrl: 'Lists/Events', force: true } }));
+ await command.action(logger, { options: { debug: true, verbose: true, webUrl: 'https://contoso.sharepoint.com/sites/portal', id: '03e45e84-1992-4d42-9116-26f756012634', listUrl: 'Lists/Events', force: true } });
assert.strictEqual(getStub.lastCall.args[0].url, 'https://contoso.sharepoint.com/sites/portal/_api/web/GetList(\'%2Fsites%2Fportal%2FLists%2FEvents\')/fields/getbyid(\'03e45e84-1992-4d42-9116-26f756012634\')');
});
@@ -203,17 +194,17 @@ describe(commands.FIELD_REMOVE, () => {
const getStub = sinon.stub(request, 'get').callsFake(async (opts) => {
if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/GetList(\'%2Fsites%2Fportal%2FLists%2FEvents\')/fields`) {
return {
- "value": [{
- "Id": "03e45e84-1992-4d42-9116-26f756012634",
- "Group": "MyGroup"
+ 'value': [{
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634',
+ 'Group': 'MyGroup'
},
{
- "Id": "03e45e84-1992-4d42-9116-26f756012635",
- "Group": "MyGroup"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012635',
+ 'Group': 'MyGroup'
},
{
- "Id": "03e45e84-1992-4d42-9116-26f756012636",
- "Group": "DifferentGroup"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012636',
+ 'Group': 'DifferentGroup'
}]
};
}
@@ -221,15 +212,14 @@ describe(commands.FIELD_REMOVE, () => {
});
const deletion = sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/GetList(\'%2Fsites%2Fportal%2FLists%2FEvents\')/fields/getbyid(\'03e45e84-1992-4d42-9116-26f756012634\')`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/GetList('%2Fsites%2Fportal%2FLists%2FEvents')/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) {
return {
- "Id": "03e45e84-1992-4d42-9116-26f756012634"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634'
};
}
-
- if ((opts.url as string).indexOf(`/_api/web/GetList(\'%2Fsites%2Fportal%2FLists%2FEvents\')/fields/getbyid(\'03e45e84-1992-4d42-9116-26f756012635\')`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/GetList('%2Fsites%2Fportal%2FLists%2FEvents')/fields/getbyid('03e45e84-1992-4d42-9116-26f756012635')`) {
return {
- "Id": "03e45e84-1992-4d42-9116-26f756012635"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012635'
};
}
@@ -247,17 +237,17 @@ describe(commands.FIELD_REMOVE, () => {
const getStub = sinon.stub(request, 'get').callsFake(async (opts) => {
if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/fields`) {
return {
- "value": [{
- "Id": "03e45e84-1992-4d42-9116-26f756012634",
- "Group": "MyGroup"
+ 'value': [{
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634',
+ 'Group': 'MyGroup'
},
{
- "Id": "03e45e84-1992-4d42-9116-26f756012635",
- "Group": "MyGroup"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012635',
+ 'Group': 'MyGroup'
},
{
- "Id": "03e45e84-1992-4d42-9116-26f756012636",
- "Group": "DifferentGroup"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012636',
+ 'Group': 'DifferentGroup'
}]
};
}
@@ -265,15 +255,14 @@ describe(commands.FIELD_REMOVE, () => {
});
const deletion = sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/fields/getbyid(\'03e45e84-1992-4d42-9116-26f756012634\')`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) {
return {
- "Id": "03e45e84-1992-4d42-9116-26f756012634"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634'
};
}
-
- if ((opts.url as string).indexOf(`/_api/web/fields/getbyid(\'03e45e84-1992-4d42-9116-26f756012635\')`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/fields/getbyid('03e45e84-1992-4d42-9116-26f756012635')`) {
return {
- "Id": "03e45e84-1992-4d42-9116-26f756012635"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012635'
};
}
@@ -291,17 +280,17 @@ describe(commands.FIELD_REMOVE, () => {
const getStub = sinon.stub(request, 'get').callsFake(async (opts) => {
if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/fields`) {
return {
- "value": [{
- "Id": "03e45e84-1992-4d42-9116-26f756012634",
- "Group": "MyGroup"
+ 'value': [{
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634',
+ 'Group': 'MyGroup'
},
{
- "Id": "03e45e84-1992-4d42-9116-26f756012635",
- "Group": "MyGroup"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012635',
+ 'Group': 'MyGroup'
},
{
- "Id": "03e45e84-1992-4d42-9116-26f756012636",
- "Group": "DifferentGroup"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012636',
+ 'Group': 'DifferentGroup'
}]
};
}
@@ -311,7 +300,7 @@ describe(commands.FIELD_REMOVE, () => {
const deletion = sinon.stub(request, 'post').callsFake(async (opts) => {
if ((opts.url as string).indexOf(`/_api/web/fields`) > -1) {
return {
- "Id": "03e45e84-1992-4d42-9116-26f756012634"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634'
};
}
@@ -338,13 +327,12 @@ describe(commands.FIELD_REMOVE, () => {
const getStub = sinon.stub(request, 'get').rejects(error);
const deletion = sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/fields/getbyid(\'03e45e84-1992-4d42-9116-26f756012635\')`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/fields/getbyid('03e45e84-1992-4d42-9116-26f756012635')`) {
return {
- "Id": "03e45e84-1992-4d42-9116-26f756012635"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012635'
};
}
-
- if ((opts.url as string).indexOf(`/_api/web/fields/getbyid(\'03e45e84-1992-4d42-9116-26f756012634\')`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) {
throw error;
}
@@ -371,17 +359,17 @@ describe(commands.FIELD_REMOVE, () => {
const getStub = sinon.stub(request, 'get').callsFake(async (opts) => {
if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/fields`) {
return {
- "value": [{
- "Id": "03e45e84-1992-4d42-9116-26f756012634",
- "Group": "MyGroup"
+ 'value': [{
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634',
+ 'Group': 'MyGroup'
},
{
- "Id": "03e45e84-1992-4d42-9116-26f756012635",
- "Group": "MyGroup"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012635',
+ 'Group': 'MyGroup'
},
{
- "Id": "03e45e84-1992-4d42-9116-26f756012636",
- "Group": "DifferentGroup"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012636',
+ 'Group': 'DifferentGroup'
}]
};
}
@@ -389,13 +377,12 @@ describe(commands.FIELD_REMOVE, () => {
});
const deletion = sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/fields/getbyid(\'03e45e84-1992-4d42-9116-26f756012635\')`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/fields/getbyid('03e45e84-1992-4d42-9116-26f756012635')`) {
return {
- "Id": "03e45e84-1992-4d42-9116-26f756012635"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012635'
};
}
-
- if ((opts.url as string).indexOf(`/_api/web/fields/getbyid(\'03e45e84-1992-4d42-9116-26f756012634\')`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) {
throw error;
}
@@ -411,9 +398,9 @@ describe(commands.FIELD_REMOVE, () => {
it('calls the correct get url when field title and list title specified (verbose)', async () => {
const getStub = sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/lists`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle('Documents')/fields/getbyinternalnameortitle('Title')`) {
return {
- "Id": "03e45e84-1992-4d42-9116-26f756012634"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634'
};
}
@@ -426,9 +413,9 @@ describe(commands.FIELD_REMOVE, () => {
it('calls the correct get url when field title and list title specified', async () => {
const getStub = sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/lists`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle('Documents')/fields/getbyinternalnameortitle('Title')`) {
return {
- "Id": "03e45e84-1992-4d42-9116-26f756012634"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634'
};
}
@@ -441,9 +428,9 @@ describe(commands.FIELD_REMOVE, () => {
it('calls the correct get url when field title and list url specified', async () => {
const getStub = sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/lists`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/lists(guid'03e45e84-1992-4d42-9116-26f756012634')/fields/getbyinternalnameortitle('Title')`) {
return {
- "Id": "03e45e84-1992-4d42-9116-26f756012634"
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634'
};
}
@@ -454,6 +441,51 @@ describe(commands.FIELD_REMOVE, () => {
assert.strictEqual(getStub.lastCall.args[0].url, 'https://contoso.sharepoint.com/sites/portal/_api/web/lists(guid\'03e45e84-1992-4d42-9116-26f756012634\')/fields/getbyinternalnameortitle(\'Title\')');
});
+ it('calls the correct get url when field internalName and list title specified (verbose)', async () => {
+ const getStub = sinon.stub(request, 'post').callsFake(async (opts) => {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle('Documents')/fields/getbyinternalnameortitle('Title')`) {
+ return {
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634'
+ };
+ }
+
+ throw 'Invalid request';
+ });
+
+ await command.action(logger, { options: { debug: true, verbose: true, webUrl: 'https://contoso.sharepoint.com/sites/portal', internalName: 'Title', listTitle: 'Documents', force: true } });
+ assert.strictEqual(getStub.lastCall.args[0].url, 'https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle(\'Documents\')/fields/getbyinternalnameortitle(\'Title\')');
+ });
+
+ it('calls the correct get url when field internalName and list title specified', async () => {
+ const getStub = sinon.stub(request, 'post').callsFake(async (opts) => {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle('Documents')/fields/getbyinternalnameortitle('Title')`) {
+ return {
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634'
+ };
+ }
+
+ throw 'Invalid request';
+ });
+
+ await command.action(logger, { options: { webUrl: 'https://contoso.sharepoint.com/sites/portal', internalName: 'Title', listTitle: 'Documents', force: true } });
+ assert.strictEqual(getStub.lastCall.args[0].url, 'https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle(\'Documents\')/fields/getbyinternalnameortitle(\'Title\')');
+ });
+
+ it('calls the correct get url when field internalName and list url specified', async () => {
+ const getStub = sinon.stub(request, 'post').callsFake(async (opts) => {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/lists(guid'03e45e84-1992-4d42-9116-26f756012634')/fields/getbyinternalnameortitle('Title')`) {
+ return {
+ 'Id': '03e45e84-1992-4d42-9116-26f756012634'
+ };
+ }
+
+ throw 'Invalid request';
+ });
+
+ await command.action(logger, { options: { debug: true, webUrl: 'https://contoso.sharepoint.com/sites/portal', internalName: 'Title', listId: '03e45e84-1992-4d42-9116-26f756012634', force: true } });
+ assert.strictEqual(getStub.lastCall.args[0].url, 'https://contoso.sharepoint.com/sites/portal/_api/web/lists(guid\'03e45e84-1992-4d42-9116-26f756012634\')/fields/getbyinternalnameortitle(\'Title\')');
+ });
+
it('correctly handles site column not found', async () => {
const error = {
error: {
@@ -466,7 +498,7 @@ describe(commands.FIELD_REMOVE, () => {
}
};
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf('/_api/web/fields/getbyinternalnameortitle(') > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/fields/getbyinternalnameortitle('actionTitle')`) {
throw error;
}
throw 'Invalid request';
@@ -479,14 +511,14 @@ describe(commands.FIELD_REMOVE, () => {
it('correctly handles list column not found', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/lists/getByTitle('Documents')/fields/getbyid(`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle('Documents')/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) {
throw {
error: {
- "odata.error": {
- "code": "-2147024809, System.ArgumentException",
- "message": {
- "lang": "en-US",
- "value": "Invalid field name. {03e45e84-1992-4d42-9116-26f756012634} /sites/portal/Shared Documents"
+ 'odata.error': {
+ 'code': '-2147024809, System.ArgumentException',
+ 'message': {
+ 'lang': 'en-US',
+ 'value': 'Invalid field name. {03e45e84-1992-4d42-9116-26f756012634} /sites/portal/Shared Documents'
}
}
}
@@ -502,14 +534,14 @@ describe(commands.FIELD_REMOVE, () => {
it('correctly handles list not found', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_api/web/lists/getByTitle('Documents')/fields/getbyid(`) > -1) {
+ if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/web/lists/getByTitle('Documents')/fields/getbyid('03e45e84-1992-4d42-9116-26f756012634')`) {
throw {
error: {
- "odata.error": {
- "code": "-1, System.ArgumentException",
- "message": {
- "lang": "en-US",
- "value": "List 'Documents' does not exist at site with URL 'https://contoso.sharepoint.com/sites/portal'."
+ 'odata.error': {
+ 'code': '-1, System.ArgumentException',
+ 'message': {
+ 'lang': 'en-US',
+ 'value': 'List \'Documents\' does not exist at site with URL \'https://contoso.sharepoint.com/sites/portal\'.'
}
}
}
@@ -520,7 +552,7 @@ describe(commands.FIELD_REMOVE, () => {
});
await assert.rejects(command.action(logger, { options: { debug: true, webUrl: 'https://contoso.sharepoint.com/sites/portal', id: '03e45e84-1992-4d42-9116-26f756012634', listTitle: 'Documents', force: true } } as any),
- new CommandError("List 'Documents' does not exist at site with URL 'https://contoso.sharepoint.com/sites/portal'."));
+ new CommandError('List \'Documents\' does not exist at site with URL \'https://contoso.sharepoint.com/sites/portal\'.'));
});
it('supports specifying URL', () => {
@@ -534,7 +566,7 @@ describe(commands.FIELD_REMOVE, () => {
assert(containsTypeOption);
});
- it('fails validation if both id and title options are not passed', async () => {
+ it('fails validation if either of id, title and internalName options are not passed', async () => {
sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => {
if (settingName === settingsNames.prompt) {
return false;
diff --git a/src/m365/spo/commands/field/field-remove.ts b/src/m365/spo/commands/field/field-remove.ts
index fb8efabb529..1fb8a700d2d 100644
--- a/src/m365/spo/commands/field/field-remove.ts
+++ b/src/m365/spo/commands/field/field-remove.ts
@@ -19,6 +19,7 @@ interface Options extends GlobalOptions {
group?: string;
listTitle?: string;
title?: string;
+ internalName?: string;
listUrl?: string;
webUrl: string;
}
@@ -50,6 +51,7 @@ class SpoFieldRemoveCommand extends SpoCommand {
id: typeof args.options.id !== 'undefined',
group: typeof args.options.group !== 'undefined',
title: typeof args.options.title !== 'undefined',
+ internalName: typeof args.options.internalName !== 'undefined',
force: (!(!args.options.force)).toString()
});
});
@@ -75,6 +77,9 @@ class SpoFieldRemoveCommand extends SpoCommand {
{
option: '-t, --title [title]'
},
+ {
+ option: '--internalName [internalName]'
+ },
{
option: '-g, --group [group]'
},
@@ -106,7 +111,7 @@ class SpoFieldRemoveCommand extends SpoCommand {
}
#initOptionSets(): void {
- this.optionSets.push({ options: ['id', 'title', 'group'] });
+ this.optionSets.push({ options: ['id', 'title', 'internalName', 'group'] });
}
public async commandAction(logger: Logger, args: CommandArgs): Promise {
@@ -191,7 +196,8 @@ class SpoFieldRemoveCommand extends SpoCommand {
}
else {
try {
- await removeField(listRestUrl, args.options.id, args.options.title);
+ const columnName: string | undefined = args.options.title ? args.options.title : args.options.internalName;
+ await removeField(listRestUrl, args.options.id, columnName);
// REST post call doesn't return anything
}
catch (err: any) {
@@ -204,7 +210,7 @@ class SpoFieldRemoveCommand extends SpoCommand {
await prepareRemoval();
}
else {
- const confirmMessage: string = `Are you sure you want to remove the ${args.options.group ? 'fields' : 'field'} ${args.options.id || args.options.title || 'from group ' + args.options.group} ${messageEnd}?`;
+ const confirmMessage: string = `Are you sure you want to remove the ${args.options.group ? 'fields' : 'field'} ${args.options.id || args.options.title || args.options.internalName || 'from group ' + args.options.group} ${messageEnd}?`;
const result = await cli.promptForConfirmation({ message: confirmMessage });
diff --git a/src/m365/spo/commands/field/field-set.spec.ts b/src/m365/spo/commands/field/field-set.spec.ts
index adeb18a8efd..4a87e64672c 100644
--- a/src/m365/spo/commands/field/field-set.spec.ts
+++ b/src/m365/spo/commands/field/field-set.spec.ts
@@ -76,7 +76,7 @@ describe(commands.FIELD_SET, () => {
it('updates site column specified by title', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
if (opts.headers &&
opts.headers['X-RequestDigest'] !== 'ABC') {
throw 'Invalid request';
@@ -112,9 +112,47 @@ describe(commands.FIELD_SET, () => {
assert(loggerLogSpy.notCalled);
});
+ it('updates site column specified by internalName', async () => {
+ sinon.stub(request, 'post').callsFake(async (opts) => {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
+ if (opts.headers &&
+ opts.headers['X-RequestDigest'] !== 'ABC') {
+ throw 'Invalid request';
+ }
+
+ if (opts.data === `MyColumn`) {
+ return JSON.stringify([{
+ "SchemaVersion": "15.0.0.0",
+ "LibraryVersion": "16.0.8231.1213",
+ "ErrorInfo": null,
+ "TraceCorrelationId": "7c0aa19e-1058-0000-37ae-14170affbedb"
+ }, 664, {
+ "IsNull": false
+ }, 665, {
+ "_ObjectType_": "SP.FieldText",
+ "_ObjectIdentity_": "7c0aa19e-1058-0000-37ae-14170affbedb|740c6a0b-85e2-48a0-a494-e0f1759d4aa7:site:ff7a8065-9120-4c0a-982a-163ab9014179:web:e781d3dc-238d-44f7-8724-5e3e9eabcd6e:field:5d021339-4d62-4fe9-9d2a-c99bc56a157a"
+ }]);
+ }
+
+ if (opts.data === `My columnfalse`) {
+ return JSON.stringify([
+ {
+ "SchemaVersion": "15.0.0.0", "LibraryVersion": "16.0.8231.1213", "ErrorInfo": null, "TraceCorrelationId": "b909a19e-5020-0000-37ae-17f800b4ea4c"
+ }
+ ]);
+ }
+ }
+
+ throw 'Invalid request';
+ });
+
+ await command.action(logger, { options: { webUrl: 'https://contoso.sharepoint.com', internalName: 'MyColumn', Description: 'My column' } });
+ assert(loggerLogSpy.notCalled);
+ });
+
it('updates site column specified by id, pushing the changes to existing lists', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
if (opts.headers &&
opts.headers['X-RequestDigest'] !== 'ABC') {
throw 'Invalid request';
@@ -151,7 +189,7 @@ describe(commands.FIELD_SET, () => {
it('updates list column specified by id, list specified by id', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
if (opts.headers &&
opts.headers['X-RequestDigest'] !== 'ABC') {
throw 'Invalid request';
@@ -204,7 +242,7 @@ describe(commands.FIELD_SET, () => {
it('updates list column specified by title, list specified by title', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
if (opts.headers &&
opts.headers['X-RequestDigest'] !== 'ABC') {
throw 'Invalid request';
@@ -254,6 +292,58 @@ describe(commands.FIELD_SET, () => {
await command.action(logger, { options: { debug: true, webUrl: 'https://contoso.sharepoint.com', listTitle: 'My List', title: 'MyColumn', Description: 'My column' } });
});
+ it('updates list column specified by internalName, list specified by title', async () => {
+ sinon.stub(request, 'post').callsFake(async (opts) => {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
+ if (opts.headers &&
+ opts.headers['X-RequestDigest'] !== 'ABC') {
+ throw 'Invalid request';
+ }
+
+ if (opts.data === `My List`) {
+ return JSON.stringify([{
+ "SchemaVersion": "15.0.0.0",
+ "LibraryVersion": "16.0.8231.1213",
+ "ErrorInfo": null,
+ "TraceCorrelationId": "270fa19e-f0f7-0000-37ae-1733ad1b6703"
+ }, 664, {
+ "IsNull": false
+ }, 665, {
+ "_ObjectType_": "SP.List",
+ "_ObjectIdentity_": "270fa19e-f0f7-0000-37ae-1733ad1b6703|740c6a0b-85e2-48a0-a494-e0f1759d4aa7:site:ff7a8065-9120-4c0a-982a-163ab9014179:web:e781d3dc-238d-44f7-8724-5e3e9eabcd6e:list:03cef05c-ba50-4dcf-a876-304f0626085c",
+ "_ObjectVersion_": "6"
+ }]);
+ }
+
+ if (opts.data === `MyColumn`) {
+ return JSON.stringify([{
+ "SchemaVersion": "15.0.0.0",
+ "LibraryVersion": "16.0.8231.1213",
+ "ErrorInfo": null,
+ "TraceCorrelationId": "7c0aa19e-1058-0000-37ae-14170affbedb"
+ }, 664, {
+ "IsNull": false
+ }, 665, {
+ "_ObjectType_": "SP.FieldText",
+ "_ObjectIdentity_": "fe0ea19e-7022-0000-37ae-1357e77e046c|740c6a0b-85e2-48a0-a494-e0f1759d4aa7:site:ff7a8065-9120-4c0a-982a-163ab9014179:web:e781d3dc-238d-44f7-8724-5e3e9eabcd6e:list:03cef05c-ba50-4dcf-a876-304f0626085c:field:5d021339-4d62-4fe9-9d2a-c99bc56a157a"
+ }]);
+ }
+
+ if (opts.data === `My columnfalse`) {
+ return JSON.stringify([
+ {
+ "SchemaVersion": "15.0.0.0", "LibraryVersion": "16.0.8231.1213", "ErrorInfo": null, "TraceCorrelationId": "b909a19e-5020-0000-37ae-17f800b4ea4c"
+ }
+ ]);
+ }
+ }
+
+ throw 'Invalid request';
+ });
+
+ await command.action(logger, { options: { debug: true, webUrl: 'https://contoso.sharepoint.com', listTitle: 'My List', internalName: 'MyColumn', Description: 'My column' } });
+ });
+
it('updates list column specified by name, list specified by url', async () => {
const webUrl = 'https://contoso.sharepoint.com';
const listUrl = '/lists/TestList';
@@ -309,9 +399,64 @@ describe(commands.FIELD_SET, () => {
await command.action(logger, { options: { debug: true, webUrl: webUrl, listUrl: listUrl, title: 'MyColumn', Description: 'My column Description' } });
});
+ it('updates list column specified by internalName, list specified by url', async () => {
+ const webUrl = 'https://contoso.sharepoint.com';
+ const listUrl = '/lists/TestList';
+ const listServerRelativeUrl: string = urlUtil.getServerRelativePath(webUrl, listUrl);
+ sinon.stub(request, 'post').callsFake(async (opts) => {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
+ if (opts.headers &&
+ opts.headers['X-RequestDigest'] !== 'ABC') {
+ throw 'Invalid request';
+ }
+
+ if (opts.data === `${listServerRelativeUrl}`) {
+ return JSON.stringify([{
+ "SchemaVersion": "15.0.0.0",
+ "LibraryVersion": "16.0.8231.1213",
+ "ErrorInfo": null,
+ "TraceCorrelationId": "270fa19e-f0f7-0000-37ae-1733ad1b6703"
+ }, 664, {
+ "IsNull": false
+ }, 665, {
+ "_ObjectType_": "SP.List",
+ "_ObjectIdentity_": "270fa19e-f0f7-0000-37ae-1733ad1b6703|740c6a0b-85e2-48a0-a494-e0f1759d4aa7:site:ff7a8065-9120-4c0a-982a-163ab9014179:web:e781d3dc-238d-44f7-8724-5e3e9eabcd6e:list:03cef05c-ba50-4dcf-a876-304f0626085c",
+ "_ObjectVersion_": "6"
+ }]);
+ }
+
+ if (opts.data === `MyColumn`) {
+ return JSON.stringify([{
+ "SchemaVersion": "15.0.0.0",
+ "LibraryVersion": "16.0.8231.1213",
+ "ErrorInfo": null,
+ "TraceCorrelationId": "7c0aa19e-1058-0000-37ae-14170affbedb"
+ }, 664, {
+ "IsNull": false
+ }, 665, {
+ "_ObjectType_": "SP.FieldText",
+ "_ObjectIdentity_": "fe0ea19e-7022-0000-37ae-1357e77e046c|740c6a0b-85e2-48a0-a494-e0f1759d4aa7:site:ff7a8065-9120-4c0a-982a-163ab9014179:web:e781d3dc-238d-44f7-8724-5e3e9eabcd6e:list:03cef05c-ba50-4dcf-a876-304f0626085c:field:5d021339-4d62-4fe9-9d2a-c99bc56a157a"
+ }]);
+ }
+
+ if (opts.data === `My column Descriptionfalse`) {
+ return JSON.stringify([
+ {
+ "SchemaVersion": "15.0.0.0", "LibraryVersion": "16.0.8231.1213", "ErrorInfo": null, "TraceCorrelationId": "b909a19e-5020-0000-37ae-17f800b4ea4c"
+ }
+ ]);
+ }
+ }
+
+ throw 'Invalid request';
+ });
+
+ await command.action(logger, { options: { debug: true, webUrl: webUrl, listUrl: listUrl, internalName: 'MyColumn', Description: 'My column Description' } });
+ });
+
it('correctly escapes XML in list title', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
if (opts.headers &&
opts.headers['X-RequestDigest'] !== 'ABC') {
throw 'Invalid request';
@@ -363,7 +508,7 @@ describe(commands.FIELD_SET, () => {
it('ignores global options when creating request data', async () => {
const postStub: Sinon.SinonStub = sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
if (opts.headers &&
opts.headers['X-RequestDigest'] !== 'ABC') {
throw 'Invalid request';
@@ -416,7 +561,7 @@ describe(commands.FIELD_SET, () => {
it('correctly escapes XML in field title', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
if (opts.headers &&
opts.headers['X-RequestDigest'] !== 'abc') {
throw 'Invalid request';
@@ -452,9 +597,47 @@ describe(commands.FIELD_SET, () => {
assert(loggerLogSpy.notCalled);
});
+ it('correctly escapes XML in field internalName', async () => {
+ sinon.stub(request, 'post').callsFake(async (opts) => {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
+ if (opts.headers &&
+ opts.headers['X-RequestDigest'] !== 'abc') {
+ throw 'Invalid request';
+ }
+
+ if (opts.data === `MyColumn>`) {
+ return JSON.stringify([{
+ "SchemaVersion": "15.0.0.0",
+ "LibraryVersion": "16.0.8231.1213",
+ "ErrorInfo": null,
+ "TraceCorrelationId": "7c0aa19e-1058-0000-37ae-14170affbedb"
+ }, 664, {
+ "IsNull": false
+ }, 665, {
+ "_ObjectType_": "SP.FieldText",
+ "_ObjectIdentity_": "7c0aa19e-1058-0000-37ae-14170affbedb|740c6a0b-85e2-48a0-a494-e0f1759d4aa7:site:ff7a8065-9120-4c0a-982a-163ab9014179:web:e781d3dc-238d-44f7-8724-5e3e9eabcd6e:field:5d021339-4d62-4fe9-9d2a-c99bc56a157a"
+ }]);
+ }
+
+ if (opts.data === `My columnfalse`) {
+ return JSON.stringify([
+ {
+ "SchemaVersion": "15.0.0.0", "LibraryVersion": "16.0.8231.1213", "ErrorInfo": null, "TraceCorrelationId": "b909a19e-5020-0000-37ae-17f800b4ea4c"
+ }
+ ]);
+ }
+ }
+
+ throw 'Invalid request';
+ });
+
+ await assert.rejects(command.action(logger, { options: { webUrl: 'https://contoso.sharepoint.com', internalName: 'MyColumn>', Description: 'My column' } }));
+ assert(loggerLogSpy.notCalled);
+ });
+
it('correctly escapes XML in field properties', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
if (opts.headers &&
opts.headers['X-RequestDigest'] !== 'abc') {
throw 'Invalid request';
@@ -492,7 +675,7 @@ describe(commands.FIELD_SET, () => {
it('correctly handles an error when the field specified by id doesn\'t exist', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
if (opts.headers &&
opts.headers['X-RequestDigest'] !== 'ABC') {
throw 'Invalid request';
@@ -523,7 +706,7 @@ describe(commands.FIELD_SET, () => {
it('correctly handles an error when the field specified by title doesn\'t exist', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
if (opts.headers &&
opts.headers['X-RequestDigest'] !== 'ABC') {
throw 'Invalid request';
@@ -552,9 +735,40 @@ describe(commands.FIELD_SET, () => {
new CommandError(`Column 'MyColumn' does not exist. It may have been deleted by another user.`));
});
+ it('correctly handles an error when the field specified by internalName doesn\'t exist', async () => {
+ sinon.stub(request, 'post').callsFake(async (opts) => {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
+ if (opts.headers &&
+ opts.headers['X-RequestDigest'] !== 'ABC') {
+ throw 'Invalid request';
+ }
+
+ if (opts.data === `MyColumn`) {
+ return JSON.stringify([{
+ "SchemaVersion": "15.0.0.0",
+ "LibraryVersion": "16.0.8231.1213",
+ "ErrorInfo": {
+ "ErrorMessage": "Column 'MyColumn' does not exist. It may have been deleted by another user.",
+ "ErrorValue": null,
+ "TraceCorrelationId": "4c0fa19e-b007-0000-37ae-1d177693b378",
+ "ErrorCode": -2147024809,
+ "ErrorTypeName": "System.ArgumentException"
+ },
+ "TraceCorrelationId": "4c0fa19e-b007-0000-37ae-1d177693b378"
+ }]);
+ }
+ }
+
+ throw 'Invalid request';
+ });
+
+ await assert.rejects(command.action(logger, { options: { webUrl: 'https://contoso.sharepoint.com', internalName: 'MyColumn', Description: 'My column' } } as any),
+ new CommandError(`Column 'MyColumn' does not exist. It may have been deleted by another user.`));
+ });
+
it('correctly handles an error when the list specified by id doesn\'t exist', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
if (opts.headers &&
opts.headers['X-RequestDigest'] !== 'ABC') {
throw 'Invalid request';
@@ -585,7 +799,7 @@ describe(commands.FIELD_SET, () => {
it('correctly handles an error when the list specified by title doesn\'t exist', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
if (opts.headers &&
opts.headers['X-RequestDigest'] !== 'ABC') {
throw 'Invalid request';
@@ -616,7 +830,7 @@ describe(commands.FIELD_SET, () => {
it('correctly handles an error when updating the field failed', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
- if ((opts.url as string).indexOf(`/_vti_bin/client.svc/ProcessQuery`) > -1) {
+ if (opts.url === 'https://contoso.sharepoint.com/_vti_bin/client.svc/ProcessQuery') {
if (opts.headers &&
opts.headers['X-RequestDigest'] !== 'ABC') {
throw 'Invalid request';
@@ -669,7 +883,7 @@ describe(commands.FIELD_SET, () => {
assert.notStrictEqual(actual, true);
});
- it('fails validation if neither id nor title are specified', async () => {
+ it('fails validation if either id, title, or internalName are not specified', async () => {
sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => {
if (settingName === settingsNames.prompt) {
return false;
@@ -695,6 +909,45 @@ describe(commands.FIELD_SET, () => {
assert.notStrictEqual(actual, true);
});
+ it('fails validation if both id and internalName are specified', async () => {
+ sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => {
+ if (settingName === settingsNames.prompt) {
+ return false;
+ }
+
+ return defaultValue;
+ });
+
+ const actual = await command.validate({ options: { webUrl: 'https://contoso.sharepoint.com', id: '330f29c5-5c4c-465f-9f4b-7903020ae1ce', internalName: 'MyColumn' } }, commandInfo);
+ assert.notStrictEqual(actual, true);
+ });
+
+ it('fails validation if both title and internalName are specified', async () => {
+ sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => {
+ if (settingName === settingsNames.prompt) {
+ return false;
+ }
+
+ return defaultValue;
+ });
+
+ const actual = await command.validate({ options: { webUrl: 'https://contoso.sharepoint.com', title: 'MyColumn', internalName: 'MyColumn' } }, commandInfo);
+ assert.notStrictEqual(actual, true);
+ });
+
+ it('fails validation if id, title and internalName are specified', async () => {
+ sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => {
+ if (settingName === settingsNames.prompt) {
+ return false;
+ }
+
+ return defaultValue;
+ });
+
+ const actual = await command.validate({ options: { webUrl: 'https://contoso.sharepoint.com', id: '330f29c5-5c4c-465f-9f4b-7903020ae1ce', title: 'MyColumn', internalName: 'MyColumn' } }, commandInfo);
+ assert.notStrictEqual(actual, true);
+ });
+
it('fails validation if id is specified and is not a valid GUID', async () => {
const actual = await command.validate({ options: { webUrl: 'https://contoso.sharepoint.com', id: 'invalid' } }, commandInfo);
assert.notStrictEqual(actual, true);
@@ -720,6 +973,11 @@ describe(commands.FIELD_SET, () => {
assert.strictEqual(actual, true);
});
+ it('passes validation when webUrl, listId and internalName are specified', async () => {
+ const actual = await command.validate({ options: { webUrl: 'https://contoso.sharepoint.com', listId: '330f29c5-5c4c-465f-9f4b-7903020ae1ce', internalName: 'MyColumn' } }, commandInfo);
+ assert.strictEqual(actual, true);
+ });
+
it('passes validation when webUrl, listTitle and id are specified', async () => {
const actual = await command.validate({ options: { webUrl: 'https://contoso.sharepoint.com', listTitle: 'My List', id: '330f29c5-5c4c-465f-9f4b-7903020ae1ce' } }, commandInfo);
assert.strictEqual(actual, true);
diff --git a/src/m365/spo/commands/field/field-set.ts b/src/m365/spo/commands/field/field-set.ts
index f95eeb0f7f1..64fd67f10e8 100644
--- a/src/m365/spo/commands/field/field-set.ts
+++ b/src/m365/spo/commands/field/field-set.ts
@@ -16,6 +16,7 @@ interface CommandArgs {
interface Options extends GlobalOptions {
id?: string;
title?: string;
+ internalName?: string;
listId?: string;
listTitle?: string;
listUrl?: string;
@@ -46,6 +47,7 @@ class SpoFieldSetCommand extends SpoCommand {
Object.assign(this.telemetryProperties, {
id: typeof args.options.id !== 'undefined',
title: typeof args.options.title !== 'undefined',
+ internalName: typeof args.options.internalName !== 'undefined',
listId: typeof args.options.listId !== 'undefined',
listTitle: typeof args.options.listTitle !== 'undefined',
listUrl: typeof args.options.listUrl !== 'undefined',
@@ -74,6 +76,9 @@ class SpoFieldSetCommand extends SpoCommand {
{
option: '-t, --title [title]'
},
+ {
+ option: '--internalName [internalName]'
+ },
{
option: '--updateExistingLists'
}
@@ -109,7 +114,7 @@ class SpoFieldSetCommand extends SpoCommand {
}
#initOptionSets(): void {
- this.optionSets.push({ options: ['id', 'title'] });
+ this.optionSets.push({ options: ['id', 'title', 'internalName'] });
}
public allowUnknownOptions(): boolean | undefined {
@@ -158,7 +163,7 @@ class SpoFieldSetCommand extends SpoCommand {
// retrieve column CSOM object id
const fieldQuery: string = args.options.id ?
`${formatting.escapeXml(args.options.id)}` :
- `${formatting.escapeXml(args.options.name || args.options.title)}`;
+ `${formatting.escapeXml(args.options.name || args.options.title || args.options.internalName)}`;
let requestOptions: CliRequestOptions = {
url: `${args.options.webUrl}/_vti_bin/client.svc/ProcessQuery`,
@@ -206,6 +211,7 @@ class SpoFieldSetCommand extends SpoCommand {
'listUrl',
'id',
'title',
+ 'internalName',
'updateExistingLists',
'debug',
'verbose',