diff --git a/templates/nodejs/doc/api/api_doc.md.mustache b/templates/nodejs/doc/api/api_doc.md.mustache index e7746965..72cea7c7 100644 --- a/templates/nodejs/doc/api/api_doc.md.mustache +++ b/templates/nodejs/doc/api/api_doc.md.mustache @@ -25,7 +25,8 @@ All URIs are relative to *{{basePath}}* | Name | Type | Required | Description | | ------------- | ------------- | ------------- | ------------- |{{/-last}}{{/allParams}} {{#allParams}} | **{{paramName}}** | {{#isPrimitiveType}}**{{#isFile}}string \| Readable \| Buffer{{/isFile}}{{^isFile}}{{dataType}}{{/isFile}}**{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isContainer}}**{{dataType}}**{{/isContainer}}{{#isFile}}**{{dataType}}**{{/isFile}}{{^isFile}}{{^isContainer}}[**{{dataType}}**](../model/{{baseType}}.md){{/isContainer}}{{/isFile}}{{/isPrimitiveType}}| {{#required}}**yes**{{/required}}{{^required}}no{{/required}}| {{description}} | -{{/allParams}}{{#vendorExtensions.x-client-chunk-upload}}| **progressListener** | **(event: UploadProgressEvent) => void \| undefined** | no | Optional upload progress listener |{{/vendorExtensions.x-client-chunk-upload}} +{{/allParams}}{{#vendorExtensions.x-client-chunk-upload}}| **progressListener** | **(event: UploadProgressEvent) => void \| undefined** | no | Optional upload progress listener |{{/vendorExtensions.x-client-chunk-upload}}{{#vendorExtensions.x-client-copy-from-response}} +| **{{paramName}}** | **string \| undefined** | no | Optional {{paramName}} |{{/vendorExtensions.x-client-copy-from-response}} ### Return type diff --git a/templates/nodejs/src/api/api.ts.mustache b/templates/nodejs/src/api/api.ts.mustache index f2c36aed..feb8d567 100644 --- a/templates/nodejs/src/api/api.ts.mustache +++ b/templates/nodejs/src/api/api.ts.mustache @@ -41,16 +41,18 @@ export default class {{classname}} { {{#summary}} * {{&summary}} * This will create a progressive upload session.{{/summary}}{{#allParams}}{{^isFile}} - * @param {{paramName}} {{description}}{{/isFile}}{{/allParams}} + * @param {{paramName}} {{description}}{{/isFile}}{{/allParams}}{{#vendorExtensions.x-client-copy-from-response}} + * @param {{paramName}} optional {{paramName}} value{{/vendorExtensions.x-client-copy-from-response}} */ - public create{{#titlecase}}{{nickname}}{{/titlecase}}ProgressiveSession({{#allParams}}{{^isFile}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}{{#vendorExtensions.x-optional-object}} = {}{{/vendorExtensions.x-optional-object}}{{^-last}}, {{/-last}}{{/isFile}}{{/allParams}}): ProgressiveSession<{{{returnType}}}> { + public create{{#titlecase}}{{nickname}}{{/titlecase}}ProgressiveSession({{#allParams}}{{^isFile}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}{{#vendorExtensions.x-optional-object}} = {}{{/vendorExtensions.x-optional-object}}{{^-last}}, {{/-last}}{{/isFile}}{{/allParams}}{{#vendorExtensions.x-client-copy-from-response}} {{paramName}}?: string, {{/vendorExtensions.x-client-copy-from-response}}): ProgressiveSession<{{{returnType}}}> { class {{#titlecase}}{{nickname}}{{/titlecase}}ProgressiveSession { private httpClient: HttpClient; private currentPart = 1;{{#vendorExtensions.x-client-copy-from-response}} private {{paramName}}?: string;{{/vendorExtensions.x-client-copy-from-response}} - constructor(httpClient: HttpClient) { - this.httpClient = httpClient; + constructor(httpClient: HttpClient{{#vendorExtensions.x-client-copy-from-response}}, {{paramName}}?: string{{/vendorExtensions.x-client-copy-from-response}}) { + this.httpClient = httpClient;{{#vendorExtensions.x-client-copy-from-response}} + this.{{paramName}} = {{paramName}};{{/vendorExtensions.x-client-copy-from-response}} } uploadPart(file: string, progressListener?: (event: UploadProgressEvent) => void) { @@ -174,7 +176,7 @@ export default class {{classname}} { } } - return new {{#titlecase}}{{nickname}}{{/titlecase}}ProgressiveSession<{{{returnType}}}>(this.httpClient); + return new {{#titlecase}}{{nickname}}{{/titlecase}}ProgressiveSession<{{{returnType}}}>(this.httpClient{{#vendorExtensions.x-client-copy-from-response}}, {{paramName}}{{/vendorExtensions.x-client-copy-from-response}}); } {{/vendorExtensions.x-client-chunk-upload}} {{#vendorExtensions.x-group-parameters}} @@ -204,10 +206,15 @@ export default class {{classname}} { * @param {{paramName}} {{description}} {{/allParams}} */ - public async {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{#isFile}}{{#vendorExtensions.x-client-chunk-upload}}string{{/vendorExtensions.x-client-chunk-upload}}{{^vendorExtensions.x-client-chunk-upload}}string | Readable | Buffer{{/vendorExtensions.x-client-chunk-upload}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}}{{#vendorExtensions.x-optional-object}} = {}{{/vendorExtensions.x-optional-object}}{{^-last}}, {{/-last}}{{/allParams}}{{#vendorExtensions.x-client-chunk-upload}}, progressListener?: (event: UploadProgressEvent) => void{{/vendorExtensions.x-client-chunk-upload}}): Promise<{{#returnType}}{{{returnType}}}{{/returnType}} {{^returnType}}void{{/returnType}}> { + public async {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{#isFile}}{{#vendorExtensions.x-client-chunk-upload}}string{{/vendorExtensions.x-client-chunk-upload}}{{^vendorExtensions.x-client-chunk-upload}}string | Readable | Buffer{{/vendorExtensions.x-client-chunk-upload}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}}{{#vendorExtensions.x-optional-object}} = {}{{/vendorExtensions.x-optional-object}}{{^-last}}, {{/-last}}{{/allParams}}{{#vendorExtensions.x-client-chunk-upload}}, progressListener?: (event: UploadProgressEvent) => void, {{/vendorExtensions.x-client-chunk-upload}}{{#vendorExtensions.x-client-copy-from-response}}{{paramName}}?: string, {{/vendorExtensions.x-client-copy-from-response}}): Promise<{{#returnType}}{{{returnType}}}{{/returnType}} {{^returnType}}void{{/returnType}}> { {{/vendorExtensions.x-group-parameters}} const queryParams: QueryOptions = {}; queryParams.headers = {}; + {{#vendorExtensions.x-client-chunk-upload}} + const toRelay: { [key: string]: string | undefined } = { + {{#vendorExtensions.x-client-copy-from-response}}{{paramName}}, {{/vendorExtensions.x-client-copy-from-response}} + }; + {{/vendorExtensions.x-client-chunk-upload}} {{#allParams}} {{#required}} {{^isFile}} @@ -301,8 +308,20 @@ export default class {{classname}} { {{#hasFormParams}} const formData = new FormData(); - {{/hasFormParams}} + + {{/hasFormParams}}{{#vendorExtensions.x-client-copy-from-response}} + Object.keys(toRelay).forEach((key) => { + if (toRelay[key] !== undefined) { + formData.append(key, toRelay[key]); + } + }); + {{/vendorExtensions.x-client-copy-from-response}} {{#formParams}} + {{#vendorExtensions.x-client-copy-from-response}} + if ({{paramName}}) { + formData.append('{{paramName}}', {{paramName}}); + } + {{/vendorExtensions.x-client-copy-from-response}} {{#isArray}} if ({{paramName}}) { {{#isCollectionFormatMulti}} @@ -316,7 +335,6 @@ export default class {{classname}} { } {{/isArray}} {{^isArray}} - {{^isFile}} if (typeof {{paramName}} !== undefined) { formData.append('{{baseName}}', {{paramName}}); @@ -362,7 +380,7 @@ export default class {{classname}} { ) as {{{returnType}}}); } let uploadChunkSize = chunkSize; - let lastBody; + let lastBody: {{{returnType}}} | undefined = undefined; let stream; let chunkNumber = 0; @@ -383,6 +401,12 @@ export default class {{classname}} { stream = createReadStream(file, { start: offset, end: uploadChunkSize + offset - 1}); chunkFormData.append(filename, stream, filename); + Object.keys(toRelay).forEach((key) => { + if (toRelay[key] !== undefined) { + chunkFormData.append(key, toRelay[key]); + } + }); + queryParams.body = chunkFormData; queryParams.headers['Content-Range'] = `part ${part}/${partsCount}`; part++; @@ -407,6 +431,12 @@ export default class {{classname}} { "{{{returnType}}}", "{{returnFormat}}" ) as {{{returnType}}}); + Object.keys(toRelay).forEach((key) => { + if ((lastBody as unknown as any)[key] !== undefined) { + toRelay[key] = (lastBody as unknown as any)[key]; + } + }); + stream.close(); } diff --git a/templates/php/src/VideoUploader.php b/templates/php/src/VideoUploader.php index 3b63bcef..1141fc42 100644 --- a/templates/php/src/VideoUploader.php +++ b/templates/php/src/VideoUploader.php @@ -53,7 +53,8 @@ public function uploadWithUploadToken(string $token, \SplFileObject $file, strin return $this->execute( '/upload?token='.$token, $file, - $this->getChunkSize($contentRange) + $this->getChunkSize($contentRange), + $videoId ); } @@ -65,14 +66,13 @@ public function uploadWithUploadToken(string $token, \SplFileObject $file, strin * @return Video * @throws ClientExceptionInterface */ - private function execute(string $path, \SplFileObject $file, int $chunkSize): Video + private function execute(string $path, \SplFileObject $file, int $chunkSize, string $videoId = null): Video { $start = 0; $fileSize = filesize($file->getRealPath()); $handle = fopen($file->getRealPath(), 'r'); $response = null; - $videoId = null; $part = 1; $partsCount = ceil($fileSize / $chunkSize); diff --git a/templates/php/statics/.github/workflows/test.yml b/templates/php/statics/.github/workflows/test.yml index 998f124c..ece4cdd4 100644 --- a/templates/php/statics/.github/workflows/test.yml +++ b/templates/php/statics/.github/workflows/test.yml @@ -13,11 +13,11 @@ jobs: - name: Install dependancies uses: php-actions/composer@v5 with: - php_version: 7.3 + php_version: 8.1 - name: PHPUnit tests uses: php-actions/phpunit@v2 env: API_KEY: ${{ secrets.API_KEY }} BASE_URI: https://sandbox.api.video with: - args: tests \ No newline at end of file + args: tests --log-junit output.xml \ No newline at end of file diff --git a/templates/php/tests/Api/VideosApiTest.php b/templates/php/tests/Api/VideosApiTest.php index cf820177..ef16e55b 100644 --- a/templates/php/tests/Api/VideosApiTest.php +++ b/templates/php/tests/Api/VideosApiTest.php @@ -258,6 +258,33 @@ public function testUploadThumbnail() $this->assertEquals('thumbnail.jpg', basename($video->getAssets()->getThumbnail())); } + public function testUploadWithUploadTokenWithVideoId() + { + $token = (new Helper($this->client))->createUploadToken(); + + $video = $this->client->videos()->create((new VideoCreationPayload()) + ->setTitle('Test video creation') + ->setDescription('Test description')); + + // No authorization needed for this endpoint + $client = new Client( + $_ENV['BASE_URI'], + null, + new Psr18Client() + ); + + $uploadedVideo = $client->videos()->uploadWithUploadToken( + $token->getToken(), + new SplFileObject(__DIR__ . '/../resources/558k.mp4'), + null, + $video->getVideoId() + ); + + $this->client->uploadTokens()->deleteToken($token->getToken()); + + $this->assertNotNull($uploadedVideo->getAssets()->getPlayer()); + } + public function testUploadWithUploadToken() { $token = (new Helper($this->client))->createUploadToken(); @@ -274,6 +301,8 @@ public function testUploadWithUploadToken() new SplFileObject(__DIR__ . '/../resources/558k.mp4') ); + $this->client->uploadTokens()->deleteToken($token->getToken()); + $this->assertNotNull($uploadedVideo->getAssets()->getPlayer()); } }